@twin.org/entity 0.0.3 → 0.0.4-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/decorators/entityDecorator.js +2 -1
- package/dist/es/decorators/entityDecorator.js.map +1 -1
- package/dist/es/models/IEntitySchema.js.map +1 -1
- package/dist/es/models/IEntitySchemaOptions.js.map +1 -1
- package/dist/es/models/IEntitySchemaProperty.js.map +1 -1
- package/dist/es/utils/entitySchemaHelper.js +21 -0
- package/dist/es/utils/entitySchemaHelper.js.map +1 -1
- package/dist/types/models/IEntitySchema.d.ts +1 -5
- package/dist/types/models/IEntitySchemaOptions.d.ts +4 -0
- package/dist/types/models/IEntitySchemaProperty.d.ts +4 -0
- package/dist/types/utils/entitySchemaHelper.d.ts +10 -0
- package/docs/changelog.md +229 -0
- package/docs/reference/classes/EntitySchemaHelper.md +32 -0
- package/docs/reference/interfaces/IEntitySchema.md +26 -6
- package/docs/reference/interfaces/IEntitySchemaOptions.md +12 -0
- package/docs/reference/interfaces/IEntitySchemaProperty.md +8 -0
- package/locales/en.json +2 -1
- package/package.json +5 -5
|
@@ -13,7 +13,8 @@ export function entity(options) {
|
|
|
13
13
|
return (target) => {
|
|
14
14
|
const entitySchema = DecoratorHelper.getSchema(target);
|
|
15
15
|
entitySchema.type = target.name;
|
|
16
|
-
entitySchema.
|
|
16
|
+
entitySchema.description = options?.description;
|
|
17
|
+
entitySchema.version = options?.version;
|
|
17
18
|
DecoratorHelper.setSchema(target, entitySchema);
|
|
18
19
|
};
|
|
19
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entityDecorator.js","sourceRoot":"","sources":["../../../src/decorators/entityDecorator.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,uDAAuD;AACvD,OAAO,kBAAkB,CAAC;AAC1B,OAAO,OAAO,CAAC;AAEf,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,OAA8B;IACpD,OAAO,CAAC,MAAW,EAAE,EAAE;QACtB,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACvD,YAAY,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QAChC,YAAY,CAAC,OAAO,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"entityDecorator.js","sourceRoot":"","sources":["../../../src/decorators/entityDecorator.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,uDAAuD;AACvD,OAAO,kBAAkB,CAAC;AAC1B,OAAO,OAAO,CAAC;AAEf,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,OAA8B;IACpD,OAAO,CAAC,MAAW,EAAE,EAAE;QACtB,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACvD,YAAY,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QAChC,YAAY,CAAC,WAAW,GAAG,OAAO,EAAE,WAAW,CAAC;QAChD,YAAY,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC;QAExC,eAAe,CAAC,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjD,CAAC,CAAC;AACH,CAAC","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport \"reflect-metadata\";\nimport \"tslib\";\nimport type { IEntitySchemaOptions } from \"../models/IEntitySchemaOptions.js\";\nimport { DecoratorHelper } from \"../utils/decoratorHelper.js\";\n\n/**\n * Decorator to produce schema data for entity.\n * @param options The options for the entity.\n * @returns The class decorator.\n */\nexport function entity(options?: IEntitySchemaOptions): any {\n\treturn (target: any) => {\n\t\tconst entitySchema = DecoratorHelper.getSchema(target);\n\t\tentitySchema.type = target.name;\n\t\tentitySchema.description = options?.description;\n\t\tentitySchema.version = options?.version;\n\n\t\tDecoratorHelper.setSchema(target, entitySchema);\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IEntitySchema.js","sourceRoot":"","sources":["../../../src/models/IEntitySchema.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IEntitySchemaOptions } from \"./IEntitySchemaOptions.js\";\nimport type { IEntitySchemaProperty } from \"./IEntitySchemaProperty.js\";\n\n/**\n * Definition for an entity schema.\n */\nexport interface IEntitySchema<T = unknown> {\n\t/**\n\t * The type of the entity.\n\t */\n\ttype: string | undefined;\n\n\t/**\n\t * The
|
|
1
|
+
{"version":3,"file":"IEntitySchema.js","sourceRoot":"","sources":["../../../src/models/IEntitySchema.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IEntitySchemaOptions } from \"./IEntitySchemaOptions.js\";\nimport type { IEntitySchemaProperty } from \"./IEntitySchemaProperty.js\";\n\n/**\n * Definition for an entity schema.\n */\nexport interface IEntitySchema<T = unknown> extends IEntitySchemaOptions {\n\t/**\n\t * The type of the entity.\n\t */\n\ttype: string | undefined;\n\n\t/**\n\t * The properties of the entity.\n\t */\n\tproperties?: IEntitySchemaProperty<T>[];\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IEntitySchemaOptions.js","sourceRoot":"","sources":["../../../src/models/IEntitySchemaOptions.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Definition for an entity schema options.\n */\nexport interface IEntitySchemaOptions {\n\t/**\n\t * Description of the object.\n\t */\n\tdescription?: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"IEntitySchemaOptions.js","sourceRoot":"","sources":["../../../src/models/IEntitySchemaOptions.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Definition for an entity schema options.\n */\nexport interface IEntitySchemaOptions {\n\t/**\n\t * Description of the object.\n\t */\n\tdescription?: string;\n\n\t/**\n\t * The schema version. Used to drive ordered migrations. Absent is treated as version 0.\n\t */\n\tversion?: number;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IEntitySchemaProperty.js","sourceRoot":"","sources":["../../../src/models/IEntitySchemaProperty.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { EntitySchemaPropertyFormat } from \"./entitySchemaPropertyFormat.js\";\nimport type { EntitySchemaPropertyType } from \"./entitySchemaPropertyType.js\";\nimport type { SortDirection } from \"./sortDirection.js\";\n\n/**\n * Definition for an entity schema property.\n */\nexport interface IEntitySchemaProperty<T = unknown> {\n\t/**\n\t * The property name from the entity.\n\t */\n\tproperty: keyof T;\n\n\t/**\n\t * The type of the property.\n\t */\n\ttype: EntitySchemaPropertyType;\n\n\t/**\n\t * The format of the property.\n\t */\n\tformat?: EntitySchemaPropertyFormat;\n\n\t/**\n\t * Is this the primary index property.\n\t */\n\tisPrimary?: boolean;\n\n\t/**\n\t * Is this a secondary index property.\n\t */\n\tisSecondary?: boolean;\n\n\t/**\n\t * Default sort direction for this field, leave empty if not sortable.\n\t */\n\tsortDirection?: SortDirection;\n\n\t/**\n\t * Is the property optional.\n\t */\n\toptional?: boolean;\n\n\t/**\n\t * The type of the item (only applies when type is `array`).\n\t */\n\titemType?: EntitySchemaPropertyType;\n\n\t/**\n\t * The type ref of the item (only applies when type is either `array` or `object`).\n\t */\n\titemTypeRef?: string;\n\n\t/**\n\t * Description of the object.\n\t */\n\tdescription?: string;\n\n\t/**\n\t * Examples of the property values.\n\t */\n\texamples?: unknown[];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"IEntitySchemaProperty.js","sourceRoot":"","sources":["../../../src/models/IEntitySchemaProperty.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { EntitySchemaPropertyFormat } from \"./entitySchemaPropertyFormat.js\";\nimport type { EntitySchemaPropertyType } from \"./entitySchemaPropertyType.js\";\nimport type { SortDirection } from \"./sortDirection.js\";\n\n/**\n * Definition for an entity schema property.\n */\nexport interface IEntitySchemaProperty<T = unknown> {\n\t/**\n\t * The property name from the entity.\n\t */\n\tproperty: keyof T;\n\n\t/**\n\t * The type of the property.\n\t */\n\ttype: EntitySchemaPropertyType;\n\n\t/**\n\t * The format of the property.\n\t */\n\tformat?: EntitySchemaPropertyFormat;\n\n\t/**\n\t * Is this the primary index property.\n\t */\n\tisPrimary?: boolean;\n\n\t/**\n\t * Is this a secondary index property.\n\t */\n\tisSecondary?: boolean;\n\n\t/**\n\t * Default sort direction for this field, leave empty if not sortable.\n\t */\n\tsortDirection?: SortDirection;\n\n\t/**\n\t * Is the property optional.\n\t */\n\toptional?: boolean;\n\n\t/**\n\t * The type of the item (only applies when type is `array`).\n\t */\n\titemType?: EntitySchemaPropertyType;\n\n\t/**\n\t * The type ref of the item (only applies when type is either `array` or `object`).\n\t */\n\titemTypeRef?: string;\n\n\t/**\n\t * Description of the object.\n\t */\n\tdescription?: string;\n\n\t/**\n\t * Examples of the property values.\n\t */\n\texamples?: unknown[];\n\n\t/**\n\t * A default value which can be used in migrations when the property value is not provided.\n\t */\n\tdefaultValue?: unknown;\n}\n"]}
|
|
@@ -19,6 +19,27 @@ export class EntitySchemaHelper {
|
|
|
19
19
|
static getSchema(target) {
|
|
20
20
|
return DecoratorHelper.getSchema(target);
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Get the version of the entity schema, defaulting to 0 when absent.
|
|
24
|
+
* This is the single source of truth for the "absent version = v0" convention.
|
|
25
|
+
* When a version is present it must be a non-negative integer >= 0.
|
|
26
|
+
* @param entitySchema The entity schema to read the version from.
|
|
27
|
+
* @returns The declared version, or 0 if no version was set.
|
|
28
|
+
* @throws GuardError if entitySchema is undefined or version is not an integer.
|
|
29
|
+
* @throws GeneralError if version is present but less than 0.
|
|
30
|
+
*/
|
|
31
|
+
static getVersion(entitySchema) {
|
|
32
|
+
Guards.object(EntitySchemaHelper.CLASS_NAME, "entitySchema", entitySchema);
|
|
33
|
+
if (!Is.empty(entitySchema?.version)) {
|
|
34
|
+
Guards.integer(EntitySchemaHelper.CLASS_NAME, "entitySchema.version", entitySchema?.version);
|
|
35
|
+
if (entitySchema.version < 0) {
|
|
36
|
+
throw new GeneralError(EntitySchemaHelper.CLASS_NAME, "versionMustBeGreaterThanOrEqualZero", {
|
|
37
|
+
version: entitySchema.version
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return entitySchema.version ?? 0;
|
|
42
|
+
}
|
|
22
43
|
/**
|
|
23
44
|
* Get the primary key from the entity schema.
|
|
24
45
|
* @param entitySchema The entity schema to find the primary key from.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entitySchemaHelper.js","sourceRoot":"","sources":["../../../src/utils/entitySchemaHelper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { GeneralError, Guards, Is } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { DecoratorHelper } from \"./decoratorHelper.js\";\nimport type { IEntitySchema } from \"../models/IEntitySchema.js\";\nimport type { IEntitySchemaProperty } from \"../models/IEntitySchemaProperty.js\";\nimport type { IEntitySort } from \"../models/IEntitySort.js\";\nimport type { SortDirection } from \"../models/sortDirection.js\";\n\n/**\n * Class to help with entity schema operations.\n */\nexport class EntitySchemaHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<EntitySchemaHelper>();\n\n\t/**\n\t * Get the schema for the specified object.\n\t * @param target The object to get the schema data for.\n\t * @returns The schema for the object if it can be found.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static getSchema<T = unknown>(target: any): IEntitySchema<T> {\n\t\treturn DecoratorHelper.getSchema<T>(target);\n\t}\n\n\t/**\n\t * Get the primary key from the entity schema.\n\t * @param entitySchema The entity schema to find the primary key from.\n\t * @returns The key if only one was found.\n\t * @throws If no primary key was found, or more than one.\n\t */\n\tpublic static getPrimaryKey<T>(entitySchema: IEntitySchema<T>): IEntitySchemaProperty<T> {\n\t\tGuards.object<IEntitySchema<T>>(\n\t\t\tEntitySchemaHelper.CLASS_NAME,\n\t\t\tnameof(entitySchema),\n\t\t\tentitySchema\n\t\t);\n\n\t\tconst primaryKeys = (entitySchema.properties ?? [])?.filter(p => p.isPrimary);\n\t\tif (primaryKeys.length === 0) {\n\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"noIsPrimary\");\n\t\t}\n\t\tif (primaryKeys.length > 1) {\n\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"multipleIsPrimary\");\n\t\t}\n\t\treturn primaryKeys[0];\n\t}\n\n\t/**\n\t * Get the sort properties from the schema.\n\t * @param entitySchema The entity schema to find the primary key from.\n\t * @returns The sort keys from the schema or undefined if there are none.\n\t */\n\tpublic static getSortProperties<T>(entitySchema: IEntitySchema<T>): IEntitySort<T>[] | undefined {\n\t\tGuards.object<IEntitySchema<T>>(\n\t\t\tEntitySchemaHelper.CLASS_NAME,\n\t\t\tnameof(entitySchema),\n\t\t\tentitySchema\n\t\t);\n\n\t\tconst sortFields = (entitySchema.properties ?? []).filter(p => !Is.undefined(p.sortDirection));\n\n\t\treturn sortFields.length > 0\n\t\t\t? sortFields.map(\n\t\t\t\t\tp =>\n\t\t\t\t\t\t({\n\t\t\t\t\t\t\tproperty: p.property,\n\t\t\t\t\t\t\ttype: p.type,\n\t\t\t\t\t\t\tsortDirection: p.sortDirection\n\t\t\t\t\t\t}) as IEntitySort<T>\n\t\t\t\t)\n\t\t\t: undefined;\n\t}\n\n\t/**\n\t * Build sort properties from the schema and override if necessary.\n\t * @param entitySchema The entity schema to retrieve the default sort keys.\n\t * @param overrideSortKeys The override sort keys.\n\t * @returns The finalised sort keys.\n\t */\n\tpublic static buildSortProperties<T>(\n\t\tentitySchema: IEntitySchema<T>,\n\t\toverrideSortKeys?: {\n\t\t\tproperty: keyof T;\n\t\t\tsortDirection: SortDirection;\n\t\t}[]\n\t): IEntitySort<T>[] | undefined {\n\t\tGuards.object(EntitySchemaHelper.CLASS_NAME, nameof(entitySchema), entitySchema);\n\n\t\tlet finalSortKeys: IEntitySort<T>[] | undefined;\n\n\t\tif (Is.arrayValue(overrideSortKeys)) {\n\t\t\tfinalSortKeys = [];\n\n\t\t\tfor (const sortKey of overrideSortKeys) {\n\t\t\t\tconst property = (entitySchema.properties ?? []).find(p => p.property === sortKey.property);\n\t\t\t\tif (property) {\n\t\t\t\t\tfinalSortKeys.push({\n\t\t\t\t\t\tproperty: sortKey.property,\n\t\t\t\t\t\tsortDirection: sortKey.sortDirection,\n\t\t\t\t\t\ttype: property.type\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfinalSortKeys = EntitySchemaHelper.getSortProperties(entitySchema);\n\t\t}\n\n\t\treturn finalSortKeys;\n\t}\n\n\t/**\n\t * Validate the entity against the schema.\n\t * @param entity The entity to validate.\n\t * @param entitySchema The schema to validate against.\n\t * @throws If the entity is invalid.\n\t */\n\tpublic static validateEntity<T>(entity: T, entitySchema: IEntitySchema<T>): void {\n\t\tGuards.object(EntitySchemaHelper.CLASS_NAME, nameof(entity), entity);\n\t\tGuards.object<IEntitySchema<T>>(\n\t\t\tEntitySchemaHelper.CLASS_NAME,\n\t\t\tnameof(entitySchema),\n\t\t\tentitySchema\n\t\t);\n\n\t\tconst properties = entitySchema.properties ?? [];\n\t\tif (properties.length === 0 && Is.objectValue(entity)) {\n\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"invalidEntityProperties\");\n\t\t}\n\n\t\tconst allKeys = Object.keys(entity);\n\n\t\tfor (const prop of properties) {\n\t\t\tconst idx = allKeys.indexOf(prop.property as string);\n\t\t\tif (idx !== -1) {\n\t\t\t\tallKeys.splice(idx, 1);\n\t\t\t}\n\n\t\t\tconst value = entity[prop.property];\n\n\t\t\tif (Is.empty(value)) {\n\t\t\t\t// If the value is empty but the property is not optional, then it's invalid\n\t\t\t\tif (!prop.optional) {\n\t\t\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"invalidOptional\", {\n\t\t\t\t\t\tproperty: prop.property,\n\t\t\t\t\t\ttype: prop.type\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (prop.type === \"integer\" && Is.integer(value)) {\n\t\t\t\t// If the schema expects an integer and the value is an integer, then it's valid\n\t\t\t} else if (\n\t\t\t\tprop.type === \"object\" &&\n\t\t\t\t(Is.object(value) ||\n\t\t\t\t\tIs.array(value) ||\n\t\t\t\t\tIs.string(value) ||\n\t\t\t\t\tIs.number(value) ||\n\t\t\t\t\tIs.boolean(value) ||\n\t\t\t\t\tIs.null(value))\n\t\t\t) {\n\t\t\t\t// If the schema expects an object and the value is anything that can be JSON serialised, then it's valid\n\t\t\t} else if (prop.type === \"array\" && Is.array(value)) {\n\t\t\t\t// If the schema expects an array and the value is an array, then it's valid\n\t\t\t} else if (prop.type !== typeof value) {\n\t\t\t\t// The schema type does not match the value type\n\t\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"invalidEntityProperty\", {\n\t\t\t\t\tvalue,\n\t\t\t\t\tproperty: prop.property,\n\t\t\t\t\ttype: prop.type\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (allKeys.length > 0) {\n\t\t\t// There are keys in the entity that are not in the schema\n\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"invalidEntityKeys\", {\n\t\t\t\tkeys: allKeys.join(\", \")\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"entitySchemaHelper.js","sourceRoot":"","sources":["../../../src/utils/entitySchemaHelper.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { GeneralError, Guards, Is } from \"@twin.org/core\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { DecoratorHelper } from \"./decoratorHelper.js\";\nimport type { IEntitySchema } from \"../models/IEntitySchema.js\";\nimport type { IEntitySchemaProperty } from \"../models/IEntitySchemaProperty.js\";\nimport type { IEntitySort } from \"../models/IEntitySort.js\";\nimport type { SortDirection } from \"../models/sortDirection.js\";\n\n/**\n * Class to help with entity schema operations.\n */\nexport class EntitySchemaHelper {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<EntitySchemaHelper>();\n\n\t/**\n\t * Get the schema for the specified object.\n\t * @param target The object to get the schema data for.\n\t * @returns The schema for the object if it can be found.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic static getSchema<T = unknown>(target: any): IEntitySchema<T> {\n\t\treturn DecoratorHelper.getSchema<T>(target);\n\t}\n\n\t/**\n\t * Get the version of the entity schema, defaulting to 0 when absent.\n\t * This is the single source of truth for the \"absent version = v0\" convention.\n\t * When a version is present it must be a non-negative integer >= 0.\n\t * @param entitySchema The entity schema to read the version from.\n\t * @returns The declared version, or 0 if no version was set.\n\t * @throws GuardError if entitySchema is undefined or version is not an integer.\n\t * @throws GeneralError if version is present but less than 0.\n\t */\n\tpublic static getVersion(entitySchema: IEntitySchema): number {\n\t\tGuards.object<IEntitySchema>(EntitySchemaHelper.CLASS_NAME, nameof(entitySchema), entitySchema);\n\n\t\tif (!Is.empty(entitySchema?.version)) {\n\t\t\tGuards.integer(\n\t\t\t\tEntitySchemaHelper.CLASS_NAME,\n\t\t\t\tnameof(entitySchema?.version),\n\t\t\t\tentitySchema?.version\n\t\t\t);\n\t\t\tif (entitySchema.version < 0) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tEntitySchemaHelper.CLASS_NAME,\n\t\t\t\t\t\"versionMustBeGreaterThanOrEqualZero\",\n\t\t\t\t\t{\n\t\t\t\t\t\tversion: entitySchema.version\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn entitySchema.version ?? 0;\n\t}\n\n\t/**\n\t * Get the primary key from the entity schema.\n\t * @param entitySchema The entity schema to find the primary key from.\n\t * @returns The key if only one was found.\n\t * @throws If no primary key was found, or more than one.\n\t */\n\tpublic static getPrimaryKey<T>(entitySchema: IEntitySchema<T>): IEntitySchemaProperty<T> {\n\t\tGuards.object<IEntitySchema<T>>(\n\t\t\tEntitySchemaHelper.CLASS_NAME,\n\t\t\tnameof(entitySchema),\n\t\t\tentitySchema\n\t\t);\n\n\t\tconst primaryKeys = (entitySchema.properties ?? [])?.filter(p => p.isPrimary);\n\t\tif (primaryKeys.length === 0) {\n\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"noIsPrimary\");\n\t\t}\n\t\tif (primaryKeys.length > 1) {\n\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"multipleIsPrimary\");\n\t\t}\n\t\treturn primaryKeys[0];\n\t}\n\n\t/**\n\t * Get the sort properties from the schema.\n\t * @param entitySchema The entity schema to find the primary key from.\n\t * @returns The sort keys from the schema or undefined if there are none.\n\t */\n\tpublic static getSortProperties<T>(entitySchema: IEntitySchema<T>): IEntitySort<T>[] | undefined {\n\t\tGuards.object<IEntitySchema<T>>(\n\t\t\tEntitySchemaHelper.CLASS_NAME,\n\t\t\tnameof(entitySchema),\n\t\t\tentitySchema\n\t\t);\n\n\t\tconst sortFields = (entitySchema.properties ?? []).filter(p => !Is.undefined(p.sortDirection));\n\n\t\treturn sortFields.length > 0\n\t\t\t? sortFields.map(\n\t\t\t\t\tp =>\n\t\t\t\t\t\t({\n\t\t\t\t\t\t\tproperty: p.property,\n\t\t\t\t\t\t\ttype: p.type,\n\t\t\t\t\t\t\tsortDirection: p.sortDirection\n\t\t\t\t\t\t}) as IEntitySort<T>\n\t\t\t\t)\n\t\t\t: undefined;\n\t}\n\n\t/**\n\t * Build sort properties from the schema and override if necessary.\n\t * @param entitySchema The entity schema to retrieve the default sort keys.\n\t * @param overrideSortKeys The override sort keys.\n\t * @returns The finalised sort keys.\n\t */\n\tpublic static buildSortProperties<T>(\n\t\tentitySchema: IEntitySchema<T>,\n\t\toverrideSortKeys?: {\n\t\t\tproperty: keyof T;\n\t\t\tsortDirection: SortDirection;\n\t\t}[]\n\t): IEntitySort<T>[] | undefined {\n\t\tGuards.object(EntitySchemaHelper.CLASS_NAME, nameof(entitySchema), entitySchema);\n\n\t\tlet finalSortKeys: IEntitySort<T>[] | undefined;\n\n\t\tif (Is.arrayValue(overrideSortKeys)) {\n\t\t\tfinalSortKeys = [];\n\n\t\t\tfor (const sortKey of overrideSortKeys) {\n\t\t\t\tconst property = (entitySchema.properties ?? []).find(p => p.property === sortKey.property);\n\t\t\t\tif (property) {\n\t\t\t\t\tfinalSortKeys.push({\n\t\t\t\t\t\tproperty: sortKey.property,\n\t\t\t\t\t\tsortDirection: sortKey.sortDirection,\n\t\t\t\t\t\ttype: property.type\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfinalSortKeys = EntitySchemaHelper.getSortProperties(entitySchema);\n\t\t}\n\n\t\treturn finalSortKeys;\n\t}\n\n\t/**\n\t * Validate the entity against the schema.\n\t * @param entity The entity to validate.\n\t * @param entitySchema The schema to validate against.\n\t * @throws If the entity is invalid.\n\t */\n\tpublic static validateEntity<T>(entity: T, entitySchema: IEntitySchema<T>): void {\n\t\tGuards.object(EntitySchemaHelper.CLASS_NAME, nameof(entity), entity);\n\t\tGuards.object<IEntitySchema<T>>(\n\t\t\tEntitySchemaHelper.CLASS_NAME,\n\t\t\tnameof(entitySchema),\n\t\t\tentitySchema\n\t\t);\n\n\t\tconst properties = entitySchema.properties ?? [];\n\t\tif (properties.length === 0 && Is.objectValue(entity)) {\n\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"invalidEntityProperties\");\n\t\t}\n\n\t\tconst allKeys = Object.keys(entity);\n\n\t\tfor (const prop of properties) {\n\t\t\tconst idx = allKeys.indexOf(prop.property as string);\n\t\t\tif (idx !== -1) {\n\t\t\t\tallKeys.splice(idx, 1);\n\t\t\t}\n\n\t\t\tconst value = entity[prop.property];\n\n\t\t\tif (Is.empty(value)) {\n\t\t\t\t// If the value is empty but the property is not optional, then it's invalid\n\t\t\t\tif (!prop.optional) {\n\t\t\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"invalidOptional\", {\n\t\t\t\t\t\tproperty: prop.property,\n\t\t\t\t\t\ttype: prop.type\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (prop.type === \"integer\" && Is.integer(value)) {\n\t\t\t\t// If the schema expects an integer and the value is an integer, then it's valid\n\t\t\t} else if (\n\t\t\t\tprop.type === \"object\" &&\n\t\t\t\t(Is.object(value) ||\n\t\t\t\t\tIs.array(value) ||\n\t\t\t\t\tIs.string(value) ||\n\t\t\t\t\tIs.number(value) ||\n\t\t\t\t\tIs.boolean(value) ||\n\t\t\t\t\tIs.null(value))\n\t\t\t) {\n\t\t\t\t// If the schema expects an object and the value is anything that can be JSON serialised, then it's valid\n\t\t\t} else if (prop.type === \"array\" && Is.array(value)) {\n\t\t\t\t// If the schema expects an array and the value is an array, then it's valid\n\t\t\t} else if (prop.type !== typeof value) {\n\t\t\t\t// The schema type does not match the value type\n\t\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"invalidEntityProperty\", {\n\t\t\t\t\tvalue,\n\t\t\t\t\tproperty: prop.property,\n\t\t\t\t\ttype: prop.type\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (allKeys.length > 0) {\n\t\t\t// There are keys in the entity that are not in the schema\n\t\t\tthrow new GeneralError(EntitySchemaHelper.CLASS_NAME, \"invalidEntityKeys\", {\n\t\t\t\tkeys: allKeys.join(\", \")\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
|
|
@@ -3,15 +3,11 @@ import type { IEntitySchemaProperty } from "./IEntitySchemaProperty.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Definition for an entity schema.
|
|
5
5
|
*/
|
|
6
|
-
export interface IEntitySchema<T = unknown> {
|
|
6
|
+
export interface IEntitySchema<T = unknown> extends IEntitySchemaOptions {
|
|
7
7
|
/**
|
|
8
8
|
* The type of the entity.
|
|
9
9
|
*/
|
|
10
10
|
type: string | undefined;
|
|
11
|
-
/**
|
|
12
|
-
* The options for the entity.
|
|
13
|
-
*/
|
|
14
|
-
options?: IEntitySchemaOptions;
|
|
15
11
|
/**
|
|
16
12
|
* The properties of the entity.
|
|
17
13
|
*/
|
|
@@ -16,6 +16,16 @@ export declare class EntitySchemaHelper {
|
|
|
16
16
|
* @returns The schema for the object if it can be found.
|
|
17
17
|
*/
|
|
18
18
|
static getSchema<T = unknown>(target: any): IEntitySchema<T>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the version of the entity schema, defaulting to 0 when absent.
|
|
21
|
+
* This is the single source of truth for the "absent version = v0" convention.
|
|
22
|
+
* When a version is present it must be a non-negative integer >= 0.
|
|
23
|
+
* @param entitySchema The entity schema to read the version from.
|
|
24
|
+
* @returns The declared version, or 0 if no version was set.
|
|
25
|
+
* @throws GuardError if entitySchema is undefined or version is not an integer.
|
|
26
|
+
* @throws GeneralError if version is present but less than 0.
|
|
27
|
+
*/
|
|
28
|
+
static getVersion(entitySchema: IEntitySchema): number;
|
|
19
29
|
/**
|
|
20
30
|
* Get the primary key from the entity schema.
|
|
21
31
|
* @param entitySchema The entity schema to find the primary key from.
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,234 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.4-next.10](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.4-next.9...entity-v0.0.4-next.10) (2026-06-15)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add context id features ([#206](https://github.com/iotaledger/twin-framework/issues/206)) ([ef0d4ee](https://github.com/iotaledger/twin-framework/commit/ef0d4ee11a4f5fc6cc6f52a4958ce905c04ee13b))
|
|
9
|
+
* add guards arrayEndsWith and arrayStartsWith ([95d875e](https://github.com/iotaledger/twin-framework/commit/95d875ec8ccb4713c145fdde941d4cfedcec2ed3))
|
|
10
|
+
* add IEntitySchemaDiff and entitySchemaDiff utility ([#282](https://github.com/iotaledger/twin-framework/issues/282)) ([9d63e94](https://github.com/iotaledger/twin-framework/commit/9d63e94021ee2ffc138004ee68cf53d08a6b17f9))
|
|
11
|
+
* add support for null in EntityConditions.compare ([922c4ba](https://github.com/iotaledger/twin-framework/commit/922c4ba8af578b4e7eaaf21b3c37a9d788941487))
|
|
12
|
+
* add version field to IEntitySchema and EntitySchemaHelper.getVersion for migration support ([#346](https://github.com/iotaledger/twin-framework/issues/346)) ([e74557e](https://github.com/iotaledger/twin-framework/commit/e74557e4ccbda5b9971f4cfcd0852ba5957cead0))
|
|
13
|
+
* entity schema decorators default value ([33397c2](https://github.com/iotaledger/twin-framework/commit/33397c2e24978a91257371a4c63ce7f6a7125d0c))
|
|
14
|
+
* entity schema diff updates ([#294](https://github.com/iotaledger/twin-framework/issues/294)) ([7a7a94d](https://github.com/iotaledger/twin-framework/commit/7a7a94d14ea5e785dd68fd6de1c5a84941721d28))
|
|
15
|
+
* eslint migration to flat config ([74427d7](https://github.com/iotaledger/twin-framework/commit/74427d78d342167f7850e49ab87269326355befe))
|
|
16
|
+
* locales validation ([#197](https://github.com/iotaledger/twin-framework/issues/197)) ([55fdadb](https://github.com/iotaledger/twin-framework/commit/55fdadb13595ce0047f787bd1d4135d429a99f12))
|
|
17
|
+
* relocate core packages from tools ([bcab8f3](https://github.com/iotaledger/twin-framework/commit/bcab8f3160442ea4fcaf442947462504f3d6a17d))
|
|
18
|
+
* support for object comparisons in entity conditions ([edae91d](https://github.com/iotaledger/twin-framework/commit/edae91d3205524080188a35e0ab04da036fa4f39))
|
|
19
|
+
* typescript 6 update ([1d10f31](https://github.com/iotaledger/twin-framework/commit/1d10f31e6516ec622773f45e88af82fe749b384a))
|
|
20
|
+
* update dependencies ([4da77ab](https://github.com/iotaledger/twin-framework/commit/4da77ab30f499e52825ac5a76f51436ceb59c26e))
|
|
21
|
+
* update dependencies ([f3bd015](https://github.com/iotaledger/twin-framework/commit/f3bd015efd169196b7e0335f5cab876ba6ca1d75))
|
|
22
|
+
* use cause instead of inner for errors ([1f4acc4](https://github.com/iotaledger/twin-framework/commit/1f4acc4d7a6b71a134d9547da9bf40de1e1e49da))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* ensure __decorate is defined for decorators ([103a563](https://github.com/iotaledger/twin-framework/commit/103a563ce01ebdef6240d2e590e7b026e8692684))
|
|
28
|
+
* update copyright year ([#260](https://github.com/iotaledger/twin-framework/issues/260)) ([c4ad930](https://github.com/iotaledger/twin-framework/commit/c4ad930fcc84ba6b5447a8074574329870b4c3f5))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Dependencies
|
|
32
|
+
|
|
33
|
+
* The following workspace dependencies were updated
|
|
34
|
+
* dependencies
|
|
35
|
+
* @twin.org/nameof bumped from 0.0.4-next.9 to 0.0.4-next.10
|
|
36
|
+
* @twin.org/core bumped from 0.0.4-next.9 to 0.0.4-next.10
|
|
37
|
+
* devDependencies
|
|
38
|
+
* @twin.org/nameof-transformer bumped from 0.0.4-next.9 to 0.0.4-next.10
|
|
39
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.9 to 0.0.4-next.10
|
|
40
|
+
* @twin.org/validate-locales bumped from 0.0.4-next.9 to 0.0.4-next.10
|
|
41
|
+
|
|
42
|
+
## [0.0.4-next.9](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.4-next.8...entity-v0.0.4-next.9) (2026-06-15)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Miscellaneous Chores
|
|
46
|
+
|
|
47
|
+
* **entity:** Synchronize repo versions
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Dependencies
|
|
51
|
+
|
|
52
|
+
* The following workspace dependencies were updated
|
|
53
|
+
* dependencies
|
|
54
|
+
* @twin.org/nameof bumped from 0.0.4-next.8 to 0.0.4-next.9
|
|
55
|
+
* @twin.org/core bumped from 0.0.4-next.8 to 0.0.4-next.9
|
|
56
|
+
* devDependencies
|
|
57
|
+
* @twin.org/nameof-transformer bumped from 0.0.4-next.8 to 0.0.4-next.9
|
|
58
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.8 to 0.0.4-next.9
|
|
59
|
+
* @twin.org/validate-locales bumped from 0.0.4-next.8 to 0.0.4-next.9
|
|
60
|
+
|
|
61
|
+
## [0.0.4-next.8](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.4-next.7...entity-v0.0.4-next.8) (2026-06-10)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### Miscellaneous Chores
|
|
65
|
+
|
|
66
|
+
* **entity:** Synchronize repo versions
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
### Dependencies
|
|
70
|
+
|
|
71
|
+
* The following workspace dependencies were updated
|
|
72
|
+
* dependencies
|
|
73
|
+
* @twin.org/nameof bumped from 0.0.4-next.7 to 0.0.4-next.8
|
|
74
|
+
* @twin.org/core bumped from 0.0.4-next.7 to 0.0.4-next.8
|
|
75
|
+
* devDependencies
|
|
76
|
+
* @twin.org/nameof-transformer bumped from 0.0.4-next.7 to 0.0.4-next.8
|
|
77
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.7 to 0.0.4-next.8
|
|
78
|
+
* @twin.org/validate-locales bumped from 0.0.4-next.7 to 0.0.4-next.8
|
|
79
|
+
|
|
80
|
+
## [0.0.4-next.7](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.4-next.6...entity-v0.0.4-next.7) (2026-06-10)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
### Miscellaneous Chores
|
|
84
|
+
|
|
85
|
+
* **entity:** Synchronize repo versions
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
### Dependencies
|
|
89
|
+
|
|
90
|
+
* The following workspace dependencies were updated
|
|
91
|
+
* dependencies
|
|
92
|
+
* @twin.org/nameof bumped from 0.0.4-next.6 to 0.0.4-next.7
|
|
93
|
+
* @twin.org/core bumped from 0.0.4-next.6 to 0.0.4-next.7
|
|
94
|
+
* devDependencies
|
|
95
|
+
* @twin.org/nameof-transformer bumped from 0.0.4-next.6 to 0.0.4-next.7
|
|
96
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.6 to 0.0.4-next.7
|
|
97
|
+
* @twin.org/validate-locales bumped from 0.0.4-next.6 to 0.0.4-next.7
|
|
98
|
+
|
|
99
|
+
## [0.0.4-next.6](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.4-next.5...entity-v0.0.4-next.6) (2026-06-05)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
### Features
|
|
103
|
+
|
|
104
|
+
* entity schema decorators default value ([33397c2](https://github.com/iotaledger/twin-framework/commit/33397c2e24978a91257371a4c63ce7f6a7125d0c))
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
### Dependencies
|
|
108
|
+
|
|
109
|
+
* The following workspace dependencies were updated
|
|
110
|
+
* dependencies
|
|
111
|
+
* @twin.org/nameof bumped from 0.0.4-next.5 to 0.0.4-next.6
|
|
112
|
+
* @twin.org/core bumped from 0.0.4-next.5 to 0.0.4-next.6
|
|
113
|
+
* devDependencies
|
|
114
|
+
* @twin.org/nameof-transformer bumped from 0.0.4-next.5 to 0.0.4-next.6
|
|
115
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.5 to 0.0.4-next.6
|
|
116
|
+
* @twin.org/validate-locales bumped from 0.0.4-next.5 to 0.0.4-next.6
|
|
117
|
+
|
|
118
|
+
## [0.0.4-next.5](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.4-next.4...entity-v0.0.4-next.5) (2026-06-04)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
### Features
|
|
122
|
+
|
|
123
|
+
* add version field to IEntitySchema and EntitySchemaHelper.getVersion for migration support ([#346](https://github.com/iotaledger/twin-framework/issues/346)) ([e74557e](https://github.com/iotaledger/twin-framework/commit/e74557e4ccbda5b9971f4cfcd0852ba5957cead0))
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
### Dependencies
|
|
127
|
+
|
|
128
|
+
* The following workspace dependencies were updated
|
|
129
|
+
* dependencies
|
|
130
|
+
* @twin.org/nameof bumped from 0.0.4-next.4 to 0.0.4-next.5
|
|
131
|
+
* @twin.org/core bumped from 0.0.4-next.4 to 0.0.4-next.5
|
|
132
|
+
* devDependencies
|
|
133
|
+
* @twin.org/nameof-transformer bumped from 0.0.4-next.4 to 0.0.4-next.5
|
|
134
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.4 to 0.0.4-next.5
|
|
135
|
+
* @twin.org/validate-locales bumped from 0.0.4-next.4 to 0.0.4-next.5
|
|
136
|
+
|
|
137
|
+
## [0.0.4-next.4](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.4-next.3...entity-v0.0.4-next.4) (2026-06-02)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
### Miscellaneous Chores
|
|
141
|
+
|
|
142
|
+
* **entity:** Synchronize repo versions
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
### Dependencies
|
|
146
|
+
|
|
147
|
+
* The following workspace dependencies were updated
|
|
148
|
+
* dependencies
|
|
149
|
+
* @twin.org/nameof bumped from 0.0.4-next.3 to 0.0.4-next.4
|
|
150
|
+
* @twin.org/core bumped from 0.0.4-next.3 to 0.0.4-next.4
|
|
151
|
+
* devDependencies
|
|
152
|
+
* @twin.org/nameof-transformer bumped from 0.0.4-next.3 to 0.0.4-next.4
|
|
153
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.3 to 0.0.4-next.4
|
|
154
|
+
* @twin.org/validate-locales bumped from 0.0.4-next.3 to 0.0.4-next.4
|
|
155
|
+
|
|
156
|
+
## [0.0.4-next.3](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.4-next.2...entity-v0.0.4-next.3) (2026-05-28)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
### Miscellaneous Chores
|
|
160
|
+
|
|
161
|
+
* **entity:** Synchronize repo versions
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
### Dependencies
|
|
165
|
+
|
|
166
|
+
* The following workspace dependencies were updated
|
|
167
|
+
* dependencies
|
|
168
|
+
* @twin.org/nameof bumped from 0.0.4-next.2 to 0.0.4-next.3
|
|
169
|
+
* @twin.org/core bumped from 0.0.4-next.2 to 0.0.4-next.3
|
|
170
|
+
* devDependencies
|
|
171
|
+
* @twin.org/nameof-transformer bumped from 0.0.4-next.2 to 0.0.4-next.3
|
|
172
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.2 to 0.0.4-next.3
|
|
173
|
+
* @twin.org/validate-locales bumped from 0.0.4-next.2 to 0.0.4-next.3
|
|
174
|
+
|
|
175
|
+
## [0.0.4-next.2](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.4-next.1...entity-v0.0.4-next.2) (2026-05-28)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
### Miscellaneous Chores
|
|
179
|
+
|
|
180
|
+
* **entity:** Synchronize repo versions
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
### Dependencies
|
|
184
|
+
|
|
185
|
+
* The following workspace dependencies were updated
|
|
186
|
+
* dependencies
|
|
187
|
+
* @twin.org/nameof bumped from 0.0.4-next.1 to 0.0.4-next.2
|
|
188
|
+
* @twin.org/core bumped from 0.0.4-next.1 to 0.0.4-next.2
|
|
189
|
+
* devDependencies
|
|
190
|
+
* @twin.org/nameof-transformer bumped from 0.0.4-next.1 to 0.0.4-next.2
|
|
191
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.1 to 0.0.4-next.2
|
|
192
|
+
* @twin.org/validate-locales bumped from 0.0.4-next.1 to 0.0.4-next.2
|
|
193
|
+
|
|
194
|
+
## [0.0.4-next.1](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.4-next.0...entity-v0.0.4-next.1) (2026-05-27)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
### Features
|
|
198
|
+
|
|
199
|
+
* add context id features ([#206](https://github.com/iotaledger/twin-framework/issues/206)) ([ef0d4ee](https://github.com/iotaledger/twin-framework/commit/ef0d4ee11a4f5fc6cc6f52a4958ce905c04ee13b))
|
|
200
|
+
* add guards arrayEndsWith and arrayStartsWith ([95d875e](https://github.com/iotaledger/twin-framework/commit/95d875ec8ccb4713c145fdde941d4cfedcec2ed3))
|
|
201
|
+
* add IEntitySchemaDiff and entitySchemaDiff utility ([#282](https://github.com/iotaledger/twin-framework/issues/282)) ([9d63e94](https://github.com/iotaledger/twin-framework/commit/9d63e94021ee2ffc138004ee68cf53d08a6b17f9))
|
|
202
|
+
* add support for null in EntityConditions.compare ([922c4ba](https://github.com/iotaledger/twin-framework/commit/922c4ba8af578b4e7eaaf21b3c37a9d788941487))
|
|
203
|
+
* entity schema diff updates ([#294](https://github.com/iotaledger/twin-framework/issues/294)) ([7a7a94d](https://github.com/iotaledger/twin-framework/commit/7a7a94d14ea5e785dd68fd6de1c5a84941721d28))
|
|
204
|
+
* eslint migration to flat config ([74427d7](https://github.com/iotaledger/twin-framework/commit/74427d78d342167f7850e49ab87269326355befe))
|
|
205
|
+
* locales validation ([#197](https://github.com/iotaledger/twin-framework/issues/197)) ([55fdadb](https://github.com/iotaledger/twin-framework/commit/55fdadb13595ce0047f787bd1d4135d429a99f12))
|
|
206
|
+
* relocate core packages from tools ([bcab8f3](https://github.com/iotaledger/twin-framework/commit/bcab8f3160442ea4fcaf442947462504f3d6a17d))
|
|
207
|
+
* support for object comparisons in entity conditions ([edae91d](https://github.com/iotaledger/twin-framework/commit/edae91d3205524080188a35e0ab04da036fa4f39))
|
|
208
|
+
* typescript 6 update ([1d10f31](https://github.com/iotaledger/twin-framework/commit/1d10f31e6516ec622773f45e88af82fe749b384a))
|
|
209
|
+
* update dependencies ([4da77ab](https://github.com/iotaledger/twin-framework/commit/4da77ab30f499e52825ac5a76f51436ceb59c26e))
|
|
210
|
+
* update dependencies ([f3bd015](https://github.com/iotaledger/twin-framework/commit/f3bd015efd169196b7e0335f5cab876ba6ca1d75))
|
|
211
|
+
* use cause instead of inner for errors ([1f4acc4](https://github.com/iotaledger/twin-framework/commit/1f4acc4d7a6b71a134d9547da9bf40de1e1e49da))
|
|
212
|
+
* use new shared store mechanism ([#131](https://github.com/iotaledger/twin-framework/issues/131)) ([934385b](https://github.com/iotaledger/twin-framework/commit/934385b2fbaf9f5c00a505ebf9d093bd5a425f55))
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
### Bug Fixes
|
|
216
|
+
|
|
217
|
+
* ensure __decorate is defined for decorators ([103a563](https://github.com/iotaledger/twin-framework/commit/103a563ce01ebdef6240d2e590e7b026e8692684))
|
|
218
|
+
* update copyright year ([#260](https://github.com/iotaledger/twin-framework/issues/260)) ([c4ad930](https://github.com/iotaledger/twin-framework/commit/c4ad930fcc84ba6b5447a8074574329870b4c3f5))
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
### Dependencies
|
|
222
|
+
|
|
223
|
+
* The following workspace dependencies were updated
|
|
224
|
+
* dependencies
|
|
225
|
+
* @twin.org/nameof bumped from 0.0.4-next.0 to 0.0.4-next.1
|
|
226
|
+
* @twin.org/core bumped from 0.0.4-next.0 to 0.0.4-next.1
|
|
227
|
+
* devDependencies
|
|
228
|
+
* @twin.org/nameof-transformer bumped from 0.0.4-next.0 to 0.0.4-next.1
|
|
229
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.4-next.0 to 0.0.4-next.1
|
|
230
|
+
* @twin.org/validate-locales bumped from 0.0.4-next.0 to 0.0.4-next.1
|
|
231
|
+
|
|
3
232
|
## [0.0.3](https://github.com/iotaledger/twin-framework/compare/entity-v0.0.3...entity-v0.0.3) (2026-05-27)
|
|
4
233
|
|
|
5
234
|
|
|
@@ -50,6 +50,38 @@ The schema for the object if it can be found.
|
|
|
50
50
|
|
|
51
51
|
***
|
|
52
52
|
|
|
53
|
+
### getVersion() {#getversion}
|
|
54
|
+
|
|
55
|
+
> `static` **getVersion**(`entitySchema`): `number`
|
|
56
|
+
|
|
57
|
+
Get the version of the entity schema, defaulting to 0 when absent.
|
|
58
|
+
This is the single source of truth for the "absent version = v0" convention.
|
|
59
|
+
When a version is present it must be a non-negative integer >= 0.
|
|
60
|
+
|
|
61
|
+
#### Parameters
|
|
62
|
+
|
|
63
|
+
##### entitySchema
|
|
64
|
+
|
|
65
|
+
[`IEntitySchema`](../interfaces/IEntitySchema.md)
|
|
66
|
+
|
|
67
|
+
The entity schema to read the version from.
|
|
68
|
+
|
|
69
|
+
#### Returns
|
|
70
|
+
|
|
71
|
+
`number`
|
|
72
|
+
|
|
73
|
+
The declared version, or 0 if no version was set.
|
|
74
|
+
|
|
75
|
+
#### Throws
|
|
76
|
+
|
|
77
|
+
GuardError if entitySchema is undefined or version is not an integer.
|
|
78
|
+
|
|
79
|
+
#### Throws
|
|
80
|
+
|
|
81
|
+
GeneralError if version is present but less than 0.
|
|
82
|
+
|
|
83
|
+
***
|
|
84
|
+
|
|
53
85
|
### getPrimaryKey() {#getprimarykey}
|
|
54
86
|
|
|
55
87
|
> `static` **getPrimaryKey**\<`T`\>(`entitySchema`): [`IEntitySchemaProperty`](../interfaces/IEntitySchemaProperty.md)\<`T`\>
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Definition for an entity schema.
|
|
4
4
|
|
|
5
|
+
## Extends
|
|
6
|
+
|
|
7
|
+
- [`IEntitySchemaOptions`](IEntitySchemaOptions.md)
|
|
8
|
+
|
|
5
9
|
## Type Parameters
|
|
6
10
|
|
|
7
11
|
### T
|
|
@@ -18,16 +22,32 @@ The type of the entity.
|
|
|
18
22
|
|
|
19
23
|
***
|
|
20
24
|
|
|
21
|
-
###
|
|
25
|
+
### properties? {#properties}
|
|
22
26
|
|
|
23
|
-
> `optional` **
|
|
27
|
+
> `optional` **properties?**: [`IEntitySchemaProperty`](IEntitySchemaProperty.md)\<`T`\>[]
|
|
24
28
|
|
|
25
|
-
The
|
|
29
|
+
The properties of the entity.
|
|
26
30
|
|
|
27
31
|
***
|
|
28
32
|
|
|
29
|
-
###
|
|
33
|
+
### description? {#description}
|
|
30
34
|
|
|
31
|
-
> `optional` **
|
|
35
|
+
> `optional` **description?**: `string`
|
|
32
36
|
|
|
33
|
-
|
|
37
|
+
Description of the object.
|
|
38
|
+
|
|
39
|
+
#### Inherited from
|
|
40
|
+
|
|
41
|
+
[`IEntitySchemaOptions`](IEntitySchemaOptions.md).[`description`](IEntitySchemaOptions.md#description)
|
|
42
|
+
|
|
43
|
+
***
|
|
44
|
+
|
|
45
|
+
### version? {#version}
|
|
46
|
+
|
|
47
|
+
> `optional` **version?**: `number`
|
|
48
|
+
|
|
49
|
+
The schema version. Used to drive ordered migrations. Absent is treated as version 0.
|
|
50
|
+
|
|
51
|
+
#### Inherited from
|
|
52
|
+
|
|
53
|
+
[`IEntitySchemaOptions`](IEntitySchemaOptions.md).[`version`](IEntitySchemaOptions.md#version)
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Definition for an entity schema options.
|
|
4
4
|
|
|
5
|
+
## Extended by
|
|
6
|
+
|
|
7
|
+
- [`IEntitySchema`](IEntitySchema.md)
|
|
8
|
+
|
|
5
9
|
## Properties
|
|
6
10
|
|
|
7
11
|
### description? {#description}
|
|
@@ -9,3 +13,11 @@ Definition for an entity schema options.
|
|
|
9
13
|
> `optional` **description?**: `string`
|
|
10
14
|
|
|
11
15
|
Description of the object.
|
|
16
|
+
|
|
17
|
+
***
|
|
18
|
+
|
|
19
|
+
### version? {#version}
|
|
20
|
+
|
|
21
|
+
> `optional` **version?**: `number`
|
|
22
|
+
|
|
23
|
+
The schema version. Used to drive ordered migrations. Absent is treated as version 0.
|
|
@@ -95,3 +95,11 @@ Description of the object.
|
|
|
95
95
|
> `optional` **examples?**: `unknown`[]
|
|
96
96
|
|
|
97
97
|
Examples of the property values.
|
|
98
|
+
|
|
99
|
+
***
|
|
100
|
+
|
|
101
|
+
### defaultValue? {#defaultvalue}
|
|
102
|
+
|
|
103
|
+
> `optional` **defaultValue?**: `unknown`
|
|
104
|
+
|
|
105
|
+
A default value which can be used in migrations when the property value is not provided.
|
package/locales/en.json
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"invalidEntityProperties": "The schema has no properties defined, but the entity has properties",
|
|
11
11
|
"invalidEntityProperty": "The entity value of \"{value}\" does not match the type \"{type}\" for property \"{property}\"",
|
|
12
12
|
"invalidOptional": "The entity property \"{property}\" of type \"{type}\" is not optional, but no value has been provided",
|
|
13
|
-
"invalidEntityKeys": "The entity had additional properties that are not in the schema, \"{keys}\""
|
|
13
|
+
"invalidEntityKeys": "The entity had additional properties that are not in the schema, \"{keys}\"",
|
|
14
|
+
"versionMustBeGreaterThanOrEqualZero": "Property \"entitySchema.version\" must be an integer >= 0, but got {version}"
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/entity",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4-next.10",
|
|
4
4
|
"description": "Helpers for defining and working with entities",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
|
-
"url": "git+https://github.com/iotaledger/framework.git",
|
|
7
|
+
"url": "git+https://github.com/iotaledger/twin-framework.git",
|
|
8
8
|
"directory": "packages/entity"
|
|
9
9
|
},
|
|
10
10
|
"author": "martyn.janes@iota.org",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"node": ">=20.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@twin.org/core": "
|
|
18
|
-
"@twin.org/nameof": "
|
|
17
|
+
"@twin.org/core": "0.0.4-next.10",
|
|
18
|
+
"@twin.org/nameof": "0.0.4-next.10",
|
|
19
19
|
"reflect-metadata": "0.2.2",
|
|
20
20
|
"tslib": "2.8.1"
|
|
21
21
|
},
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"blockchain"
|
|
44
44
|
],
|
|
45
45
|
"bugs": {
|
|
46
|
-
"url": "git+https://github.com/iotaledger/framework/issues"
|
|
46
|
+
"url": "git+https://github.com/iotaledger/twin-framework/issues"
|
|
47
47
|
},
|
|
48
48
|
"homepage": "https://twindev.org"
|
|
49
49
|
}
|