graphddb 0.2.4 → 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/README.md +322 -305
- package/dist/{chunk-GCPEUPAA.js → chunk-6AIAHP3A.js} +1129 -156
- package/dist/{chunk-IQEOJVHI.js → chunk-QEOFIXTN.js} +1194 -60
- package/dist/{chunk-LNESVUTO.js → chunk-QQNP43JL.js} +1 -1
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +275 -73
- package/dist/index.js +131 -7
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +2 -2
- package/dist/{types-BEeQ_nSd.d.ts → types-xJRn5qkv.d.ts} +1567 -237
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
buildBridgeBundle,
|
|
17
17
|
buildContexts,
|
|
18
18
|
buildContracts,
|
|
19
|
+
buildMaintenanceGraph,
|
|
19
20
|
buildManifest,
|
|
20
21
|
buildOperations,
|
|
21
22
|
buildProjection,
|
|
@@ -56,6 +57,7 @@ import {
|
|
|
56
57
|
getEntityWrites,
|
|
57
58
|
getImplicitKeyFields,
|
|
58
59
|
hydrate,
|
|
60
|
+
identity,
|
|
59
61
|
isCommandModelContract,
|
|
60
62
|
isCommandPlan,
|
|
61
63
|
isContractComposeNode,
|
|
@@ -66,6 +68,7 @@ import {
|
|
|
66
68
|
isEdgeWritesDefinition,
|
|
67
69
|
isEntityWritesDefinition,
|
|
68
70
|
isLifecycleContract,
|
|
71
|
+
isMaintainTrigger,
|
|
69
72
|
isMutationFragment,
|
|
70
73
|
isMutationInputRef,
|
|
71
74
|
isPlannedCommandMethod,
|
|
@@ -73,11 +76,13 @@ import {
|
|
|
73
76
|
isSelectBuilder,
|
|
74
77
|
isTransactionRef,
|
|
75
78
|
lifecyclePhaseForIntent,
|
|
79
|
+
maintainTrigger,
|
|
76
80
|
mapWithConcurrency,
|
|
77
81
|
mintContractKeyFieldRef,
|
|
78
82
|
mintContractParamRef,
|
|
79
83
|
mutation,
|
|
80
84
|
plan,
|
|
85
|
+
preview,
|
|
81
86
|
publicCommandModel,
|
|
82
87
|
publicQueryModel,
|
|
83
88
|
query,
|
|
@@ -86,11 +91,11 @@ import {
|
|
|
86
91
|
validateDepth,
|
|
87
92
|
when,
|
|
88
93
|
wholeKeysSentinel
|
|
89
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-QEOFIXTN.js";
|
|
90
95
|
import {
|
|
91
96
|
CdcEmulator,
|
|
92
97
|
createCdcEmulator
|
|
93
|
-
} from "./chunk-
|
|
98
|
+
} from "./chunk-QQNP43JL.js";
|
|
94
99
|
import {
|
|
95
100
|
BATCH_GET_MAX_KEYS,
|
|
96
101
|
BATCH_WRITE_MAX_ITEMS,
|
|
@@ -139,7 +144,7 @@ import {
|
|
|
139
144
|
resolveKey,
|
|
140
145
|
resolveModelClass,
|
|
141
146
|
serializeFieldValue
|
|
142
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-6AIAHP3A.js";
|
|
143
148
|
|
|
144
149
|
// src/metadata/prefix.ts
|
|
145
150
|
function derivePrefix(customPrefix, className) {
|
|
@@ -189,6 +194,7 @@ function validateGsiAmbiguity(primaryKey, gsiDefinitions) {
|
|
|
189
194
|
var pendingFields = [];
|
|
190
195
|
var pendingEmbedded = [];
|
|
191
196
|
var pendingRelations = [];
|
|
197
|
+
var pendingAggregates = [];
|
|
192
198
|
function collectField(field2) {
|
|
193
199
|
pendingFields.push(field2);
|
|
194
200
|
}
|
|
@@ -198,6 +204,9 @@ function collectEmbedded(embedded2) {
|
|
|
198
204
|
function collectRelation(relation) {
|
|
199
205
|
pendingRelations.push(relation);
|
|
200
206
|
}
|
|
207
|
+
function collectAggregate(aggregate2) {
|
|
208
|
+
pendingAggregates.push(aggregate2);
|
|
209
|
+
}
|
|
201
210
|
function drainFields() {
|
|
202
211
|
const result = pendingFields;
|
|
203
212
|
pendingFields = [];
|
|
@@ -213,6 +222,11 @@ function drainRelations() {
|
|
|
213
222
|
pendingRelations = [];
|
|
214
223
|
return result;
|
|
215
224
|
}
|
|
225
|
+
function drainAggregates() {
|
|
226
|
+
const result = pendingAggregates;
|
|
227
|
+
pendingAggregates = [];
|
|
228
|
+
return result;
|
|
229
|
+
}
|
|
216
230
|
|
|
217
231
|
// src/decorators/model.ts
|
|
218
232
|
function model(options) {
|
|
@@ -220,6 +234,7 @@ function model(options) {
|
|
|
220
234
|
const fields = drainFields();
|
|
221
235
|
const embeddedFields = drainEmbedded();
|
|
222
236
|
const relations = drainRelations();
|
|
237
|
+
const aggregates = drainAggregates();
|
|
223
238
|
const prefix = derivePrefix(options.prefix, context.name);
|
|
224
239
|
MetadataRegistry.register(target, {
|
|
225
240
|
tableName: options.table,
|
|
@@ -228,6 +243,7 @@ function model(options) {
|
|
|
228
243
|
primaryKey: null,
|
|
229
244
|
gsiDefinitions: [],
|
|
230
245
|
relations,
|
|
246
|
+
aggregates,
|
|
231
247
|
embeddedFields
|
|
232
248
|
});
|
|
233
249
|
};
|
|
@@ -322,7 +338,7 @@ function hasMany(targetFactory, keyBinding, options) {
|
|
|
322
338
|
});
|
|
323
339
|
};
|
|
324
340
|
}
|
|
325
|
-
function belongsTo(targetFactory, keyBinding) {
|
|
341
|
+
function belongsTo(targetFactory, keyBinding, options) {
|
|
326
342
|
return function(_value, context) {
|
|
327
343
|
const propertyName = String(context.name);
|
|
328
344
|
assertRelationPropertyNameAllowed(propertyName);
|
|
@@ -330,7 +346,8 @@ function belongsTo(targetFactory, keyBinding) {
|
|
|
330
346
|
type: "belongsTo",
|
|
331
347
|
propertyName,
|
|
332
348
|
targetFactory,
|
|
333
|
-
keyBinding
|
|
349
|
+
keyBinding,
|
|
350
|
+
options
|
|
334
351
|
});
|
|
335
352
|
};
|
|
336
353
|
}
|
|
@@ -347,6 +364,29 @@ function hasOne(targetFactory, keyBinding) {
|
|
|
347
364
|
};
|
|
348
365
|
}
|
|
349
366
|
|
|
367
|
+
// src/decorators/aggregate.ts
|
|
368
|
+
function aggregate(targetFactory, keyBinding, options) {
|
|
369
|
+
return function(_value, context) {
|
|
370
|
+
collectAggregate({
|
|
371
|
+
propertyName: String(context.name),
|
|
372
|
+
targetFactory,
|
|
373
|
+
keyBinding,
|
|
374
|
+
options
|
|
375
|
+
});
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function count() {
|
|
379
|
+
return { op: "count" };
|
|
380
|
+
}
|
|
381
|
+
function max(field2) {
|
|
382
|
+
if (typeof field2 !== "string" || field2.length === 0) {
|
|
383
|
+
throw new Error(
|
|
384
|
+
`max(...) requires a non-empty source field name to aggregate (e.g. max('createdAt')), but received ${JSON.stringify(field2)}.`
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
return { op: "max", field: field2 };
|
|
388
|
+
}
|
|
389
|
+
|
|
350
390
|
// src/operations/declarative-transaction.ts
|
|
351
391
|
var PLACEHOLDER_RE = /\{[^{}]+\}/g;
|
|
352
392
|
function resolveTemplate(template, params, element) {
|
|
@@ -484,6 +524,79 @@ function entityByName(manifest, name) {
|
|
|
484
524
|
function physicalTableName(manifest, logical) {
|
|
485
525
|
return manifest.tables[logical]?.physicalName ?? logical;
|
|
486
526
|
}
|
|
527
|
+
function applyMaintainTransform(op, args, value) {
|
|
528
|
+
if (op === "identity") return value;
|
|
529
|
+
if (op === "preview") {
|
|
530
|
+
const n = args[0];
|
|
531
|
+
if (typeof n !== "number" || !Number.isInteger(n) || n <= 0) {
|
|
532
|
+
throw new Error(
|
|
533
|
+
`declarative transaction: a maintenance \`preview\` projection has a non-positive-integer length bound (${JSON.stringify(n)}).`
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
if (value === null || value === void 0) return value;
|
|
537
|
+
return String(value).slice(0, n);
|
|
538
|
+
}
|
|
539
|
+
throw new Error(
|
|
540
|
+
`declarative transaction: unknown maintenance projection op '${String(op)}' (expected 'identity' / 'preview').`
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
function buildMaintainProjection(maintain, params, element) {
|
|
544
|
+
const out = {};
|
|
545
|
+
for (const [attr, transform] of Object.entries(maintain.projection)) {
|
|
546
|
+
const value = resolveValue(`{${transform.inputField}}`, params, element);
|
|
547
|
+
out[attr] = applyMaintainTransform(transform.op, transform.args, value);
|
|
548
|
+
}
|
|
549
|
+
return out;
|
|
550
|
+
}
|
|
551
|
+
function buildMaintainUpdateItem(spec, maintain, table, key2, params, element) {
|
|
552
|
+
const update = { TableName: table, Key: key2 };
|
|
553
|
+
if (maintain.kind === "counter") {
|
|
554
|
+
const counter = maintain.counter;
|
|
555
|
+
if (counter === void 0) {
|
|
556
|
+
throw new Error(
|
|
557
|
+
`declarative transaction: a 'counter' maintenance write on '${spec.entity}' has no \`counter\` payload.`
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
update.UpdateExpression = "ADD #a0 :a0";
|
|
561
|
+
update.ExpressionAttributeNames = { "#a0": counter.attribute };
|
|
562
|
+
update.ExpressionAttributeValues = {
|
|
563
|
+
":a0": typeof counter.delta === "string" ? Number(counter.delta) : counter.delta
|
|
564
|
+
};
|
|
565
|
+
return { Update: update };
|
|
566
|
+
}
|
|
567
|
+
const projection = buildMaintainProjection(maintain, params, element);
|
|
568
|
+
if (maintain.kind === "collection") {
|
|
569
|
+
const field2 = maintain.collection?.field;
|
|
570
|
+
if (field2 === void 0) {
|
|
571
|
+
throw new Error(
|
|
572
|
+
`declarative transaction: a 'collection' maintenance write on '${spec.entity}' has no \`collection.field\`.`
|
|
573
|
+
);
|
|
574
|
+
}
|
|
575
|
+
update.UpdateExpression = "SET #c = list_append(if_not_exists(#c, :empty), :item)";
|
|
576
|
+
update.ExpressionAttributeNames = { "#c": field2 };
|
|
577
|
+
update.ExpressionAttributeValues = { ":empty": [], ":item": [projection] };
|
|
578
|
+
} else {
|
|
579
|
+
const names = {};
|
|
580
|
+
const values = {};
|
|
581
|
+
const sets = [];
|
|
582
|
+
let i = 0;
|
|
583
|
+
for (const [attr, value] of Object.entries(projection)) {
|
|
584
|
+
names[`#m${i}`] = attr;
|
|
585
|
+
values[`:m${i}`] = value;
|
|
586
|
+
sets.push(`#m${i} = :m${i}`);
|
|
587
|
+
i++;
|
|
588
|
+
}
|
|
589
|
+
if (sets.length === 0) {
|
|
590
|
+
throw new Error(
|
|
591
|
+
`declarative transaction: a 'snapshot' maintenance write on '${spec.entity}' has an empty projection.`
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
update.UpdateExpression = `SET ${sets.join(", ")}`;
|
|
595
|
+
update.ExpressionAttributeNames = names;
|
|
596
|
+
update.ExpressionAttributeValues = values;
|
|
597
|
+
}
|
|
598
|
+
return { Update: update };
|
|
599
|
+
}
|
|
487
600
|
function buildTransactItem(spec, manifest, params, element) {
|
|
488
601
|
const literal2 = spec.literalKey === true;
|
|
489
602
|
const entity = literal2 ? void 0 : entityByName(manifest, spec.entity);
|
|
@@ -511,6 +624,9 @@ function buildTransactItem(spec, manifest, params, element) {
|
|
|
511
624
|
applyCondition(spec.condition, check, params, element);
|
|
512
625
|
return { ConditionCheck: check };
|
|
513
626
|
}
|
|
627
|
+
if (spec.maintain !== void 0) {
|
|
628
|
+
return buildMaintainUpdateItem(spec, spec.maintain, table, key2, params, element);
|
|
629
|
+
}
|
|
514
630
|
const changes = resolveRecord(spec.changes, params, element);
|
|
515
631
|
const adds = resolveRecord(spec.add, params, element);
|
|
516
632
|
const names = {};
|
|
@@ -600,8 +716,8 @@ async function executeDeclarativeTransaction(spec, manifest, params) {
|
|
|
600
716
|
expanded.map((e) => e.item),
|
|
601
717
|
{
|
|
602
718
|
modelBySignature,
|
|
603
|
-
limitError: (
|
|
604
|
-
`declarative transaction: expanded to ${
|
|
719
|
+
limitError: (count2) => new Error(
|
|
720
|
+
`declarative transaction: expanded to ${count2} items, exceeds the DynamoDB TransactWriteItems limit of ${MAX_TRANSACT_ITEMS}.`
|
|
605
721
|
)
|
|
606
722
|
}
|
|
607
723
|
);
|
|
@@ -1063,6 +1179,7 @@ export {
|
|
|
1063
1179
|
SPEC_VERSION,
|
|
1064
1180
|
TableMapping,
|
|
1065
1181
|
TransactionContext,
|
|
1182
|
+
aggregate,
|
|
1066
1183
|
assertBundleSerializable,
|
|
1067
1184
|
assertContractBoundaries,
|
|
1068
1185
|
assertContractN1Safe,
|
|
@@ -1077,6 +1194,7 @@ export {
|
|
|
1077
1194
|
buildContexts,
|
|
1078
1195
|
buildContracts,
|
|
1079
1196
|
buildDeleteInput,
|
|
1197
|
+
buildMaintenanceGraph,
|
|
1080
1198
|
buildManifest,
|
|
1081
1199
|
buildOperations,
|
|
1082
1200
|
buildProjection,
|
|
@@ -1094,6 +1212,7 @@ export {
|
|
|
1094
1212
|
compileSingleFragmentPlan,
|
|
1095
1213
|
cond,
|
|
1096
1214
|
contractOfMethodSpec,
|
|
1215
|
+
count,
|
|
1097
1216
|
createCdcEmulator,
|
|
1098
1217
|
createDefaultLinter,
|
|
1099
1218
|
datetime,
|
|
@@ -1146,6 +1265,7 @@ export {
|
|
|
1146
1265
|
hasMany,
|
|
1147
1266
|
hasOne,
|
|
1148
1267
|
hydrate,
|
|
1268
|
+
identity,
|
|
1149
1269
|
isColumn,
|
|
1150
1270
|
isCommandModelContract,
|
|
1151
1271
|
isCommandPlan,
|
|
@@ -1158,6 +1278,7 @@ export {
|
|
|
1158
1278
|
isEntityWritesDefinition,
|
|
1159
1279
|
isKeySegment,
|
|
1160
1280
|
isLifecycleContract,
|
|
1281
|
+
isMaintainTrigger,
|
|
1161
1282
|
isMutationFragment,
|
|
1162
1283
|
isMutationInputRef,
|
|
1163
1284
|
isParam,
|
|
@@ -1172,7 +1293,9 @@ export {
|
|
|
1172
1293
|
lifecyclePhaseForIntent,
|
|
1173
1294
|
list,
|
|
1174
1295
|
literal,
|
|
1296
|
+
maintainTrigger,
|
|
1175
1297
|
map,
|
|
1298
|
+
max,
|
|
1176
1299
|
mintContractKeyFieldRef,
|
|
1177
1300
|
mintContractParamRef,
|
|
1178
1301
|
missingGsiRule,
|
|
@@ -1183,6 +1306,7 @@ export {
|
|
|
1183
1306
|
numberSet,
|
|
1184
1307
|
param,
|
|
1185
1308
|
plan,
|
|
1309
|
+
preview,
|
|
1186
1310
|
publicCommandModel,
|
|
1187
1311
|
publicQueryModel,
|
|
1188
1312
|
query,
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as Executor, D as DynamoDBOperation, R as ReadExecOptions, a as ExecutorResult, B as BatchGetExecInput, P as PutInput, W as WriteExecOptions, b as WriteResult, U as UpdateInput, c as DeleteInput, d as BatchWriteExecItem, e as BatchExecOptions, T as TransactWriteExecItem, M as ModelStatic, f as DDBModel, C as ChangeEvent } from '../types-
|
|
1
|
+
import { E as Executor, D as DynamoDBOperation, R as ReadExecOptions, a as ExecutorResult, B as BatchGetExecInput, P as PutInput, W as WriteExecOptions, b as WriteResult, U as UpdateInput, c as DeleteInput, d as BatchWriteExecItem, e as BatchExecOptions, T as TransactWriteExecItem, M as ModelStatic, f as DDBModel, C as ChangeEvent } from '../types-xJRn5qkv.js';
|
|
2
2
|
import '@aws-sdk/client-dynamodb';
|
|
3
3
|
|
|
4
4
|
/**
|
package/dist/testing/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createCdcEmulator
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-QQNP43JL.js";
|
|
4
4
|
import {
|
|
5
5
|
ClientManager,
|
|
6
6
|
MetadataRegistry,
|
|
7
7
|
TableMapping,
|
|
8
8
|
resolveModelClass
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-6AIAHP3A.js";
|
|
10
10
|
|
|
11
11
|
// src/memory/memory-store.ts
|
|
12
12
|
function deepClone(value) {
|