@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.
- package/dist/cjs/constants.d.ts +2 -2
- package/dist/cjs/entities.d.ts +6 -6
- package/dist/cjs/index.cjs +112 -106
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/keyBuilders.d.ts +21 -21
- package/dist/cjs/mcp/admin/createTable.d.ts +1 -1
- package/dist/cjs/mcp/admin/dockerCompose.d.ts +1 -1
- package/dist/cjs/mcp/admin/status.d.ts +1 -1
- package/dist/cjs/mcp/index.cjs +143 -121
- package/dist/cjs/mcp/index.cjs.map +1 -1
- package/dist/cjs/queries.d.ts +15 -15
- package/dist/cjs/query.d.ts +7 -7
- package/dist/cjs/seedExport.d.ts +7 -7
- package/dist/cjs/types.d.ts +20 -20
- package/dist/esm/constants.d.ts +2 -2
- package/dist/esm/entities.d.ts +6 -6
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +91 -85
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/keyBuilders.d.ts +21 -21
- package/dist/esm/mcp/admin/createTable.d.ts +1 -1
- package/dist/esm/mcp/admin/dockerCompose.d.ts +1 -1
- package/dist/esm/mcp/admin/status.d.ts +1 -1
- package/dist/esm/mcp/index.js +133 -111
- package/dist/esm/mcp/index.js.map +1 -1
- package/dist/esm/queries.d.ts +15 -15
- package/dist/esm/query.d.ts +7 -7
- package/dist/esm/seedExport.d.ts +7 -7
- package/dist/esm/types.d.ts +20 -20
- package/package.json +2 -2
package/dist/esm/mcp/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getModelIndexes, populateIndexKeys, SEPARATOR,
|
|
1
|
+
import { fabricMcp } from '@jaypie/fabric/mcp';
|
|
2
|
+
import { getModelIndexes, populateIndexKeys, SEPARATOR, fabricService, ARCHIVED_SUFFIX, DELETED_SUFFIX, DEFAULT_INDEXES, getAllRegisteredIndexes } from '@jaypie/fabric';
|
|
3
3
|
import { DynamoDBClient, DescribeTableCommand, CreateTableCommand } from '@aws-sdk/client-dynamodb';
|
|
4
4
|
import { DynamoDBDocumentClient, GetCommand, PutCommand, DeleteCommand, QueryCommand } from '@aws-sdk/lib-dynamodb';
|
|
5
5
|
import { ConfigurationError } from '@jaypie/errors';
|
|
@@ -75,11 +75,11 @@ function isInitialized() {
|
|
|
75
75
|
return docClient !== null && tableName !== null;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
// Re-export shared constants from
|
|
78
|
+
// Re-export shared constants from fabric
|
|
79
79
|
// GSI names (derived from DEFAULT_INDEXES)
|
|
80
80
|
const INDEX_ALIAS = "indexAlias";
|
|
81
81
|
const INDEX_CLASS = "indexClass";
|
|
82
|
-
const
|
|
82
|
+
const INDEX_SCOPE = "indexScope";
|
|
83
83
|
const INDEX_TYPE = "indexType";
|
|
84
84
|
const INDEX_XID = "indexXid";
|
|
85
85
|
|
|
@@ -87,53 +87,53 @@ const INDEX_XID = "indexXid";
|
|
|
87
87
|
// Key Builders
|
|
88
88
|
// =============================================================================
|
|
89
89
|
/**
|
|
90
|
-
* Build the
|
|
91
|
-
* @param
|
|
90
|
+
* Build the indexScope key for hierarchical queries
|
|
91
|
+
* @param scope - The scope (APEX or "{parent.model}#{parent.id}")
|
|
92
92
|
* @param model - The entity model name
|
|
93
|
-
* @returns Composite key: "{
|
|
93
|
+
* @returns Composite key: "{scope}#{model}"
|
|
94
94
|
*/
|
|
95
|
-
function
|
|
96
|
-
return `${
|
|
95
|
+
function buildIndexScope(scope, model) {
|
|
96
|
+
return `${scope}${SEPARATOR}${model}`;
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
99
|
* Build the indexAlias key for human-friendly lookups
|
|
100
|
-
* @param
|
|
100
|
+
* @param scope - The scope
|
|
101
101
|
* @param model - The entity model name
|
|
102
102
|
* @param alias - The human-friendly alias
|
|
103
|
-
* @returns Composite key: "{
|
|
103
|
+
* @returns Composite key: "{scope}#{model}#{alias}"
|
|
104
104
|
*/
|
|
105
|
-
function buildIndexAlias(
|
|
106
|
-
return `${
|
|
105
|
+
function buildIndexAlias(scope, model, alias) {
|
|
106
|
+
return `${scope}${SEPARATOR}${model}${SEPARATOR}${alias}`;
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
109
109
|
* Build the indexClass key for category filtering
|
|
110
|
-
* @param
|
|
110
|
+
* @param scope - The scope
|
|
111
111
|
* @param model - The entity model name
|
|
112
112
|
* @param recordClass - The category classification
|
|
113
|
-
* @returns Composite key: "{
|
|
113
|
+
* @returns Composite key: "{scope}#{model}#{class}"
|
|
114
114
|
*/
|
|
115
|
-
function buildIndexClass(
|
|
116
|
-
return `${
|
|
115
|
+
function buildIndexClass(scope, model, recordClass) {
|
|
116
|
+
return `${scope}${SEPARATOR}${model}${SEPARATOR}${recordClass}`;
|
|
117
117
|
}
|
|
118
118
|
/**
|
|
119
119
|
* Build the indexType key for type filtering
|
|
120
|
-
* @param
|
|
120
|
+
* @param scope - The scope
|
|
121
121
|
* @param model - The entity model name
|
|
122
122
|
* @param type - The type classification
|
|
123
|
-
* @returns Composite key: "{
|
|
123
|
+
* @returns Composite key: "{scope}#{model}#{type}"
|
|
124
124
|
*/
|
|
125
|
-
function buildIndexType(
|
|
126
|
-
return `${
|
|
125
|
+
function buildIndexType(scope, model, type) {
|
|
126
|
+
return `${scope}${SEPARATOR}${model}${SEPARATOR}${type}`;
|
|
127
127
|
}
|
|
128
128
|
/**
|
|
129
129
|
* Build the indexXid key for external ID lookups
|
|
130
|
-
* @param
|
|
130
|
+
* @param scope - The scope
|
|
131
131
|
* @param model - The entity model name
|
|
132
132
|
* @param xid - The external ID
|
|
133
|
-
* @returns Composite key: "{
|
|
133
|
+
* @returns Composite key: "{scope}#{model}#{xid}"
|
|
134
134
|
*/
|
|
135
|
-
function buildIndexXid(
|
|
136
|
-
return `${
|
|
135
|
+
function buildIndexXid(scope, model, xid) {
|
|
136
|
+
return `${scope}${SEPARATOR}${model}${SEPARATOR}${xid}`;
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
139
139
|
* Auto-populate GSI index keys on an entity
|
|
@@ -141,7 +141,7 @@ function buildIndexXid(ou, model, xid) {
|
|
|
141
141
|
* Uses the model's registered indexes (from vocabulary registry) or
|
|
142
142
|
* DEFAULT_INDEXES if no custom indexes are registered.
|
|
143
143
|
*
|
|
144
|
-
* -
|
|
144
|
+
* - indexScope is always populated from scope + model
|
|
145
145
|
* - indexAlias is populated only when alias is present
|
|
146
146
|
* - indexClass is populated only when class is present
|
|
147
147
|
* - indexType is populated only when type is present
|
|
@@ -153,7 +153,7 @@ function buildIndexXid(ou, model, xid) {
|
|
|
153
153
|
*/
|
|
154
154
|
function indexEntity(entity, suffix = "") {
|
|
155
155
|
const indexes = getModelIndexes(entity.model);
|
|
156
|
-
// Cast through unknown to bridge the type gap between StorableEntity and
|
|
156
|
+
// Cast through unknown to bridge the type gap between StorableEntity and IndexableModel
|
|
157
157
|
return populateIndexKeys(entity, indexes, suffix);
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -177,7 +177,7 @@ function calculateEntitySuffix(entity) {
|
|
|
177
177
|
/**
|
|
178
178
|
* Get a single entity by primary key
|
|
179
179
|
*/
|
|
180
|
-
const getEntity =
|
|
180
|
+
const getEntity = fabricService({
|
|
181
181
|
alias: "getEntity",
|
|
182
182
|
description: "Get a single entity by primary key",
|
|
183
183
|
input: {
|
|
@@ -199,7 +199,7 @@ const getEntity = serviceHandler({
|
|
|
199
199
|
* Put (create or replace) an entity
|
|
200
200
|
* Auto-populates GSI index keys via indexEntity
|
|
201
201
|
*
|
|
202
|
-
* Note: This is a regular async function (not
|
|
202
|
+
* Note: This is a regular async function (not fabricService) because it accepts
|
|
203
203
|
* complex StorableEntity objects that can't be coerced by vocabulary's type system.
|
|
204
204
|
*/
|
|
205
205
|
async function putEntity({ entity, }) {
|
|
@@ -218,7 +218,7 @@ async function putEntity({ entity, }) {
|
|
|
218
218
|
* Update an existing entity
|
|
219
219
|
* Auto-populates GSI index keys and sets updatedAt
|
|
220
220
|
*
|
|
221
|
-
* Note: This is a regular async function (not
|
|
221
|
+
* Note: This is a regular async function (not fabricService) because it accepts
|
|
222
222
|
* complex StorableEntity objects that can't be coerced by vocabulary's type system.
|
|
223
223
|
*/
|
|
224
224
|
async function updateEntity({ entity, }) {
|
|
@@ -240,7 +240,7 @@ async function updateEntity({ entity, }) {
|
|
|
240
240
|
* Soft delete an entity by setting deletedAt timestamp
|
|
241
241
|
* Re-indexes with appropriate suffix based on archived/deleted state
|
|
242
242
|
*/
|
|
243
|
-
const deleteEntity =
|
|
243
|
+
const deleteEntity = fabricService({
|
|
244
244
|
alias: "deleteEntity",
|
|
245
245
|
description: "Soft delete an entity (sets deletedAt timestamp)",
|
|
246
246
|
input: {
|
|
@@ -277,7 +277,7 @@ const deleteEntity = serviceHandler({
|
|
|
277
277
|
* Archive an entity by setting archivedAt timestamp
|
|
278
278
|
* Re-indexes with appropriate suffix based on archived/deleted state
|
|
279
279
|
*/
|
|
280
|
-
const archiveEntity =
|
|
280
|
+
const archiveEntity = fabricService({
|
|
281
281
|
alias: "archiveEntity",
|
|
282
282
|
description: "Archive an entity (sets archivedAt timestamp)",
|
|
283
283
|
input: {
|
|
@@ -314,7 +314,7 @@ const archiveEntity = serviceHandler({
|
|
|
314
314
|
* Hard delete an entity (permanently removes from table)
|
|
315
315
|
* Use with caution - prefer deleteEntity for soft delete
|
|
316
316
|
*/
|
|
317
|
-
const destroyEntity =
|
|
317
|
+
const destroyEntity = fabricService({
|
|
318
318
|
alias: "destroyEntity",
|
|
319
319
|
description: "Hard delete an entity (permanently removes from table)",
|
|
320
320
|
input: {
|
|
@@ -377,16 +377,16 @@ async function executeQuery(indexName, keyValue, options = {}) {
|
|
|
377
377
|
};
|
|
378
378
|
}
|
|
379
379
|
/**
|
|
380
|
-
* Query entities by
|
|
381
|
-
* Uses
|
|
380
|
+
* Query entities by scope (parent hierarchy)
|
|
381
|
+
* Uses indexScope GSI
|
|
382
382
|
*
|
|
383
|
-
* Note: This is a regular async function (not
|
|
383
|
+
* Note: This is a regular async function (not fabricService) because it accepts
|
|
384
384
|
* complex startKey objects that can't be coerced by vocabulary's type system.
|
|
385
385
|
*/
|
|
386
|
-
async function
|
|
386
|
+
async function queryByScope({ archived = false, ascending = false, deleted = false, limit, model, scope, startKey, }) {
|
|
387
387
|
const suffix = calculateSuffix({ archived, deleted });
|
|
388
|
-
const keyValue =
|
|
389
|
-
return executeQuery(
|
|
388
|
+
const keyValue = buildIndexScope(scope, model) + suffix;
|
|
389
|
+
return executeQuery(INDEX_SCOPE, keyValue, {
|
|
390
390
|
ascending,
|
|
391
391
|
limit,
|
|
392
392
|
startKey,
|
|
@@ -396,7 +396,7 @@ async function queryByOu({ archived = false, ascending = false, deleted = false,
|
|
|
396
396
|
* Query a single entity by human-friendly alias
|
|
397
397
|
* Uses indexAlias GSI
|
|
398
398
|
*/
|
|
399
|
-
const queryByAlias =
|
|
399
|
+
const queryByAlias = fabricService({
|
|
400
400
|
alias: "queryByAlias",
|
|
401
401
|
description: "Query a single entity by human-friendly alias",
|
|
402
402
|
input: {
|
|
@@ -414,16 +414,19 @@ const queryByAlias = serviceHandler({
|
|
|
414
414
|
description: "Query deleted entities instead of active ones",
|
|
415
415
|
},
|
|
416
416
|
model: { type: String, description: "Entity model name" },
|
|
417
|
-
|
|
417
|
+
scope: { type: String, description: "Scope (@ for root)" },
|
|
418
418
|
},
|
|
419
|
-
service: async ({ alias, archived, deleted, model,
|
|
419
|
+
service: async ({ alias, archived, deleted, model, scope, }) => {
|
|
420
420
|
const aliasStr = alias;
|
|
421
421
|
const archivedBool = archived;
|
|
422
422
|
const deletedBool = deleted;
|
|
423
423
|
const modelStr = model;
|
|
424
|
-
const
|
|
425
|
-
const suffix = calculateSuffix({
|
|
426
|
-
|
|
424
|
+
const scopeStr = scope;
|
|
425
|
+
const suffix = calculateSuffix({
|
|
426
|
+
archived: archivedBool,
|
|
427
|
+
deleted: deletedBool,
|
|
428
|
+
});
|
|
429
|
+
const keyValue = buildIndexAlias(scopeStr, modelStr, aliasStr) + suffix;
|
|
427
430
|
const result = await executeQuery(INDEX_ALIAS, keyValue, {
|
|
428
431
|
limit: 1,
|
|
429
432
|
});
|
|
@@ -434,12 +437,12 @@ const queryByAlias = serviceHandler({
|
|
|
434
437
|
* Query entities by category classification
|
|
435
438
|
* Uses indexClass GSI
|
|
436
439
|
*
|
|
437
|
-
* Note: This is a regular async function (not
|
|
440
|
+
* Note: This is a regular async function (not fabricService) because it accepts
|
|
438
441
|
* complex startKey objects that can't be coerced by vocabulary's type system.
|
|
439
442
|
*/
|
|
440
|
-
async function queryByClass({ archived = false, ascending = false, deleted = false, limit, model,
|
|
443
|
+
async function queryByClass({ archived = false, ascending = false, deleted = false, limit, model, scope, recordClass, startKey, }) {
|
|
441
444
|
const suffix = calculateSuffix({ archived, deleted });
|
|
442
|
-
const keyValue = buildIndexClass(
|
|
445
|
+
const keyValue = buildIndexClass(scope, model, recordClass) + suffix;
|
|
443
446
|
return executeQuery(INDEX_CLASS, keyValue, {
|
|
444
447
|
ascending,
|
|
445
448
|
limit,
|
|
@@ -450,12 +453,12 @@ async function queryByClass({ archived = false, ascending = false, deleted = fal
|
|
|
450
453
|
* Query entities by type classification
|
|
451
454
|
* Uses indexType GSI
|
|
452
455
|
*
|
|
453
|
-
* Note: This is a regular async function (not
|
|
456
|
+
* Note: This is a regular async function (not fabricService) because it accepts
|
|
454
457
|
* complex startKey objects that can't be coerced by vocabulary's type system.
|
|
455
458
|
*/
|
|
456
|
-
async function queryByType({ archived = false, ascending = false, deleted = false, limit, model,
|
|
459
|
+
async function queryByType({ archived = false, ascending = false, deleted = false, limit, model, scope, startKey, type, }) {
|
|
457
460
|
const suffix = calculateSuffix({ archived, deleted });
|
|
458
|
-
const keyValue = buildIndexType(
|
|
461
|
+
const keyValue = buildIndexType(scope, model, type) + suffix;
|
|
459
462
|
return executeQuery(INDEX_TYPE, keyValue, {
|
|
460
463
|
ascending,
|
|
461
464
|
limit,
|
|
@@ -466,7 +469,7 @@ async function queryByType({ archived = false, ascending = false, deleted = fals
|
|
|
466
469
|
* Query a single entity by external ID
|
|
467
470
|
* Uses indexXid GSI
|
|
468
471
|
*/
|
|
469
|
-
const queryByXid =
|
|
472
|
+
const queryByXid = fabricService({
|
|
470
473
|
alias: "queryByXid",
|
|
471
474
|
description: "Query a single entity by external ID",
|
|
472
475
|
input: {
|
|
@@ -483,17 +486,20 @@ const queryByXid = serviceHandler({
|
|
|
483
486
|
description: "Query deleted entities instead of active ones",
|
|
484
487
|
},
|
|
485
488
|
model: { type: String, description: "Entity model name" },
|
|
486
|
-
|
|
489
|
+
scope: { type: String, description: "Scope (@ for root)" },
|
|
487
490
|
xid: { type: String, description: "External ID" },
|
|
488
491
|
},
|
|
489
|
-
service: async ({ archived, deleted, model,
|
|
492
|
+
service: async ({ archived, deleted, model, scope, xid, }) => {
|
|
490
493
|
const archivedBool = archived;
|
|
491
494
|
const deletedBool = deleted;
|
|
492
495
|
const modelStr = model;
|
|
493
|
-
const
|
|
496
|
+
const scopeStr = scope;
|
|
494
497
|
const xidStr = xid;
|
|
495
|
-
const suffix = calculateSuffix({
|
|
496
|
-
|
|
498
|
+
const suffix = calculateSuffix({
|
|
499
|
+
archived: archivedBool,
|
|
500
|
+
deleted: deletedBool,
|
|
501
|
+
});
|
|
502
|
+
const keyValue = buildIndexXid(scopeStr, modelStr, xidStr) + suffix;
|
|
497
503
|
const result = await executeQuery(INDEX_XID, keyValue, {
|
|
498
504
|
limit: 1,
|
|
499
505
|
});
|
|
@@ -614,7 +620,7 @@ function createTableParams(tableName, billingMode) {
|
|
|
614
620
|
/**
|
|
615
621
|
* Create DynamoDB table with Jaypie GSI schema
|
|
616
622
|
*/
|
|
617
|
-
const createTableHandler =
|
|
623
|
+
const createTableHandler = fabricService({
|
|
618
624
|
alias: "dynamodb_create_table",
|
|
619
625
|
description: "Create DynamoDB table with Jaypie GSI schema",
|
|
620
626
|
input: {
|
|
@@ -678,7 +684,7 @@ const DEFAULT_TABLE_NAME = "jaypie-local";
|
|
|
678
684
|
/**
|
|
679
685
|
* Generate docker-compose.yml for local DynamoDB development
|
|
680
686
|
*/
|
|
681
|
-
const dockerComposeHandler =
|
|
687
|
+
const dockerComposeHandler = fabricService({
|
|
682
688
|
alias: "dynamodb_generate_docker_compose",
|
|
683
689
|
description: "Generate docker-compose.yml for local DynamoDB development",
|
|
684
690
|
input: {
|
|
@@ -776,7 +782,7 @@ function ensureInitialized() {
|
|
|
776
782
|
/**
|
|
777
783
|
* Check DynamoDB connection status and configuration
|
|
778
784
|
*/
|
|
779
|
-
const statusHandler =
|
|
785
|
+
const statusHandler = fabricService({
|
|
780
786
|
alias: "dynamodb_status",
|
|
781
787
|
description: "Check DynamoDB connection status and configuration",
|
|
782
788
|
service: async () => {
|
|
@@ -807,12 +813,12 @@ function wrapWithInit(handler) {
|
|
|
807
813
|
return wrapped;
|
|
808
814
|
}
|
|
809
815
|
// MCP-specific serviceHandler wrappers for functions with complex inputs
|
|
810
|
-
// Note: These wrap the regular async functions to make them work with
|
|
816
|
+
// Note: These wrap the regular async functions to make them work with fabricMcp
|
|
811
817
|
/**
|
|
812
818
|
* MCP wrapper for putEntity
|
|
813
819
|
* Accepts entity JSON directly from LLM
|
|
814
820
|
*/
|
|
815
|
-
const mcpPutEntity =
|
|
821
|
+
const mcpPutEntity = fabricService({
|
|
816
822
|
alias: "dynamodb_put",
|
|
817
823
|
description: "Create or replace an entity in DynamoDB (auto-indexes GSI keys)",
|
|
818
824
|
input: {
|
|
@@ -820,10 +826,18 @@ const mcpPutEntity = serviceHandler({
|
|
|
820
826
|
id: { type: String, description: "Entity ID (sort key)" },
|
|
821
827
|
model: { type: String, description: "Entity model name (partition key)" },
|
|
822
828
|
name: { type: String, description: "Entity name" },
|
|
823
|
-
|
|
829
|
+
scope: { type: String, description: "Scope (@ for root)" },
|
|
824
830
|
// Optional fields
|
|
825
|
-
alias: {
|
|
826
|
-
|
|
831
|
+
alias: {
|
|
832
|
+
type: String,
|
|
833
|
+
required: false,
|
|
834
|
+
description: "Human-friendly alias",
|
|
835
|
+
},
|
|
836
|
+
class: {
|
|
837
|
+
type: String,
|
|
838
|
+
required: false,
|
|
839
|
+
description: "Category classification",
|
|
840
|
+
},
|
|
827
841
|
type: { type: String, required: false, description: "Type classification" },
|
|
828
842
|
xid: { type: String, required: false, description: "External ID" },
|
|
829
843
|
},
|
|
@@ -836,7 +850,7 @@ const mcpPutEntity = serviceHandler({
|
|
|
836
850
|
id: input.id,
|
|
837
851
|
model: input.model,
|
|
838
852
|
name: input.name,
|
|
839
|
-
|
|
853
|
+
scope: input.scope,
|
|
840
854
|
sequence: Date.now(),
|
|
841
855
|
type: input.type,
|
|
842
856
|
updatedAt: now,
|
|
@@ -849,7 +863,7 @@ const mcpPutEntity = serviceHandler({
|
|
|
849
863
|
* MCP wrapper for updateEntity
|
|
850
864
|
* Accepts entity JSON directly from LLM
|
|
851
865
|
*/
|
|
852
|
-
const mcpUpdateEntity =
|
|
866
|
+
const mcpUpdateEntity = fabricService({
|
|
853
867
|
alias: "dynamodb_update",
|
|
854
868
|
description: "Update an entity in DynamoDB (sets updatedAt, re-indexes GSI keys)",
|
|
855
869
|
input: {
|
|
@@ -858,9 +872,17 @@ const mcpUpdateEntity = serviceHandler({
|
|
|
858
872
|
model: { type: String, description: "Entity model name (partition key)" },
|
|
859
873
|
// Fields that can be updated
|
|
860
874
|
name: { type: String, required: false, description: "Entity name" },
|
|
861
|
-
|
|
862
|
-
alias: {
|
|
863
|
-
|
|
875
|
+
scope: { type: String, required: false, description: "Scope" },
|
|
876
|
+
alias: {
|
|
877
|
+
type: String,
|
|
878
|
+
required: false,
|
|
879
|
+
description: "Human-friendly alias",
|
|
880
|
+
},
|
|
881
|
+
class: {
|
|
882
|
+
type: String,
|
|
883
|
+
required: false,
|
|
884
|
+
description: "Category classification",
|
|
885
|
+
},
|
|
864
886
|
type: { type: String, required: false, description: "Type classification" },
|
|
865
887
|
xid: { type: String, required: false, description: "External ID" },
|
|
866
888
|
},
|
|
@@ -879,7 +901,7 @@ const mcpUpdateEntity = serviceHandler({
|
|
|
879
901
|
...(input.alias !== undefined && { alias: input.alias }),
|
|
880
902
|
...(input.class !== undefined && { class: input.class }),
|
|
881
903
|
...(input.name !== undefined && { name: input.name }),
|
|
882
|
-
...(input.
|
|
904
|
+
...(input.scope !== undefined && { scope: input.scope }),
|
|
883
905
|
...(input.type !== undefined && { type: input.type }),
|
|
884
906
|
...(input.xid !== undefined && { xid: input.xid }),
|
|
885
907
|
};
|
|
@@ -887,15 +909,15 @@ const mcpUpdateEntity = serviceHandler({
|
|
|
887
909
|
},
|
|
888
910
|
});
|
|
889
911
|
/**
|
|
890
|
-
* MCP wrapper for
|
|
912
|
+
* MCP wrapper for queryByScope
|
|
891
913
|
* Note: Pagination via startKey is not exposed to MCP; use limit instead
|
|
892
914
|
*/
|
|
893
|
-
const
|
|
894
|
-
alias: "
|
|
895
|
-
description: "Query entities by
|
|
915
|
+
const mcpQueryByScope = fabricService({
|
|
916
|
+
alias: "dynamodb_query_scope",
|
|
917
|
+
description: "Query entities by scope (parent hierarchy)",
|
|
896
918
|
input: {
|
|
897
919
|
model: { type: String, description: "Entity model name" },
|
|
898
|
-
|
|
920
|
+
scope: { type: String, description: "Scope (@ for root)" },
|
|
899
921
|
archived: {
|
|
900
922
|
type: Boolean,
|
|
901
923
|
default: false,
|
|
@@ -921,13 +943,13 @@ const mcpQueryByOu = serviceHandler({
|
|
|
921
943
|
},
|
|
922
944
|
},
|
|
923
945
|
service: async (input) => {
|
|
924
|
-
return
|
|
946
|
+
return queryByScope({
|
|
925
947
|
archived: input.archived,
|
|
926
948
|
ascending: input.ascending,
|
|
927
949
|
deleted: input.deleted,
|
|
928
950
|
limit: input.limit,
|
|
929
951
|
model: input.model,
|
|
930
|
-
|
|
952
|
+
scope: input.scope,
|
|
931
953
|
});
|
|
932
954
|
},
|
|
933
955
|
});
|
|
@@ -935,12 +957,12 @@ const mcpQueryByOu = serviceHandler({
|
|
|
935
957
|
* MCP wrapper for queryByClass
|
|
936
958
|
* Note: Pagination via startKey is not exposed to MCP; use limit instead
|
|
937
959
|
*/
|
|
938
|
-
const mcpQueryByClass =
|
|
960
|
+
const mcpQueryByClass = fabricService({
|
|
939
961
|
alias: "dynamodb_query_class",
|
|
940
962
|
description: "Query entities by category classification",
|
|
941
963
|
input: {
|
|
942
964
|
model: { type: String, description: "Entity model name" },
|
|
943
|
-
|
|
965
|
+
scope: { type: String, description: "Scope (@ for root)" },
|
|
944
966
|
recordClass: { type: String, description: "Category classification" },
|
|
945
967
|
archived: {
|
|
946
968
|
type: Boolean,
|
|
@@ -973,7 +995,7 @@ const mcpQueryByClass = serviceHandler({
|
|
|
973
995
|
deleted: input.deleted,
|
|
974
996
|
limit: input.limit,
|
|
975
997
|
model: input.model,
|
|
976
|
-
|
|
998
|
+
scope: input.scope,
|
|
977
999
|
recordClass: input.recordClass,
|
|
978
1000
|
});
|
|
979
1001
|
},
|
|
@@ -982,12 +1004,12 @@ const mcpQueryByClass = serviceHandler({
|
|
|
982
1004
|
* MCP wrapper for queryByType
|
|
983
1005
|
* Note: Pagination via startKey is not exposed to MCP; use limit instead
|
|
984
1006
|
*/
|
|
985
|
-
const mcpQueryByType =
|
|
1007
|
+
const mcpQueryByType = fabricService({
|
|
986
1008
|
alias: "dynamodb_query_type",
|
|
987
1009
|
description: "Query entities by type classification",
|
|
988
1010
|
input: {
|
|
989
1011
|
model: { type: String, description: "Entity model name" },
|
|
990
|
-
|
|
1012
|
+
scope: { type: String, description: "Scope (@ for root)" },
|
|
991
1013
|
type: { type: String, description: "Type classification" },
|
|
992
1014
|
archived: {
|
|
993
1015
|
type: Boolean,
|
|
@@ -1020,7 +1042,7 @@ const mcpQueryByType = serviceHandler({
|
|
|
1020
1042
|
deleted: input.deleted,
|
|
1021
1043
|
limit: input.limit,
|
|
1022
1044
|
model: input.model,
|
|
1023
|
-
|
|
1045
|
+
scope: input.scope,
|
|
1024
1046
|
type: input.type,
|
|
1025
1047
|
});
|
|
1026
1048
|
},
|
|
@@ -1032,80 +1054,80 @@ function registerDynamoDbTools(config) {
|
|
|
1032
1054
|
const { includeAdmin = true, server } = config;
|
|
1033
1055
|
const tools = [];
|
|
1034
1056
|
// Entity operations
|
|
1035
|
-
|
|
1036
|
-
|
|
1057
|
+
fabricMcp({
|
|
1058
|
+
service: wrapWithInit(getEntity),
|
|
1037
1059
|
name: "dynamodb_get",
|
|
1038
1060
|
server,
|
|
1039
1061
|
});
|
|
1040
1062
|
tools.push("dynamodb_get");
|
|
1041
|
-
|
|
1042
|
-
|
|
1063
|
+
fabricMcp({
|
|
1064
|
+
service: wrapWithInit(mcpPutEntity),
|
|
1043
1065
|
name: "dynamodb_put",
|
|
1044
1066
|
server,
|
|
1045
1067
|
});
|
|
1046
1068
|
tools.push("dynamodb_put");
|
|
1047
|
-
|
|
1048
|
-
|
|
1069
|
+
fabricMcp({
|
|
1070
|
+
service: wrapWithInit(mcpUpdateEntity),
|
|
1049
1071
|
name: "dynamodb_update",
|
|
1050
1072
|
server,
|
|
1051
1073
|
});
|
|
1052
1074
|
tools.push("dynamodb_update");
|
|
1053
|
-
|
|
1054
|
-
|
|
1075
|
+
fabricMcp({
|
|
1076
|
+
service: wrapWithInit(deleteEntity),
|
|
1055
1077
|
name: "dynamodb_delete",
|
|
1056
1078
|
server,
|
|
1057
1079
|
});
|
|
1058
1080
|
tools.push("dynamodb_delete");
|
|
1059
|
-
|
|
1060
|
-
|
|
1081
|
+
fabricMcp({
|
|
1082
|
+
service: wrapWithInit(archiveEntity),
|
|
1061
1083
|
name: "dynamodb_archive",
|
|
1062
1084
|
server,
|
|
1063
1085
|
});
|
|
1064
1086
|
tools.push("dynamodb_archive");
|
|
1065
|
-
|
|
1066
|
-
|
|
1087
|
+
fabricMcp({
|
|
1088
|
+
service: wrapWithInit(destroyEntity),
|
|
1067
1089
|
name: "dynamodb_destroy",
|
|
1068
1090
|
server,
|
|
1069
1091
|
});
|
|
1070
1092
|
tools.push("dynamodb_destroy");
|
|
1071
1093
|
// Query operations
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
name: "
|
|
1094
|
+
fabricMcp({
|
|
1095
|
+
service: wrapWithInit(mcpQueryByScope),
|
|
1096
|
+
name: "dynamodb_query_scope",
|
|
1075
1097
|
server,
|
|
1076
1098
|
});
|
|
1077
|
-
tools.push("
|
|
1078
|
-
|
|
1079
|
-
|
|
1099
|
+
tools.push("dynamodb_query_scope");
|
|
1100
|
+
fabricMcp({
|
|
1101
|
+
service: wrapWithInit(queryByAlias),
|
|
1080
1102
|
name: "dynamodb_query_alias",
|
|
1081
1103
|
server,
|
|
1082
1104
|
});
|
|
1083
1105
|
tools.push("dynamodb_query_alias");
|
|
1084
|
-
|
|
1085
|
-
|
|
1106
|
+
fabricMcp({
|
|
1107
|
+
service: wrapWithInit(mcpQueryByClass),
|
|
1086
1108
|
name: "dynamodb_query_class",
|
|
1087
1109
|
server,
|
|
1088
1110
|
});
|
|
1089
1111
|
tools.push("dynamodb_query_class");
|
|
1090
|
-
|
|
1091
|
-
|
|
1112
|
+
fabricMcp({
|
|
1113
|
+
service: wrapWithInit(mcpQueryByType),
|
|
1092
1114
|
name: "dynamodb_query_type",
|
|
1093
1115
|
server,
|
|
1094
1116
|
});
|
|
1095
1117
|
tools.push("dynamodb_query_type");
|
|
1096
|
-
|
|
1097
|
-
|
|
1118
|
+
fabricMcp({
|
|
1119
|
+
service: wrapWithInit(queryByXid),
|
|
1098
1120
|
name: "dynamodb_query_xid",
|
|
1099
1121
|
server,
|
|
1100
1122
|
});
|
|
1101
1123
|
tools.push("dynamodb_query_xid");
|
|
1102
1124
|
// Admin tools (MCP-only)
|
|
1103
1125
|
if (includeAdmin) {
|
|
1104
|
-
|
|
1126
|
+
fabricMcp({ service: statusHandler, server });
|
|
1105
1127
|
tools.push("dynamodb_status");
|
|
1106
|
-
|
|
1128
|
+
fabricMcp({ service: createTableHandler, server });
|
|
1107
1129
|
tools.push("dynamodb_create_table");
|
|
1108
|
-
|
|
1130
|
+
fabricMcp({ service: dockerComposeHandler, server });
|
|
1109
1131
|
tools.push("dynamodb_generate_docker_compose");
|
|
1110
1132
|
}
|
|
1111
1133
|
return { tools };
|