local-serverless-stack 0.6.0 → 0.8.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/CHANGELOG.md +54 -0
- package/README.md +99 -11
- package/bin/cli.js +31 -3
- package/dist/server/engine/backends/localstack-backend.d.ts +25 -0
- package/dist/server/engine/backends/localstack-backend.d.ts.map +1 -0
- package/dist/server/engine/backends/localstack-backend.js +199 -0
- package/dist/server/engine/backends/localstack-backend.js.map +1 -0
- package/dist/server/engine/backends/self-backend.d.ts +32 -0
- package/dist/server/engine/backends/self-backend.d.ts.map +1 -0
- package/dist/server/engine/backends/self-backend.js +205 -0
- package/dist/server/engine/backends/self-backend.js.map +1 -0
- package/dist/server/engine/bus.d.ts +10 -0
- package/dist/server/engine/bus.d.ts.map +1 -0
- package/dist/server/engine/bus.js +24 -0
- package/dist/server/engine/bus.js.map +1 -0
- package/dist/server/engine/dispatch/dispatcher.d.ts +46 -0
- package/dist/server/engine/dispatch/dispatcher.d.ts.map +1 -0
- package/dist/server/engine/dispatch/dispatcher.js +312 -0
- package/dist/server/engine/dispatch/dispatcher.js.map +1 -0
- package/dist/server/engine/dispatch/scheduler.d.ts +47 -0
- package/dist/server/engine/dispatch/scheduler.d.ts.map +1 -0
- package/dist/server/engine/dispatch/scheduler.js +328 -0
- package/dist/server/engine/dispatch/scheduler.js.map +1 -0
- package/dist/server/engine/dispatch/sqs-poller.d.ts +25 -0
- package/dist/server/engine/dispatch/sqs-poller.d.ts.map +1 -0
- package/dist/server/engine/dispatch/sqs-poller.js +242 -0
- package/dist/server/engine/dispatch/sqs-poller.js.map +1 -0
- package/dist/server/engine/dispatch/stream-tailer.d.ts +22 -0
- package/dist/server/engine/dispatch/stream-tailer.d.ts.map +1 -0
- package/dist/server/engine/dispatch/stream-tailer.js +205 -0
- package/dist/server/engine/dispatch/stream-tailer.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/decimal.d.ts +5 -0
- package/dist/server/engine/emulators/dynamodb/expressions/decimal.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/decimal.js +91 -0
- package/dist/server/engine/emulators/dynamodb/expressions/decimal.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/evaluate.d.ts +24 -0
- package/dist/server/engine/emulators/dynamodb/expressions/evaluate.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/evaluate.js +183 -0
- package/dist/server/engine/emulators/dynamodb/expressions/evaluate.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/expression-types.d.ts +29 -0
- package/dist/server/engine/emulators/dynamodb/expressions/expression-types.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/expression-types.js +12 -0
- package/dist/server/engine/emulators/dynamodb/expressions/expression-types.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/index.d.ts +13 -0
- package/dist/server/engine/emulators/dynamodb/expressions/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/index.js +244 -0
- package/dist/server/engine/emulators/dynamodb/expressions/index.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/lexer.d.ts +11 -0
- package/dist/server/engine/emulators/dynamodb/expressions/lexer.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/lexer.js +109 -0
- package/dist/server/engine/emulators/dynamodb/expressions/lexer.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/parser.d.ts +23 -0
- package/dist/server/engine/emulators/dynamodb/expressions/parser.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/parser.js +541 -0
- package/dist/server/engine/emulators/dynamodb/expressions/parser.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/index.d.ts +46 -0
- package/dist/server/engine/emulators/dynamodb/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/index.js +572 -0
- package/dist/server/engine/emulators/dynamodb/index.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/query.d.ts +12 -0
- package/dist/server/engine/emulators/dynamodb/query.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/query.js +237 -0
- package/dist/server/engine/emulators/dynamodb/query.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/schema.d.ts +58 -0
- package/dist/server/engine/emulators/dynamodb/schema.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/schema.js +284 -0
- package/dist/server/engine/emulators/dynamodb/schema.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/streams.d.ts +28 -0
- package/dist/server/engine/emulators/dynamodb/streams.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/streams.js +100 -0
- package/dist/server/engine/emulators/dynamodb/streams.js.map +1 -0
- package/dist/server/engine/emulators/events/index.d.ts +53 -0
- package/dist/server/engine/emulators/events/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/events/index.js +417 -0
- package/dist/server/engine/emulators/events/index.js.map +1 -0
- package/dist/server/engine/emulators/events/pattern.d.ts +3 -0
- package/dist/server/engine/emulators/events/pattern.d.ts.map +1 -0
- package/dist/server/engine/emulators/events/pattern.js +125 -0
- package/dist/server/engine/emulators/events/pattern.js.map +1 -0
- package/dist/server/engine/emulators/lambda-ctl/index.d.ts +55 -0
- package/dist/server/engine/emulators/lambda-ctl/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/lambda-ctl/index.js +461 -0
- package/dist/server/engine/emulators/lambda-ctl/index.js.map +1 -0
- package/dist/server/engine/emulators/s3/index.d.ts +45 -0
- package/dist/server/engine/emulators/s3/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/s3/index.js +591 -0
- package/dist/server/engine/emulators/s3/index.js.map +1 -0
- package/dist/server/engine/emulators/sns/index.d.ts +22 -0
- package/dist/server/engine/emulators/sns/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/sns/index.js +135 -0
- package/dist/server/engine/emulators/sns/index.js.map +1 -0
- package/dist/server/engine/emulators/sqs/index.d.ts +66 -0
- package/dist/server/engine/emulators/sqs/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/sqs/index.js +552 -0
- package/dist/server/engine/emulators/sqs/index.js.map +1 -0
- package/dist/server/engine/emulators/sqs/md5.d.ts +8 -0
- package/dist/server/engine/emulators/sqs/md5.d.ts.map +1 -0
- package/dist/server/engine/emulators/sqs/md5.js +36 -0
- package/dist/server/engine/emulators/sqs/md5.js.map +1 -0
- package/dist/server/engine/emulators/sqs/queue.d.ts +105 -0
- package/dist/server/engine/emulators/sqs/queue.d.ts.map +1 -0
- package/dist/server/engine/emulators/sqs/queue.js +371 -0
- package/dist/server/engine/emulators/sqs/queue.js.map +1 -0
- package/dist/server/engine/emulators/sts.d.ts +8 -0
- package/dist/server/engine/emulators/sts.d.ts.map +1 -0
- package/dist/server/engine/emulators/sts.js +23 -0
- package/dist/server/engine/emulators/sts.js.map +1 -0
- package/dist/server/engine/engine-backend.d.ts +17 -0
- package/dist/server/engine/engine-backend.d.ts.map +1 -0
- package/dist/server/engine/engine-backend.js +7 -0
- package/dist/server/engine/engine-backend.js.map +1 -0
- package/dist/server/engine/engine-manager.d.ts +22 -0
- package/dist/server/engine/engine-manager.d.ts.map +1 -0
- package/dist/server/engine/engine-manager.js +74 -0
- package/dist/server/engine/engine-manager.js.map +1 -0
- package/dist/server/engine/http/aws-chunked.d.ts +3 -0
- package/dist/server/engine/http/aws-chunked.d.ts.map +1 -0
- package/dist/server/engine/http/aws-chunked.js +50 -0
- package/dist/server/engine/http/aws-chunked.js.map +1 -0
- package/dist/server/engine/http/errors.d.ts +20 -0
- package/dist/server/engine/http/errors.d.ts.map +1 -0
- package/dist/server/engine/http/errors.js +43 -0
- package/dist/server/engine/http/errors.js.map +1 -0
- package/dist/server/engine/http/protocols/aws-json.d.ts +8 -0
- package/dist/server/engine/http/protocols/aws-json.d.ts.map +1 -0
- package/dist/server/engine/http/protocols/aws-json.js +42 -0
- package/dist/server/engine/http/protocols/aws-json.js.map +1 -0
- package/dist/server/engine/http/protocols/query-xml.d.ts +7 -0
- package/dist/server/engine/http/protocols/query-xml.d.ts.map +1 -0
- package/dist/server/engine/http/protocols/query-xml.js +35 -0
- package/dist/server/engine/http/protocols/query-xml.js.map +1 -0
- package/dist/server/engine/http/router.d.ts +8 -0
- package/dist/server/engine/http/router.d.ts.map +1 -0
- package/dist/server/engine/http/router.js +391 -0
- package/dist/server/engine/http/router.js.map +1 -0
- package/dist/server/engine/http/sigv4.d.ts +9 -0
- package/dist/server/engine/http/sigv4.d.ts.map +1 -0
- package/dist/server/engine/http/sigv4.js +33 -0
- package/dist/server/engine/http/sigv4.js.map +1 -0
- package/dist/server/engine/http/xml.d.ts +16 -0
- package/dist/server/engine/http/xml.d.ts.map +1 -0
- package/dist/server/engine/http/xml.js +92 -0
- package/dist/server/engine/http/xml.js.map +1 -0
- package/dist/server/engine/store/atomic.d.ts +4 -0
- package/dist/server/engine/store/atomic.d.ts.map +1 -0
- package/dist/server/engine/store/atomic.js +35 -0
- package/dist/server/engine/store/atomic.js.map +1 -0
- package/dist/server/engine/store/engine-store.d.ts +9 -0
- package/dist/server/engine/store/engine-store.d.ts.map +1 -0
- package/dist/server/engine/store/engine-store.js +218 -0
- package/dist/server/engine/store/engine-store.js.map +1 -0
- package/dist/server/engine/store/store-types.d.ts +37 -0
- package/dist/server/engine/store/store-types.d.ts.map +1 -0
- package/dist/server/engine/store/store-types.js +17 -0
- package/dist/server/engine/store/store-types.js.map +1 -0
- package/dist/server/engine/store/wal.d.ts +49 -0
- package/dist/server/engine/store/wal.d.ts.map +1 -0
- package/dist/server/engine/store/wal.js +328 -0
- package/dist/server/engine/store/wal.js.map +1 -0
- package/dist/server/engine/types.d.ts +137 -0
- package/dist/server/engine/types.d.ts.map +1 -0
- package/dist/server/engine/types.js +8 -0
- package/dist/server/engine/types.js.map +1 -0
- package/dist/server/index.js +12 -9
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/services.d.ts.map +1 -1
- package/dist/server/routes/services.js +2 -0
- package/dist/server/routes/services.js.map +1 -1
- package/dist/server/services/cloudformation-parser.d.ts +26 -2
- package/dist/server/services/cloudformation-parser.d.ts.map +1 -1
- package/dist/server/services/cloudformation-parser.js +60 -3
- package/dist/server/services/cloudformation-parser.js.map +1 -1
- package/dist/server/services/config-manager.d.ts +27 -0
- package/dist/server/services/config-manager.d.ts.map +1 -1
- package/dist/server/services/config-manager.js +67 -7
- package/dist/server/services/config-manager.js.map +1 -1
- package/dist/server/services/localstack-manager.d.ts +0 -7
- package/dist/server/services/localstack-manager.d.ts.map +1 -1
- package/dist/server/services/localstack-manager.js +11 -173
- package/dist/server/services/localstack-manager.js.map +1 -1
- package/dist/server/services/resource-provisioner.d.ts +6 -0
- package/dist/server/services/resource-provisioner.d.ts.map +1 -1
- package/dist/server/services/resource-provisioner.js +171 -7
- package/dist/server/services/resource-provisioner.js.map +1 -1
- package/dist/server/services/service-registrar.js +2 -2
- package/dist/server/services/service-registrar.js.map +1 -1
- package/dist/ui/assets/ApisPage-a9i2qD0Z.js +1 -0
- package/dist/ui/assets/BucketDetailPage-Cz27N0KV.js +1 -0
- package/dist/ui/assets/BucketsPage-CZ7wGmUN.js +1 -0
- package/dist/ui/assets/{DynamoPage-B1__Rjr2.js → DynamoPage-BZMs1iW8.js} +1 -1
- package/dist/ui/assets/DynamoTablePage-BQsGkhtO.js +3 -0
- package/dist/ui/assets/LambdaDetailPage-DJb7xqRB.js +4 -0
- package/dist/ui/assets/LambdasPage-Ctg1l-Lg.js +1 -0
- package/dist/ui/assets/OverviewPage-DiijblCA.js +1 -0
- package/dist/ui/assets/QueueDetailPage-DRpSqost.js +1 -0
- package/dist/ui/assets/QueuesPage-CY0bDGwV.js +1 -0
- package/dist/ui/assets/ServiceDetailPage-CYTEdtts.js +2 -0
- package/dist/ui/assets/ServicesPage-OlV_rr-q.js +2 -0
- package/dist/ui/assets/index-C1KdKPDS.css +1 -0
- package/dist/ui/assets/index-DA_C1HOg.js +36 -0
- package/dist/ui/index.html +2 -2
- package/package.json +2 -1
- package/dist/ui/assets/ApisPage-DdgKjEdS.js +0 -1
- package/dist/ui/assets/BucketDetailPage-DZQGxm0y.js +0 -1
- package/dist/ui/assets/BucketsPage-xYXzxCvd.js +0 -1
- package/dist/ui/assets/DynamoTablePage-BCoxPdXW.js +0 -3
- package/dist/ui/assets/LambdaDetailPage-B85CA8tb.js +0 -4
- package/dist/ui/assets/LambdasPage-_TtxQMT_.js +0 -1
- package/dist/ui/assets/OverviewPage-CqTKTY64.js +0 -1
- package/dist/ui/assets/QueueDetailPage-BOr_sImA.js +0 -1
- package/dist/ui/assets/QueuesPage-DpByfcM5.js +0 -1
- package/dist/ui/assets/ServiceDetailPage-DsWgV-ad.js +0 -2
- package/dist/ui/assets/ServicesPage-CGlpsj98.js +0 -2
- package/dist/ui/assets/index-BWlB542w.js +0 -36
- package/dist/ui/assets/index-EYnsoJOq.css +0 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// Query/Scan engine: index resolution, key-condition matching, ordering,
|
|
2
|
+
// pagination (ExclusiveStartKey/LastEvaluatedKey) and index read semantics
|
|
3
|
+
// (sparse items, KEYS_ONLY/INCLUDE projections). Per PRD RF3.4, GSI/LSI
|
|
4
|
+
// queries are answered by scanning the base table — index semantics are
|
|
5
|
+
// enforced at read time, never maintained on write.
|
|
6
|
+
import { validationError } from '../../http/errors.js';
|
|
7
|
+
import { applyProjection, assertPlaceholdersUsed, attributeValuesEqual, compareAttributeValues, compileCondition, parseKeyCondition, } from './expressions/index.js';
|
|
8
|
+
import { beginsWith } from './expressions/evaluate.js';
|
|
9
|
+
import { canonicalKey, tableKeyAttrs, validateProvidedKey, wireTypeOf } from './schema.js';
|
|
10
|
+
function resolveView(table, indexName) {
|
|
11
|
+
const tableKeys = tableKeyAttrs(table);
|
|
12
|
+
if (indexName === undefined) {
|
|
13
|
+
return { pk: tableKeys[0], sk: tableKeys[1], tuple: tableKeys };
|
|
14
|
+
}
|
|
15
|
+
const index = [...table.globalSecondaryIndexes, ...table.localSecondaryIndexes]
|
|
16
|
+
.find((idx) => idx.indexName === indexName);
|
|
17
|
+
if (!index) {
|
|
18
|
+
throw validationError(`The table does not have the specified index: ${String(indexName)}`);
|
|
19
|
+
}
|
|
20
|
+
const types = new Map(table.attributeDefinitions.map((d) => [d.AttributeName, d.AttributeType]));
|
|
21
|
+
const viewKeys = index.keySchema.map((el) => ({ name: el.AttributeName, type: types.get(el.AttributeName) }));
|
|
22
|
+
const tuple = [...viewKeys];
|
|
23
|
+
for (const attr of tableKeys) {
|
|
24
|
+
if (!tuple.some((t) => t.name === attr.name))
|
|
25
|
+
tuple.push(attr);
|
|
26
|
+
}
|
|
27
|
+
return { index, pk: viewKeys[0], sk: viewKeys[1], tuple };
|
|
28
|
+
}
|
|
29
|
+
// Sparse-index semantics: an item is visible in a view only when every view
|
|
30
|
+
// key attribute is present with the declared type.
|
|
31
|
+
function visibleInView(view, item) {
|
|
32
|
+
return view.tuple.every(({ name, type }) => wireTypeOf(item[name]) === type);
|
|
33
|
+
}
|
|
34
|
+
export function indexHasItem(table, index, item) {
|
|
35
|
+
const types = new Map(table.attributeDefinitions.map((d) => [d.AttributeName, d.AttributeType]));
|
|
36
|
+
return index.keySchema.every((el) => wireTypeOf(item[el.AttributeName]) === types.get(el.AttributeName));
|
|
37
|
+
}
|
|
38
|
+
function compareTuples(view, a, b) {
|
|
39
|
+
for (const { name } of view.tuple) {
|
|
40
|
+
const cmp = compareAttributeValues(a[name], b[name]);
|
|
41
|
+
if (cmp !== 0)
|
|
42
|
+
return cmp;
|
|
43
|
+
}
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
function viewKeyOf(view, item) {
|
|
47
|
+
const key = {};
|
|
48
|
+
for (const { name } of view.tuple)
|
|
49
|
+
key[name] = structuredClone(item[name]);
|
|
50
|
+
return key;
|
|
51
|
+
}
|
|
52
|
+
function readStartKey(view, raw) {
|
|
53
|
+
if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
54
|
+
throw validationError('The provided starting key is invalid');
|
|
55
|
+
}
|
|
56
|
+
const key = raw;
|
|
57
|
+
for (const { name, type } of view.tuple) {
|
|
58
|
+
if (wireTypeOf(key[name]) !== type) {
|
|
59
|
+
throw validationError('The provided starting key is invalid');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return key;
|
|
63
|
+
}
|
|
64
|
+
// Index projection applied at read: the base-table scan sees every attribute,
|
|
65
|
+
// but a GSI/LSI reader must only observe what the index projects.
|
|
66
|
+
function stripToProjection(view, item) {
|
|
67
|
+
if (!view.index || view.index.projection.ProjectionType === 'ALL')
|
|
68
|
+
return structuredClone(item);
|
|
69
|
+
const keep = new Set(view.tuple.map((attr) => attr.name));
|
|
70
|
+
for (const name of view.index.projection.NonKeyAttributes ?? [])
|
|
71
|
+
keep.add(name);
|
|
72
|
+
const out = {};
|
|
73
|
+
for (const name of keep) {
|
|
74
|
+
if (item[name] !== undefined)
|
|
75
|
+
out[name] = structuredClone(item[name]);
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
function readLimit(raw) {
|
|
80
|
+
if (raw === undefined)
|
|
81
|
+
return undefined;
|
|
82
|
+
if (typeof raw !== 'number' || !Number.isInteger(raw) || raw < 1) {
|
|
83
|
+
throw validationError('Limit must be an integer greater than or equal to 1');
|
|
84
|
+
}
|
|
85
|
+
return raw;
|
|
86
|
+
}
|
|
87
|
+
// The classic parity rule pinned by tests: Limit counts items EXAMINED
|
|
88
|
+
// (ScannedCount) before FilterExpression, not items returned — and a page
|
|
89
|
+
// that stops exactly on the limit still carries a LastEvaluatedKey (AWS
|
|
90
|
+
// cannot know it was the last item; neither do we pretend to).
|
|
91
|
+
function paginate(view, ordered, input, filter, ctx) {
|
|
92
|
+
const limit = readLimit(input.Limit);
|
|
93
|
+
const collected = [];
|
|
94
|
+
let scanned = 0;
|
|
95
|
+
let lastExamined;
|
|
96
|
+
let limitHit = false;
|
|
97
|
+
for (const item of ordered) {
|
|
98
|
+
scanned++;
|
|
99
|
+
lastExamined = item;
|
|
100
|
+
const visible = stripToProjection(view, item);
|
|
101
|
+
if (!filter || filter.evaluate(visible))
|
|
102
|
+
collected.push(visible);
|
|
103
|
+
if (limit !== undefined && scanned >= limit) {
|
|
104
|
+
limitHit = true;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const result = { count: collected.length, scannedCount: scanned };
|
|
109
|
+
if (limitHit && lastExamined)
|
|
110
|
+
result.lastEvaluatedKey = viewKeyOf(view, lastExamined);
|
|
111
|
+
if (input.Select !== 'COUNT') {
|
|
112
|
+
result.items = typeof input.ProjectionExpression === 'string'
|
|
113
|
+
? collected.map((item) => applyProjection(input.ProjectionExpression, item, ctx))
|
|
114
|
+
: collected;
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
function resolveKeyCondition(view, expression, ctx) {
|
|
119
|
+
const parsed = parseKeyCondition(expression, ctx);
|
|
120
|
+
let partition = parsed.partition;
|
|
121
|
+
let sort = parsed.sort;
|
|
122
|
+
// The parser designates the first `=` term as partition when both terms are
|
|
123
|
+
// equalities — swap by schema when it guessed the sort key.
|
|
124
|
+
if (partition.name !== view.pk.name && sort?.operator === '=' && sort.name === view.pk.name) {
|
|
125
|
+
const previous = partition;
|
|
126
|
+
partition = { name: sort.name, value: sort.values[0] };
|
|
127
|
+
sort = { name: previous.name, operator: '=', values: [previous.value] };
|
|
128
|
+
}
|
|
129
|
+
if (partition.name !== view.pk.name) {
|
|
130
|
+
throw validationError(`Query condition missed key schema element: ${view.pk.name}`);
|
|
131
|
+
}
|
|
132
|
+
if (wireTypeOf(partition.value) !== view.pk.type) {
|
|
133
|
+
throw validationError('One or more parameter values were invalid: Condition parameter type does not match schema type');
|
|
134
|
+
}
|
|
135
|
+
if (!sort)
|
|
136
|
+
return { pkValue: partition.value };
|
|
137
|
+
if (!view.sk)
|
|
138
|
+
throw validationError('Query key condition not supported');
|
|
139
|
+
if (sort.name !== view.sk.name) {
|
|
140
|
+
throw validationError(`Query condition missed key schema element: ${view.sk.name}`);
|
|
141
|
+
}
|
|
142
|
+
if (sort.operator === 'begins_with' && view.sk.type === 'N') {
|
|
143
|
+
throw validationError('Function begins_with is only supported for the sort key of type String or Binary');
|
|
144
|
+
}
|
|
145
|
+
for (const value of sort.values) {
|
|
146
|
+
if (wireTypeOf(value) !== view.sk.type) {
|
|
147
|
+
throw validationError('One or more parameter values were invalid: Condition parameter type does not match schema type');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return { pkValue: partition.value, sort: { operator: sort.operator, values: sort.values } };
|
|
151
|
+
}
|
|
152
|
+
function sortKeyMatches(condition, actual) {
|
|
153
|
+
if (!condition)
|
|
154
|
+
return true;
|
|
155
|
+
const { operator, values } = condition;
|
|
156
|
+
switch (operator) {
|
|
157
|
+
case '=': return compareAttributeValues(actual, values[0]) === 0;
|
|
158
|
+
case '<': return compareAttributeValues(actual, values[0]) < 0;
|
|
159
|
+
case '<=': return compareAttributeValues(actual, values[0]) <= 0;
|
|
160
|
+
case '>': return compareAttributeValues(actual, values[0]) > 0;
|
|
161
|
+
case '>=': return compareAttributeValues(actual, values[0]) >= 0;
|
|
162
|
+
case 'BETWEEN':
|
|
163
|
+
return compareAttributeValues(actual, values[0]) >= 0 && compareAttributeValues(actual, values[1]) <= 0;
|
|
164
|
+
case 'begins_with': return beginsWith(actual, values[0]);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
// Query
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
export function executeQuery(table, items, rawInput) {
|
|
171
|
+
const input = rawInput;
|
|
172
|
+
const view = resolveView(table, input.IndexName);
|
|
173
|
+
const ctx = { names: input.ExpressionAttributeNames, values: input.ExpressionAttributeValues };
|
|
174
|
+
if (typeof input.KeyConditionExpression !== 'string') {
|
|
175
|
+
throw validationError('Either the KeyConditions or KeyConditionExpression parameter must be specified in the request.');
|
|
176
|
+
}
|
|
177
|
+
assertPlaceholdersUsed([input.KeyConditionExpression, input.FilterExpression, input.ProjectionExpression], ctx);
|
|
178
|
+
const condition = resolveKeyCondition(view, input.KeyConditionExpression, ctx);
|
|
179
|
+
// AWS allows filtering on non-key attributes only; that validation is
|
|
180
|
+
// intentionally skipped here (assumption flagged in the module report).
|
|
181
|
+
const filter = typeof input.FilterExpression === 'string'
|
|
182
|
+
? compileCondition(input.FilterExpression, ctx, 'FilterExpression')
|
|
183
|
+
: undefined;
|
|
184
|
+
const forward = input.ScanIndexForward !== false;
|
|
185
|
+
let candidates = items
|
|
186
|
+
.filter((item) => visibleInView(view, item)
|
|
187
|
+
&& attributeValuesEqual(item[view.pk.name], condition.pkValue)
|
|
188
|
+
&& (!view.sk || sortKeyMatches(condition.sort, item[view.sk.name])))
|
|
189
|
+
.sort((a, b) => compareTuples(view, a, b));
|
|
190
|
+
if (!forward)
|
|
191
|
+
candidates.reverse();
|
|
192
|
+
if (input.ExclusiveStartKey !== undefined) {
|
|
193
|
+
const startKey = readStartKey(view, input.ExclusiveStartKey);
|
|
194
|
+
const startIndex = candidates.findIndex((item) => (forward
|
|
195
|
+
? compareTuples(view, item, startKey) > 0
|
|
196
|
+
: compareTuples(view, item, startKey) < 0));
|
|
197
|
+
candidates = startIndex === -1 ? [] : candidates.slice(startIndex);
|
|
198
|
+
}
|
|
199
|
+
return paginate(view, candidates, input, filter, ctx);
|
|
200
|
+
}
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
// Scan
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
// Segment/TotalSegments are accepted and ignored: the store is a single
|
|
205
|
+
// insertion-ordered map, so parallel-scan hints have nothing to shard.
|
|
206
|
+
export function executeScan(table, items, rawInput) {
|
|
207
|
+
const input = rawInput;
|
|
208
|
+
const view = resolveView(table, input.IndexName);
|
|
209
|
+
const ctx = { names: input.ExpressionAttributeNames, values: input.ExpressionAttributeValues };
|
|
210
|
+
assertPlaceholdersUsed([input.FilterExpression, input.ProjectionExpression], ctx);
|
|
211
|
+
const filter = typeof input.FilterExpression === 'string'
|
|
212
|
+
? compileCondition(input.FilterExpression, ctx, 'FilterExpression')
|
|
213
|
+
: undefined;
|
|
214
|
+
let candidates = items.filter((item) => visibleInView(view, item));
|
|
215
|
+
// Base-table scan order is the store's insertion order; index scans sort by
|
|
216
|
+
// the view tuple so ExclusiveStartKey positioning is deterministic.
|
|
217
|
+
if (view.index)
|
|
218
|
+
candidates.sort((a, b) => compareTuples(view, a, b));
|
|
219
|
+
if (input.ExclusiveStartKey !== undefined) {
|
|
220
|
+
const startKey = readStartKey(view, input.ExclusiveStartKey);
|
|
221
|
+
if (view.index) {
|
|
222
|
+
const startIndex = candidates.findIndex((item) => compareTuples(view, item, startKey) > 0);
|
|
223
|
+
candidates = startIndex === -1 ? [] : candidates.slice(startIndex);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
// Positional match on the canonical key. If the marker item was deleted
|
|
227
|
+
// mid-pagination the scan restarts from the top (dev-tool trade-off).
|
|
228
|
+
validateProvidedKey(table, startKey);
|
|
229
|
+
const marker = canonicalKey(table, startKey);
|
|
230
|
+
const markerIndex = candidates.findIndex((item) => canonicalKey(table, item) === marker);
|
|
231
|
+
if (markerIndex !== -1)
|
|
232
|
+
candidates = candidates.slice(markerIndex + 1);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return paginate(view, candidates, input, filter, ctx);
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../../../src/server/engine/emulators/dynamodb/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { AttributeMap, AttributeValue } from '../../types.js';
|
|
2
|
+
export type KeyAttributeType = 'S' | 'N' | 'B';
|
|
3
|
+
export type StreamViewType = 'KEYS_ONLY' | 'NEW_IMAGE' | 'OLD_IMAGE' | 'NEW_AND_OLD_IMAGES';
|
|
4
|
+
export interface KeySchemaElement {
|
|
5
|
+
AttributeName: string;
|
|
6
|
+
KeyType: 'HASH' | 'RANGE';
|
|
7
|
+
}
|
|
8
|
+
export interface AttributeDefinition {
|
|
9
|
+
AttributeName: string;
|
|
10
|
+
AttributeType: KeyAttributeType;
|
|
11
|
+
}
|
|
12
|
+
export interface ProjectionRecord {
|
|
13
|
+
ProjectionType: 'ALL' | 'KEYS_ONLY' | 'INCLUDE';
|
|
14
|
+
NonKeyAttributes?: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface IndexRecord {
|
|
17
|
+
indexName: string;
|
|
18
|
+
keySchema: KeySchemaElement[];
|
|
19
|
+
projection: ProjectionRecord;
|
|
20
|
+
}
|
|
21
|
+
export interface TableRecord {
|
|
22
|
+
tableName: string;
|
|
23
|
+
tableId: string;
|
|
24
|
+
createdAtMs: number;
|
|
25
|
+
keySchema: KeySchemaElement[];
|
|
26
|
+
attributeDefinitions: AttributeDefinition[];
|
|
27
|
+
billingMode: 'PROVISIONED' | 'PAY_PER_REQUEST';
|
|
28
|
+
readCapacityUnits: number;
|
|
29
|
+
writeCapacityUnits: number;
|
|
30
|
+
globalSecondaryIndexes: IndexRecord[];
|
|
31
|
+
localSecondaryIndexes: IndexRecord[];
|
|
32
|
+
streamSpecification?: {
|
|
33
|
+
StreamEnabled: boolean;
|
|
34
|
+
StreamViewType: StreamViewType;
|
|
35
|
+
};
|
|
36
|
+
latestStreamLabel?: string;
|
|
37
|
+
ttl?: {
|
|
38
|
+
attributeName: string;
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface KeyAttribute {
|
|
43
|
+
name: string;
|
|
44
|
+
type: KeyAttributeType;
|
|
45
|
+
}
|
|
46
|
+
export declare function tableArnFor(account: string, region: string, tableName: string): string;
|
|
47
|
+
export declare function streamArnFor(account: string, region: string, record: TableRecord): string;
|
|
48
|
+
export declare function buildTableRecord(input: Record<string, unknown>): TableRecord;
|
|
49
|
+
export declare function tableKeyAttrs(record: TableRecord): KeyAttribute[];
|
|
50
|
+
export declare function wireTypeOf(value: AttributeValue | undefined): string | undefined;
|
|
51
|
+
export declare function validateItemKey(record: TableRecord, item: AttributeMap): void;
|
|
52
|
+
export declare function validateProvidedKey(record: TableRecord, key: unknown): AttributeMap;
|
|
53
|
+
export declare function canonicalKey(record: TableRecord, source: AttributeMap): string;
|
|
54
|
+
export declare function keyMapOf(record: TableRecord, item: AttributeMap): AttributeMap;
|
|
55
|
+
export declare function itemSizeBytes(item: AttributeMap): number;
|
|
56
|
+
export declare function assertItemSize(item: AttributeMap): void;
|
|
57
|
+
export declare function rejectLegacyParams(input: Record<string, unknown>, params: string[]): void;
|
|
58
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../../src/server/engine/emulators/dynamodb/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
// Table metadata for the DynamoDB emulator: CreateTable validation into a
|
|
2
|
+
// persisted TableRecord, key extraction/validation against the schema, the
|
|
3
|
+
// canonical item-key encoding used by the ItemTable, ARN builders and the
|
|
4
|
+
// AWS-style item size estimate that backs the 400 KB limit.
|
|
5
|
+
import crypto from 'crypto';
|
|
6
|
+
import { validationError } from '../../http/errors.js';
|
|
7
|
+
import { normalizeDecimal } from './expressions/index.js';
|
|
8
|
+
const NAME_PATTERN = /^[a-zA-Z0-9_.-]{3,255}$/;
|
|
9
|
+
const INVALID_NAME_MESSAGE = 'Invalid table/index name. Table/index names must be between 3 and 255 characters long, ' +
|
|
10
|
+
"and may contain only the characters a-z, A-Z, 0-9, '_' (underscore), '-' (dash), and '.' (dot)";
|
|
11
|
+
const STREAM_VIEW_TYPES = ['KEYS_ONLY', 'NEW_IMAGE', 'OLD_IMAGE', 'NEW_AND_OLD_IMAGES'];
|
|
12
|
+
const MAX_ITEM_BYTES = 400 * 1024;
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// ARNs
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
export function tableArnFor(account, region, tableName) {
|
|
17
|
+
return `arn:aws:dynamodb:${region}:${account}:table/${tableName}`;
|
|
18
|
+
}
|
|
19
|
+
export function streamArnFor(account, region, record) {
|
|
20
|
+
return `${tableArnFor(account, region, record.tableName)}/stream/${record.latestStreamLabel}`;
|
|
21
|
+
}
|
|
22
|
+
function parseAttributeDefinitions(raw) {
|
|
23
|
+
if (!Array.isArray(raw) || raw.length === 0) {
|
|
24
|
+
throw validationError('One or more parameter values were invalid: AttributeDefinitions must not be empty');
|
|
25
|
+
}
|
|
26
|
+
return raw.map((def) => {
|
|
27
|
+
const name = def?.AttributeName;
|
|
28
|
+
const type = def?.AttributeType;
|
|
29
|
+
if (typeof name !== 'string' || name.length === 0 || (type !== 'S' && type !== 'N' && type !== 'B')) {
|
|
30
|
+
throw validationError('One or more parameter values were invalid: AttributeType must be one of S, N or B');
|
|
31
|
+
}
|
|
32
|
+
return { AttributeName: name, AttributeType: type };
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
// AWS also rejects AttributeDefinitions entries not used by any key — the
|
|
36
|
+
// provisioner only ever defines key attributes, so extras are tolerated here.
|
|
37
|
+
function parseKeySchema(raw, defined, where) {
|
|
38
|
+
if (!Array.isArray(raw) || raw.length < 1 || raw.length > 2) {
|
|
39
|
+
throw validationError(`One or more parameter values were invalid: Invalid KeySchema on ${where}: 1 or 2 key elements required`);
|
|
40
|
+
}
|
|
41
|
+
const elements = raw;
|
|
42
|
+
if (elements[0]?.KeyType !== 'HASH') {
|
|
43
|
+
throw validationError('Invalid KeySchema: The first KeySchemaElement is not a HASH key type');
|
|
44
|
+
}
|
|
45
|
+
if (elements.length === 2 && elements[1]?.KeyType !== 'RANGE') {
|
|
46
|
+
throw validationError('Invalid KeySchema: The second KeySchemaElement is not a RANGE key type');
|
|
47
|
+
}
|
|
48
|
+
return elements.map((el) => {
|
|
49
|
+
const name = el.AttributeName;
|
|
50
|
+
if (typeof name !== 'string' || name.length === 0) {
|
|
51
|
+
throw validationError(`One or more parameter values were invalid: Invalid KeySchema on ${where}: AttributeName is required`);
|
|
52
|
+
}
|
|
53
|
+
if (!defined.has(name)) {
|
|
54
|
+
throw validationError('One or more parameter values were invalid: Some index key attributes are not defined in AttributeDefinitions. ' +
|
|
55
|
+
`Keys: [${name}], AttributeDefinitions: [${[...defined.keys()].join(', ')}]`);
|
|
56
|
+
}
|
|
57
|
+
return { AttributeName: name, KeyType: el.KeyType };
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function parseProjection(raw) {
|
|
61
|
+
const wire = raw;
|
|
62
|
+
const type = wire?.ProjectionType ?? 'ALL';
|
|
63
|
+
if (type !== 'ALL' && type !== 'KEYS_ONLY' && type !== 'INCLUDE') {
|
|
64
|
+
throw validationError('One or more parameter values were invalid: ProjectionType must be one of ALL, KEYS_ONLY or INCLUDE');
|
|
65
|
+
}
|
|
66
|
+
const projection = { ProjectionType: type };
|
|
67
|
+
if (type === 'INCLUDE') {
|
|
68
|
+
if (!Array.isArray(wire?.NonKeyAttributes) || wire.NonKeyAttributes.length === 0) {
|
|
69
|
+
throw validationError('One or more parameter values were invalid: NonKeyAttributes is required when ProjectionType is INCLUDE');
|
|
70
|
+
}
|
|
71
|
+
projection.NonKeyAttributes = wire.NonKeyAttributes.map(String);
|
|
72
|
+
}
|
|
73
|
+
return projection;
|
|
74
|
+
}
|
|
75
|
+
function parseIndexes(raw, defined, seenNames, kind, tableHashAttr) {
|
|
76
|
+
if (raw === undefined)
|
|
77
|
+
return [];
|
|
78
|
+
if (!Array.isArray(raw)) {
|
|
79
|
+
throw validationError(`One or more parameter values were invalid: ${kind === 'GSI' ? 'GlobalSecondaryIndexes' : 'LocalSecondaryIndexes'} must be a list`);
|
|
80
|
+
}
|
|
81
|
+
return raw.map((idx) => {
|
|
82
|
+
const indexName = idx?.IndexName;
|
|
83
|
+
if (typeof indexName !== 'string' || !NAME_PATTERN.test(indexName)) {
|
|
84
|
+
throw validationError(INVALID_NAME_MESSAGE);
|
|
85
|
+
}
|
|
86
|
+
if (seenNames.has(indexName)) {
|
|
87
|
+
throw validationError(`One or more parameter values were invalid: Duplicate index name: ${indexName}`);
|
|
88
|
+
}
|
|
89
|
+
seenNames.add(indexName);
|
|
90
|
+
const keySchema = parseKeySchema(idx.KeySchema, defined, indexName);
|
|
91
|
+
if (kind === 'LSI') {
|
|
92
|
+
if (keySchema[0].AttributeName !== tableHashAttr) {
|
|
93
|
+
throw validationError('One or more parameter values were invalid: Index KeySchema does not have the same leading hash key as table KeySchema');
|
|
94
|
+
}
|
|
95
|
+
if (keySchema.length !== 2) {
|
|
96
|
+
throw validationError('One or more parameter values were invalid: Local secondary indexes must have a range key');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { indexName, keySchema, projection: parseProjection(idx.Projection) };
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
export function buildTableRecord(input) {
|
|
103
|
+
const wire = input;
|
|
104
|
+
if (typeof wire.TableName !== 'string' || !NAME_PATTERN.test(wire.TableName)) {
|
|
105
|
+
throw validationError(INVALID_NAME_MESSAGE);
|
|
106
|
+
}
|
|
107
|
+
const attributeDefinitions = parseAttributeDefinitions(wire.AttributeDefinitions);
|
|
108
|
+
const defined = new Map(attributeDefinitions.map((d) => [d.AttributeName, d.AttributeType]));
|
|
109
|
+
const keySchema = parseKeySchema(wire.KeySchema, defined, wire.TableName);
|
|
110
|
+
const seenIndexNames = new Set();
|
|
111
|
+
const globalSecondaryIndexes = parseIndexes(wire.GlobalSecondaryIndexes, defined, seenIndexNames, 'GSI', keySchema[0].AttributeName);
|
|
112
|
+
const localSecondaryIndexes = parseIndexes(wire.LocalSecondaryIndexes, defined, seenIndexNames, 'LSI', keySchema[0].AttributeName);
|
|
113
|
+
if (wire.BillingMode !== undefined && wire.BillingMode !== 'PROVISIONED' && wire.BillingMode !== 'PAY_PER_REQUEST') {
|
|
114
|
+
throw validationError('One or more parameter values were invalid: BillingMode must be one of PROVISIONED, PAY_PER_REQUEST');
|
|
115
|
+
}
|
|
116
|
+
const billingMode = wire.BillingMode === 'PAY_PER_REQUEST' ? 'PAY_PER_REQUEST' : 'PROVISIONED';
|
|
117
|
+
// AWS requires ProvisionedThroughput with PROVISIONED; local dev tolerates
|
|
118
|
+
// its absence with a small default instead of failing the registration.
|
|
119
|
+
const readCapacityUnits = billingMode === 'PROVISIONED' ? Number(wire.ProvisionedThroughput?.ReadCapacityUnits ?? 5) : 0;
|
|
120
|
+
const writeCapacityUnits = billingMode === 'PROVISIONED' ? Number(wire.ProvisionedThroughput?.WriteCapacityUnits ?? 5) : 0;
|
|
121
|
+
const record = {
|
|
122
|
+
tableName: wire.TableName,
|
|
123
|
+
tableId: crypto.randomUUID(),
|
|
124
|
+
createdAtMs: Date.now(),
|
|
125
|
+
keySchema,
|
|
126
|
+
attributeDefinitions,
|
|
127
|
+
billingMode,
|
|
128
|
+
readCapacityUnits,
|
|
129
|
+
writeCapacityUnits,
|
|
130
|
+
globalSecondaryIndexes,
|
|
131
|
+
localSecondaryIndexes,
|
|
132
|
+
};
|
|
133
|
+
if (wire.StreamSpecification?.StreamEnabled === true) {
|
|
134
|
+
const viewType = wire.StreamSpecification.StreamViewType;
|
|
135
|
+
if (typeof viewType !== 'string' || !STREAM_VIEW_TYPES.includes(viewType)) {
|
|
136
|
+
throw validationError('One or more parameter values were invalid: StreamViewType must be one of KEYS_ONLY, NEW_IMAGE, OLD_IMAGE, NEW_AND_OLD_IMAGES');
|
|
137
|
+
}
|
|
138
|
+
record.streamSpecification = { StreamEnabled: true, StreamViewType: viewType };
|
|
139
|
+
// AWS stream labels are ISO-8601 without the trailing Z.
|
|
140
|
+
record.latestStreamLabel = new Date().toISOString().replace(/Z$/, '');
|
|
141
|
+
}
|
|
142
|
+
return record;
|
|
143
|
+
}
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
// Key validation / extraction
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
export function tableKeyAttrs(record) {
|
|
148
|
+
const types = new Map(record.attributeDefinitions.map((d) => [d.AttributeName, d.AttributeType]));
|
|
149
|
+
return record.keySchema.map((el) => ({ name: el.AttributeName, type: types.get(el.AttributeName) }));
|
|
150
|
+
}
|
|
151
|
+
export function wireTypeOf(value) {
|
|
152
|
+
if (value === undefined || value === null)
|
|
153
|
+
return undefined;
|
|
154
|
+
for (const tag of ['S', 'N', 'B', 'BOOL', 'NULL', 'L', 'M', 'SS', 'NS', 'BS']) {
|
|
155
|
+
if (value[tag] !== undefined)
|
|
156
|
+
return tag;
|
|
157
|
+
}
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
function keyValueIsEmpty(type, value) {
|
|
161
|
+
return (type === 'S' && value.S === '') || (type === 'B' && value.B === '');
|
|
162
|
+
}
|
|
163
|
+
// PutItem/BatchWriteItem item validation: key attributes present, typed per
|
|
164
|
+
// the schema and non-empty. AWS-worded errors.
|
|
165
|
+
export function validateItemKey(record, item) {
|
|
166
|
+
for (const { name, type } of tableKeyAttrs(record)) {
|
|
167
|
+
const value = item[name];
|
|
168
|
+
if (value === undefined) {
|
|
169
|
+
throw validationError(`One or more parameter values were invalid: Missing the key ${name} in the item`);
|
|
170
|
+
}
|
|
171
|
+
const actual = wireTypeOf(value);
|
|
172
|
+
if (actual !== type) {
|
|
173
|
+
throw validationError(`One or more parameter values were invalid: Type mismatch for key ${name} expected: ${type} actual: ${actual}`);
|
|
174
|
+
}
|
|
175
|
+
if (keyValueIsEmpty(type, value)) {
|
|
176
|
+
throw validationError(`One or more parameter values were invalid: The AttributeValue for a key attribute cannot contain an empty string value. Key: ${name}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Key-parameter validation for GetItem/DeleteItem/UpdateItem/BatchGetItem.
|
|
181
|
+
export function validateProvidedKey(record, key) {
|
|
182
|
+
if (key === undefined || key === null || typeof key !== 'object' || Array.isArray(key)) {
|
|
183
|
+
throw validationError('One of the required keys was not given a value');
|
|
184
|
+
}
|
|
185
|
+
const keyMap = key;
|
|
186
|
+
const attrs = tableKeyAttrs(record);
|
|
187
|
+
const allowed = new Set(attrs.map((a) => a.name));
|
|
188
|
+
for (const name of Object.keys(keyMap)) {
|
|
189
|
+
if (!allowed.has(name))
|
|
190
|
+
throw validationError('The provided key element does not match the schema');
|
|
191
|
+
}
|
|
192
|
+
for (const { name, type } of attrs) {
|
|
193
|
+
const value = keyMap[name];
|
|
194
|
+
if (value === undefined)
|
|
195
|
+
throw validationError('One of the required keys was not given a value');
|
|
196
|
+
if (wireTypeOf(value) !== type || keyValueIsEmpty(type, value)) {
|
|
197
|
+
throw validationError('The provided key element does not match the schema');
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return keyMap;
|
|
201
|
+
}
|
|
202
|
+
// ---------------------------------------------------------------------------
|
|
203
|
+
// Canonical key encoding
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
// Stable, collision-free map key: every component is length-prefixed
|
|
206
|
+
// (`<type>#<length>#<value>`) and components are joined with `|`, so no value
|
|
207
|
+
// bytes can be confused with the separators. N is normalized (sign kept,
|
|
208
|
+
// leading/trailing zeros stripped) so "01" and "1.0" collide as AWS requires;
|
|
209
|
+
// B is round-tripped through Buffer to normalize base64 padding.
|
|
210
|
+
export function canonicalKey(record, source) {
|
|
211
|
+
return tableKeyAttrs(record)
|
|
212
|
+
.map(({ name, type }) => {
|
|
213
|
+
const value = source[name];
|
|
214
|
+
const text = type === 'S' ? value.S
|
|
215
|
+
: type === 'N' ? normalizeDecimal(value.N)
|
|
216
|
+
: Buffer.from(value.B, 'base64').toString('base64');
|
|
217
|
+
return `${type}#${text.length}#${text}`;
|
|
218
|
+
})
|
|
219
|
+
.join('|');
|
|
220
|
+
}
|
|
221
|
+
// The table-key attributes of an item, deep-cloned (stream Keys / LEK material).
|
|
222
|
+
export function keyMapOf(record, item) {
|
|
223
|
+
const key = {};
|
|
224
|
+
for (const { name } of tableKeyAttrs(record))
|
|
225
|
+
key[name] = structuredClone(item[name]);
|
|
226
|
+
return key;
|
|
227
|
+
}
|
|
228
|
+
// ---------------------------------------------------------------------------
|
|
229
|
+
// Item size (approximation of the AWS storage-size formula)
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
function valueSizeBytes(value) {
|
|
232
|
+
if (value.S !== undefined)
|
|
233
|
+
return Buffer.byteLength(value.S);
|
|
234
|
+
if (value.N !== undefined)
|
|
235
|
+
return value.N.length;
|
|
236
|
+
if (value.B !== undefined)
|
|
237
|
+
return Buffer.from(value.B, 'base64').length;
|
|
238
|
+
if (value.BOOL !== undefined || value.NULL !== undefined)
|
|
239
|
+
return 1;
|
|
240
|
+
if (value.SS !== undefined)
|
|
241
|
+
return value.SS.reduce((sum, m) => sum + Buffer.byteLength(m), 0);
|
|
242
|
+
if (value.NS !== undefined)
|
|
243
|
+
return value.NS.reduce((sum, m) => sum + m.length, 0);
|
|
244
|
+
if (value.BS !== undefined)
|
|
245
|
+
return value.BS.reduce((sum, m) => sum + Buffer.from(m, 'base64').length, 0);
|
|
246
|
+
if (value.L !== undefined)
|
|
247
|
+
return 3 + value.L.reduce((sum, el) => sum + 1 + valueSizeBytes(el), 0);
|
|
248
|
+
if (value.M !== undefined) {
|
|
249
|
+
return 3 + Object.entries(value.M).reduce((sum, [name, el]) => sum + Buffer.byteLength(name) + valueSizeBytes(el) + 1, 0);
|
|
250
|
+
}
|
|
251
|
+
return 0;
|
|
252
|
+
}
|
|
253
|
+
export function itemSizeBytes(item) {
|
|
254
|
+
let total = 0;
|
|
255
|
+
for (const [name, value] of Object.entries(item)) {
|
|
256
|
+
total += Buffer.byteLength(name) + valueSizeBytes(value);
|
|
257
|
+
}
|
|
258
|
+
return total;
|
|
259
|
+
}
|
|
260
|
+
export function assertItemSize(item) {
|
|
261
|
+
if (itemSizeBytes(item) > MAX_ITEM_BYTES) {
|
|
262
|
+
throw validationError('Item size has exceeded the maximum allowed size');
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// ---------------------------------------------------------------------------
|
|
266
|
+
// Legacy (pre-expression) parameters — explicit rejection per PRD RF3.6
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
const LEGACY_REPLACEMENT = {
|
|
269
|
+
AttributeUpdates: 'UpdateExpression',
|
|
270
|
+
Expected: 'ConditionExpression',
|
|
271
|
+
KeyConditions: 'KeyConditionExpression',
|
|
272
|
+
QueryFilter: 'FilterExpression',
|
|
273
|
+
ScanFilter: 'FilterExpression',
|
|
274
|
+
AttributesToGet: 'ProjectionExpression',
|
|
275
|
+
ConditionalOperator: 'expression operators (AND/OR)',
|
|
276
|
+
};
|
|
277
|
+
export function rejectLegacyParams(input, params) {
|
|
278
|
+
for (const param of params) {
|
|
279
|
+
if (input[param] !== undefined) {
|
|
280
|
+
throw validationError(`The legacy parameter ${param} is not supported by the LSS self engine — use ${LEGACY_REPLACEMENT[param]} instead`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../../src/server/engine/emulators/dynamodb/schema.ts"],"names":[],"mappings":"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"}
|