@twin.org/entity-storage-models 0.0.3-next.3 → 0.0.3-next.30

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.
Files changed (79) hide show
  1. package/README.md +2 -2
  2. package/dist/es/factories/schemaMigrationFactory.js +17 -0
  3. package/dist/es/factories/schemaMigrationFactory.js.map +1 -0
  4. package/dist/es/helpers/entityStorageHelper.js +126 -0
  5. package/dist/es/helpers/entityStorageHelper.js.map +1 -0
  6. package/dist/es/helpers/migrationHelper.js +232 -0
  7. package/dist/es/helpers/migrationHelper.js.map +1 -0
  8. package/dist/es/index.js +14 -1
  9. package/dist/es/index.js.map +1 -1
  10. package/dist/es/models/IEntityStorageComponent.js.map +1 -1
  11. package/dist/es/models/IEntityStorageConnector.js.map +1 -1
  12. package/dist/es/models/IEntityStorageMigrationConnector.js +2 -0
  13. package/dist/es/models/IEntityStorageMigrationConnector.js.map +1 -0
  14. package/dist/es/models/IMigrationOptions.js +4 -0
  15. package/dist/es/models/IMigrationOptions.js.map +1 -0
  16. package/dist/es/models/IResolvedMigrationStep.js +2 -0
  17. package/dist/es/models/IResolvedMigrationStep.js.map +1 -0
  18. package/dist/es/models/ISchemaMigration.js +2 -0
  19. package/dist/es/models/ISchemaMigration.js.map +1 -0
  20. package/dist/es/models/api/IEntityStorageCountRequest.js +4 -0
  21. package/dist/es/models/api/IEntityStorageCountRequest.js.map +1 -0
  22. package/dist/es/models/api/IEntityStorageCountResponse.js +4 -0
  23. package/dist/es/models/api/IEntityStorageCountResponse.js.map +1 -0
  24. package/dist/es/models/api/IEntityStorageEmptyRequest.js +4 -0
  25. package/dist/es/models/api/IEntityStorageEmptyRequest.js.map +1 -0
  26. package/dist/es/models/api/IEntityStorageGetRequest.js.map +1 -1
  27. package/dist/es/models/api/IEntityStorageRemoveBatchRequest.js +4 -0
  28. package/dist/es/models/api/IEntityStorageRemoveBatchRequest.js.map +1 -0
  29. package/dist/es/models/api/IEntityStorageRemoveRequest.js.map +1 -1
  30. package/dist/es/models/api/IEntityStorageSetBatchRequest.js +4 -0
  31. package/dist/es/models/api/IEntityStorageSetBatchRequest.js.map +1 -0
  32. package/dist/es/models/api/IEntityStorageSetRequest.js.map +1 -1
  33. package/dist/es/models/entityPropertyTransformer.js +2 -0
  34. package/dist/es/models/entityPropertyTransformer.js.map +1 -0
  35. package/dist/types/factories/schemaMigrationFactory.d.ts +14 -0
  36. package/dist/types/helpers/entityStorageHelper.d.ts +59 -0
  37. package/dist/types/helpers/migrationHelper.d.ts +65 -0
  38. package/dist/types/index.d.ts +13 -0
  39. package/dist/types/models/IEntityStorageComponent.d.ts +38 -3
  40. package/dist/types/models/IEntityStorageConnector.d.ts +23 -0
  41. package/dist/types/models/IEntityStorageMigrationConnector.d.ts +35 -0
  42. package/dist/types/models/IMigrationOptions.d.ts +17 -0
  43. package/dist/types/models/IResolvedMigrationStep.d.ts +38 -0
  44. package/dist/types/models/ISchemaMigration.d.ts +30 -0
  45. package/dist/types/models/api/IEntityStorageCountRequest.d.ts +14 -0
  46. package/dist/types/models/api/IEntityStorageCountResponse.d.ts +14 -0
  47. package/dist/types/models/api/IEntityStorageEmptyRequest.d.ts +5 -0
  48. package/dist/types/models/api/IEntityStorageGetRequest.d.ts +4 -0
  49. package/dist/types/models/api/IEntityStorageRemoveBatchRequest.d.ts +9 -0
  50. package/dist/types/models/api/IEntityStorageRemoveRequest.d.ts +9 -0
  51. package/dist/types/models/api/IEntityStorageSetBatchRequest.d.ts +9 -0
  52. package/dist/types/models/api/IEntityStorageSetRequest.d.ts +9 -0
  53. package/dist/types/models/entityPropertyTransformer.d.ts +6 -0
  54. package/docs/changelog.md +308 -44
  55. package/docs/examples.md +87 -1
  56. package/docs/reference/classes/EntityStorageHelper.md +209 -0
  57. package/docs/reference/classes/MigrationHelper.md +198 -0
  58. package/docs/reference/index.md +19 -0
  59. package/docs/reference/interfaces/IEntityStorageComponent.md +105 -7
  60. package/docs/reference/interfaces/IEntityStorageConnector.md +89 -5
  61. package/docs/reference/interfaces/IEntityStorageCountRequest.md +17 -0
  62. package/docs/reference/interfaces/IEntityStorageCountResponse.md +17 -0
  63. package/docs/reference/interfaces/IEntityStorageEmptyRequest.md +3 -0
  64. package/docs/reference/interfaces/IEntityStorageGetRequest.md +10 -4
  65. package/docs/reference/interfaces/IEntityStorageGetResponse.md +1 -1
  66. package/docs/reference/interfaces/IEntityStorageListRequest.md +8 -8
  67. package/docs/reference/interfaces/IEntityStorageListResponse.md +2 -2
  68. package/docs/reference/interfaces/IEntityStorageMigrationConnector.md +402 -0
  69. package/docs/reference/interfaces/IEntityStorageRemoveBatchRequest.md +11 -0
  70. package/docs/reference/interfaces/IEntityStorageRemoveRequest.md +15 -1
  71. package/docs/reference/interfaces/IEntityStorageSetBatchRequest.md +11 -0
  72. package/docs/reference/interfaces/IEntityStorageSetRequest.md +15 -1
  73. package/docs/reference/interfaces/IMigrationOptions.md +49 -0
  74. package/docs/reference/interfaces/IResolvedMigrationStep.md +78 -0
  75. package/docs/reference/interfaces/ISchemaMigration.md +62 -0
  76. package/docs/reference/type-aliases/EntityPropertyTransformer.md +34 -0
  77. package/docs/reference/variables/SchemaMigrationFactory.md +13 -0
  78. package/locales/en.json +18 -1
  79. package/package.json +6 -4
