Class defaultAbstract

Serves as an abstract base class for entities in the ORM system. It defines standard fields such as id, type, createdAt, and updatedAt, and provides static methods for CRUD operations and queries. This class encapsulates common behaviors and properties that all entities share, leveraging decorators for attribute metadata and supporting operations like finding, creating, updating, and deleting entities.

Table classes should extend this class, and each entity should extend the table class

Entities extending DynaRecord can utilize these operations to interact with their corresponding records in the database, including handling relationships between different entities.

@Table({ name: "my-table" })
abstract class MyTable extends DynaRecord {
@PartitionKeyAttribute()
public readonly pk: PartitionKey;

@SortKeyAttribute()
public readonly sk: SortKey;
}

@Entity
class User extends MyTable {
declare readonly type: "User";
// User implementation
}

Implements

Constructors

Properties

createdAt: Date

The timestamp marking when the entity was created

id: string

A unique identifier for the entity itself, automatically generated upon creation.

type: string

The type of the entity. Set automatically to the class name at runtime.

Each entity must narrow this field to a string literal matching the class name via declare readonly type: "ClassName". This enables compile-time type safety for query filters and return type narrowing.

updatedAt: Date

The timestamp marking the last update to the entity. Initially set to the same value as createdAt.

Methods

  • Get the partition key for an entity

    Returns string

    The partition key of the entity

  • Same as the static update method but on an instance. Returns the full updated instance.

    For @ObjectAttribute fields, the returned instance deep merges the partial update with the existing object value — omitted fields are preserved, and fields set to null are removed.

    Type Parameters

    Parameters

    Returns Promise<EntityInstance<T>>

    const updatedInstance = await instance.update({ email: "newemail@example.com", profileId: 789 });
    
    const updatedInstance = await instance.update({ email: "newemail@example.com", someKey: null });
    
    // instance.address is { street: "123 Main", city: "Springfield", zip: 12345 }
    const updated = await instance.update({ address: { street: "456 Oak Ave" } });
    // updated.address is { street: "456 Oak Ave", city: "Springfield", zip: 12345 }
    const updatedInstance = await instance.update(
    { email: "newemail@example.com", profileId: 789 },
    { referentialIntegrityCheck: false }
    );
  • Create an entity. If foreign keys are included in the attributes then links will be denormalized accordingly

    Type Parameters

    Parameters

    • this: EntityClass<T>
    • attributes: CreateOptions<T>

      Attributes of the model to create

    • Optionaloptions: { referentialIntegrityCheck?: boolean }

      Optional operation options including referentialIntegrityCheck flag

    Returns Promise<Promise<EntityAttributesOnly<T>>>

    The new Entity

    const newUser = await User.create({ name: "Alice", email: "alice@example.com", profileId: "123" });
    
    const newUser = await User.create(
    { name: "Alice", email: "alice@example.com", profileId: "123" },
    { referentialIntegrityCheck: false }
    );
  • Delete an entity by ID

    • Delete all denormalized records
    • Disassociate all foreign keys of linked models

    Type Parameters

    Parameters

    • this: EntityClass<T>
    • id: string

      The id of the entity to update

    Returns Promise<void>

    await User.delete("userId");
    
  • Find an entity by Id and optionally include associations.

    Type Parameters

    Parameters

    • this: EntityClass<T>
    • id: string

      Entity Id.

    • Optionaloptions: undefined

      No options provided, returns the entity without included associations.

    Returns Promise<Optional<EntityInstance<T>>>

    An entity without included associations serialized.

    const user = await User.findById("userId");
    

    const user = await User.findById("userId", { include: [{ association: "profile" }] });
    
  • Find an entity by Id and optionally include associations.

    Type Parameters

    Parameters

    Returns Promise<Optional<FindByIdIncludesRes<T, Inc>>>

    An entity without included associations serialized.

    const user = await User.findById("userId");
    

    const user = await User.findById("userId", { include: [{ association: "profile" }] });
    
  • Returns serialized table metadata containing only serializable values. This method returns a plain object representation of the table metadata, with functions, class instances, and other non-serializable data converted to their string representations or omitted.

    Returns {
        defaultAttributes: Record<
            string,
            {
                alias: string;
                foreignKeyTarget?: string;
                name: string;
                nullable: boolean;
            },
        >;
        defaultTableAttributes: Record<
            string,
            {
                alias: string;
                foreignKeyTarget?: string;
                name: string;
                nullable: boolean;
            },
        >;
        delimiter: string;
        entities: Record<
            string,
            {
                attributes: Record<
                    string,
                    {
                        alias: string;
                        foreignKeyTarget?: string;
                        name: string;
                        nullable: boolean;
                    },
                >;
                idField?: string;
                relationships: Record<
                    string,
                    {
                        foreignKey?: string;
                        joinTableName?: string;
                        propertyName: string;
                        target?: string;
                        type: string;
                        uniDirectional?: boolean;
                    },
                >;
                tableAttributes: Record<
                    string,
                    {
                        alias: string;
                        foreignKeyTarget?: string;
                        name: string;
                        nullable: boolean;
                    },
                >;
                tableClassName: string;
            },
        >;
        name: string;
        partitionKeyAttribute: {
            alias: string;
            foreignKeyTarget?: string;
            name: string;
            nullable: boolean;
        };
        sortKeyAttribute: {
            alias: string;
            foreignKeyTarget?: string;
            name: string;
            nullable: boolean;
        };
    }

    A plain object representation of the table metadata

    const metadata = User.metadata();
    // Returns a serialized object with all metadata information
  • Constructs the partition key value

    Parameters

    • id: string

      Entity Id

    Returns string

    Constructed partition key value

    const pkValue = User.partitionKeyValue("userId");
    
  • Query an EntityPartition by EntityId (string) or by PartitionKey/SortKey conditions (object). QueryByIndex not supported with this overload. Use Query with keys and indexName option if needed.

    Filter key validation: Filter keys are strongly typed to only accept valid attribute names from the entity and its declared relationships (@HasMany, @HasOne, @BelongsTo, @HasAndBelongsToMany). The type field only accepts the entity itself or its related entity names — entities from other tables or unrelated entities are rejected. When type is specified as a single value in a $or block, filter keys are narrowed to that entity's attributes.

    Sort key validation: Both skCondition (string form) and sk (object key form) only accept the entity itself or its related entity names, matching dyna-record's single-table sort key format where SK values always start with an entity class name. Unrelated entities and entities from other tables are rejected at compile time.

    SK-scoped filter: When skCondition narrows to specific entities, the filter parameter is scoped to only those entities' attributes. For example, skCondition: { $beginsWith: "Order" } restricts the filter to Order's attributes — using attributes from other entities (e.g., lastFour from PaymentMethod) produces a compile error.

    $beginsWith prefix matching: $beginsWith accepts partial entity name prefixes that match multiple entity types. For example, $beginsWith: "Inv" matches both "Invoice" and "Inventory". The return type and filter are scoped to the union of all matching entities.

    Return type narrowing: The return type narrows automatically based on:

    • Top-level filter type: type: "Order"Array<EntityAttributesInstance<Order>>
    • Top-level filter type array: type: ["Order", "PaymentMethod"] → union of both
    • Top-level filter keys: { orderDate: "2023" } → narrows to entities that have orderDate
    • $or elements: each block narrows by type (if present) or by filter keys; return type is the union
    • AND intersection: when top-level conditions and $or both narrow, the return type is their intersection. Empty intersection → never[].
    • skCondition option: always intersected with filter narrowing. skCondition: "Order" or { $beginsWith: "Order" } → narrows to Order. { $beginsWith: "Inv" } → narrows to all entities starting with "Inv".
    • No type/keys/SK specified → union of T and all related entities (e.g., Customer | Order | PaymentMethod | ContactInformation)

    Note: When using the object key form ({ pk: "...", sk: "Order" }), the sk value is validated against entity names but does not narrow the return type due to a TypeScript inference limitation. Use filter: { type: "Order" } or the skCondition option for return type narrowing.

    Type Parameters

    Parameters

    • this: EntityClass<T>
    • key: string

      Entity Id (string) or an object with PartitionKey and optional SortKey conditions.

    • Optionaloptions: Omit<QueryOptions, "filter" | "indexName" | "skCondition"> & {
          filter?: SKScopedFilterParams<T, SK>;
      } & { filter?: F; skCondition?: SK }

      QueryOptions. Supports typed filter, consistentRead and skCondition. indexName is not supported.

      • filter

        Typed filter conditions. Keys are validated against partition entity attributes, scoped by skCondition when present. The type field accepts valid entity class names within the SK scope.

      • skCondition

        Sort key condition. Accepts entity names, entity-name-prefixed strings, or $beginsWith with exact names or partial prefixes. Narrows the return type and scopes the filter to matched entities.

      • Optionalfilter?: SKScopedFilterParams<T, SK>

        Typed filter conditions. Keys are validated against partition entity attributes, scoped by skCondition when present. The type field accepts valid entity class names within the SK scope.

      • Optionalfilter?: F

        Typed filter conditions. Keys are validated against partition entity attributes, scoped by skCondition when present. The type field accepts valid entity class names within the SK scope.

      • OptionalskCondition?: SK

        Sort key condition. Accepts entity names, entity-name-prefixed strings, or $beginsWith with exact names or partial prefixes. Narrows the return type and scopes the filter to matched entities.

    Returns Promise<InferQueryResults<T, F, SK>>

    A promise resolving to query results. The return type narrows based on the filter's type value, filter keys, and skCondition.

    const results = await Customer.query("123");
    
    const orders = await Customer.query("123", { skCondition: "Order" });
    // orders is Array<EntityAttributesInstance<Order>>
    const orders = await Customer.query("123", { skCondition: { $beginsWith: "Order" } });
    // orders is Array<EntityAttributesInstance<Order>>
    const results = await Customer.query("123", { skCondition: { $beginsWith: "C" } });
    // results includes Customer and ContactInformation (both start with "C")
    // filter accepts attributes from both entities
    const orders = await Customer.query("123", {
    skCondition: { $beginsWith: "Order" },
    filter: { type: "Order", orderDate: "2023-01-01" }
    });
    // orders is Array<EntityAttributesInstance<Order>>
    // filter: { lastFour: "1234" } would be a compile error (PaymentMethod attribute)
    const results = await Customer.query({ pk: "Customer#123", sk: "Order" });
    // results is QueryResults<Customer> — use filter type for narrowing
    const orders = await Customer.query(
    { pk: "Customer#123", sk: { $beginsWith: "Order" } },
    { filter: { type: "Order" } }
    );
    // orders is Array<EntityAttributesInstance<Order>>
    const results = await Customer.query("123", { consistentRead: true });
    
  • Query an EntityPartition by EntityId (string) or by PartitionKey/SortKey conditions (object). QueryByIndex not supported with this overload. Use Query with keys and indexName option if needed.

    Filter key validation: Filter keys are strongly typed to only accept valid attribute names from the entity and its declared relationships (@HasMany, @HasOne, @BelongsTo, @HasAndBelongsToMany). The type field only accepts the entity itself or its related entity names — entities from other tables or unrelated entities are rejected. When type is specified as a single value in a $or block, filter keys are narrowed to that entity's attributes.

    Sort key validation: Both skCondition (string form) and sk (object key form) only accept the entity itself or its related entity names, matching dyna-record's single-table sort key format where SK values always start with an entity class name. Unrelated entities and entities from other tables are rejected at compile time.

    SK-scoped filter: When skCondition narrows to specific entities, the filter parameter is scoped to only those entities' attributes. For example, skCondition: { $beginsWith: "Order" } restricts the filter to Order's attributes — using attributes from other entities (e.g., lastFour from PaymentMethod) produces a compile error.

    $beginsWith prefix matching: $beginsWith accepts partial entity name prefixes that match multiple entity types. For example, $beginsWith: "Inv" matches both "Invoice" and "Inventory". The return type and filter are scoped to the union of all matching entities.

    Return type narrowing: The return type narrows automatically based on:

    • Top-level filter type: type: "Order"Array<EntityAttributesInstance<Order>>
    • Top-level filter type array: type: ["Order", "PaymentMethod"] → union of both
    • Top-level filter keys: { orderDate: "2023" } → narrows to entities that have orderDate
    • $or elements: each block narrows by type (if present) or by filter keys; return type is the union
    • AND intersection: when top-level conditions and $or both narrow, the return type is their intersection. Empty intersection → never[].
    • skCondition option: always intersected with filter narrowing. skCondition: "Order" or { $beginsWith: "Order" } → narrows to Order. { $beginsWith: "Inv" } → narrows to all entities starting with "Inv".
    • No type/keys/SK specified → union of T and all related entities (e.g., Customer | Order | PaymentMethod | ContactInformation)

    Note: When using the object key form ({ pk: "...", sk: "Order" }), the sk value is validated against entity names but does not narrow the return type due to a TypeScript inference limitation. Use filter: { type: "Order" } or the skCondition option for return type narrowing.

    Type Parameters

    Parameters

    • this: EntityClass<T>
    • key: EntityKeyConditions<T>

      Entity Id (string) or an object with PartitionKey and optional SortKey conditions.

    • Optionaloptions: Omit<OptionsWithoutIndex<T>, "skCondition"> & { filter?: F }

      QueryOptions. Supports typed filter, consistentRead and skCondition. indexName is not supported.

      • filter

        Typed filter conditions. Keys are validated against partition entity attributes, scoped by skCondition when present. The type field accepts valid entity class names within the SK scope.

      • skCondition

        Sort key condition. Accepts entity names, entity-name-prefixed strings, or $beginsWith with exact names or partial prefixes. Narrows the return type and scopes the filter to matched entities.

      • Optionalfilter?: F

        Typed filter conditions. Keys are validated against partition entity attributes, scoped by skCondition when present. The type field accepts valid entity class names within the SK scope.

    Returns Promise<InferQueryResults<T, F>>

    A promise resolving to query results. The return type narrows based on the filter's type value, filter keys, and skCondition.

    const results = await Customer.query("123");
    
    const orders = await Customer.query("123", { skCondition: "Order" });
    // orders is Array<EntityAttributesInstance<Order>>
    const orders = await Customer.query("123", { skCondition: { $beginsWith: "Order" } });
    // orders is Array<EntityAttributesInstance<Order>>
    const results = await Customer.query("123", { skCondition: { $beginsWith: "C" } });
    // results includes Customer and ContactInformation (both start with "C")
    // filter accepts attributes from both entities
    const orders = await Customer.query("123", {
    skCondition: { $beginsWith: "Order" },
    filter: { type: "Order", orderDate: "2023-01-01" }
    });
    // orders is Array<EntityAttributesInstance<Order>>
    // filter: { lastFour: "1234" } would be a compile error (PaymentMethod attribute)
    const results = await Customer.query({ pk: "Customer#123", sk: "Order" });
    // results is QueryResults<Customer> — use filter type for narrowing
    const orders = await Customer.query(
    { pk: "Customer#123", sk: { $beginsWith: "Order" } },
    { filter: { type: "Order" } }
    );
    // orders is Array<EntityAttributesInstance<Order>>
    const results = await Customer.query("123", { consistentRead: true });
    
  • Query by PartitionKey and optional SortKey/Filter/Index conditions with an index When querying on an index, any of the entities attributes can be part of the key condition

    Type Parameters

    Parameters

    • this: EntityClass<T>
    • key: IndexKeyConditions<T>

      Any attribute defined on the entity that is part of an index's keys

    • options: { consistentRead?: undefined; filter?: FilterParams; indexName: string }

      QueryBuilderOptions

    Returns Promise<QueryResults<T>>

     const result = await User.query(
    {
    name: "SomeName" // An attribute that is part of the key condition on an index
    },
    { indexName: "myIndex" }
    );
  • Update an entity. If foreign keys are included in the attributes then:

    • Manages associated relationship links as needed
    • If the entity already had a foreign key relationship, then denormalized records will be deleted from each partition
    • Validation errors will be thrown if the attribute being removed is not nullable

    Type Parameters

    Parameters

    Returns Promise<void>

    await User.update("userId", { email: "newemail@example.com", profileId: 789 });
    
    await User.update("userId", { email: "newemail@example.com", someKey: null });
    
    await User.update(
    "userId",
    { email: "newemail@example.com", profileId: 789 },
    { referentialIntegrityCheck: false }
    );
    await User.update("userId", { address: { street: "456 Oak Ave" } });