@jaypie/dynamodb 0.2.0 → 0.3.0

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.
@@ -1,6 +1,6 @@
1
- export { APEX, ARCHIVED_SUFFIX, DELETED_SUFFIX, SEPARATOR } from "@jaypie/vocabulary";
1
+ export { APEX, ARCHIVED_SUFFIX, DELETED_SUFFIX, SEPARATOR, } from "@jaypie/fabric";
2
2
  export declare const INDEX_ALIAS = "indexAlias";
3
3
  export declare const INDEX_CLASS = "indexClass";
4
- export declare const INDEX_OU = "indexOu";
4
+ export declare const INDEX_SCOPE = "indexScope";
5
5
  export declare const INDEX_TYPE = "indexType";
6
6
  export declare const INDEX_XID = "indexXid";
@@ -2,12 +2,12 @@ import type { StorableEntity } from "./types.js";
2
2
  /**
3
3
  * Get a single entity by primary key
4
4
  */
5
- export declare const getEntity: import("@jaypie/vocabulary").ServiceHandlerFunction<Record<string, unknown>, StorableEntity | null>;
5
+ export declare const getEntity: import("@jaypie/fabric").Service<Record<string, unknown>, StorableEntity | null>;
6
6
  /**
7
7
  * Put (create or replace) an entity
8
8
  * Auto-populates GSI index keys via indexEntity
9
9
  *
10
- * Note: This is a regular async function (not serviceHandler) because it accepts
10
+ * Note: This is a regular async function (not fabricService) because it accepts
11
11
  * complex StorableEntity objects that can't be coerced by vocabulary's type system.
12
12
  */