@@ -1 +1 @@
1
- {"version":3,"file":"IEntityStorageGetRequest.js","sourceRoot":"","sources":["../../../../src/models/api/IEntityStorageGetRequest.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Get an entry from entity storage.\n */\nexport interface IEntityStorageGetRequest {\n\t/**\n\t * The parameters from the path.\n\t */\n\tpathParams: {\n\t\t/**\n\t\t * The id of the entity to get.\n\t\t */\n\t\tid: string;\n\t};\n\n\t/**\n\t * The query parameters.\n\t */\n\tquery?: {\n\t\t/**\n\t\t * The secondary index to query with the id.\n\t\t */\n\t\tsecondaryIndex?: string;\n\t};\n}\n"]}
1
+ {"version":3,"file":"IEntityStorageGetRequest.js","sourceRoot":"","sources":["../../../../src/models/api/IEntityStorageGetRequest.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Get an entry from entity storage.\n */\nexport interface IEntityStorageGetRequest {\n\t/**\n\t * The parameters from the path.\n\t */\n\tpathParams: {\n\t\t/**\n\t\t * The id of the entity to get.\n\t\t */\n\t\tid: string;\n\t};\n\n\t/**\n\t * The query parameters.\n\t */\n\tquery?: {\n\t\t/**\n\t\t * The secondary index to query with the id.\n\t\t */\n\t\tsecondaryIndex?: string;\n\n\t\t/**\n\t\t * The optional conditions to match for the entity, JSON encoded array of property/value pairs.\n\t\t */\n\t\tconditions?: string;\n\t};\n}\n"]}
@@ -0,0 +1,4 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ export {};
4
+ //# sourceMappingURL=IEntityStorageRemoveBatchRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IEntityStorageRemoveBatchRequest.js","sourceRoot":"","sources":["../../../../src/models/api/IEntityStorageRemoveBatchRequest.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Remove multiple entries from entity storage by id.\n */\nexport interface IEntityStorageRemoveBatchRequest {\n\t/**\n\t * The ids of the entities to remove.\n\t */\n\tbody: string[];\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"IEntityStorageRemoveRequest.js","sourceRoot":"","sources":["../../../../src/models/api/IEntityStorageRemoveRequest.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Remove an entry from entity storage.\n */\nexport interface IEntityStorageRemoveRequest {\n\t/**\n\t * The parameters from the path.\n\t */\n\tpathParams: {\n\t\t/**\n\t\t * The id of the entity to remove.\n\t\t */\n\t\tid: string;\n\t};\n}\n"]}
1
+ {"version":3,"file":"IEntityStorageRemoveRequest.js","sourceRoot":"","sources":["../../../../src/models/api/IEntityStorageRemoveRequest.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Remove an entry from entity storage.\n */\nexport interface IEntityStorageRemoveRequest {\n\t/**\n\t * The parameters from the path.\n\t */\n\tpathParams: {\n\t\t/**\n\t\t * The id of the entity to remove.\n\t\t */\n\t\tid: string;\n\t};\n\n\t/**\n\t * The query parameters.\n\t */\n\tquery?: {\n\t\t/**\n\t\t * The optional conditions to match for the entity, JSON encoded array of property/value pairs.\n\t\t */\n\t\tconditions?: string;\n\t};\n}\n"]}
@@ -0,0 +1,4 @@
1
+ // Copyright 2024 IOTA Stiftung.
2
+ // SPDX-License-Identifier: Apache-2.0.
3
+ export {};
4
+ //# sourceMappingURL=IEntityStorageSetBatchRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IEntityStorageSetBatchRequest.js","sourceRoot":"","sources":["../../../../src/models/api/IEntityStorageSetBatchRequest.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Set multiple entries in entity storage.\n */\nexport interface IEntityStorageSetBatchRequest {\n\t/**\n\t * The entities to set.\n\t */\n\tbody: unknown[];\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"IEntityStorageSetRequest.js","sourceRoot":"","sources":["../../../../src/models/api/IEntityStorageSetRequest.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Set an entry in entity storage.\n */\nexport interface IEntityStorageSetRequest {\n\t/**\n\t * The data to be used in the entity.\n\t */\n\tbody: unknown;\n}\n"]}
1
+ {"version":3,"file":"IEntityStorageSetRequest.js","sourceRoot":"","sources":["../../../../src/models/api/IEntityStorageSetRequest.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Set an entry in entity storage.\n */\nexport interface IEntityStorageSetRequest {\n\t/**\n\t * The data to be used in the entity.\n\t */\n\tbody: unknown;\n\n\t/**\n\t * The query parameters.\n\t */\n\tquery?: {\n\t\t/**\n\t\t * The optional conditions to match for the entity, JSON encoded array of property/value pairs.\n\t\t */\n\t\tconditions?: string;\n\t};\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=entityPropertyTransformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entityPropertyTransformer.js","sourceRoot":"","sources":["../../../src/models/entityPropertyTransformer.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IEntitySchemaProperty } from \"@twin.org/entity\";\n\n/**\n * Type for the optional transformEntityProperty function.\n * Used in migration steps for custom property transformations.\n */\nexport type EntityPropertyTransformer<T = unknown, U = unknown> = (\n\tschema1Property: IEntitySchemaProperty<T>,\n\tschemaProperty2: IEntitySchemaProperty<U>,\n\tvalue: unknown\n) => unknown;\n"]}
@@ -0,0 +1,14 @@
1
+ import { Factory } from "@twin.org/core";
2
+ import type { ISchemaMigration } from "../models/ISchemaMigration.js";
3
+ /**
4
+ * Factory for optional per-step migration overrides.
5
+ *
6
+ * Only register an entry when a version step requires property renames or a custom
7
+ * transform hook. For purely structural changes (add/remove/type-change) the
8
+ * SchemaVersionService diffs the two versioned schema classes automatically
9
+ * without needing any factory entry.
10
+ *
11
+ * Keys follow the convention "BaseSchemaName_fromVersion_toVersion",
12
+ * for example "MyEntity_0_1" for the step that migrates MyEntity from version 0 to 1.
13
+ */
14
+ export declare const SchemaMigrationFactory: Factory<ISchemaMigration<unknown, unknown>>;
@@ -0,0 +1,59 @@
1
+ import { type EntityCondition, type IEntitySchema, type SortDirection } from "@twin.org/entity";
2
+ /**
3
+ * Helper class for performing schema migrations between two connectors.
4
+ */
5
+ export declare class EntityStorageHelper {
6
+ /**
7
+ * Runtime name for the class.
8
+ */
9
+ static readonly CLASS_NAME: string;
10
+ /**
11
+ * Prepare the entity by handling undefined and null values and validating it against the schema.
12
+ * @param entity The entity to handle undefined and null values for.
13
+ * @param schema The schema to validate the entity against.
14
+ * @param additionalProperties Optional list of additional properties to set on the entity.
15
+ * @param options Options controlling how null/undefined optional properties are stored.
16
+ * @param options.nullBehavior "omit" strips null/undefined optional properties before writing
17
+ * (NoSQL — avoids index-key type errors). "nullify" converts undefined to null (SQL — the default).
18
+ * @returns The entity with undefined and null values handled.
19
+ */
20
+ static prepareEntity<T>(entity: T, schema: IEntitySchema<T>, additionalProperties?: {
21
+ property: string;
22
+ value: unknown;
23
+ }[], options?: {
24
+ nullBehavior?: "omit" | "nullify";
25
+ }): T;
26
+ /**
27
+ * Un-prepare the entity by removing null values.
28
+ * @param entity The entity to handle undefined and null values for.
29
+ * @param removeProperties Optional list of properties to remove from the entity.
30
+ * @returns The entity with undefined and null values handled.
31
+ */
32
+ static unPrepareEntity<T>(entity: Partial<T> | undefined, removeProperties?: string[]): T;
33
+ /**
34
+ * Validate that every sort property in the list is indexed in the schema (isPrimary, isSecondary,
35
+ * or has a default sortDirection), throwing sortNotIndexed for the first violation found.
36
+ * @param schema The entity schema to validate against.
37
+ * @param sortProperties The sort properties to check.
38
+ * @throws GeneralError If a sort property is not indexed in the schema.
39
+ */
40
+ static validateSortProperties<T>(schema: IEntitySchema<T>, sortProperties?: {
41
+ property: keyof T;
42
+ sortDirection: SortDirection;
43
+ }[]): void;
44
+ /**
45
+ * Validate that every property in the list exists in the schema, throwing propertyNotInSchema
46
+ * for the first property that is not found.
47
+ * @param schema The entity schema to validate against.
48
+ * @param properties The properties to check.
49
+ * @throws GeneralError If a property does not exist in the schema.
50
+ */
51
+ static validateProperties<T>(schema: IEntitySchema<T>, properties?: (keyof T)[]): void;
52
+ /**
53
+ * Deep-clone condition tree and normalise null/undefined to undefined on Equals/NotEquals leaves
54
+ * so in-memory evaluation matches stored-absent semantics (optional absent props are omitted/undefined).
55
+ * @param condition The user-supplied condition (not mutated).
56
+ * @returns A clone safe to pass to check.
57
+ */
58
+ static normalizeConditionValues<T>(condition: EntityCondition<T>): EntityCondition<T>;
59
+ }
@@ -0,0 +1,65 @@
1
+ import { type IEntitySchemaDiff } from "@twin.org/entity";
2
+ import type { EntityPropertyTransformer } from "../models/entityPropertyTransformer.js";
3
+ import type { IEntityStorageConnector } from "../models/IEntityStorageConnector.js";
4
+ import type { IEntityStorageMigrationConnector } from "../models/IEntityStorageMigrationConnector.js";
5
+ import type { IMigrationOptions } from "../models/IMigrationOptions.js";
6
+ import type { IResolvedMigrationStep } from "../models/IResolvedMigrationStep.js";
7
+ /**
8
+ * Helper class for performing entity schema migrations between two connectors.
9
+ * The chain-based API (migrateWithChain / applyEntityChain) is the single migration
10
+ * path: a chain of one step covers the same case as a traditional single-step migration.
11
+ */
12
+ export declare class MigrationHelper {
13
+ /**
14
+ * Runtime name for the class.
15
+ */
16
+ static readonly CLASS_NAME: string;
17
+ /**
18
+ * Performs a chain migration in a single connector swap, regardless of how many version
19
+ * steps the chain spans. Creates one target connector, reads all source entities, applies
20
+ * applyEntityChain to each, writes them to the target, then finalizes the migration.
21
+ * A chain of one step is equivalent to a traditional single-step migration.
22
+ * @param sourceConnector The connector holding data at the stored schema version.
23
+ * @param targetSchemaName The schema name for the current version (used to create the target connector).
24
+ * @param steps Ordered, fully-resolved migration steps from stored to current version.
25
+ * @param options Optional migration options.
26
+ * @param loggingComponentType The optional component type to use for logging the migration progress.
27
+ * @returns The finalized connector and the count of migrated entities.
28
+ */
29
+ static migrateWithChain(sourceConnector: IEntityStorageMigrationConnector, targetSchemaName: string, steps: IResolvedMigrationStep[], options?: IMigrationOptions, loggingComponentType?: string): Promise<{
30
+ finalConnector: IEntityStorageConnector;
31
+ migrated: number;
32
+ }>;
33
+ /**
34
+ * Reads all entities from one partition of the source connector, applies the migration
35
+ * chain to each entity, and writes the results to the target connector.
36
+ * @param source The connector to read from (already bootstrapped).
37
+ * @param target The connector to write to (already bootstrapped).
38
+ * @param steps Ordered, fully-resolved migration steps.
39
+ * @param options Optional migration options (batchSize, progress callbacks, transformEntityProperty).
40
+ * @returns The number of entities migrated.
41
+ */
42
+ static migratePartitionWithChain(source: IEntityStorageMigrationConnector, target: IEntityStorageConnector, steps: IResolvedMigrationStep[], options?: IMigrationOptions): Promise<number>;
43
+ /**
44
+ * Transforms a single entity through an ordered chain of fully-resolved migration steps.
45
+ * For each step the method diffs fromProperties against toProperties, then applies
46
+ * applyEntityTransform. Each step's output feeds the next step's input so that
47
+ * per-step transformEntityProperty hooks are honoured throughout the chain.
48
+ * @param entity The entity to transform (at the shape described by steps[0].fromProperties).
49
+ * @param steps Ordered, fully-resolved migration steps from stored version to current version.
50
+ * Each step's fromProperties and toProperties are resolved by the caller before invocation.
51
+ * @returns The entity transformed to the shape described by steps[last].toProperties.
52
+ */
53
+ static applyEntityChain(entity: unknown, steps: IResolvedMigrationStep[]): unknown;
54
+ /**
55
+ * Applies the entity transformation for a single diff, handling added, removed, and
56
+ * modified properties according to the provided schema diff and optional transform hook.
57
+ * @param entity The entity to transform.
58
+ * @param schemaDiff The schema diff between the old and new schemas.
59
+ * @param transformEntityProperty Optional per-property transform hook for object/array properties.
60
+ * @returns The transformed entity ready to be written to the new schema.
61
+ * @throws GeneralError if a transformation is required for an object or array property but no transformEntityProperty function is provided.
62
+ * @throws GeneralError if coercion of a modified property results in undefined for a non-optional target property.
63
+ */
64
+ static applyEntityTransform<T = unknown, U = unknown>(entity: Partial<T>, schemaDiff: IEntitySchemaDiff<T, U>, transformEntityProperty?: EntityPropertyTransformer<T, U>): U;
65
+ }
@@ -1,9 +1,22 @@
1
1
  export * from "./factories/entityStorageConnectorFactory.js";
2
+ export * from "./factories/schemaMigrationFactory.js";
3
+ export * from "./helpers/entityStorageHelper.js";
4
+ export * from "./helpers/migrationHelper.js";
5
+ export * from "./models/api/IEntityStorageCountRequest.js";
6
+ export * from "./models/api/IEntityStorageCountResponse.js";
7
+ export * from "./models/api/IEntityStorageEmptyRequest.js";
2
8
  export * from "./models/api/IEntityStorageGetRequest.js";
3
9
  export * from "./models/api/IEntityStorageGetResponse.js";
4
10
  export * from "./models/api/IEntityStorageListRequest.js";
5
11
  export * from "./models/api/IEntityStorageListResponse.js";
12
+ export * from "./models/api/IEntityStorageRemoveBatchRequest.js";
6
13
  export * from "./models/api/IEntityStorageRemoveRequest.js";
14
+ export * from "./models/api/IEntityStorageSetBatchRequest.js";
7
15
  export * from "./models/api/IEntityStorageSetRequest.js";
16
+ export * from "./models/entityPropertyTransformer.js";
8
17
  export * from "./models/IEntityStorageComponent.js";
9
18
  export * from "./models/IEntityStorageConnector.js";
19
+ export * from "./models/IEntityStorageMigrationConnector.js";
20
+ export * from "./models/IMigrationOptions.js";
21
+ export * from "./models/IResolvedMigrationStep.js";
22
+ export * from "./models/ISchemaMigration.js";
@@ -7,22 +7,46 @@ export interface IEntityStorageComponent<T = unknown> extends IComponent {
7
7
  /**
8
8
  * Set an entity.
9
9
  * @param entity The entity to set.
10
+ * @param conditions The optional conditions to match for the entities.
10
11
  * @returns The id of the entity.
11
12
  */
12
- set(entity: T): Promise<void>;
13
+ set(entity: T, conditions?: {
14
+ property: keyof T;
15
+ value: unknown;
16
+ }[]): Promise<void>;
17
+ /**
18
+ * Set multiple entities in a batch.
19
+ * @param entities The entities to set.
20
+ * @returns Nothing.
21
+ */
22
+ setBatch(entities: T[]): Promise<void>;
13
23
  /**
14
24
  * Get an entity.
15
25
  * @param id The id of the entity to get, or the index value if secondaryIndex is set.
16
26
  * @param secondaryIndex Get the item using a secondary index.
27
+ * @param conditions The optional conditions to match for the entities.
17
28
  * @returns The object if it can be found or undefined.
18
29
  */
19
- get(id: string, secondaryIndex?: keyof T): Promise<T | undefined>;
30
+ get(id: string, secondaryIndex?: keyof T, conditions?: {
31
+ property: keyof T;
32
+ value: unknown;
33
+ }[]): Promise<T | undefined>;
20
34
  /**
21
35
  * Remove the entity.
22
36
  * @param id The id of the entity to remove.
37
+ * @param conditions The optional conditions to match for the entities.
38
+ * @returns Nothing.
39
+ */
40
+ remove(id: string, conditions?: {
41
+ property: keyof T;
42
+ value: unknown;
43
+ }[]): Promise<void>;
44
+ /**
45
+ * Remove multiple entities by id.
46
+ * @param ids The ids of the entities to remove.
23
47
  * @returns Nothing.
24
48
  */
25
- remove(id: string): Promise<void>;
49
+ removeBatch(ids: string[]): Promise<void>;
26
50
  /**
27
51
  * Query all the entities which match the conditions.
28
52
  * @param conditions The conditions to match for the entities.
@@ -44,4 +68,15 @@ export interface IEntityStorageComponent<T = unknown> extends IComponent {
44
68
  */
45
69
  cursor?: string;
46
70
  }>;
71
+ /**
72
+ * Remove all entities from the storage.
73
+ * @returns Nothing.
74
+ */
75
+ empty(): Promise<void>;
76
+ /**
77
+ * Count all the entities which match the conditions.
78
+ * @param conditions The optional conditions to match for the entities.
79
+ * @returns The total count of entities in the storage.
80
+ */
81
+ count(conditions?: EntityCondition<T>): Promise<number>;
47
82
  }
