@jaypie/dynamodb 0.0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/entities.d.ts +16 -47
- package/dist/cjs/index.cjs +220 -137
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +1 -2
- package/dist/cjs/mcp/admin/createTable.d.ts +8 -0
- package/dist/cjs/mcp/admin/dockerCompose.d.ts +12 -0
- package/dist/cjs/mcp/admin/index.d.ts +3 -0
- package/dist/cjs/mcp/admin/status.d.ts +9 -0
- package/dist/cjs/mcp/autoInit.d.ts +5 -0
- package/dist/cjs/mcp/index.cjs +1090 -0
- package/dist/cjs/mcp/index.cjs.map +1 -0
- package/dist/cjs/mcp/index.d.ts +17 -0
- package/dist/cjs/queries.d.ts +36 -25
- package/dist/esm/entities.d.ts +16 -47
- package/dist/esm/index.d.ts +1 -2
- package/dist/esm/index.js +221 -138
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mcp/admin/createTable.d.ts +8 -0
- package/dist/esm/mcp/admin/dockerCompose.d.ts +12 -0
- package/dist/esm/mcp/admin/index.d.ts +3 -0
- package/dist/esm/mcp/admin/status.d.ts +9 -0
- package/dist/esm/mcp/autoInit.d.ts +5 -0
- package/dist/esm/mcp/index.d.ts +17 -0
- package/dist/esm/mcp/index.js +1084 -0
- package/dist/esm/mcp/index.js.map +1 -0
- package/dist/esm/queries.d.ts +36 -25
- package/package.json +16 -3
package/dist/cjs/entities.d.ts
CHANGED
|
@@ -1,71 +1,40 @@
|
|
|
1
1
|
import type { FabricEntity } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Parameters for getEntity
|
|
4
|
-
*/
|
|
5
|
-
export interface GetEntityParams {
|
|
6
|
-
/** Entity ID (sort key) */
|
|
7
|
-
id: string;
|
|
8
|
-
/** Entity model (partition key) */
|
|
9
|
-
model: string;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Parameters for putEntity
|
|
13
|
-
*/
|
|
14
|
-
export interface PutEntityParams<T extends FabricEntity> {
|
|
15
|
-
/** The entity to save */
|
|
16
|
-
entity: T;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Parameters for updateEntity
|
|
20
|
-
*/
|
|
21
|
-
export interface UpdateEntityParams<T extends FabricEntity> {
|
|
22
|
-
/** The entity with updated fields */
|
|
23
|
-
entity: T;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Parameters for deleteEntity (soft delete)
|
|
27
|
-
*/
|
|
28
|
-
export interface DeleteEntityParams {
|
|
29
|
-
/** Entity ID (sort key) */
|
|
30
|
-
id: string;
|
|
31
|
-
/** Entity model (partition key) */
|
|
32
|
-
model: string;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Parameters for archiveEntity
|
|
36
|
-
*/
|
|
37
|
-
export interface ArchiveEntityParams {
|
|
38
|
-
/** Entity ID (sort key) */
|
|
39
|
-
id: string;
|
|
40
|
-
/** Entity model (partition key) */
|
|
41
|
-
model: string;
|
|
42
|
-
}
|
|
43
2
|
/**
|
|
44
3
|
* Get a single entity by primary key
|
|
45
4
|
*/
|
|
46
|
-
export declare
|
|
5
|
+
export declare const getEntity: import("@jaypie/vocabulary").ServiceHandlerFunction<Record<string, unknown>, FabricEntity | null>;
|
|
47
6
|
/**
|
|
48
7
|
* Put (create or replace) an entity
|
|
49
8
|
* Auto-populates GSI index keys via indexEntity
|
|
9
|
+
*
|
|
10
|
+
* Note: This is a regular async function (not serviceHandler) because it accepts
|
|
11
|
+
* complex FabricEntity objects that can't be coerced by vocabulary's type system.
|
|
50
12
|
*/
|
|
51
|
-
export declare function putEntity
|
|
13
|
+
export declare function putEntity({ entity, }: {
|
|
14
|
+
entity: FabricEntity;
|
|
15
|
+
}): Promise<FabricEntity>;
|
|
52
16
|
/**
|
|
53
17
|
* Update an existing entity
|
|
54
18
|
* Auto-populates GSI index keys and sets updatedAt
|
|
19
|
+
*
|
|
20
|
+
* Note: This is a regular async function (not serviceHandler) because it accepts
|
|
21
|
+
* complex FabricEntity objects that can't be coerced by vocabulary's type system.
|
|
55
22
|
*/
|
|
56
|
-
export declare function updateEntity
|
|
23
|
+
export declare function updateEntity({ entity, }: {
|
|
24
|
+
entity: FabricEntity;
|
|
25
|
+
}): Promise<FabricEntity>;
|
|
57
26
|
/**
|
|
58
27
|
* Soft delete an entity by setting deletedAt timestamp
|
|
59
28
|
* Re-indexes with appropriate suffix based on archived/deleted state
|
|
60
29
|
*/
|
|
61
|
-
export declare
|
|
30
|
+
export declare const deleteEntity: import("@jaypie/vocabulary").ServiceHandlerFunction<Record<string, unknown>, boolean>;
|
|
62
31
|
/**
|
|
63
32
|
* Archive an entity by setting archivedAt timestamp
|
|
64
33
|
* Re-indexes with appropriate suffix based on archived/deleted state
|
|
65
34
|
*/
|
|
66
|
-
export declare
|
|
35
|
+
export declare const archiveEntity: import("@jaypie/vocabulary").ServiceHandlerFunction<Record<string, unknown>, boolean>;
|
|
67
36
|
/**
|
|
68
37
|
* Hard delete an entity (permanently removes from table)
|
|
69
38
|
* Use with caution - prefer deleteEntity for soft delete
|
|
70
39
|
*/
|
|
71
|
-
export declare
|
|
40
|
+
export declare const destroyEntity: import("@jaypie/vocabulary").ServiceHandlerFunction<Record<string, unknown>, boolean>;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -3,6 +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
7
|
|
|
7
8
|
const DEFAULT_REGION = "us-east-1";
|
|
8
9
|
const LOCAL_CREDENTIALS = {
|
|
@@ -187,25 +188,51 @@ function indexEntity(entity, suffix = "") {
|
|
|
187
188
|
}
|
|
188
189
|
|
|
189
190
|
/**
|
|
190
|
-
*
|
|
191
|
+
* Calculate suffix based on entity's archived/deleted state
|
|
191
192
|
*/
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
193
|
+
function calculateEntitySuffix(entity) {
|
|
194
|
+
const hasArchived = Boolean(entity.archivedAt);
|
|
195
|
+
const hasDeleted = Boolean(entity.deletedAt);
|
|
196
|
+
if (hasArchived && hasDeleted) {
|
|
197
|
+
return ARCHIVED_SUFFIX + DELETED_SUFFIX;
|
|
198
|
+
}
|
|
199
|
+
if (hasArchived) {
|
|
200
|
+
return ARCHIVED_SUFFIX;
|
|
201
|
+
}
|
|
202
|
+
if (hasDeleted) {
|
|
203
|
+
return DELETED_SUFFIX;
|
|
204
|
+
}
|
|
205
|
+
return "";
|
|
202
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Get a single entity by primary key
|
|
209
|
+
*/
|
|
210
|
+
const getEntity = vocabulary.serviceHandler({
|
|
211
|
+
alias: "getEntity",
|
|
212
|
+
description: "Get a single entity by primary key",
|
|
213
|
+
input: {
|
|
214
|
+
id: { type: String, description: "Entity ID (sort key)" },
|
|
215
|
+
model: { type: String, description: "Entity model (partition key)" },
|
|
216
|
+
},
|
|
217
|
+
service: async ({ id, model }) => {
|
|
218
|
+
const docClient = getDocClient();
|
|
219
|
+
const tableName = getTableName();
|
|
220
|
+
const command = new libDynamodb.GetCommand({
|
|
221
|
+
Key: { id, model },
|
|
222
|
+
TableName: tableName,
|
|
223
|
+
});
|
|
224
|
+
const response = await docClient.send(command);
|
|
225
|
+
return response.Item ?? null;
|
|
226
|
+
},
|
|
227
|
+
});
|
|
203
228
|
/**
|
|
204
229
|
* Put (create or replace) an entity
|
|
205
230
|
* Auto-populates GSI index keys via indexEntity
|
|
231
|
+
*
|
|
232
|
+
* Note: This is a regular async function (not serviceHandler) because it accepts
|
|
233
|
+
* complex FabricEntity objects that can't be coerced by vocabulary's type system.
|
|
206
234
|
*/
|
|
207
|
-
async function putEntity(
|
|
208
|
-
const { entity } = params;
|
|
235
|
+
async function putEntity({ entity, }) {
|
|
209
236
|
const docClient = getDocClient();
|
|
210
237
|
const tableName = getTableName();
|
|
211
238
|
// Auto-populate index keys
|
|
@@ -220,9 +247,11 @@ async function putEntity(params) {
|
|
|
220
247
|
/**
|
|
221
248
|
* Update an existing entity
|
|
222
249
|
* Auto-populates GSI index keys and sets updatedAt
|
|
250
|
+
*
|
|
251
|
+
* Note: This is a regular async function (not serviceHandler) because it accepts
|
|
252
|
+
* complex FabricEntity objects that can't be coerced by vocabulary's type system.
|
|
223
253
|
*/
|
|
224
|
-
async function updateEntity(
|
|
225
|
-
const { entity } = params;
|
|
254
|
+
async function updateEntity({ entity, }) {
|
|
226
255
|
const docClient = getDocClient();
|
|
227
256
|
const tableName = getTableName();
|
|
228
257
|
// Update timestamp and re-index
|
|
@@ -237,98 +266,102 @@ async function updateEntity(params) {
|
|
|
237
266
|
await docClient.send(command);
|
|
238
267
|
return updatedEntity;
|
|
239
268
|
}
|
|
240
|
-
/**
|
|
241
|
-
* Calculate suffix based on entity's archived/deleted state
|
|
242
|
-
*/
|
|
243
|
-
function calculateEntitySuffix(entity) {
|
|
244
|
-
const hasArchived = Boolean(entity.archivedAt);
|
|
245
|
-
const hasDeleted = Boolean(entity.deletedAt);
|
|
246
|
-
if (hasArchived && hasDeleted) {
|
|
247
|
-
return ARCHIVED_SUFFIX + DELETED_SUFFIX;
|
|
248
|
-
}
|
|
249
|
-
if (hasArchived) {
|
|
250
|
-
return ARCHIVED_SUFFIX;
|
|
251
|
-
}
|
|
252
|
-
if (hasDeleted) {
|
|
253
|
-
return DELETED_SUFFIX;
|
|
254
|
-
}
|
|
255
|
-
return "";
|
|
256
|
-
}
|
|
257
269
|
/**
|
|
258
270
|
* Soft delete an entity by setting deletedAt timestamp
|
|
259
271
|
* Re-indexes with appropriate suffix based on archived/deleted state
|
|
260
272
|
*/
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
273
|
+
const deleteEntity = vocabulary.serviceHandler({
|
|
274
|
+
alias: "deleteEntity",
|
|
275
|
+
description: "Soft delete an entity (sets deletedAt timestamp)",
|
|
276
|
+
input: {
|
|
277
|
+
id: { type: String, description: "Entity ID (sort key)" },
|
|
278
|
+
model: { type: String, description: "Entity model (partition key)" },
|
|
279
|
+
},
|
|
280
|
+
service: async ({ id, model }) => {
|
|
281
|
+
const docClient = getDocClient();
|
|
282
|
+
const tableName = getTableName();
|
|
283
|
+
// Fetch the current entity
|
|
284
|
+
const existing = await getEntity({ id, model });
|
|
285
|
+
if (!existing) {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
const now = new Date().toISOString();
|
|
289
|
+
// Build updated entity with deletedAt
|
|
290
|
+
const updatedEntity = {
|
|
291
|
+
...existing,
|
|
292
|
+
deletedAt: now,
|
|
293
|
+
updatedAt: now,
|
|
294
|
+
};
|
|
295
|
+
// Calculate suffix based on combined state (may already be archived)
|
|
296
|
+
const suffix = calculateEntitySuffix(updatedEntity);
|
|
297
|
+
const deletedEntity = indexEntity(updatedEntity, suffix);
|
|
298
|
+
const command = new libDynamodb.PutCommand({
|
|
299
|
+
Item: deletedEntity,
|
|
300
|
+
TableName: tableName,
|
|
301
|
+
});
|
|
302
|
+
await docClient.send(command);
|
|
303
|
+
return true;
|
|
304
|
+
},
|
|
305
|
+
});
|
|
287
306
|
/**
|
|
288
307
|
* Archive an entity by setting archivedAt timestamp
|
|
289
308
|
* Re-indexes with appropriate suffix based on archived/deleted state
|
|
290
309
|
*/
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
310
|
+
const archiveEntity = vocabulary.serviceHandler({
|
|
311
|
+
alias: "archiveEntity",
|
|
312
|
+
description: "Archive an entity (sets archivedAt timestamp)",
|
|
313
|
+
input: {
|
|
314
|
+
id: { type: String, description: "Entity ID (sort key)" },
|
|
315
|
+
model: { type: String, description: "Entity model (partition key)" },
|
|
316
|
+
},
|
|
317
|
+
service: async ({ id, model }) => {
|
|
318
|
+
const docClient = getDocClient();
|
|
319
|
+
const tableName = getTableName();
|
|
320
|
+
// Fetch the current entity
|
|
321
|
+
const existing = await getEntity({ id, model });
|
|
322
|
+
if (!existing) {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
const now = new Date().toISOString();
|
|
326
|
+
// Build updated entity with archivedAt
|
|
327
|
+
const updatedEntity = {
|
|
328
|
+
...existing,
|
|
329
|
+
archivedAt: now,
|
|
330
|
+
updatedAt: now,
|
|
331
|
+
};
|
|
332
|
+
// Calculate suffix based on combined state (may already be deleted)
|
|
333
|
+
const suffix = calculateEntitySuffix(updatedEntity);
|
|
334
|
+
const archivedEntity = indexEntity(updatedEntity, suffix);
|
|
335
|
+
const command = new libDynamodb.PutCommand({
|
|
336
|
+
Item: archivedEntity,
|
|
337
|
+
TableName: tableName,
|
|
338
|
+
});
|
|
339
|
+
await docClient.send(command);
|
|
340
|
+
return true;
|
|
341
|
+
},
|
|
342
|
+
});
|
|
317
343
|
/**
|
|
318
344
|
* Hard delete an entity (permanently removes from table)
|
|
319
345
|
* Use with caution - prefer deleteEntity for soft delete
|
|
320
346
|
*/
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
})
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
347
|
+
const destroyEntity = vocabulary.serviceHandler({
|
|
348
|
+
alias: "destroyEntity",
|
|
349
|
+
description: "Hard delete an entity (permanently removes from table)",
|
|
350
|
+
input: {
|
|
351
|
+
id: { type: String, description: "Entity ID (sort key)" },
|
|
352
|
+
model: { type: String, description: "Entity model (partition key)" },
|
|
353
|
+
},
|
|
354
|
+
service: async ({ id, model }) => {
|
|
355
|
+
const docClient = getDocClient();
|
|
356
|
+
const tableName = getTableName();
|
|
357
|
+
const command = new libDynamodb.DeleteCommand({
|
|
358
|
+
Key: { id, model },
|
|
359
|
+
TableName: tableName,
|
|
360
|
+
});
|
|
361
|
+
await docClient.send(command);
|
|
362
|
+
return true;
|
|
363
|
+
},
|
|
364
|
+
});
|
|
332
365
|
|
|
333
366
|
/**
|
|
334
367
|
* Calculate the suffix based on archived/deleted flags
|
|
@@ -377,76 +410,126 @@ async function executeQuery(indexName, keyValue, options = {}) {
|
|
|
377
410
|
* Query entities by organizational unit (parent hierarchy)
|
|
378
411
|
* Uses indexOu GSI
|
|
379
412
|
*
|
|
380
|
-
*
|
|
381
|
-
*
|
|
382
|
-
* @throws ConfigurationError if both archived and deleted are true
|
|
413
|
+
* Note: This is a regular async function (not serviceHandler) because it accepts
|
|
414
|
+
* complex startKey objects that can't be coerced by vocabulary's type system.
|
|
383
415
|
*/
|
|
384
|
-
async function queryByOu(
|
|
385
|
-
const { archived, deleted, model, ou, ...options } = params;
|
|
416
|
+
async function queryByOu({ archived = false, ascending = false, deleted = false, limit, model, ou, startKey, }) {
|
|
386
417
|
const suffix = calculateSuffix({ archived, deleted });
|
|
387
418
|
const keyValue = buildIndexOu(ou, model) + suffix;
|
|
388
|
-
return executeQuery(INDEX_OU, keyValue,
|
|
419
|
+
return executeQuery(INDEX_OU, keyValue, {
|
|
420
|
+
ascending,
|
|
421
|
+
limit,
|
|
422
|
+
startKey,
|
|
423
|
+
});
|
|
389
424
|
}
|
|
390
425
|
/**
|
|
391
426
|
* Query a single entity by human-friendly alias
|
|
392
427
|
* Uses indexAlias GSI
|
|
393
|
-
*
|
|
394
|
-
* @param params.archived - Query archived entities instead of active ones
|
|
395
|
-
* @param params.deleted - Query deleted entities instead of active ones
|
|
396
|
-
* @throws ConfigurationError if both archived and deleted are true
|
|
397
|
-
* @returns The matching entity or null if not found
|
|
398
428
|
*/
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
429
|
+
const queryByAlias = vocabulary.serviceHandler({
|
|
430
|
+
alias: "queryByAlias",
|
|
431
|
+
description: "Query a single entity by human-friendly alias",
|
|
432
|
+
input: {
|
|
433
|
+
alias: { type: String, description: "Human-friendly alias" },
|
|
434
|
+
archived: {
|
|
435
|
+
type: Boolean,
|
|
436
|
+
default: false,
|
|
437
|
+
required: false,
|
|
438
|
+
description: "Query archived entities instead of active ones",
|
|
439
|
+
},
|
|
440
|
+
deleted: {
|
|
441
|
+
type: Boolean,
|
|
442
|
+
default: false,
|
|
443
|
+
required: false,
|
|
444
|
+
description: "Query deleted entities instead of active ones",
|
|
445
|
+
},
|
|
446
|
+
model: { type: String, description: "Entity model name" },
|
|
447
|
+
ou: { type: String, description: "Organizational unit (@ for root)" },
|
|
448
|
+
},
|
|
449
|
+
service: async ({ alias, archived, deleted, model, ou, }) => {
|
|
450
|
+
const aliasStr = alias;
|
|
451
|
+
const archivedBool = archived;
|
|
452
|
+
const deletedBool = deleted;
|
|
453
|
+
const modelStr = model;
|
|
454
|
+
const ouStr = ou;
|
|
455
|
+
const suffix = calculateSuffix({ archived: archivedBool, deleted: deletedBool });
|
|
456
|
+
const keyValue = buildIndexAlias(ouStr, modelStr, aliasStr) + suffix;
|
|
457
|
+
const result = await executeQuery(INDEX_ALIAS, keyValue, {
|
|
458
|
+
limit: 1,
|
|
459
|
+
});
|
|
460
|
+
return result.items[0] ?? null;
|
|
461
|
+
},
|
|
462
|
+
});
|
|
406
463
|
/**
|
|
407
464
|
* Query entities by category classification
|
|
408
465
|
* Uses indexClass GSI
|
|
409
466
|
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
* @throws ConfigurationError if both archived and deleted are true
|
|
467
|
+
* Note: This is a regular async function (not serviceHandler) because it accepts
|
|
468
|
+
* complex startKey objects that can't be coerced by vocabulary's type system.
|
|
413
469
|
*/
|
|
414
|
-
async function queryByClass(
|
|
415
|
-
const { archived, deleted, model, ou, recordClass, ...options } = params;
|
|
470
|
+
async function queryByClass({ archived = false, ascending = false, deleted = false, limit, model, ou, recordClass, startKey, }) {
|
|
416
471
|
const suffix = calculateSuffix({ archived, deleted });
|
|
417
472
|
const keyValue = buildIndexClass(ou, model, recordClass) + suffix;
|
|
418
|
-
return executeQuery(INDEX_CLASS, keyValue,
|
|
473
|
+
return executeQuery(INDEX_CLASS, keyValue, {
|
|
474
|
+
ascending,
|
|
475
|
+
limit,
|
|
476
|
+
startKey,
|
|
477
|
+
});
|
|
419
478
|
}
|
|
420
479
|
/**
|
|
421
480
|
* Query entities by type classification
|
|
422
481
|
* Uses indexType GSI
|
|
423
482
|
*
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
* @throws ConfigurationError if both archived and deleted are true
|
|
483
|
+
* Note: This is a regular async function (not serviceHandler) because it accepts
|
|
484
|
+
* complex startKey objects that can't be coerced by vocabulary's type system.
|
|
427
485
|
*/
|
|
428
|
-
async function queryByType(
|
|
429
|
-
const { archived, deleted, model, ou, type, ...options } = params;
|
|
486
|
+
async function queryByType({ archived = false, ascending = false, deleted = false, limit, model, ou, startKey, type, }) {
|
|
430
487
|
const suffix = calculateSuffix({ archived, deleted });
|
|
431
488
|
const keyValue = buildIndexType(ou, model, type) + suffix;
|
|
432
|
-
return executeQuery(INDEX_TYPE, keyValue,
|
|
489
|
+
return executeQuery(INDEX_TYPE, keyValue, {
|
|
490
|
+
ascending,
|
|
491
|
+
limit,
|
|
492
|
+
startKey,
|
|
493
|
+
});
|
|
433
494
|
}
|
|
434
495
|
/**
|
|
435
496
|
* Query a single entity by external ID
|
|
436
497
|
* Uses indexXid GSI
|
|
437
|
-
*
|
|
438
|
-
* @param params.archived - Query archived entities instead of active ones
|
|
439
|
-
* @param params.deleted - Query deleted entities instead of active ones
|
|
440
|
-
* @throws ConfigurationError if both archived and deleted are true
|
|
441
|
-
* @returns The matching entity or null if not found
|
|
442
498
|
*/
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
499
|
+
const queryByXid = vocabulary.serviceHandler({
|
|
500
|
+
alias: "queryByXid",
|
|
501
|
+
description: "Query a single entity by external ID",
|
|
502
|
+
input: {
|
|
503
|
+
archived: {
|
|
504
|
+
type: Boolean,
|
|
505
|
+
default: false,
|
|
506
|
+
required: false,
|
|
507
|
+
description: "Query archived entities instead of active ones",
|
|
508
|
+
},
|
|
509
|
+
deleted: {
|
|
510
|
+
type: Boolean,
|
|
511
|
+
default: false,
|
|
512
|
+
required: false,
|
|
513
|
+
description: "Query deleted entities instead of active ones",
|
|
514
|
+
},
|
|
515
|
+
model: { type: String, description: "Entity model name" },
|
|
516
|
+
ou: { type: String, description: "Organizational unit (@ for root)" },
|
|
517
|
+
xid: { type: String, description: "External ID" },
|
|
518
|
+
},
|
|
519
|
+
service: async ({ archived, deleted, model, ou, xid, }) => {
|
|
520
|
+
const archivedBool = archived;
|
|
521
|
+
const deletedBool = deleted;
|
|
522
|
+
const modelStr = model;
|
|
523
|
+
const ouStr = ou;
|
|
524
|
+
const xidStr = xid;
|
|
525
|
+
const suffix = calculateSuffix({ archived: archivedBool, deleted: deletedBool });
|
|
526
|
+
const keyValue = buildIndexXid(ouStr, modelStr, xidStr) + suffix;
|
|
527
|
+
const result = await executeQuery(INDEX_XID, keyValue, {
|
|
528
|
+
limit: 1,
|
|
529
|
+
});
|
|
530
|
+
return result.items[0] ?? null;
|
|
531
|
+
},
|
|
532
|
+
});
|
|
450
533
|
|
|
451
534
|
exports.APEX = APEX;
|
|
452
535
|
exports.ARCHIVED_SUFFIX = ARCHIVED_SUFFIX;
|