13
13
  export declare function putEntity({ entity, }: {
@@ -17,7 +17,7 @@ export declare function putEntity({ entity, }: {
17
17
  * Update an existing entity
18
18
  * Auto-populates GSI index keys and sets updatedAt
19
19
  *
20
- * Note: This is a regular async function (not serviceHandler) because it accepts
20
+ * Note: This is a regular async function (not fabricService) because it accepts
21
21
  * complex StorableEntity objects that can't be coerced by vocabulary's type system.
22
22
  */
23
23
  export declare function updateEntity({ entity, }: {
@@ -27,14 +27,14 @@ export declare function updateEntity({ entity, }: {
27
27
  * Soft delete an entity by setting deletedAt timestamp
28
28
  * Re-indexes with appropriate suffix based on archived/deleted state
29
29
  */
30
- export declare const deleteEntity: import("@jaypie/vocabulary").ServiceHandlerFunction<Record<string, unknown>, boolean>;
30
+ export declare const deleteEntity: import("@jaypie/fabric").Service<Record<string, unknown>, boolean>;
31
31
  /**
32
32
  * Archive an entity by setting archivedAt timestamp
33
33
  * Re-indexes with appropriate suffix based on archived/deleted state
34
34
  */
35
- export declare const archiveEntity: import("@jaypie/vocabulary").ServiceHandlerFunction<Record<string, unknown>, boolean>;
35
+ export declare const archiveEntity: import("@jaypie/fabric").Service<Record<string, unknown>, boolean>;
36
36
  /**
37
37
  * Hard delete an entity (permanently removes from table)
38
38
  * Use with caution - prefer deleteEntity for soft delete
39
39
  */
40
- export declare const destroyEntity: import("@jaypie/vocabulary").ServiceHandlerFunction<Record<string, unknown>, boolean>;
40
+ export declare const destroyEntity: import("@jaypie/fabric").Service<Record<string, unknown>, boolean>;
@@ -3,7 +3,7 @@
3
3
  var clientDynamodb = require('@aws-sdk/client-dynamodb');
4
4
  var libDynamodb = require('@aws-sdk/lib-dynamodb');
5
5
  var errors = require('@jaypie/errors');
6
- var vocabulary = require('@jaypie/vocabulary');
6
+ var fabric = require('@jaypie/fabric');
7
7
 
8
8
  // Environment variable names
9
9
  const ENV_AWS_REGION = "AWS_REGION";
@@ -83,11 +83,11 @@ function resetClient() {
83
83
  tableName = null;
84
84
  }
85
85
 
86
- // Re-export shared constants from vocabulary
86
+ // Re-export shared constants from fabric
87
87
  // GSI names (derived from DEFAULT_INDEXES)
88
88
  const INDEX_ALIAS = "indexAlias";
89
89
  const INDEX_CLASS = "indexClass";
90
- const INDEX_OU = "indexOu";
90
+ const INDEX_SCOPE = "indexScope";
91
91
  const INDEX_TYPE = "indexType";
92
92
  const INDEX_XID = "indexXid";
93
93
 
@@ -95,53 +95,53 @@ const INDEX_XID = "indexXid";
95
95
  // Key Builders
96
96
  // =============================================================================
97
97
  /**
98
- * Build the indexOu key for hierarchical queries
99
- * @param ou - The organizational unit (APEX or "{parent.model}#{parent.id}")
98
+ * Build the indexScope key for hierarchical queries
99
+ * @param scope - The scope (APEX or "{parent.model}#{parent.id}")
100
100
  * @param model - The entity model name
101
- * @returns Composite key: "{ou}#{model}"
101
+ * @returns Composite key: "{scope}#{model}"
102
102
  */
103
- function buildIndexOu(ou, model) {
104
- return `${ou}${vocabulary.SEPARATOR}${model}`;
103
+ function buildIndexScope(scope, model) {
104
+ return `${scope}${fabric.SEPARATOR}${model}`;
105
105
  }
106
106
  /**
107
107
  * Build the indexAlias key for human-friendly lookups
108
- * @param ou - The organizational unit
108
+ * @param scope - The scope
109
109
  * @param model - The entity model name
110
110
  * @param alias - The human-friendly alias
111
- * @returns Composite key: "{ou}#{model}#{alias}"
111
+ * @returns Composite key: "{scope}#{model}#{alias}"
112
112
  */
113
- function buildIndexAlias(ou, model, alias) {
114
- return `${ou}${vocabulary.SEPARATOR}${model}${vocabulary.SEPARATOR}${alias}`;
113
+ function buildIndexAlias(scope, model, alias) {
114
+ return `${scope}${fabric.SEPARATOR}${model}${fabric.SEPARATOR}${alias}`;
115
115
  }
116
116
  /**
117
117
  * Build the indexClass key for category filtering
118
- * @param ou - The organizational unit
118
+ * @param scope - The scope
119
119
  * @param model - The entity model name
120
120
  * @param recordClass - The category classification
121
- * @returns Composite key: "{ou}#{model}#{class}"
121
+ * @returns Composite key: "{scope}#{model}#{class}"
122
122
  */
123
- function buildIndexClass(ou, model, recordClass) {
124
- return `${ou}${vocabulary.SEPARATOR}${model}${vocabulary.SEPARATOR}${recordClass}`;
123
+ function buildIndexClass(scope, model, recordClass) {
124
+ return `${scope}${fabric.SEPARATOR}${model}${fabric.SEPARATOR}${recordClass}`;
125
125
  }
126
126
  /**
127
127
  * Build the indexType key for type filtering
128
- * @param ou - The organizational unit
128
+ * @param scope - The scope
129
129
  * @param model - The entity model name
130
130
  * @param type - The type classification
131
- * @returns Composite key: "{ou}#{model}#{type}"
131
+ * @returns Composite key: "{scope}#{model}#{type}"
132
132
  */
133
- function buildIndexType(ou, model, type) {
134
- return `${ou}${vocabulary.SEPARATOR}${model}${vocabulary.SEPARATOR}${type}`;
133
+ function buildIndexType(scope, model, type) {
134
+ return `${scope}${fabric.SEPARATOR}${model}${fabric.SEPARATOR}${type}`;
135
135
  }
136
136
  /**
137
137
  * Build the indexXid key for external ID lookups
138
- * @param ou - The organizational unit
138
+ * @param scope - The scope
139
139
  * @param model - The entity model name
140
140
  * @param xid - The external ID
141
- * @returns Composite key: "{ou}#{model}#{xid}"
141
+ * @returns Composite key: "{scope}#{model}#{xid}"
142
142
  */
143
- function buildIndexXid(ou, model, xid) {
144
- return `${ou}${vocabulary.SEPARATOR}${model}${vocabulary.SEPARATOR}${xid}`;
143
+ function buildIndexXid(scope, model, xid) {
144
+ return `${scope}${fabric.SEPARATOR}${model}${fabric.SEPARATOR}${xid}`;
145
145
  }
146
146
  // =============================================================================
147
147
  // New Vocabulary-Based Functions
@@ -155,18 +155,18 @@ function buildIndexXid(ou, model, xid) {
155
155
  * @returns Composite key string
156
156
  */
157
157
  function buildCompositeKey(entity, fields, suffix) {
158
- return vocabulary.buildCompositeKey(entity, fields, suffix);
158
+ return fabric.buildCompositeKey(entity, fields, suffix);
159
159
  }
160
160
  /**
161
- * Calculate the organizational unit from a parent reference
161
+ * Calculate the scope from a parent reference
162
162
  * @param parent - Optional parent entity reference
163
163
  * @returns APEX ("@") if no parent, otherwise "{parent.model}#{parent.id}"
164
164
  */
165
- function calculateOu(parent) {
165
+ function calculateScope(parent) {
166
166
  if (!parent) {
167
- return vocabulary.APEX;
167
+ return fabric.APEX;
168
168
  }
169
- return vocabulary.calculateOu(parent);
169
+ return fabric.calculateScope(parent);
170
170
  }
171
171
  /**
172
172
  * Auto-populate GSI index keys on an entity
@@ -174,7 +174,7 @@ function calculateOu(parent) {
174
174
  * Uses the model's registered indexes (from vocabulary registry) or
175
175
  * DEFAULT_INDEXES if no custom indexes are registered.
176
176
  *
177
- * - indexOu is always populated from ou + model
177
+ * - indexScope is always populated from scope + model
178
178
  * - indexAlias is populated only when alias is present
179
179
  * - indexClass is populated only when class is present
180
180
  * - indexType is populated only when type is present
@@ -185,9 +185,9 @@ function calculateOu(parent) {
185
185
  * @returns The entity with populated index keys
186
186
  */
187
187
  function indexEntity(entity, suffix = "") {
188
- const indexes = vocabulary.getModelIndexes(entity.model);
189
- // Cast through unknown to bridge the type gap between StorableEntity and IndexableEntity
190
- return vocabulary.populateIndexKeys(entity, indexes, suffix);
188
+ const indexes = fabric.getModelIndexes(entity.model);
189
+ // Cast through unknown to bridge the type gap between StorableEntity and IndexableModel
190
+ return fabric.populateIndexKeys(entity, indexes, suffix);
191
191
  }
192
192
 
193
193
  /**
@@ -197,20 +197,20 @@ function calculateEntitySuffix(entity) {
197
197
  const hasArchived = Boolean(entity.archivedAt);
198
198
  const hasDeleted = Boolean(entity.deletedAt);
199
199
  if (hasArchived && hasDeleted) {
200
- return vocabulary.ARCHIVED_SUFFIX + vocabulary.DELETED_SUFFIX;
200
+ return fabric.ARCHIVED_SUFFIX + fabric.DELETED_SUFFIX;
201
201
  }
202
202
  if (hasArchived) {
203
- return vocabulary.ARCHIVED_SUFFIX;
203
+ return fabric.ARCHIVED_SUFFIX;
204
204
  }
205
205
  if (hasDeleted) {
206
- return vocabulary.DELETED_SUFFIX;
206
+ return fabric.DELETED_SUFFIX;
207
207
  }
208
208
  return "";
209
209
  }
210
210
  /**
211
211
  * Get a single entity by primary key
212
212
  */
213
- const getEntity = vocabulary.serviceHandler({
213
+ const getEntity = fabric.fabricService({
214
214
  alias: "getEntity",
215
215
  description: "Get a single entity by primary key",
216
216
  input: {
@@ -232,7 +232,7 @@ const getEntity = vocabulary.serviceHandler({
232
232
  * Put (create or replace) an entity
233
233
  * Auto-populates GSI index keys via indexEntity
234
234
  *
235
- * Note: This is a regular async function (not serviceHandler) because it accepts
235
+ * Note: This is a regular async function (not fabricService) because it accepts
236
236
  * complex StorableEntity objects that can't be coerced by vocabulary's type system.
237
237
  */
238
238
  async function putEntity({ entity, }) {
@@ -251,7 +251,7 @@ async function putEntity({ entity, }) {
251
251
  * Update an existing entity
252
252
  * Auto-populates GSI index keys and sets updatedAt
253
253
  *
254
- * Note: This is a regular async function (not serviceHandler) because it accepts
254
+ * Note: This is a regular async function (not fabricService) because it accepts
255
255
  * complex StorableEntity objects that can't be coerced by vocabulary's type system.
256
256
  */
257
257
  async function updateEntity({ entity, }) {
@@ -273,7 +273,7 @@ async function updateEntity({ entity, }) {
273
273
  * Soft delete an entity by setting deletedAt timestamp
274
274
  * Re-indexes with appropriate suffix based on archived/deleted state
275
275
  */
276
- const deleteEntity = vocabulary.serviceHandler({
276
+ const deleteEntity = fabric.fabricService({
277
277
  alias: "deleteEntity",
278
278
  description: "Soft delete an entity (sets deletedAt timestamp)",
279
279
  input: {
@@ -310,7 +310,7 @@ const deleteEntity = vocabulary.serviceHandler({
310
310
  * Archive an entity by setting archivedAt timestamp
311
311
  * Re-indexes with appropriate suffix based on archived/deleted state
312
312
  */
313
- const archiveEntity = vocabulary.serviceHandler({
313
+ const archiveEntity = fabric.fabricService({
314
314
  alias: "archiveEntity",
315
315
  description: "Archive an entity (sets archivedAt timestamp)",
316
316
  input: {
@@ -347,7 +347,7 @@ const archiveEntity = vocabulary.serviceHandler({
347
347
  * Hard delete an entity (permanently removes from table)
348
348
  * Use with caution - prefer deleteEntity for soft delete
349
349
  */
350
- const destroyEntity = vocabulary.serviceHandler({
350
+ const destroyEntity = fabric.fabricService({
351
351
  alias: "destroyEntity",
352
352
  description: "Hard delete an entity (permanently removes from table)",
353
353
  input: {
@@ -372,13 +372,13 @@ const destroyEntity = vocabulary.serviceHandler({
372
372
  */
373
373
  function calculateSuffix$1({ archived, deleted, }) {
374
374
  if (archived && deleted) {
375
- return vocabulary.ARCHIVED_SUFFIX + vocabulary.DELETED_SUFFIX;
375
+ return fabric.ARCHIVED_SUFFIX + fabric.DELETED_SUFFIX;
376
376
  }
377
377
  if (archived) {
378
- return vocabulary.ARCHIVED_SUFFIX;
378
+ return fabric.ARCHIVED_SUFFIX;
379
379
  }
380
380
  if (deleted) {
381
- return vocabulary.DELETED_SUFFIX;
381
+ return fabric.DELETED_SUFFIX;
382
382
  }
383
383
  return "";
384
384
  }
@@ -410,16 +410,16 @@ async function executeQuery(indexName, keyValue, options = {}) {
410
410
  };
411
411
  }
412
412
  /**
413
- * Query entities by organizational unit (parent hierarchy)
414
- * Uses indexOu GSI
413
+ * Query entities by scope (parent hierarchy)
414
+ * Uses indexScope GSI
415
415
  *
416
- * Note: This is a regular async function (not serviceHandler) because it accepts
416
+ * Note: This is a regular async function (not fabricService) because it accepts
417
417
  * complex startKey objects that can't be coerced by vocabulary's type system.
418
418
  */
419
- async function queryByOu({ archived = false, ascending = false, deleted = false, limit, model, ou, startKey, }) {
419
+ async function queryByScope({ archived = false, ascending = false, deleted = false, limit, model, scope, startKey, }) {
420
420
  const suffix = calculateSuffix$1({ archived, deleted });
421
- const keyValue = buildIndexOu(ou, model) + suffix;
422
- return executeQuery(INDEX_OU, keyValue, {
421
+ const keyValue = buildIndexScope(scope, model) + suffix;
422
+ return executeQuery(INDEX_SCOPE, keyValue, {
423
423
  ascending,
424
424
  limit,
425
425
  startKey,
@@ -429,7 +429,7 @@ async function queryByOu({ archived = false, ascending = false, deleted = false,
429
429
  * Query a single entity by human-friendly alias
430
430
  * Uses indexAlias GSI
431
431
  */
432
- const queryByAlias = vocabulary.serviceHandler({
432
+ const queryByAlias = fabric.fabricService({
433
433
  alias: "queryByAlias",
434
434
  description: "Query a single entity by human-friendly alias",
435
435
  input: {
@@ -447,16 +447,19 @@ const queryByAlias = vocabulary.serviceHandler({
447
447
  description: "Query deleted entities instead of active ones",
448
448
  },
449
449
  model: { type: String, description: "Entity model name" },
450
- ou: { type: String, description: "Organizational unit (@ for root)" },
450
+ scope: { type: String, description: "Scope (@ for root)" },
451
451
  },
452
- service: async ({ alias, archived, deleted, model, ou, }) => {
452
+ service: async ({ alias, archived, deleted, model, scope, }) => {
453
453
  const aliasStr = alias;
454
454
  const archivedBool = archived;
455
455
  const deletedBool = deleted;
456
456
  const modelStr = model;
457
- const ouStr = ou;
458
- const suffix = calculateSuffix$1({ archived: archivedBool, deleted: deletedBool });
459
- const keyValue = buildIndexAlias(ouStr, modelStr, aliasStr) + suffix;
457
+ const scopeStr = scope;
458
+ const suffix = calculateSuffix$1({
459
+ archived: archivedBool,
460
+ deleted: deletedBool,
461
+ });
462
+ const keyValue = buildIndexAlias(scopeStr, modelStr, aliasStr) + suffix;
460
463
  const result = await executeQuery(INDEX_ALIAS, keyValue, {
461
464
  limit: 1,
462
465
  });
@@ -467,12 +470,12 @@ const queryByAlias = vocabulary.serviceHandler({
467
470
  * Query entities by category classification
468
471
  * Uses indexClass GSI
469
472
  *
470
- * Note: This is a regular async function (not serviceHandler) because it accepts
473
+ * Note: This is a regular async function (not fabricService) because it accepts
471
474
  * complex startKey objects that can't be coerced by vocabulary's type system.
472
475
  */
473
- async function queryByClass({ archived = false, ascending = false, deleted = false, limit, model, ou, recordClass, startKey, }) {
476
+ async function queryByClass({ archived = false, ascending = false, deleted = false, limit, model, scope, recordClass, startKey, }) {
474
477
  const suffix = calculateSuffix$1({ archived, deleted });
475
- const keyValue = buildIndexClass(ou, model, recordClass) + suffix;
478
+ const keyValue = buildIndexClass(scope, model, recordClass) + suffix;
476
479
  return executeQuery(INDEX_CLASS, keyValue, {
477
480
  ascending,
478
481
  limit,
@@ -483,12 +486,12 @@ async function queryByClass({ archived = false, ascending = false, deleted = fal
483
486
  * Query entities by type classification
484
487
  * Uses indexType GSI
485
488
  *
486
- * Note: This is a regular async function (not serviceHandler) because it accepts
489
+ * Note: This is a regular async function (not fabricService) because it accepts
487
490
  * complex startKey objects that can't be coerced by vocabulary's type system.
488
491
  */
489
- async function queryByType({ archived = false, ascending = false, deleted = false, limit, model, ou, startKey, type, }) {
492
+ async function queryByType({ archived = false, ascending = false, deleted = false, limit, model, scope, startKey, type, }) {
490
493
  const suffix = calculateSuffix$1({ archived, deleted });
491
- const keyValue = buildIndexType(ou, model, type) + suffix;
494
+ const keyValue = buildIndexType(scope, model, type) + suffix;
492
495
  return executeQuery(INDEX_TYPE, keyValue, {
493
496
  ascending,
494
497
  limit,
@@ -499,7 +502,7 @@ async function queryByType({ archived = false, ascending = false, deleted = fals
499
502
  * Query a single entity by external ID
500
503
  * Uses indexXid GSI
501
504
  */
502
- const queryByXid = vocabulary.serviceHandler({
505
+ const queryByXid = fabric.fabricService({
503
506
  alias: "queryByXid",
504
507
  description: "Query a single entity by external ID",
505
508
  input: {
@@ -516,17 +519,20 @@ const queryByXid = vocabulary.serviceHandler({
516
519
  description: "Query deleted entities instead of active ones",
517
520
  },
518
521
  model: { type: String, description: "Entity model name" },
519
- ou: { type: String, description: "Organizational unit (@ for root)" },
522
+ scope: { type: String, description: "Scope (@ for root)" },
520
523
  xid: { type: String, description: "External ID" },
521
524
  },
522
- service: async ({ archived, deleted, model, ou, xid, }) => {
525
+ service: async ({ archived, deleted, model, scope, xid, }) => {
523
526
  const archivedBool = archived;
524
527
  const deletedBool = deleted;
525
528
  const modelStr = model;
526
- const ouStr = ou;
529
+ const scopeStr = scope;
527
530
  const xidStr = xid;
528
- const suffix = calculateSuffix$1({ archived: archivedBool, deleted: deletedBool });
529
- const keyValue = buildIndexXid(ouStr, modelStr, xidStr) + suffix;
531
+ const suffix = calculateSuffix$1({
532
+ archived: archivedBool,
533
+ deleted: deletedBool,
534
+ });
535
+ const keyValue = buildIndexXid(scopeStr, modelStr, xidStr) + suffix;
530
536
  const result = await executeQuery(INDEX_XID, keyValue, {
531
537
  limit: 1,
532
538
  });
@@ -549,13 +555,13 @@ const queryByXid = vocabulary.serviceHandler({
549
555
  */
550
556
  function calculateSuffix(archived, deleted) {
551
557
  if (archived && deleted) {
552
- return vocabulary.ARCHIVED_SUFFIX + vocabulary.DELETED_SUFFIX;
558
+ return fabric.ARCHIVED_SUFFIX + fabric.DELETED_SUFFIX;
553
559
  }
554
560
  if (archived) {
555
- return vocabulary.ARCHIVED_SUFFIX;
561
+ return fabric.ARCHIVED_SUFFIX;
556
562
  }
557
563
  if (deleted) {
558
- return vocabulary.DELETED_SUFFIX;
564
+ return fabric.DELETED_SUFFIX;
559
565
  }
560
566
  return "";
561
567
  }
@@ -566,8 +572,8 @@ function buildFilterObject(params) {
566
572
  const result = {
567
573
  model: params.model,
568
574
  };
569
- if (params.ou !== undefined) {
570
- result.ou = params.ou;
575
+ if (params.scope !== undefined) {
576
+ result.scope = params.scope;
571
577
  }
572
578
  if (params.filter) {
573
579
  Object.assign(result, params.filter);
@@ -637,14 +643,14 @@ function selectBestIndex(indexes, filterFields) {
637
643
  * specific query function (queryByOu, queryByAlias, etc.) to use.
638
644
  *
639
645
  * @example
640
- * // Uses indexOu (pk: ["ou", "model"])
641
- * const allMessages = await query({ model: "message", ou: `chat#${chatId}` });
646
+ * // Uses indexScope (pk: ["scope", "model"])
647
+ * const allMessages = await query({ model: "message", scope: `chat#${chatId}` });
642
648
  *
643
649
  * @example
644
- * // Uses indexAlias (pk: ["ou", "model", "alias"])
650
+ * // Uses indexAlias (pk: ["scope", "model", "alias"])
645
651
  * const byAlias = await query({
646
652
  * model: "record",
647
- * ou: "@",
653
+ * scope: "@",
648
654
  * filter: { alias: "my-record" },
649
655
  * });
650
656
  *
@@ -660,7 +666,7 @@ async function query(params) {
660
666
  // Build the combined filter object
661
667
  const filterFields = buildFilterObject(params);
662
668
  // Get indexes for this model (custom or DEFAULT_INDEXES)
663
- const indexes = vocabulary.getModelIndexes(model);
669
+ const indexes = fabric.getModelIndexes(model);
664
670
  // Select the best matching index
665
671
  const selectedIndex = selectBestIndex(indexes, filterFields);
666
672
  const indexName = selectedIndex.name ?? generateIndexName(selectedIndex.pk);
@@ -703,18 +709,18 @@ function generateIndexName(pk) {
703
709
  /**
704
710
  * Seed a single entity if it doesn't already exist
705
711
  *
706
- * @param entity - Partial entity with at least alias, model, and ou
712
+ * @param entity - Partial entity with at least alias, model, and scope
707
713
  * @returns true if entity was created, false if it already exists
708
714
  */
709
715
  async function seedEntityIfNotExists(entity) {
710
- if (!entity.alias || !entity.model || !entity.ou) {
711
- throw new Error("Entity must have alias, model, and ou to check existence");
716
+ if (!entity.alias || !entity.model || !entity.scope) {
717
+ throw new Error("Entity must have alias, model, and scope to check existence");
712
718
  }
713
719
  // Check if entity already exists
714
720
  const existing = await queryByAlias({
715
721
  alias: entity.alias,
716
722
  model: entity.model,
717
- ou: entity.ou,
723
+ scope: entity.scope,
718
724
  });
719
725
  if (existing) {
720
726
  return false;
@@ -726,7 +732,7 @@ async function seedEntityIfNotExists(entity) {
726
732
  id: entity.id ?? crypto.randomUUID(),
727
733
  model: entity.model,
728
734
  name: entity.name ?? entity.alias,
729
- ou: entity.ou,
735
+ scope: entity.scope,
730
736
  sequence: entity.sequence ?? Date.now(),
731
737
  updatedAt: entity.updatedAt ?? now,
732
738
  ...entity,
@@ -756,15 +762,15 @@ async function seedEntities(entities, options = {}) {
756
762
  for (const entity of entities) {
757
763
  const alias = entity.alias ?? entity.name ?? "unknown";
758
764
  try {
759
- if (!entity.model || !entity.ou) {
760
- throw new Error("Entity must have model and ou");
765
+ if (!entity.model || !entity.scope) {
766
+ throw new Error("Entity must have model and scope");
761
767
  }
762
768
  // For entities with alias, check existence
763
769
  if (entity.alias) {
764
770
  const existing = await queryByAlias({
765
771
  alias: entity.alias,
766
772
  model: entity.model,
767
- ou: entity.ou,
773
+ scope: entity.scope,
768
774
  });
769
775
  if (existing && !replace) {
770
776
  result.skipped.push(alias);
@@ -786,7 +792,7 @@ async function seedEntities(entities, options = {}) {
786
792
  id: entity.id ?? crypto.randomUUID(),
787
793
  model: entity.model,
788
794
  name: entity.name ?? entity.alias ?? "Unnamed",
789
- ou: entity.ou,
795
+ scope: entity.scope,
790
796
  sequence: entity.sequence ?? Date.now(),
791
797
  updatedAt: entity.updatedAt ?? now,
792
798
  ...entity,
@@ -802,27 +808,27 @@ async function seedEntities(entities, options = {}) {
802
808
  return result;
803
809
  }
804
810
  /**
805
- * Export entities by model and organizational unit
811
+ * Export entities by model and scope
806
812
  *
807
- * - Paginates through all matching entities via queryByOu
813
+ * - Paginates through all matching entities via queryByScope
808
814
  * - Returns entities sorted by sequence (ascending)
809
815
  *
810
816
  * @param model - The entity model name
811
- * @param ou - The organizational unit
817
+ * @param scope - The scope (APEX or "{parent.model}#{parent.id}")
812
818
  * @param limit - Optional maximum number of entities to export
813
819
  * @returns Export result with entities and count
814
820
  */
815
- async function exportEntities(model, ou, limit) {
821
+ async function exportEntities(model, scope, limit) {
816
822
  const entities = [];
817
823
  let startKey;
818
824
  let remaining = limit;
819
825
  do {
820
826
  const batchLimit = remaining !== undefined ? Math.min(remaining, 100) : undefined;
821
- const { items, lastEvaluatedKey } = await queryByOu({
827
+ const { items, lastEvaluatedKey } = await queryByScope({
822
828
  ascending: true,
823
829
  limit: batchLimit,
824
830
  model,
825
- ou,
831
+ scope,
826
832
  startKey,
827
833
  });
828
834
  entities.push(...items);
@@ -840,48 +846,48 @@ async function exportEntities(model, ou, limit) {
840
846
  * Export entities as a JSON string
841
847
  *
842
848
  * @param model - The entity model name
843
- * @param ou - The organizational unit
849
+ * @param scope - The scope (APEX or "{parent.model}#{parent.id}")
844
850
  * @param pretty - Format JSON with indentation (default: true)
845
851
  * @returns JSON string of exported entities
846
852
  */
847
- async function exportEntitiesToJson(model, ou, pretty = true) {
848
- const { entities } = await exportEntities(model, ou);
853
+ async function exportEntitiesToJson(model, scope, pretty = true) {
854
+ const { entities } = await exportEntities(model, scope);
849
855
  return pretty ? JSON.stringify(entities, null, 2) : JSON.stringify(entities);
850
856
  }
851
857
 
852
858
  Object.defineProperty(exports, "APEX", {
853
859
  enumerable: true,
854
- get: function () { return vocabulary.APEX; }
860
+ get: function () { return fabric.APEX; }
855
861
  });
856
862
  Object.defineProperty(exports, "ARCHIVED_SUFFIX", {
857
863
  enumerable: true,
858
- get: function () { return vocabulary.ARCHIVED_SUFFIX; }
864
+ get: function () { return fabric.ARCHIVED_SUFFIX; }
859
865
  });
860
866
  Object.defineProperty(exports, "DEFAULT_INDEXES", {
861
867
  enumerable: true,
862
- get: function () { return vocabulary.DEFAULT_INDEXES; }
868
+ get: function () { return fabric.DEFAULT_INDEXES; }
863
869
  });
864
870
  Object.defineProperty(exports, "DELETED_SUFFIX", {
865
871
  enumerable: true,
866
- get: function () { return vocabulary.DELETED_SUFFIX; }
872
+ get: function () { return fabric.DELETED_SUFFIX; }
867
873
  });
868
874
  Object.defineProperty(exports, "SEPARATOR", {
869
875
  enumerable: true,
870
- get: function () { return vocabulary.SEPARATOR; }
876
+ get: function () { return fabric.SEPARATOR; }
871
877
  });
872
878
  exports.INDEX_ALIAS = INDEX_ALIAS;
873
879
  exports.INDEX_CLASS = INDEX_CLASS;
874
- exports.INDEX_OU = INDEX_OU;
880
+ exports.INDEX_SCOPE = INDEX_SCOPE;
875
881
  exports.INDEX_TYPE = INDEX_TYPE;
876
882
  exports.INDEX_XID = INDEX_XID;
877
883
  exports.archiveEntity = archiveEntity;
878
884
  exports.buildCompositeKey = buildCompositeKey;
879
885
  exports.buildIndexAlias = buildIndexAlias;
880
886
  exports.buildIndexClass = buildIndexClass;
881
- exports.buildIndexOu = buildIndexOu;
887
+ exports.buildIndexScope = buildIndexScope;
882
888
  exports.buildIndexType = buildIndexType;
883
889
  exports.buildIndexXid = buildIndexXid;
884
- exports.calculateOu = calculateOu;
890
+ exports.calculateScope = calculateScope;
885
891
  exports.deleteEntity = deleteEntity;
886
892
  exports.destroyEntity = destroyEntity;
887
893
  exports.exportEntities = exportEntities;
@@ -896,7 +902,7 @@ exports.putEntity = putEntity;
896
902
  exports.query = query;
897
903
  exports.queryByAlias = queryByAlias;
898
904
  exports.queryByClass = queryByClass;
899
- exports.queryByOu = queryByOu;
905
+ exports.queryByScope = queryByScope;
900
906
  exports.queryByType = queryByType;
901
907
  exports.queryByXid = queryByXid;
902
908
  exports.resetClient = resetClient;