@@ -19,6 +19,12 @@ export interface IEntityStorageConnector<T = unknown> extends IComponent {
19
19
  property: keyof T;
20
20
  value: unknown;
21
21
  }[]): Promise<void>;
22
+ /**
23
+ * Set multiple entities in a batch.
24
+ * @param entities The entities to set.
25
+ * @returns Nothing.
26
+ */
27
+ setBatch(entities: T[]): Promise<void>;
22
28
  /**
23
29
  * Get an entity.
24
30
  * @param id The id of the entity to get, or the index value if secondaryIndex is set.
@@ -40,6 +46,12 @@ export interface IEntityStorageConnector<T = unknown> extends IComponent {
40
46
  property: keyof T;
41
47
  value: unknown;
42
48
  }[]): Promise<void>;
49
+ /**
50
+ * Remove multiple entities by id.
51
+ * @param ids The ids of the entities to remove.
52
+ * @returns Nothing.
53
+ */
54
+ removeBatch(ids: string[]): Promise<void>;
43
55
  /**
44
56
  * Query all the entities which match the conditions.
45
57
  * @param conditions The conditions to match for the entities.
@@ -63,4 +75,15 @@ export interface IEntityStorageConnector<T = unknown> extends IComponent {
63
75
  */
64
76
  cursor?: string;
