velocious 1.0.644 → 1.0.646
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/README.md +11 -9
- package/build/authorization/ability.js +36 -13
- package/build/background-jobs/adapter.js +9 -0
- package/build/background-jobs/main.js +35 -10
- package/build/background-jobs/store.js +217 -38
- package/build/background-jobs/types.js +15 -0
- package/build/configuration-types.js +1 -1
- package/build/configuration.js +45 -9
- package/build/database/drivers/base-column.js +8 -0
- package/build/database/drivers/mssql/sql/update.js +1 -3
- package/build/database/drivers/mysql/sql/update.js +1 -3
- package/build/database/drivers/pgsql/column.js +22 -0
- package/build/database/drivers/pgsql/sql/update.js +1 -3
- package/build/database/drivers/sqlite/sql/alter-table.js +11 -1
- package/build/database/drivers/sqlite/sql/update.js +1 -3
- package/build/database/query/index.js +2 -2
- package/build/database/query/model-class-query.js +26 -10
- package/build/database/query/preloader/has-many.js +4 -1
- package/build/database/query/query-data.js +2 -1
- package/build/database/query/update-base.js +14 -0
- package/build/database/query/with-count.js +3 -1
- package/build/database/record/acts-as-list.js +37 -13
- package/build/database/record/attachments/store.js +336 -26
- package/build/database/record/auditing.js +6 -3
- package/build/database/record/index.js +197 -42
- package/build/database/record/instance-relationships/belongs-to.js +2 -1
- package/build/database/record/validators/uniqueness.js +8 -5
- package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +24 -8
- package/build/frontend-model-controller.js +136 -53
- package/build/frontend-model-resource/base-resource.js +87 -37
- package/build/frontend-model-resource/velocious-attachment-resource.js +98 -31
- package/build/frontend-models/base.js +307 -59
- package/build/frontend-models/preloader.js +6 -3
- package/build/frontend-models/query.js +15 -6
- package/build/frontend-models/resource-definition.js +21 -2
- package/build/frontend-models/use-destroyed-event.js +1 -1
- package/build/frontend-models/use-model-class-event.js +2 -2
- package/build/frontend-models/use-updated-event.js +1 -1
- package/build/frontend-models/websocket-channel.js +256 -93
- package/build/frontend-models/websocket-publishers.js +218 -18
- package/build/http-server/client/websocket-session.js +13 -1
- package/build/http-server/websocket-channel.js +15 -2
- package/build/src/authorization/ability.d.ts +9 -3
- package/build/src/authorization/ability.d.ts.map +1 -1
- package/build/src/authorization/ability.js +33 -14
- package/build/src/background-jobs/adapter.d.ts +6 -0
- package/build/src/background-jobs/adapter.d.ts.map +1 -1
- package/build/src/background-jobs/adapter.js +9 -1
- package/build/src/background-jobs/main.d.ts +6 -0
- package/build/src/background-jobs/main.d.ts.map +1 -1
- package/build/src/background-jobs/main.js +34 -11
- package/build/src/background-jobs/store.d.ts +66 -12
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +191 -35
- package/build/src/background-jobs/types.d.ts +55 -0
- package/build/src/background-jobs/types.d.ts.map +1 -1
- package/build/src/background-jobs/types.js +16 -1
- package/build/src/configuration-types.d.ts +3 -3
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +2 -2
- package/build/src/configuration.d.ts +18 -8
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +38 -7
- package/build/src/database/drivers/base-column.d.ts +5 -0
- package/build/src/database/drivers/base-column.d.ts.map +1 -1
- package/build/src/database/drivers/base-column.js +8 -1
- package/build/src/database/drivers/mssql/sql/update.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/sql/update.js +2 -4
- package/build/src/database/drivers/mysql/sql/update.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/sql/update.js +2 -4
- package/build/src/database/drivers/pgsql/column.d.ts +5 -0
- package/build/src/database/drivers/pgsql/column.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/column.js +19 -1
- package/build/src/database/drivers/pgsql/sql/update.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/sql/update.js +2 -4
- package/build/src/database/drivers/sqlite/sql/alter-table.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/sql/alter-table.js +6 -2
- package/build/src/database/drivers/sqlite/sql/update.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/sql/update.js +2 -4
- package/build/src/database/query/index.d.ts +4 -4
- package/build/src/database/query/index.d.ts.map +1 -1
- package/build/src/database/query/index.js +3 -3
- package/build/src/database/query/model-class-query.d.ts +8 -2
- package/build/src/database/query/model-class-query.d.ts.map +1 -1
- package/build/src/database/query/model-class-query.js +25 -11
- package/build/src/database/query/preloader/has-many.d.ts.map +1 -1
- package/build/src/database/query/preloader/has-many.js +4 -2
- package/build/src/database/query/query-data.d.ts.map +1 -1
- package/build/src/database/query/query-data.js +3 -2
- package/build/src/database/query/update-base.d.ts +7 -0
- package/build/src/database/query/update-base.d.ts.map +1 -1
- package/build/src/database/query/update-base.js +13 -1
- package/build/src/database/query/with-count.d.ts.map +1 -1
- package/build/src/database/query/with-count.js +3 -2
- package/build/src/database/record/acts-as-list.d.ts.map +1 -1
- package/build/src/database/record/acts-as-list.js +35 -14
- package/build/src/database/record/attachments/store.d.ts +67 -0
- package/build/src/database/record/attachments/store.d.ts.map +1 -1
- package/build/src/database/record/attachments/store.js +301 -25
- package/build/src/database/record/auditing.d.ts.map +1 -1
- package/build/src/database/record/auditing.js +7 -4
- package/build/src/database/record/index.d.ts +78 -26
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +171 -42
- package/build/src/database/record/instance-relationships/belongs-to.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/belongs-to.js +3 -2
- package/build/src/database/record/validators/uniqueness.d.ts.map +1 -1
- package/build/src/database/record/validators/uniqueness.js +8 -6
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +4 -4
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +24 -12
- package/build/src/frontend-model-controller.d.ts +29 -8
- package/build/src/frontend-model-controller.d.ts.map +1 -1
- package/build/src/frontend-model-controller.js +122 -51
- package/build/src/frontend-model-resource/base-resource.d.ts +51 -24
- package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
- package/build/src/frontend-model-resource/base-resource.js +83 -37
- package/build/src/frontend-model-resource/velocious-attachment-resource.d.ts +45 -26
- package/build/src/frontend-model-resource/velocious-attachment-resource.d.ts.map +1 -1
- package/build/src/frontend-model-resource/velocious-attachment-resource.js +89 -31
- package/build/src/frontend-models/base.d.ts +53 -20
- package/build/src/frontend-models/base.d.ts.map +1 -1
- package/build/src/frontend-models/base.js +275 -59
- package/build/src/frontend-models/preloader.d.ts.map +1 -1
- package/build/src/frontend-models/preloader.js +6 -4
- package/build/src/frontend-models/query.d.ts +2 -2
- package/build/src/frontend-models/query.d.ts.map +1 -1
- package/build/src/frontend-models/query.js +14 -7
- package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
- package/build/src/frontend-models/resource-definition.js +20 -3
- package/build/src/frontend-models/use-destroyed-event.d.ts +1 -1
- package/build/src/frontend-models/use-destroyed-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-destroyed-event.js +2 -2
- package/build/src/frontend-models/use-model-class-event.d.ts +2 -2
- package/build/src/frontend-models/use-model-class-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-model-class-event.js +3 -3
- package/build/src/frontend-models/use-updated-event.d.ts +1 -1
- package/build/src/frontend-models/use-updated-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-updated-event.js +2 -2
- package/build/src/frontend-models/websocket-channel.d.ts +60 -41
- package/build/src/frontend-models/websocket-channel.d.ts.map +1 -1
- package/build/src/frontend-models/websocket-channel.js +225 -85
- package/build/src/frontend-models/websocket-publishers.d.ts +9 -0
- package/build/src/frontend-models/websocket-publishers.d.ts.map +1 -1
- package/build/src/frontend-models/websocket-publishers.js +190 -19
- package/build/src/http-server/client/websocket-session.d.ts.map +1 -1
- package/build/src/http-server/client/websocket-session.js +11 -2
- package/build/src/http-server/websocket-channel.d.ts +20 -8
- package/build/src/http-server/websocket-channel.d.ts.map +1 -1
- package/build/src/http-server/websocket-channel.js +15 -3
- package/build/src/sync/sync-api-client.d.ts.map +1 -1
- package/build/src/sync/sync-api-client.js +4 -3
- package/build/src/sync/sync-client.d.ts.map +1 -1
- package/build/src/sync/sync-client.js +3 -2
- package/build/src/sync/sync-envelope-replay-service.d.ts.map +1 -1
- package/build/src/sync/sync-envelope-replay-service.js +6 -5
- package/build/src/sync/sync-publisher.d.ts.map +1 -1
- package/build/src/sync/sync-publisher.js +4 -3
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts +2 -2
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts.map +1 -1
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +3 -3
- package/build/src/testing/test-profiler.d.ts +4 -4
- package/build/src/testing/test-profiler.d.ts.map +1 -1
- package/build/src/testing/test-profiler.js +3 -3
- package/build/src/testing/test-runner.d.ts +271 -117
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +496 -427
- package/build/src/testing/test.d.ts +11 -72
- package/build/src/testing/test.d.ts.map +1 -1
- package/build/src/testing/test.js +131 -284
- package/build/src/testing/velocious-attempt-executor.d.ts +14 -29
- package/build/src/testing/velocious-attempt-executor.d.ts.map +1 -1
- package/build/src/testing/velocious-attempt-executor.js +52 -46
- package/build/src/testing/velocious-runner-reporter.d.ts +29 -34
- package/build/src/testing/velocious-runner-reporter.d.ts.map +1 -1
- package/build/src/testing/velocious-runner-reporter.js +145 -57
- package/build/src/testing/velocious-suite-hook-executor.d.ts +5 -23
- package/build/src/testing/velocious-suite-hook-executor.d.ts.map +1 -1
- package/build/src/testing/velocious-suite-hook-executor.js +22 -47
- package/build/src/testing/velocious-test-arguments.d.ts +11 -6
- package/build/src/testing/velocious-test-arguments.d.ts.map +1 -1
- package/build/src/testing/velocious-test-arguments.js +18 -10
- package/build/src/utils/model-primary-key.d.ts +73 -0
- package/build/src/utils/model-primary-key.d.ts.map +1 -0
- package/build/src/utils/model-primary-key.js +144 -0
- package/build/sync/sync-api-client.js +3 -2
- package/build/sync/sync-client.js +2 -1
- package/build/sync/sync-envelope-replay-service.js +5 -4
- package/build/sync/sync-publisher.js +3 -2
- package/build/testing/browser-frontend-model-event-hook-scenarios.js +2 -2
- package/build/testing/test-profiler.js +2 -2
- package/build/testing/test-runner.js +493 -449
- package/build/testing/test.js +164 -306
- package/build/testing/velocious-attempt-executor.js +55 -45
- package/build/testing/velocious-runner-reporter.js +156 -58
- package/build/testing/velocious-suite-hook-executor.js +22 -50
- package/build/testing/velocious-test-arguments.js +19 -10
- package/build/utils/model-primary-key.js +171 -0
- package/package.json +6 -5
- package/src/authorization/ability.js +36 -13
- package/src/background-jobs/adapter.js +9 -0
- package/src/background-jobs/main.js +35 -10
- package/src/background-jobs/store.js +217 -38
- package/src/background-jobs/types.js +15 -0
- package/src/configuration-types.js +1 -1
- package/src/configuration.js +45 -9
- package/src/database/drivers/base-column.js +8 -0
- package/src/database/drivers/mssql/sql/update.js +1 -3
- package/src/database/drivers/mysql/sql/update.js +1 -3
- package/src/database/drivers/pgsql/column.js +22 -0
- package/src/database/drivers/pgsql/sql/update.js +1 -3
- package/src/database/drivers/sqlite/sql/alter-table.js +11 -1
- package/src/database/drivers/sqlite/sql/update.js +1 -3
- package/src/database/query/index.js +2 -2
- package/src/database/query/model-class-query.js +26 -10
- package/src/database/query/preloader/has-many.js +4 -1
- package/src/database/query/query-data.js +2 -1
- package/src/database/query/update-base.js +14 -0
- package/src/database/query/with-count.js +3 -1
- package/src/database/record/acts-as-list.js +37 -13
- package/src/database/record/attachments/store.js +336 -26
- package/src/database/record/auditing.js +6 -3
- package/src/database/record/index.js +197 -42
- package/src/database/record/instance-relationships/belongs-to.js +2 -1
- package/src/database/record/validators/uniqueness.js +8 -5
- package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +24 -8
- package/src/frontend-model-controller.js +136 -53
- package/src/frontend-model-resource/base-resource.js +87 -37
- package/src/frontend-model-resource/velocious-attachment-resource.js +98 -31
- package/src/frontend-models/base.js +307 -59
- package/src/frontend-models/preloader.js +6 -3
- package/src/frontend-models/query.js +15 -6
- package/src/frontend-models/resource-definition.js +21 -2
- package/src/frontend-models/use-destroyed-event.js +1 -1
- package/src/frontend-models/use-model-class-event.js +2 -2
- package/src/frontend-models/use-updated-event.js +1 -1
- package/src/frontend-models/websocket-channel.js +256 -93
- package/src/frontend-models/websocket-publishers.js +218 -18
- package/src/http-server/client/websocket-session.js +13 -1
- package/src/http-server/websocket-channel.js +15 -2
- package/src/sync/sync-api-client.js +3 -2
- package/src/sync/sync-client.js +2 -1
- package/src/sync/sync-envelope-replay-service.js +5 -4
- package/src/sync/sync-publisher.js +3 -2
- package/src/testing/browser-frontend-model-event-hook-scenarios.js +2 -2
- package/src/testing/test-profiler.js +2 -2
- package/src/testing/test-runner.js +493 -449
- package/src/testing/test.js +164 -306
- package/src/testing/velocious-attempt-executor.js +55 -45
- package/src/testing/velocious-runner-reporter.js +156 -58
- package/src/testing/velocious-suite-hook-executor.js +22 -50
- package/src/testing/velocious-test-arguments.js +19 -10
- package/src/utils/model-primary-key.js +171 -0
- package/build/src/testing/testing-package-adapter.d.ts +0 -9
- package/build/src/testing/testing-package-adapter.d.ts.map +0 -1
- package/build/src/testing/testing-package-adapter.js +0 -69
- package/build/testing/testing-package-adapter.js +0 -76
- package/build/tsconfig.tsbuildinfo +0 -1
- package/src/testing/testing-package-adapter.js +0 -76
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export type ModelPrimaryKeyScalar = string | number;
|
|
2
|
+
export type ModelPrimaryKeyDefinition = string | string[];
|
|
3
|
+
export type CompositeModelPrimaryKeyValue = Record<string, ModelPrimaryKeyScalar>;
|
|
4
|
+
export type ModelPrimaryKeyValue = ModelPrimaryKeyScalar | CompositeModelPrimaryKeyValue;
|
|
5
|
+
/** @typedef {string | number} ModelPrimaryKeyScalar */
|
|
6
|
+
/** @typedef {string | string[]} ModelPrimaryKeyDefinition */
|
|
7
|
+
/** @typedef {Record<string, ModelPrimaryKeyScalar>} CompositeModelPrimaryKeyValue */
|
|
8
|
+
/** @typedef {ModelPrimaryKeyScalar | CompositeModelPrimaryKeyValue} ModelPrimaryKeyValue */
|
|
9
|
+
/**
|
|
10
|
+
* Validates an untrusted composite identity and returns its definition-ordered values.
|
|
11
|
+
* @param {string[]} primaryKey - Composite primary-key definition.
|
|
12
|
+
* @param {ReturnType<typeof JSON.parse>} value - Candidate identity.
|
|
13
|
+
* @returns {CompositeModelPrimaryKeyValue} - Validated identity.
|
|
14
|
+
*/
|
|
15
|
+
export declare function validatedCompositePrimaryKeyValue(primaryKey: string[], value: ReturnType<typeof JSON.parse>): CompositeModelPrimaryKeyValue;
|
|
16
|
+
/**
|
|
17
|
+
* Returns a scalar primary-key definition or fails at a feature boundary that cannot represent composite identities.
|
|
18
|
+
* @param {ModelPrimaryKeyDefinition} primaryKey - Primary-key definition.
|
|
19
|
+
* @param {string} operation - Operation requiring a scalar identity.
|
|
20
|
+
* @returns {string} - Scalar primary-key column or attribute name.
|
|
21
|
+
*/
|
|
22
|
+
export declare function scalarModelPrimaryKey(primaryKey: ModelPrimaryKeyDefinition, operation: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Returns a scalar identity or fails at a feature boundary that cannot represent composite identities.
|
|
25
|
+
* @param {ModelPrimaryKeyValue} value - Model identity.
|
|
26
|
+
* @param {string} operation - Operation requiring a scalar identity.
|
|
27
|
+
* @returns {ModelPrimaryKeyScalar} - Scalar identity.
|
|
28
|
+
*/
|
|
29
|
+
export declare function scalarModelPrimaryKeyValue(value: ModelPrimaryKeyValue, operation: string): ModelPrimaryKeyScalar;
|
|
30
|
+
/**
|
|
31
|
+
* Builds query conditions from a scalar or composite model identity.
|
|
32
|
+
* @param {ModelPrimaryKeyDefinition} primaryKey - Primary-key definition.
|
|
33
|
+
* @param {ReturnType<typeof JSON.parse>} value - Candidate identity.
|
|
34
|
+
* @returns {Record<string, ModelPrimaryKeyScalar>} - Primary-key query conditions.
|
|
35
|
+
*/
|
|
36
|
+
export declare function modelPrimaryKeyConditions(primaryKey: ModelPrimaryKeyDefinition, value: ReturnType<typeof JSON.parse>): Record<string, ModelPrimaryKeyScalar>;
|
|
37
|
+
/**
|
|
38
|
+
* Builds a qualified SQL predicate matching any supplied composite identity.
|
|
39
|
+
* @param {object} args - Arguments.
|
|
40
|
+
* @param {typeof import("../database/record/index.js").default} args.modelClass - Model class owning the identity attributes.
|
|
41
|
+
* @param {string[]} args.primaryKey - Composite primary-key definition.
|
|
42
|
+
* @param {import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>} args.query - Query receiving the predicate.
|
|
43
|
+
* @param {ModelPrimaryKeyValue[]} args.values - Candidate identities.
|
|
44
|
+
* @returns {string} - Qualified SQL predicate.
|
|
45
|
+
*/
|
|
46
|
+
export declare function compositeModelPrimaryKeyCohortSql({ modelClass, primaryKey, query, values }: {
|
|
47
|
+
modelClass: typeof import("../database/record/index.js").default;
|
|
48
|
+
primaryKey: string[];
|
|
49
|
+
query: import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>;
|
|
50
|
+
values: ModelPrimaryKeyValue[];
|
|
51
|
+
}): string;
|
|
52
|
+
/**
|
|
53
|
+
* Reads a scalar or composite identity through the owning model's value reader.
|
|
54
|
+
* @param {ModelPrimaryKeyDefinition} primaryKey - Primary-key definition.
|
|
55
|
+
* @param {(key: string) => ReturnType<typeof JSON.parse>} read - Primary-key value reader.
|
|
56
|
+
* @returns {ModelPrimaryKeyValue} - Model identity.
|
|
57
|
+
*/
|
|
58
|
+
export declare function readModelPrimaryKeyValue(primaryKey: ModelPrimaryKeyDefinition, read: (key: string) => ReturnType<typeof JSON.parse>): ModelPrimaryKeyValue;
|
|
59
|
+
/**
|
|
60
|
+
* Returns an unambiguous map key while preserving legacy scalar map keys.
|
|
61
|
+
* @param {ModelPrimaryKeyDefinition} primaryKey - Primary-key definition.
|
|
62
|
+
* @param {ReturnType<typeof JSON.parse>} value - Candidate identity.
|
|
63
|
+
* @returns {string} - Canonical identity key.
|
|
64
|
+
*/
|
|
65
|
+
export declare function modelPrimaryKeyCacheKey(primaryKey: ModelPrimaryKeyDefinition, value: ReturnType<typeof JSON.parse>): string;
|
|
66
|
+
/**
|
|
67
|
+
* Restores a model identity from its canonical string representation.
|
|
68
|
+
* @param {ModelPrimaryKeyDefinition} primaryKey - Primary-key definition.
|
|
69
|
+
* @param {string} cacheKey - Canonical identity key.
|
|
70
|
+
* @returns {ModelPrimaryKeyValue} - Restored identity.
|
|
71
|
+
*/
|
|
72
|
+
export declare function modelPrimaryKeyValueFromCacheKey(primaryKey: ModelPrimaryKeyDefinition, cacheKey: string): ModelPrimaryKeyValue;
|
|
73
|
+
//# sourceMappingURL=model-primary-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-primary-key.d.ts","sourceRoot":"","sources":["../../../src/utils/model-primary-key.js"],"names":[],"mappings":"AAII,YAA2B,qBAAqB,GAAtC,MAAM,GAAG,MAAM,CAAuB;AAChD,YAA6B,yBAAyB,GAA5C,MAAM,GAAG,MAAM,EAAE,CAA2B;AACtD,YAAiD,6BAA6B,GAApE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAA+B;AAC9E,YAAiE,oBAAoB,GAA3E,qBAAqB,GAAG,6BAA6B,CAAsB;AAHzF,uDAAuD;AACvD,6DAA6D;AAC7D,qFAAqF;AACrF,4FAA4F;AAE5F;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAAC,UAAU,EAJjD,MAAM,EAI2C,EAAE,KAAK,EAHxD,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAG4B,GAFtD,6BAA6B,CA2BzC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAJrC,yBAIqC,EAAE,SAAS,EAHhD,MAGgD,GAF9C,MAAM,CAQlB;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAJrC,oBAIqC,EAAE,SAAS,EAHhD,MAGgD,GAF9C,qBAAqB,CAQjC;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAJzC,yBAIyC,EAAE,KAAK,EAHhD,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAGoB,GAF9C,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAMjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAAC,EAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAC,EANtF;IAAmE,UAAU,EAArE,cAAc,6BAA6B,EAAE,OAAO,CAC5D;IAAuB,UAAU,EAAzB,MAAM,EAAE,CAChB;IAA6H,KAAK,EAA1H,OAAO,wCAAwC,EAAE,OAAO,CAAC,cAAc,6BAA6B,EAAE,OAAO,CAAC,CACtH;IAAqC,MAAM,EAAnC,oBAAoB,EAAE,CAC9B;CAEsF,GAF5E,MAAM,CAiBlB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAJxC,yBAIwC,EAAE,IAAI,EAH9C,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAGC,GAF5C,oBAAoB,CAWhC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAJvC,yBAIuC,EAAE,KAAK,EAH9C,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAGkB,GAF5C,MAAM,CAQlB;AAED;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,UAAU,EAJhD,yBAIgD,EAAE,QAAQ,EAH1D,MAG0D,GAFxD,oBAAoB,CA2BhC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import isPlainObject from "./plain-object.js";
|
|
3
|
+
/** @typedef {string | number} ModelPrimaryKeyScalar */
|
|
4
|
+
/** @typedef {string | string[]} ModelPrimaryKeyDefinition */
|
|
5
|
+
/** @typedef {Record<string, ModelPrimaryKeyScalar>} CompositeModelPrimaryKeyValue */
|
|
6
|
+
/** @typedef {ModelPrimaryKeyScalar | CompositeModelPrimaryKeyValue} ModelPrimaryKeyValue */
|
|
7
|
+
/**
|
|
8
|
+
* Validates an untrusted composite identity and returns its definition-ordered values.
|
|
9
|
+
* @param {string[]} primaryKey - Composite primary-key definition.
|
|
10
|
+
* @param {ReturnType<typeof JSON.parse>} value - Candidate identity.
|
|
11
|
+
* @returns {CompositeModelPrimaryKeyValue} - Validated identity.
|
|
12
|
+
*/
|
|
13
|
+
export function validatedCompositePrimaryKeyValue(primaryKey, value) {
|
|
14
|
+
if (!isPlainObject(value)) {
|
|
15
|
+
throw new TypeError("Expected composite primary key identity to be a plain object.");
|
|
16
|
+
}
|
|
17
|
+
const valueKeys = Object.keys(value);
|
|
18
|
+
if (valueKeys.length !== primaryKey.length || primaryKey.some((key) => !Object.prototype.hasOwnProperty.call(value, key))) {
|
|
19
|
+
throw new TypeError(`Expected composite primary key identity fields: ${primaryKey.join(", ")}.`);
|
|
20
|
+
}
|
|
21
|
+
/** @type {CompositeModelPrimaryKeyValue} */
|
|
22
|
+
const validatedValue = {};
|
|
23
|
+
for (const key of primaryKey) {
|
|
24
|
+
const keyValue = value[key];
|
|
25
|
+
if (typeof keyValue !== "string" && typeof keyValue !== "number") {
|
|
26
|
+
throw new TypeError(`Expected composite primary key identity field '${key}' to be a string or number.`);
|
|
27
|
+
}
|
|
28
|
+
validatedValue[key] = keyValue;
|
|
29
|
+
}
|
|
30
|
+
return validatedValue;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns a scalar primary-key definition or fails at a feature boundary that cannot represent composite identities.
|
|
34
|
+
* @param {ModelPrimaryKeyDefinition} primaryKey - Primary-key definition.
|
|
35
|
+
* @param {string} operation - Operation requiring a scalar identity.
|
|
36
|
+
* @returns {string} - Scalar primary-key column or attribute name.
|
|
37
|
+
*/
|
|
38
|
+
export function scalarModelPrimaryKey(primaryKey, operation) {
|
|
39
|
+
if (Array.isArray(primaryKey)) {
|
|
40
|
+
throw new Error(`${operation} does not support composite primary keys.`);
|
|
41
|
+
}
|
|
42
|
+
return primaryKey;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Returns a scalar identity or fails at a feature boundary that cannot represent composite identities.
|
|
46
|
+
* @param {ModelPrimaryKeyValue} value - Model identity.
|
|
47
|
+
* @param {string} operation - Operation requiring a scalar identity.
|
|
48
|
+
* @returns {ModelPrimaryKeyScalar} - Scalar identity.
|
|
49
|
+
*/
|
|
50
|
+
export function scalarModelPrimaryKeyValue(value, operation) {
|
|
51
|
+
if (typeof value !== "string" && typeof value !== "number") {
|
|
52
|
+
throw new Error(`${operation} does not support composite primary keys.`);
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Builds query conditions from a scalar or composite model identity.
|
|
58
|
+
* @param {ModelPrimaryKeyDefinition} primaryKey - Primary-key definition.
|
|
59
|
+
* @param {ReturnType<typeof JSON.parse>} value - Candidate identity.
|
|
60
|
+
* @returns {Record<string, ModelPrimaryKeyScalar>} - Primary-key query conditions.
|
|
61
|
+
*/
|
|
62
|
+
export function modelPrimaryKeyConditions(primaryKey, value) {
|
|
63
|
+
if (Array.isArray(primaryKey))
|
|
64
|
+
return validatedCompositePrimaryKeyValue(primaryKey, value);
|
|
65
|
+
return { [primaryKey]: /** @type {ModelPrimaryKeyScalar} */ (value) };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Builds a qualified SQL predicate matching any supplied composite identity.
|
|
69
|
+
* @param {object} args - Arguments.
|
|
70
|
+
* @param {typeof import("../database/record/index.js").default} args.modelClass - Model class owning the identity attributes.
|
|
71
|
+
* @param {string[]} args.primaryKey - Composite primary-key definition.
|
|
72
|
+
* @param {import("../database/query/model-class-query.js").default<typeof import("../database/record/index.js").default>} args.query - Query receiving the predicate.
|
|
73
|
+
* @param {ModelPrimaryKeyValue[]} args.values - Candidate identities.
|
|
74
|
+
* @returns {string} - Qualified SQL predicate.
|
|
75
|
+
*/
|
|
76
|
+
export function compositeModelPrimaryKeyCohortSql({ modelClass, primaryKey, query, values }) {
|
|
77
|
+
if (values.length === 0)
|
|
78
|
+
return "(1 = 0)";
|
|
79
|
+
const tableSql = query.driver.quoteTable(query.getTableReferenceForJoin());
|
|
80
|
+
return `(${values.map((value) => {
|
|
81
|
+
const conditions = modelPrimaryKeyConditions(primaryKey, value);
|
|
82
|
+
const identitySql = primaryKey.map((attributeName) => {
|
|
83
|
+
const columnName = modelClass.getColumnNameForAttributeName(attributeName);
|
|
84
|
+
return `${tableSql}.${query.driver.quoteColumn(columnName)} = ${query.driver.quote(conditions[attributeName])}`;
|
|
85
|
+
}).join(" AND ");
|
|
86
|
+
return `(${identitySql})`;
|
|
87
|
+
}).join(" OR ")})`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Reads a scalar or composite identity through the owning model's value reader.
|
|
91
|
+
* @param {ModelPrimaryKeyDefinition} primaryKey - Primary-key definition.
|
|
92
|
+
* @param {(key: string) => ReturnType<typeof JSON.parse>} read - Primary-key value reader.
|
|
93
|
+
* @returns {ModelPrimaryKeyValue} - Model identity.
|
|
94
|
+
*/
|
|
95
|
+
export function readModelPrimaryKeyValue(primaryKey, read) {
|
|
96
|
+
if (!Array.isArray(primaryKey))
|
|
97
|
+
return /** @type {ModelPrimaryKeyScalar} */ (read(primaryKey));
|
|
98
|
+
/** @type {CompositeModelPrimaryKeyValue} */
|
|
99
|
+
const value = {};
|
|
100
|
+
for (const key of primaryKey)
|
|
101
|
+
value[key] = /** @type {ModelPrimaryKeyScalar} */ (read(key));
|
|
102
|
+
return validatedCompositePrimaryKeyValue(primaryKey, value);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Returns an unambiguous map key while preserving legacy scalar map keys.
|
|
106
|
+
* @param {ModelPrimaryKeyDefinition} primaryKey - Primary-key definition.
|
|
107
|
+
* @param {ReturnType<typeof JSON.parse>} value - Candidate identity.
|
|
108
|
+
* @returns {string} - Canonical identity key.
|
|
109
|
+
*/
|
|
110
|
+
export function modelPrimaryKeyCacheKey(primaryKey, value) {
|
|
111
|
+
if (!Array.isArray(primaryKey))
|
|
112
|
+
return String(value);
|
|
113
|
+
const validatedValue = validatedCompositePrimaryKeyValue(primaryKey, value);
|
|
114
|
+
return JSON.stringify(primaryKey.map((key) => validatedValue[key]));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Restores a model identity from its canonical string representation.
|
|
118
|
+
* @param {ModelPrimaryKeyDefinition} primaryKey - Primary-key definition.
|
|
119
|
+
* @param {string} cacheKey - Canonical identity key.
|
|
120
|
+
* @returns {ModelPrimaryKeyValue} - Restored identity.
|
|
121
|
+
*/
|
|
122
|
+
export function modelPrimaryKeyValueFromCacheKey(primaryKey, cacheKey) {
|
|
123
|
+
if (!Array.isArray(primaryKey))
|
|
124
|
+
return cacheKey;
|
|
125
|
+
let parsed;
|
|
126
|
+
try {
|
|
127
|
+
parsed = JSON.parse(cacheKey);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (!(error instanceof SyntaxError))
|
|
131
|
+
throw error;
|
|
132
|
+
throw new TypeError("Expected composite primary key cache value to be valid JSON.", { cause: error });
|
|
133
|
+
}
|
|
134
|
+
if (!Array.isArray(parsed) || parsed.length !== primaryKey.length) {
|
|
135
|
+
throw new TypeError(`Expected composite primary key cache value with ${primaryKey.length} fields.`);
|
|
136
|
+
}
|
|
137
|
+
/** @type {CompositeModelPrimaryKeyValue} */
|
|
138
|
+
const value = {};
|
|
139
|
+
for (let index = 0; index < primaryKey.length; index += 1) {
|
|
140
|
+
value[primaryKey[index]] = parsed[index];
|
|
141
|
+
}
|
|
142
|
+
return validatedCompositePrimaryKeyValue(primaryKey, value);
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtcHJpbWFyeS1rZXkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbHMvbW9kZWwtcHJpbWFyeS1rZXkuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sYUFBYSxNQUFNLG1CQUFtQixDQUFBO0FBRTdDLHVEQUF1RDtBQUN2RCw2REFBNkQ7QUFDN0QscUZBQXFGO0FBQ3JGLDRGQUE0RjtBQUU1Rjs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxpQ0FBaUMsQ0FBQyxVQUFVLEVBQUUsS0FBSztJQUNqRSxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDMUIsTUFBTSxJQUFJLFNBQVMsQ0FBQywrREFBK0QsQ0FBQyxDQUFBO0lBQ3RGLENBQUM7SUFFRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBRXBDLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxVQUFVLENBQUMsTUFBTSxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDMUgsTUFBTSxJQUFJLFNBQVMsQ0FBQyxtREFBbUQsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDbEcsQ0FBQztJQUVELDRDQUE0QztJQUM1QyxNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUE7SUFFekIsS0FBSyxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUM3QixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUE7UUFFM0IsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFLENB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QUM7UUFDbEUsTUFBTSxJQUFJLFNBQVMsQ0FBQyxtREFBbUQsVUFBVSxDQUFDLE1BQU0sVUFBVSxDQUFDLENBQUE7SUFDckcsQ0FBQztJQUVELDRDQUE0QztJQUM1QyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUE7SUFFaEIsS0FBSyxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzFELEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDMUMsQ0FBQztJQUVELE9BQU8saUNBQWlDLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFBO0FBQzdELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IGlzUGxhaW5PYmplY3QgZnJvbSBcIi4vcGxhaW4tb2JqZWN0LmpzXCJcblxuLyoqIEB0eXBlZGVmIHtzdHJpbmcgfCBudW1iZXJ9IE1vZGVsUHJpbWFyeUtleVNjYWxhciAqL1xuLyoqIEB0eXBlZGVmIHtzdHJpbmcgfCBzdHJpbmdbXX0gTW9kZWxQcmltYXJ5S2V5RGVmaW5pdGlvbiAqL1xuLyoqIEB0eXBlZGVmIHtSZWNvcmQ8c3RyaW5nLCBNb2RlbFByaW1hcnlLZXlTY2FsYXI+fSBDb21wb3NpdGVNb2RlbFByaW1hcnlLZXlWYWx1ZSAqL1xuLyoqIEB0eXBlZGVmIHtNb2RlbFByaW1hcnlLZXlTY2FsYXIgfCBDb21wb3NpdGVNb2RlbFByaW1hcnlLZXlWYWx1ZX0gTW9kZWxQcmltYXJ5S2V5VmFsdWUgKi9cblxuLyoqXG4gKiBWYWxpZGF0ZXMgYW4gdW50cnVzdGVkIGNvbXBvc2l0ZSBpZGVudGl0eSBhbmQgcmV0dXJucyBpdHMgZGVmaW5pdGlvbi1vcmRlcmVkIHZhbHVlcy5cbiAqIEBwYXJhbSB7c3RyaW5nW119IHByaW1hcnlLZXkgLSBDb21wb3NpdGUgcHJpbWFyeS1rZXkgZGVmaW5pdGlvbi5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHZhbHVlIC0gQ2FuZGlkYXRlIGlkZW50aXR5LlxuICogQHJldHVybnMge0NvbXBvc2l0ZU1vZGVsUHJpbWFyeUtleVZhbHVlfSAtIFZhbGlkYXRlZCBpZGVudGl0eS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlZENvbXBvc2l0ZVByaW1hcnlLZXlWYWx1ZShwcmltYXJ5S2V5LCB2YWx1ZSkge1xuICBpZiAoIWlzUGxhaW5PYmplY3QodmFsdWUpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNvbXBvc2l0ZSBwcmltYXJ5IGtleSBpZGVudGl0eSB0byBiZSBhIHBsYWluIG9iamVjdC5cIilcbiAgfVxuXG4gIGNvbnN0IHZhbHVlS2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKVxuXG4gIGlmICh2YWx1ZUtleXMubGVuZ3RoICE9PSBwcmltYXJ5S2V5Lmxlbmd0aCB8fCBwcmltYXJ5S2V5LnNvbWUoKGtleSkgPT4gIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwga2V5KSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBFeHBlY3RlZCBjb21wb3NpdGUgcHJpbWFyeSBrZXkgaWRlbnRpdHkgZmllbGRzOiAke3ByaW1hcnlLZXkuam9pbihcIiwgXCIpfS5gKVxuICB9XG5cbiAgLyoqIEB0eXBlIHtDb21wb3NpdGVNb2RlbFByaW1hcnlLZXlWYWx1ZX0gKi9cbiAgY29uc3QgdmFsaWRhdGVkVmFsdWUgPSB7fVxuXG4gIGZvciAoY29uc3Qga2V5IG9mIHByaW1hcnlLZXkpIHtcbiAgICBjb25zdCBrZXlWYWx1ZSA9IHZhbHVlW2tleV1cblxuICAgIGlmICh0eXBlb2Yga2V5VmFsdWUgIT09IFwic3RyaW5nXCIgJiYgdHlwZW9mIGtleVZhbHVlICE9PSBcIm51bWJlclwiKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBFeHBlY3RlZCBjb21wb3NpdGUgcHJpbWFyeSBrZXkgaWRlbnRpdHkgZmllbGQgJyR7a2V5fScgdG8gYmUgYSBzdHJpbmcgb3IgbnVtYmVyLmApXG4gICAgfVxuXG4gICAgdmFsaWRhdGVkVmFsdWVba2V5XSA9IGtleVZhbHVlXG4gIH1cblxuICByZXR1cm4gdmFsaWRhdGVkVmFsdWVcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgc2NhbGFyIHByaW1hcnkta2V5IGRlZmluaXRpb24gb3IgZmFpbHMgYXQgYSBmZWF0dXJlIGJvdW5kYXJ5IHRoYXQgY2Fubm90IHJlcHJlc2VudCBjb21wb3NpdGUgaWRlbnRpdGllcy5cbiAqIEBwYXJhbSB7TW9kZWxQcmltYXJ5S2V5RGVmaW5pdGlvbn0gcHJpbWFyeUtleSAtIFByaW1hcnkta2V5IGRlZmluaXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gb3BlcmF0aW9uIC0gT3BlcmF0aW9uIHJlcXVpcmluZyBhIHNjYWxhciBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IC0gU2NhbGFyIHByaW1hcnkta2V5IGNvbHVtbiBvciBhdHRyaWJ1dGUgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjYWxhck1vZGVsUHJpbWFyeUtleShwcmltYXJ5S2V5LCBvcGVyYXRpb24pIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkocHJpbWFyeUtleSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7b3BlcmF0aW9ufSBkb2VzIG5vdCBzdXBwb3J0IGNvbXBvc2l0ZSBwcmltYXJ5IGtleXMuYClcbiAgfVxuXG4gIHJldHVybiBwcmltYXJ5S2V5XG59XG5cbi8qKlxuICogUmV0dXJucyBhIHNjYWxhciBpZGVudGl0eSBvciBmYWlscyBhdCBhIGZlYXR1cmUgYm91bmRhcnkgdGhhdCBjYW5ub3QgcmVwcmVzZW50IGNvbXBvc2l0ZSBpZGVudGl0aWVzLlxuICogQHBhcmFtIHtNb2RlbFByaW1hcnlLZXlWYWx1ZX0gdmFsdWUgLSBNb2RlbCBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRpb24gLSBPcGVyYXRpb24gcmVxdWlyaW5nIGEgc2NhbGFyIGlkZW50aXR5LlxuICogQHJldHVybnMge01vZGVsUHJpbWFyeUtleVNjYWxhcn0gLSBTY2FsYXIgaWRlbnRpdHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzY2FsYXJNb2RlbFByaW1hcnlLZXlWYWx1ZSh2YWx1ZSwgb3BlcmF0aW9uKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIgJiYgdHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke29wZXJhdGlvbn0gZG9lcyBub3Qgc3VwcG9ydCBjb21wb3NpdGUgcHJpbWFyeSBrZXlzLmApXG4gIH1cblxuICByZXR1cm4gdmFsdWVcbn1cblxuLyoqXG4gKiBCdWlsZHMgcXVlcnkgY29uZGl0aW9ucyBmcm9tIGEgc2NhbGFyIG9yIGNvbXBvc2l0ZSBtb2RlbCBpZGVudGl0eS5cbiAqIEBwYXJhbSB7TW9kZWxQcmltYXJ5S2V5RGVmaW5pdGlvbn0gcHJpbWFyeUtleSAtIFByaW1hcnkta2V5IGRlZmluaXRpb24uXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSB2YWx1ZSAtIENhbmRpZGF0ZSBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBNb2RlbFByaW1hcnlLZXlTY2FsYXI+fSAtIFByaW1hcnkta2V5IHF1ZXJ5IGNvbmRpdGlvbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbFByaW1hcnlLZXlDb25kaXRpb25zKHByaW1hcnlLZXksIHZhbHVlKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHByaW1hcnlLZXkpKSByZXR1cm4gdmFsaWRhdGVkQ29tcG9zaXRlUHJpbWFyeUtleVZhbHVlKHByaW1hcnlLZXksIHZhbHVlKVxuXG4gIHJldHVybiB7W3ByaW1hcnlLZXldOiAvKiogQHR5cGUge01vZGVsUHJpbWFyeUtleVNjYWxhcn0gKi8gKHZhbHVlKX1cbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBxdWFsaWZpZWQgU1FMIHByZWRpY2F0ZSBtYXRjaGluZyBhbnkgc3VwcGxpZWQgY29tcG9zaXRlIGlkZW50aXR5LlxuICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmd1bWVudHMuXG4gKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gYXJncy5tb2RlbENsYXNzIC0gTW9kZWwgY2xhc3Mgb3duaW5nIHRoZSBpZGVudGl0eSBhdHRyaWJ1dGVzLlxuICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5wcmltYXJ5S2V5IC0gQ29tcG9zaXRlIHByaW1hcnkta2V5IGRlZmluaXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHQ8dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0Pn0gYXJncy5xdWVyeSAtIFF1ZXJ5IHJlY2VpdmluZyB0aGUgcHJlZGljYXRlLlxuICogQHBhcmFtIHtNb2RlbFByaW1hcnlLZXlWYWx1ZVtdfSBhcmdzLnZhbHVlcyAtIENhbmRpZGF0ZSBpZGVudGl0aWVzLlxuICogQHJldHVybnMge3N0cmluZ30gLSBRdWFsaWZpZWQgU1FMIHByZWRpY2F0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBvc2l0ZU1vZGVsUHJpbWFyeUtleUNvaG9ydFNxbCh7bW9kZWxDbGFzcywgcHJpbWFyeUtleSwgcXVlcnksIHZhbHVlc30pIHtcbiAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDApIHJldHVybiBcIigxID0gMClcIlxuXG4gIGNvbnN0IHRhYmxlU3FsID0gcXVlcnkuZHJpdmVyLnF1b3RlVGFibGUocXVlcnkuZ2V0VGFibGVSZWZlcmVuY2VGb3JKb2luKCkpXG5cbiAgcmV0dXJuIGAoJHt2YWx1ZXMubWFwKCh2YWx1ZSkgPT4ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSBtb2RlbFByaW1hcnlLZXlDb25kaXRpb25zKHByaW1hcnlLZXksIHZhbHVlKVxuICAgIGNvbnN0IGlkZW50aXR5U3FsID0gcHJpbWFyeUtleS5tYXAoKGF0dHJpYnV0ZU5hbWUpID0+IHtcbiAgICAgIGNvbnN0IGNvbHVtbk5hbWUgPSBtb2RlbENsYXNzLmdldENvbHVtbk5hbWVGb3JBdHRyaWJ1dGVOYW1lKGF0dHJpYnV0ZU5hbWUpXG5cbiAgICAgIHJldHVybiBgJHt0YWJsZVNxbH0uJHtxdWVyeS5kcml2ZXIucXVvdGVDb2x1bW4oY29sdW1uTmFtZSl9ID0gJHtxdWVyeS5kcml2ZXIucXVvdGUoY29uZGl0aW9uc1thdHRyaWJ1dGVOYW1lXSl9YFxuICAgIH0pLmpvaW4oXCIgQU5EIFwiKVxuXG4gICAgcmV0dXJuIGAoJHtpZGVudGl0eVNxbH0pYFxuICB9KS5qb2luKFwiIE9SIFwiKX0pYFxufVxuXG4vKipcbiAqIFJlYWRzIGEgc2NhbGFyIG9yIGNvbXBvc2l0ZSBpZGVudGl0eSB0aHJvdWdoIHRoZSBvd25pbmcgbW9kZWwncyB2YWx1ZSByZWFkZXIuXG4gKiBAcGFyYW0ge01vZGVsUHJpbWFyeUtleURlZmluaXRpb259IHByaW1hcnlLZXkgLSBQcmltYXJ5LWtleSBkZWZpbml0aW9uLlxuICogQHBhcmFtIHsoa2V5OiBzdHJpbmcpID0+IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSByZWFkIC0gUHJpbWFyeS1rZXkgdmFsdWUgcmVhZGVyLlxuICogQHJldHVybnMge01vZGVsUHJpbWFyeUtleVZhbHVlfSAtIE1vZGVsIGlkZW50aXR5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZE1vZGVsUHJpbWFyeUtleVZhbHVlKHByaW1hcnlLZXksIHJlYWQpIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KHByaW1hcnlLZXkpKSByZXR1cm4gLyoqIEB0eXBlIHtNb2RlbFByaW1hcnlLZXlTY2FsYXJ9ICovIChyZWFkKHByaW1hcnlLZXkpKVxuXG4gIC8qKiBAdHlwZSB7Q29tcG9zaXRlTW9kZWxQcmltYXJ5S2V5VmFsdWV9ICovXG4gIGNvbnN0IHZhbHVlID0ge31cblxuICBmb3IgKGNvbnN0IGtleSBvZiBwcmltYXJ5S2V5KSB2YWx1ZVtrZXldID0gLyoqIEB0eXBlIHtNb2RlbFByaW1hcnlLZXlTY2FsYXJ9ICovIChyZWFkKGtleSkpXG5cbiAgcmV0dXJuIHZhbGlkYXRlZENvbXBvc2l0ZVByaW1hcnlLZXlWYWx1ZShwcmltYXJ5S2V5LCB2YWx1ZSlcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIHVuYW1iaWd1b3VzIG1hcCBrZXkgd2hpbGUgcHJlc2VydmluZyBsZWdhY3kgc2NhbGFyIG1hcCBrZXlzLlxuICogQHBhcmFtIHtNb2RlbFByaW1hcnlLZXlEZWZpbml0aW9ufSBwcmltYXJ5S2V5IC0gUHJpbWFyeS1rZXkgZGVmaW5pdGlvbi5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHZhbHVlIC0gQ2FuZGlkYXRlIGlkZW50aXR5LlxuICogQHJldHVybnMge3N0cmluZ30gLSBDYW5vbmljYWwgaWRlbnRpdHkga2V5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbW9kZWxQcmltYXJ5S2V5Q2FjaGVLZXkocHJpbWFyeUtleSwgdmFsdWUpIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KHByaW1hcnlLZXkpKSByZXR1cm4gU3RyaW5nKHZhbHVlKVxuXG4gIGNvbnN0IHZhbGlkYXRlZFZhbHVlID0gdmFsaWRhdGVkQ29tcG9zaXRlUHJpbWFyeUtleVZhbHVlKHByaW1hcnlLZXksIHZhbHVlKVxuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShwcmltYXJ5S2V5Lm1hcCgoa2V5KSA9PiB2YWxpZGF0ZWRWYWx1ZVtrZXldKSlcbn1cblxuLyoqXG4gKiBSZXN0b3JlcyBhIG1vZGVsIGlkZW50aXR5IGZyb20gaXRzIGNhbm9uaWNhbCBzdHJpbmcgcmVwcmVzZW50YXRpb24uXG4gKiBAcGFyYW0ge01vZGVsUHJpbWFyeUtleURlZmluaXRpb259IHByaW1hcnlLZXkgLSBQcmltYXJ5LWtleSBkZWZpbml0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGNhY2hlS2V5IC0gQ2Fub25pY2FsIGlkZW50aXR5IGtleS5cbiAqIEByZXR1cm5zIHtNb2RlbFByaW1hcnlLZXlWYWx1ZX0gLSBSZXN0b3JlZCBpZGVudGl0eS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vZGVsUHJpbWFyeUtleVZhbHVlRnJvbUNhY2hlS2V5KHByaW1hcnlLZXksIGNhY2hlS2V5KSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShwcmltYXJ5S2V5KSkgcmV0dXJuIGNhY2hlS2V5XG5cbiAgbGV0IHBhcnNlZFxuXG4gIHRyeSB7XG4gICAgcGFyc2VkID0gSlNPTi5wYXJzZShjYWNoZUtleSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoIShlcnJvciBpbnN0YW5jZW9mIFN5bnRheEVycm9yKSkgdGhyb3cgZXJyb3JcblxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjb21wb3NpdGUgcHJpbWFyeSBrZXkgY2FjaGUgdmFsdWUgdG8gYmUgdmFsaWQgSlNPTi5cIiwge2NhdXNlOiBlcnJvcn0pXG4gIH1cblxuICBpZiAoIUFycmF5LmlzQXJyYXkocGFyc2VkKSB8fCBwYXJzZWQubGVuZ3RoICE9PSBwcmltYXJ5S2V5Lmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEV4cGVjdGVkIGNvbXBvc2l0ZSBwcmltYXJ5IGtleSBjYWNoZSB2YWx1ZSB3aXRoICR7cHJpbWFyeUtleS5sZW5ndGh9IGZpZWxkcy5gKVxuICB9XG5cbiAgLyoqIEB0eXBlIHtDb21wb3NpdGVNb2RlbFByaW1hcnlLZXlWYWx1ZX0gKi9cbiAgY29uc3QgdmFsdWUgPSB7fVxuXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBwcmltYXJ5S2V5Lmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHZhbHVlW3ByaW1hcnlLZXlbaW5kZXhdXSA9IHBhcnNlZFtpbmRleF1cbiAgfVxuXG4gIHJldHVybiB2YWxpZGF0ZWRDb21wb3NpdGVQcmltYXJ5S2V5VmFsdWUocHJpbWFyeUtleSwgdmFsdWUpXG59XG4iXX0=
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import {optionalBoolean, optionalInteger} from "typanic"
|
|
4
4
|
|
|
5
5
|
import recordChanges from "../database/record-changes.js"
|
|
6
|
+
import {scalarModelPrimaryKeyValue} from "../utils/model-primary-key.js"
|
|
6
7
|
import {applySyncReplayResultToLocalMutationLog} from "./conflict-strategy.js"
|
|
7
8
|
|
|
8
9
|
/** @typedef {import("./sync-api-client-types.js").SyncChangeApplyResult} SyncChangeApplyResult */
|
|
@@ -35,7 +36,7 @@ export default class SyncApiClient {
|
|
|
35
36
|
* @returns {Promise<import("./local-mutation-log.js").LocalMutationLogRecord>} Appended intent.
|
|
36
37
|
*/
|
|
37
38
|
static async queueConflictTrackedSync({baseVersion, conflictTracking, data, operation, resource, resourceType, syncType}) {
|
|
38
|
-
const resourceId = String(resource.id())
|
|
39
|
+
const resourceId = String(scalarModelPrimaryKeyValue(resource.id(), `Conflict-tracked sync for ${resourceType}`))
|
|
39
40
|
const records = await conflictTracking.mutationLog.records()
|
|
40
41
|
const predecessor = records
|
|
41
42
|
.filter((record) => record.mutation.model === resourceType && record.mutation.payload?.resourceId === resourceId)
|
|
@@ -675,7 +676,7 @@ export default class SyncApiClient {
|
|
|
675
676
|
* @returns {Promise<ReturnType<typeof JSON.parse>>} Local sync row.
|
|
676
677
|
*/
|
|
677
678
|
static async queueLocalSync(args) {
|
|
678
|
-
const resourceRecordId = args.resource.id()
|
|
679
|
+
const resourceRecordId = scalarModelPrimaryKeyValue(args.resource.id(), "Local sync queueing")
|
|
679
680
|
const modelClass = args.resource.constructor
|
|
680
681
|
|
|
681
682
|
if (typeof modelClass.getModelName !== "function") {
|
|
@@ -4,6 +4,7 @@ import Configuration from "../configuration.js"
|
|
|
4
4
|
import {isBooleanColumnType} from "../database/column-types.js"
|
|
5
5
|
import Logger from "../logger.js"
|
|
6
6
|
import {captureRemoteRequestContext, mergeRemoteRequestContext} from "../remote-request-context.js"
|
|
7
|
+
import {scalarModelPrimaryKey} from "../utils/model-primary-key.js"
|
|
7
8
|
import restArgsError from "../utils/rest-args-error.js"
|
|
8
9
|
import VelociousWebsocketClient from "../http-client/websocket-client.js"
|
|
9
10
|
|
|
@@ -1243,7 +1244,7 @@ function derivedSyncAttributes({modelClass, resourceType}) {
|
|
|
1243
1244
|
const localOnlyAttributes = []
|
|
1244
1245
|
|
|
1245
1246
|
if (modelClass.hasPrimaryKey()) {
|
|
1246
|
-
const primaryKeyColumn = modelClass.primaryKey()
|
|
1247
|
+
const primaryKeyColumn = scalarModelPrimaryKey(modelClass.primaryKey(), `Derived sync attributes for ${resourceType}`)
|
|
1247
1248
|
|
|
1248
1249
|
localOnlyAttributes.push(columnNameToAttributeName[primaryKeyColumn] || primaryKeyColumn)
|
|
1249
1250
|
}
|
|
@@ -11,6 +11,7 @@ import sha256Hex from "../utils/sha256-hex.js"
|
|
|
11
11
|
import {decodeReplayPersistedData, serializeReplayPersistedData} from "./sync-replay-persisted-data.js"
|
|
12
12
|
import {ValidationError} from "../database/record/index.js"
|
|
13
13
|
import VelociousError from "../velocious-error.js"
|
|
14
|
+
import {scalarModelPrimaryKey, scalarModelPrimaryKeyValue} from "../utils/model-primary-key.js"
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Resolved routed-resource registration for one replay resource type.
|
|
@@ -800,7 +801,7 @@ export default class SyncEnvelopeReplayService {
|
|
|
800
801
|
if (mutation.baseVersion === undefined || mutation.baseVersion === null) return null
|
|
801
802
|
|
|
802
803
|
const ModelClass = resource.modelClass()
|
|
803
|
-
const primaryKey = ModelClass.primaryKey()
|
|
804
|
+
const primaryKey = scalarModelPrimaryKey(ModelClass.primaryKey(), `Offline sync conflict handling for ${ModelClass.name}`)
|
|
804
805
|
const primaryKeyAttribute = ModelClass.resolveAttributeName(primaryKey)
|
|
805
806
|
const versionAttribute = this.conflictStrategy.versionAttribute
|
|
806
807
|
const versionAttributeName = ModelClass.resolveAttributeName(versionAttribute)
|
|
@@ -944,7 +945,7 @@ export default class SyncEnvelopeReplayService {
|
|
|
944
945
|
if (columnName) allowedKeys.add(columnName)
|
|
945
946
|
}
|
|
946
947
|
|
|
947
|
-
const primaryKey = ModelClass.primaryKey()
|
|
948
|
+
const primaryKey = scalarModelPrimaryKey(ModelClass.primaryKey(), `Offline sync attribute filtering for ${ModelClass.name}`)
|
|
948
949
|
const primaryKeyAttribute = ModelClass.getColumnNameToAttributeNameMap()[primaryKey]
|
|
949
950
|
|
|
950
951
|
/** @type {Record<string, ReturnType<typeof JSON.parse>>} */
|
|
@@ -981,7 +982,7 @@ export default class SyncEnvelopeReplayService {
|
|
|
981
982
|
*/
|
|
982
983
|
async createRoutedReplayRecord({attributes, mutation, resource}) {
|
|
983
984
|
const ModelClass = resource.modelClass()
|
|
984
|
-
const primaryKey = ModelClass.primaryKey()
|
|
985
|
+
const primaryKey = scalarModelPrimaryKey(ModelClass.primaryKey(), `Offline sync create for ${ModelClass.name}`)
|
|
985
986
|
const conflictingIds = await ModelClass.where({[primaryKey]: mutation.resourceId}).pluck(primaryKey)
|
|
986
987
|
|
|
987
988
|
if (conflictingIds.length > 0) {
|
|
@@ -1007,7 +1008,7 @@ export default class SyncEnvelopeReplayService {
|
|
|
1007
1008
|
if (ability) {
|
|
1008
1009
|
const memberIds = await ModelClass
|
|
1009
1010
|
.accessibleFor(resource.syncAbilityAction("create"), ability)
|
|
1010
|
-
.where({[primaryKey]: record.id()})
|
|
1011
|
+
.where({[primaryKey]: scalarModelPrimaryKeyValue(record.id(), `Offline sync create authorization for ${ModelClass.name}`)})
|
|
1011
1012
|
.pluck(primaryKey)
|
|
1012
1013
|
|
|
1013
1014
|
if (memberIds.length === 0) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import Configuration from "../configuration.js"
|
|
4
4
|
import Logger from "../logger.js"
|
|
5
|
+
import {scalarModelPrimaryKeyValue} from "../utils/model-primary-key.js"
|
|
5
6
|
import restArgsError from "../utils/rest-args-error.js"
|
|
6
7
|
|
|
7
8
|
import {declaredSyncScopeAttributes} from "./sync-scope-attributes.js"
|
|
@@ -190,7 +191,7 @@ export default class SyncPublisher {
|
|
|
190
191
|
if (isPublishingSuppressed(record)) return
|
|
191
192
|
|
|
192
193
|
const data = await resourceConfig.serialize(record)
|
|
193
|
-
const resourceId = String(record.id())
|
|
194
|
+
const resourceId = String(scalarModelPrimaryKeyValue(record.id(), `Sync publishing for ${resourceConfig.resourceType}`))
|
|
194
195
|
const syncType = operation === "destroy" ? "delete" : "update"
|
|
195
196
|
const scopeValues = await this.publishedScopeValues({record, resourceConfig})
|
|
196
197
|
/** @type {Record<string, ReturnType<typeof JSON.parse>>} */
|
|
@@ -259,7 +260,7 @@ export default class SyncPublisher {
|
|
|
259
260
|
} else if (scopePlanEntry.recordAttribute) {
|
|
260
261
|
rawValue = record.readAttribute(scopePlanEntry.recordAttribute)
|
|
261
262
|
} else {
|
|
262
|
-
rawValue = record.id()
|
|
263
|
+
rawValue = scalarModelPrimaryKeyValue(record.id(), `Sync scope publishing for ${resourceConfig.resourceType}`)
|
|
263
264
|
}
|
|
264
265
|
|
|
265
266
|
const value = rawValue === undefined || rawValue === null ? null : String(rawValue)
|
|
@@ -15,10 +15,10 @@ import wait from "awaitery/build/wait.js"
|
|
|
15
15
|
* @typedef {import("../frontend-models/base.js").FrontendModelResourceConfig} FrontendModelResourceConfig */
|
|
16
16
|
/**
|
|
17
17
|
* Defines this typedef.
|
|
18
|
-
* @typedef {{id: string, model: FrontendModelBase}} FrontendModelHookTestCreateUpdatePayload */
|
|
18
|
+
* @typedef {{id: string | import("../utils/model-primary-key.js").CompositeModelPrimaryKeyValue, model: FrontendModelBase}} FrontendModelHookTestCreateUpdatePayload */
|
|
19
19
|
/**
|
|
20
20
|
* Defines this typedef.
|
|
21
|
-
* @typedef {{id: string}} FrontendModelHookTestDestroyPayload */
|
|
21
|
+
* @typedef {{id: string | import("../utils/model-primary-key.js").CompositeModelPrimaryKeyValue}} FrontendModelHookTestDestroyPayload */
|
|
22
22
|
/**
|
|
23
23
|
* FakeSubscriptions type.
|
|
24
24
|
* @typedef {object} FakeSubscriptions
|
|
@@ -172,7 +172,7 @@ export default class TestProfiler {
|
|
|
172
172
|
this._spans = []
|
|
173
173
|
/** @type {Array<{id: string, parentId: string | undefined, file: string, line: number | undefined}>} */
|
|
174
174
|
this._scopes = []
|
|
175
|
-
/** @type {WeakMap<import("./test-runner.js").TestsArgument, string>} */
|
|
175
|
+
/** @type {WeakMap<import("./test-runner.js").TestsArgument | import("@velocious/testing/runner").SuiteDeclaration, string>} */
|
|
176
176
|
this._scopeIds = new WeakMap()
|
|
177
177
|
/** @type {Set<string>} */
|
|
178
178
|
this._customActivityNames = new Set()
|
|
@@ -243,7 +243,7 @@ export default class TestProfiler {
|
|
|
243
243
|
|
|
244
244
|
/**
|
|
245
245
|
* Registers and returns a deterministic scope identifier.
|
|
246
|
-
* @param {import("./test-runner.js").TestsArgument} scope - Scope object.
|
|
246
|
+
* @param {import("./test-runner.js").TestsArgument | import("@velocious/testing/runner").SuiteDeclaration} scope - Scope object.
|
|
247
247
|
* @param {object} args - Scope metadata.
|
|
248
248
|
* @param {string[]} args.descriptions - Scope description path.
|
|
249
249
|
* @param {string | undefined} args.filePath - Scope source path.
|