Options
All
  • Public
  • Public/Protected
  • All
Menu

@chocolatesoup/joiful-dynamodb

Index

Classes

Variables

Functions Class Decorators

Functions Property Decorators

Variables

defaultDynamoDBDocumentClient: DynamoDBDocumentClient = ...

Class Decorators Functions

  • table(name: string, opts?: TableOptions): (constructor: Function) => void
  • Sets the dynamodb table and its document client for this class.

    example
    @table('test-table')
    class Model extends Entity {
    }

    const model = new Model({ attr1: '1', attr2: '2' });
    model.create(); // This will create the record in the 'test-table' DynamoDB table.

    Parameters

    • name: string

      The DynamoDB table name to which records of this classe should be saved to and retrieved from.

    • Optional opts: TableOptions

    Returns (constructor: Function) => void

      • (constructor: Function): void
      • Parameters

        • constructor: Function

        Returns void

Property Decorators Functions

  • aliasTo(propertyName: string): (target: any, alias: string) => void
  • Sets the decorated property as an alias of another property.

    remarks

    Once the aliasTo decorator is set on an Entity Class model property, the instance, the setters and getters will be set and both variables will be linked.

    example
    class Model extends Entity {
    myProperty number;

    @aliasTo('myProperty')
    aliasProperty: number;
    }

    const model = new Model({
    aliasProperty: 1;
    })

    console.log(model.myProperty) // 1
    console.log(model.aliasProperty) // 1

    model.myProperty = 2;

    console.log(model.myProperty) // 2
    console.log(model.aliasProperty) // 2

    model.aliasProperty = 3;

    console.log(model.myProperty) // 3
    console.log(model.aliasProperty) // 3

    Parameters

    • propertyName: string

    Returns (target: any, alias: string) => void

      • (target: any, alias: string): void
      • Parameters

        • target: any
        • alias: string

        Returns void

  • aliases(aliasesNames: string[]): (target: any, propertyKey: string) => void
  • Sets a list of aliases for the decorated property.

    remarks

    Once the aliases decorator is set on an Entity Class model property, the instance will have getters and setters of each of the aliases.

    example
    class Model extends Entity {
    @aliases(['alias1', 'alias2'])
    myProperty number;
    }

    const model = new Model({
    alias1: 1,
    });

    console.log(model.myProperty) // 1
    console.log(model.alias1) // 1
    console.log(model.alias2) // 1

    model.myProperty = 2;

    console.log(model.myProperty) // 2
    console.log(model.alias1) // 2
    console.log(model.alias2) // 2

    model.alias2 = 3;

    console.log(model.myProperty) // 3
    console.log(model.alias1) // 3
    console.log(model.alias2) // 3

    Parameters

    • aliasesNames: string[]

      A list of aliases for the current property.

    Returns (target: any, propertyKey: string) => void

      • (target: any, propertyKey: string): void
      • Parameters

        • target: any
        • propertyKey: string

        Returns void

  • compositeKey(fields: string[], opts?: CompositeKeyOptions): (target: any, propertyKey: string) => void
  • Transforms the decoratored property into a combination of other properties separated by a specific delimiter.

    example
    class Model extends Entity {
    @compositeKey(['field1', 'field2'])
    compositeProperty: string;

    @prop()
    field1: string;

    @prop()
    field2: string;
    }

    const model = new Model({ field1: 'part1', field2: 'part2' });

    console.log(model.compositeProperty) // undefined;
    console.log(model.field1) // 'part1'
    console.log(model.field2) // 'part2'

    console.log(model.transformedAttributes) // { compositeProperty: 'part1#part2', field1: 'part1', field2: 'part2' }

    Parameters

    • fields: string[]

      An ordered list containing the name of the properties to be combined. The combination will be done in this order.

    • Optional opts: CompositeKeyOptions

    Returns (target: any, propertyKey: string) => void

      • (target: any, propertyKey: string): void
      • Parameters

        • target: any
        • propertyKey: string

        Returns void

  • hasMany(ChildModel: any, opts?: RelationOpts): (target: any, propertyName: string) => void
  • Sets the decorated property an array of another entity.

    remarks
    • When the hasMany is set on the parent with a foreignKey AND indexName, automatically, when querying the child with related records, it will bring the parent record too.
    example
    import * as Joi from 'joi';

    class ChildModel extends Entity {
    @prop()
    @validate(Joi.string().required())
    pk: string;

    @prop()
    sk: string;

    @prop()
    fk: string;
    }

    class ParentModel extends Entity {
    @prop({ primaryKey: true })
    pk: string;

    @hasMany(ChildModel, { nestedObject: false, required: true, foreignKey: 'fk', indexName: 'byFK' })
    children: ChildModel[];
    }

    const parent = new ParentModel({
    pk: '1',
    });

    console.log(parent.children) // []

    console.log(parent.valid) // false # As children is set as required, it is invalid as it has no children now..

    parent.children = [new ChildModel({
    pk: 'pk-from-child-1',
    sk: 'sk-from-child-1',
    }), new ChildModel({
    sk: 'sk-from-child-2',
    })]

    console.log(parent.children[0].pk) // 'pk-from-child-1'
    console.log(parent.children[0].sk) // 'sk-from-child-1'

    console.log(parent.children[1].pk) // undefined
    console.log(parent.children[1].sk) // 'sk-from-child-2'

    console.log(parent.valid) // false # As the second child is invalid, parent is also invalid.

    parent.children[1].pk = 'pk-from-child-2';

    console.log(parent.children[1].pk) // 'pk-from-child-2'
    console.log(parent.children[1].sk) // 'sk-from-child-2'

    console.log(parent.transformedAttributes) // # The children attributes do not appear in the attributes because they will become new records.

    console.log(parent.valid) // true # As now all children are valid, the parent is also valid.

    parent.create() // This will insert 3 records in the database. The parent and each of the children. All of them will have fk column set to 'ParentModel-1'

    Parameters

    • ChildModel: any

      The class of which the property should be an array of instances of. This class needs to extend the Entity class.

    • Optional opts: RelationOpts

    Returns (target: any, propertyName: string) => void

      • (target: any, propertyName: string): void
      • Parameters

        • target: any
        • propertyName: string

        Returns void

  • hasOne(ChildModel: any, opts?: RelationOpts): (target: any, propertyName: string) => void
  • Sets the decorated property as another entity.

    remarks
    • Besides validations and setting the child instance, it also creates getters and setters for all child instances in the parent. Look example for more details.
    • When the hasOne is set on the parent with a foreignKey AND indexName, automatically, when querying the child with related records, it will bring the parent record too.
    example
    import * as Joi from 'joi';

    class ChildModel extends Entity {
    @prop()
    @validate(Joi.string().required())
    pk: string;

    @prop()
    sk: string;

    @prop()
    fk: string;
    }

    class ParentModel extends Entity {
    @prop({ primaryKey: true })
    pk: string;

    @hasOne(ChildModel, { nestedObject: true, required: true })
    child1: ChildModel;

    @hasOne(ChildModel, { nestedObject: false, required: false, foreignKey: 'fk' })
    child2: ChildModel;
    }

    const parent = new ParentModel({
    pk: '1',
    child1: {
    pk: 'pk-from-child-1',
    sk: 'sk-from-child-1',
    },
    child2Sk: 'sk-from-child-2',
    });

    console.log(parent.child1.pk) // 'pk-from-child-1'
    console.log(parent.child1.sk) // 'sk-from-child-1'
    console.log(parent.child1Pk) // 'pk-from-child-1'
    console.log(parent.child1Sk) // 'sk-from-child-1'

    console.log(parent.child2.pk) // undefined
    console.log(parent.child2.sk) // 'sk-from-child-2'
    console.log(parent.child2Pk) // undefined
    console.log(parent.child2Sk) // 'sk-from-child-2'

    parent.child2.pk = 'pk-from-child-2';

    console.log(parent.child2.pk) // 'pk-from-child-2'
    console.log(parent.child2.sk) // 'sk-from-child-2'
    console.log(parent.child2Pk) // 'pk-from-child-2'
    console.log(parent.child2Sk) // 'sk-from-child-2'

    console.log(parent.transformedAttributes) // { child1: { pk: 'pk-from-child-1', sk: 'sk-from-child-1' } } # The child2 does not appear in the attributes because it will become a new record.

    console.log(parent.valid) // false # As child 2 is invalid, parent is invalid also.

    model.child2 = undefined;

    console.log(parent.valid) // true # As child 2 is not required, parent is valid.

    model.child1 = undefined;

    console.log(parent.valid) // false # As child 1 is required, the parent is invalid.

    parent.create() // This will insert 2 records in the database. The parent and the child 2. Both will have the property fk set to 'ParentModel-1'

    Parameters

    • ChildModel: any

      The class of which the property should be an instance of. This class needs to extend the Entity class.

    • Optional opts: RelationOpts

    Returns (target: any, propertyName: string) => void

      • (target: any, propertyName: string): void
      • Parameters

        • target: any
        • propertyName: string

        Returns void

  • prop(opts?: PropOptions): (target: any, propertyName: string) => void
  • Sets the decorated property as a mapped property of the Entity setting its setters and getters (this is important for the attribute mapping for inserting in the database). Besides this, all the parameters initialized with the entity model will have the correct setters and getters. You can also set some properties as primaryKeys, secondaryKeys, createdAt or updatedAt.

    example
    class Model extends Entity {
    @prop({ primaryKey: true })
    property1: string;

    @prop({ secondaryKey: true })
    property2: string;

    @prop({ createdAt: true })
    cAt: string;

    @prop({ updatedAt: true })
    uAt: string;
    }

    const model = new Model({
    property1: '1',
    property2: '2',
    cAt: '3',
    uAt: '4',
    extraAttribute: '5',
    });

    console.log(model.property1) // '1'
    console.log(model.property2) // '2'
    console.log(model.cAt) // '3'
    console.log(model.uAt) // '4'
    console.log(model.extraAttribute) // '5'

    model.property1 = 'changed1';
    console.log(model.property1) // 'changed1';

    model.property2 = 'changed2';
    console.log(model.property2) // 'changed2';

    model.cAt = 'changed3';
    console.log(model.cAt) // 'changed3';

    model.uAt = 'changed4';
    console.log(model.uAt) // 'changed4';

    model.extraAttribute = 'changed5';
    console.log(model.extraAttribute) // 'changed5';

    model.extraAttribute2 = 'changed6'; // ERROR: the setter does not exist!

    console.log(model._primaryKey) // 'property1';
    console.log(model._secondaryKey) // 'property2';
    console.log(model._createdAtKey) // 'cAt';
    console.log(model._updatedAtKey) // 'uAt';

    model.create(); // In the database it will be saved like this: { property1: 'Model-changed1', property2: 'Model-changed2', cAt: '2022-02-07T16:16:44.975Z', uAt: '2022-02-07T16:16:44.975Z', extraAttribute: 'changed5' };

    Parameters

    • Optional opts: PropOptions

    Returns (target: any, propertyName: string) => void

      • (target: any, propertyName: string): void
      • Parameters

        • target: any
        • propertyName: string

        Returns void

  • validate(joi: Schema<any>): (target: any, propertyKey?: string) => void
  • Adds validation to the decorated property or decorated Entity using Joi validation library.

    remarks

    If you are setting the decorated Entity it NEEDS to be of Joi.object() type. Remember that if you set a new validation object in the Entitiy itself you need to add the .unknown(true) if you want to accept any attribute.

    example
    import * as Joi from 'joi';

    @validate(Joi.object().unknown(true).and('attribute1', 'attribute2'))
    class Model extends Entity {
    @validate(Joi.string().required().trim())
    pk: string;

    @validate(Joi.string().trim())
    sk: string;

    @validate(Joi.string())
    attribute1: string;

    @validate(Joi.string())
    attribute2: string;
    }

    const model = new Model({ pk: '1' });

    console.log(model.valid) // true

    model.sk = '2'
    console.log(model.valid) // true

    model.pk = undefined;
    console.log(model.valid) // false

    model.pk = ' 1 2 ';
    console.log(model.validatedAttributes) // { pk: '1 2', sk: '2' } # The joi transfromation happens when validating but doesn't change the original attributes. But the transformed attributes are the ones used on save.

    model.attribute1 = '1'
    console.log(model.valid) // false # It is invalid because of the entity level validation with the Joi.object().and()

    model.attribute2 = '2'
    console.log(model.valid) // true # It is now valid because it passes the Joi.object().and() validation.

    Parameters

    • joi: Schema<any>

      The Joi validation schema.

    Returns (target: any, propertyKey?: string) => void

      • (target: any, propertyKey?: string): void
      • Parameters

        • target: any
        • Optional propertyKey: string

        Returns void

Generated using TypeDoc