65
77
  }>;
78
+ /**
79
+ * Remove all entities from the storage.
80
+ * @returns Nothing.
81
+ */
82
+ empty(): Promise<void>;
83
+ /**
84
+ * Count all the entities which match the conditions.
85
+ * @param conditions The optional conditions to match for the entities.
86
+ * @returns The total count of entities in the storage.
87
+ */
88
+ count(conditions?: EntityCondition<T>): Promise<number>;
66
89
  }
@@ -0,0 +1,35 @@
1
+ import type { IContextIds } from "@twin.org/context";
2
+ import type { IEntityStorageConnector } from "./IEntityStorageConnector.js";
3
+ import type { IMigrationOptions } from "./IMigrationOptions.js";
4
+ /**
5
+ * Interface describing an entity storage migration connector.
6
+ */
7
+ export interface IEntityStorageMigrationConnector<T = unknown> extends IEntityStorageConnector<T> {
8
+ /**
9
+ * Get a unique list of all the context ids from the storage.
10
+ * @returns The list of unique context ids.
11
+ */
12
+ getPartitionContextIds(): Promise<IContextIds[]>;
13
+ /**
14
+ * Create the target connector for performing the migration it will use a temporary storage location.
15
+ * @param newEntitySchema The name of the new entity schema to create the connector for.
16
+ * @returns Connector for performing the migration.
17
+ */
18
+ createTargetConnector<U>(newEntitySchema: string): Promise<IEntityStorageConnector<U>>;
19
+ /**
20
+ * Finalize the migration by tearing down the old connector and replacing it with the target connector.
21
+ * @param targetConnector The target connector to finalize the migration with.
22
+ * @param options The options to control how the migration is finalized.
23
+ * @param loggingComponentType The optional component type to use for logging the migration progress.
24
+ * @returns A promise that resolves when the migration is finalized and returns the final connector.
25
+ */
26
+ finalizeMigration<U>(targetConnector: IEntityStorageConnector<U>, options?: IMigrationOptions, loggingComponentType?: string): Promise<IEntityStorageConnector<U>>;
27
+ /**
28
+ * Cleanup the migration if a migration fails or needs to be aborted.
29
+ * @param targetConnector The target connector to cleanup the migration with.
30
+ * @param options The options to control how the migration is cleaned up.
31
+ * @param loggingComponentType The optional component type to use for logging the migration progress.
32
+ * @returns A promise that resolves when the migration is cleaned up.
33
+ */
34
+ cleanupMigration<U>(targetConnector: IEntityStorageConnector<U> | undefined, options?: IMigrationOptions, loggingComponentType?: string): Promise<void>;
35
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Options controlling how a schema migration is executed.
3
+ */
4
+ export interface IMigrationOptions {
5
+ /**
6
+ * Number of entities to read and write per batch.
7
+ * @default 100
8
+ */
9
+ batchSize?: number;
10
+ /**
11
+ * Called for progress tracking.
12
+ * @param progressItem The item progress being updated.
13
+ * @param itemTotal The total number of rows to migrate.
14
+ * @param itemIndex The number of rows migrated so far.
15
+ */
16
+ onProgress?: (progressItem: "partitionStart" | "partitionProgress" | "partitionEnd" | "partitionItemsStart" | "partitionItemsProgress" | "partitionItemsEnd", itemTotal: number, itemIndex: number) => Promise<void>;
17
+ }
@@ -0,0 +1,38 @@
1
+ import type { IEntitySchemaProperty } from "@twin.org/entity";
2
+ import type { EntityPropertyTransformer } from "./entityPropertyTransformer.js";
3
+ /**
4
+ * A fully-resolved single migration step used by MigrationHelper.
5
+ * The SchemaVersionService builds these by looking up versioned schema classes
6
+ * from EntitySchemaFactory (e.g. MyEntityV0, MyEntityV1) before invoking the helper,
7
+ * keeping factory knowledge out of the helper itself.
8
+ * @template T The entity type. Defaults to `unknown`. Use a concrete entity type
9
+ * when the step's source and target schemas are known at the call site.
10
+ */
11
+ export interface IResolvedMigrationStep<T = unknown, U = unknown> {
12
+ /**
13
+ * The property list of the entity at the start of this step (the "old" shape).
14
+ * Sourced from the versioned schema class registered in EntitySchemaFactory,
15
+ * e.g. EntitySchemaFactory.get("MyEntityV0").properties.
16
+ */
17
+ fromProperties: IEntitySchemaProperty<T>[];
18
+ /**
19
+ * The property list of the entity at the end of this step (the "new" shape).
20
+ * For the final step this is the live current schema's properties.
21
+ */
22
+ toProperties: IEntitySchemaProperty<U>[];
23
+ /**
24
+ * Optional property renames for this step, forwarded to EntitySchemaDiffHelper.diff.
25
+ */
26
+ renames?: {
27
+ from: string;
28
+ to: string;
29
+ }[];
30
+ /**
31
+ * Optional transformation for properties, usually only called for object and array types.
32
+ * @param schema1Property The property schema in the old schema.
33
+ * @param schemaProperty2 The property schema in the new schema.
34
+ * @param value The value of the property in the old schema.
35
+ * @returns The transformed value to match the new schema.
36
+ */
37
+ transformEntityProperty?: EntityPropertyTransformer<T, U>;
38
+ }
@@ -0,0 +1,30 @@
1
+ import type { EntityPropertyTransformer } from "./entityPropertyTransformer.js";
2
+ /**
3
+ * Optional per-step override for a single version-to-version migration.
4
+ * Only register an entry in SchemaMigrationFactory when a step requires property
5
+ * renames or a custom object/array transform. For purely structural changes
6
+ * (add/remove/type-change fields) no entry is needed — the runner diffs the two
7
+ * versioned schema classes (e.g. MyEntityV0 vs MyEntityV1) from EntitySchemaFactory
8
+ * automatically.
9
+ *
10
+ * Register under the key "BaseSchemaName_fromVersion_toVersion"
11
+ * e.g. "MyEntity_0_1" for the step that migrates from version 0 to version 1.
12
+ * The key itself encodes the version pair; no version field is needed on the object.
13
+ */
14
+ export interface ISchemaMigration<T = unknown, U = unknown> {
15
+ /**
16
+ * Optional property renames to apply during this step.
17
+ */
18
+ renames?: {
19
+ from: string;
20
+ to: string;
21
+ }[];
22
+ /**
23
+ * Optional transformation for properties, usually only called for object and array types.
24
+ * @param schema1Property The property schema in the old schema.
25
+ * @param schemaProperty2 The property schema in the new schema.
26
+ * @param value The value of the property in the old schema.
27
+ * @returns The transformed value to match the new schema.
28
+ */
29
+ transformEntityProperty?: EntityPropertyTransformer<T, U>;
30
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Count the entries in entity storage.
3
+ */
4
+ export interface IEntityStorageCountRequest {
5
+ /**
6
+ * The query parameters.
7
+ */
8
+ query?: {
9
+ /**
10
+ * The optional conditions to filter the count, JSON encoded EntityCondition.
11
+ */
12
+ conditions?: string;
13
+ };
14
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The response for counting entries in entity storage.
3
+ */
4
+ export interface IEntityStorageCountResponse {
5
+ /**
6
+ * The body of the response.
7
+ */
8
+ body: {
9
+ /**
10
+ * The total count of entities.
11
+ */
12
+ count: number;
13
+ };
14
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Remove all entries from entity storage.
3
+ */
4
+ export interface IEntityStorageEmptyRequest {
5
+ }
@@ -19,5 +19,9 @@ export interface IEntityStorageGetRequest {
19
19
  * The secondary index to query with the id.
20
20
  */
21
21
  secondaryIndex?: string;
22
+ /**
23
+ * The optional conditions to match for the entity, JSON encoded array of property/value pairs.
24
+ */
25
+ conditions?: string;
22
26
  };
23
27
  }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Remove multiple entries from entity storage by id.
3
+ */
4
+ export interface IEntityStorageRemoveBatchRequest {
5
+ /**
6
+ * The ids of the entities to remove.
7
+ */
8
+ body: string[];
9
+ }
@@ -11,4 +11,13 @@ export interface IEntityStorageRemoveRequest {
11
11
  */
12
12
  id: string;
13
13
  };
14
+ /**
15
+ * The query parameters.
16
+ */
17
+ query?: {
18
+ /**
19
+ * The optional conditions to match for the entity, JSON encoded array of property/value pairs.
20
+ */
21
+ conditions?: string;
22
+ };
14
23
  }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Set multiple entries in entity storage.
3
+ */
4
+ export interface IEntityStorageSetBatchRequest {
5
+ /**
6
+ * The entities to set.
7
+ */
8
+ body: unknown[];
9
+ }
@@ -6,4 +6,13 @@ export interface IEntityStorageSetRequest {
6
6
  * The data to be used in the entity.
7
7
  */
8
8
  body: unknown;
9
+ /**
10
+ * The query parameters.
11
+ */
12
+ query?: {
13
+ /**
14
+ * The optional conditions to match for the entity, JSON encoded array of property/value pairs.
15
+ */
16
+ conditions?: string;
17
+ };
9
18
  }
@@ -0,0 +1,6 @@
1
+ import type { IEntitySchemaProperty } from "@twin.org/entity";
2
+ /**
3
+ * Type for the optional transformEntityProperty function.
4
+ * Used in migration steps for custom property transformations.
5
+ */
6
+ export type EntityPropertyTransformer<T = unknown, U = unknown> = (schema1Property: IEntitySchemaProperty<T>, schemaProperty2: IEntitySchemaProperty<U>, value: unknown) => unknown;