@jzhuo3/dynamodb-lib 0.1.1 → 0.1.2
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 +25 -0
- package/dist/cjs/index.d.ts +22 -0
- package/dist/cjs/index.js +70 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.ts +22 -0
- package/dist/esm/index.js +71 -1
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -102,6 +102,31 @@ The constructor accepts independent configurations, rather than using one proces
|
|
|
102
102
|
|
|
103
103
|
**Update Expression builders** compose the changes passed to `update` as a command array: `Assign`, `AssignIfNotExists`, `Increment`, `Decrement`, `ListAppend`, `ListPrepend`, `Remove`, `SetAdd`, `SetDelete`.
|
|
104
104
|
|
|
105
|
+
### Inspecting expressions in unit tests
|
|
106
|
+
|
|
107
|
+
Call `expression.describe()` for a detached, JSON-serializable snapshot containing `expression`, `expressionAttributeNames`, `expressionAttributeValues`, and (for updates) `updateExpressionGroup`. Expressions without values return an empty values object.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
const description = SetAdd('tags', new Set(['a', 'b'])).describe();
|
|
111
|
+
// description.expressionAttributeValues:
|
|
112
|
+
// { ':val0': { $type: 'Set', values: ['a', 'b'] } }
|
|
113
|
+
const json = JSON.stringify(description);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Strings, booleans, null, finite numbers, arrays and plain objects keep their JSON shape. Nested native values use these explicit representations:
|
|
117
|
+
|
|
118
|
+
| Native value | Description |
|
|
119
|
+
| --- | --- |
|
|
120
|
+
| `bigint` | `{ $type: 'BigInt', value: '9007199254740993' }` |
|
|
121
|
+
| SDK `NumberValue` | `{ $type: 'NumberValue', value: '123.456' }` |
|
|
122
|
+
| `Set` | `{ $type: 'Set', values: [...] }` |
|
|
123
|
+
| `Buffer`, `ArrayBuffer`, typed array or `DataView` | `{ $type: 'Binary', encoding: 'base64', value: 'AQI=' }` |
|
|
124
|
+
| `Map` | `{ $type: 'Map', entries: [[key, value], ...] }` |
|
|
125
|
+
| `undefined` | `{ $type: 'Undefined' }` |
|
|
126
|
+
| `NaN`, positive/negative infinity | `{ $type: 'Number', value: 'NaN' }` (or `'Infinity'` / `'-Infinity'`) |
|
|
127
|
+
|
|
128
|
+
Sets and Maps retain insertion order. Binary views serialize only their visible bytes. Circular references, functions, symbols, enumerable symbol keys, and unsupported class instances (including `Date` and `Blob`) throw `TypeError`. Serialization does not validate whether a value is accepted by DynamoDB. This format is for inspection and assertions, not deserialization or sending to DynamoDB; plain objects containing `$type` remain plain objects. The live expression and its values are unchanged.
|
|
129
|
+
|
|
105
130
|
## Detailed documentation
|
|
106
131
|
|
|
107
132
|
See the [documentation index](doc/README.md) for [every service method](doc/service.md), [configuration](doc/configuration.md), [Condition Expression and Update Expression builders](doc/expressions.md), [transaction methods](doc/transactions.md), and [examples](doc/examples.md).
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -135,6 +135,20 @@ export declare function ListPrepend(attribute: string, value: Array<any>, upsert
|
|
|
135
135
|
export declare function Remove(attribute: string): DynamoDBExpression;
|
|
136
136
|
export declare function SetAdd(attribute: string, value: Set<any>): DynamoDBExpression;
|
|
137
137
|
export declare function SetDelete(attribute: string, value: Set<any>): DynamoDBExpression;
|
|
138
|
+
/** JSON-compatible value used by expression descriptions. */
|
|
139
|
+
export type DynamoDBExpressionSerializedValue = null | boolean | number | string | DynamoDBExpressionSerializedValue[] | {
|
|
140
|
+
[key: string]: DynamoDBExpressionSerializedValue;
|
|
141
|
+
};
|
|
142
|
+
export type DynamoDBExpressionDescription = {
|
|
143
|
+
/** DynamoDB expression string, e.g. `#attr0 = :val0`. */
|
|
144
|
+
expression: string;
|
|
145
|
+
/** Placeholder -> attribute name (e.g. `#attr0` -> `VersionStamp`). */
|
|
146
|
+
expressionAttributeNames: Record<string, string>;
|
|
147
|
+
/** Placeholder -> JSON-compatible value; native non-JSON values use explicit `$type` tags. */
|
|
148
|
+
expressionAttributeValues: Record<string, DynamoDBExpressionSerializedValue>;
|
|
149
|
+
/** Which update clause the expression belongs to (SET/REMOVE/ADD/DELETE). */
|
|
150
|
+
updateExpressionGroup?: 'SET' | 'REMOVE' | 'ADD' | 'DELETE';
|
|
151
|
+
};
|
|
138
152
|
export declare class DynamoDBExpression {
|
|
139
153
|
expressionAttributeNameMap: Map<string, string>;
|
|
140
154
|
expressionAttributeValueMap: Map<string, any> | null;
|
|
@@ -143,6 +157,14 @@ export declare class DynamoDBExpression {
|
|
|
143
157
|
constructor(expressionAttributeNameMap?: Map<string, string>, // e.g. #attr0 -> attribute
|
|
144
158
|
expressionAttributeValueMap?: Map<string, any> | null, // e.g. :val0 -> value
|
|
145
159
|
expression?: string, updateExpressionGroup?: "SET" | "REMOVE" | "ADD" | "DELETE" | undefined);
|
|
160
|
+
/**
|
|
161
|
+
* Detached, JSON-serializable description of the expression. Intended for logging,
|
|
162
|
+
* debugging, and unit tests that need to assert on a built expression
|
|
163
|
+
* without reaching into the internal Maps.
|
|
164
|
+
* Sets, bigint, binary, Maps, NumberValue, undefined and non-finite numbers
|
|
165
|
+
* use explicit `$type` tags. Circular and unsupported values throw TypeError.
|
|
166
|
+
*/
|
|
167
|
+
describe(): DynamoDBExpressionDescription;
|
|
146
168
|
}
|
|
147
169
|
export declare enum DynamoDBTransactionMode {
|
|
148
170
|
READ = "READ",
|
package/dist/cjs/index.js
CHANGED
|
@@ -356,6 +356,55 @@ function SetDelete(attribute, value) {
|
|
|
356
356
|
const expression = `${path} :val0`;
|
|
357
357
|
return new DynamoDBExpression(expressionAttributeNameMap, expressionAttributeValueMap, expression, 'DELETE');
|
|
358
358
|
}
|
|
359
|
+
function serializeExpressionValue(value, ancestors = new Set()) {
|
|
360
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
361
|
+
return value;
|
|
362
|
+
if (typeof value === 'number') {
|
|
363
|
+
return Number.isFinite(value) ? value : { $type: 'Number', value: String(value) };
|
|
364
|
+
}
|
|
365
|
+
if (typeof value === 'bigint')
|
|
366
|
+
return { $type: 'BigInt', value: value.toString() };
|
|
367
|
+
if (value === undefined)
|
|
368
|
+
return { $type: 'Undefined' };
|
|
369
|
+
if (typeof value !== 'object') {
|
|
370
|
+
throw new TypeError(`Cannot describe expression value of type ${typeof value}`);
|
|
371
|
+
}
|
|
372
|
+
if (ancestors.has(value))
|
|
373
|
+
throw new TypeError('Cannot describe circular expression value');
|
|
374
|
+
ancestors.add(value);
|
|
375
|
+
try {
|
|
376
|
+
if (value instanceof lib_dynamodb_1.NumberValue)
|
|
377
|
+
return { $type: 'NumberValue', value: value.toString() };
|
|
378
|
+
if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
|
379
|
+
const bytes = value instanceof ArrayBuffer
|
|
380
|
+
? Buffer.from(value)
|
|
381
|
+
: Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
382
|
+
return { $type: 'Binary', encoding: 'base64', value: bytes.toString('base64') };
|
|
383
|
+
}
|
|
384
|
+
if (value instanceof Set) {
|
|
385
|
+
return { $type: 'Set', values: Array.from(value, item => serializeExpressionValue(item, ancestors)) };
|
|
386
|
+
}
|
|
387
|
+
if (Array.isArray(value))
|
|
388
|
+
return Array.from(value, item => serializeExpressionValue(item, ancestors));
|
|
389
|
+
if (value instanceof Map) {
|
|
390
|
+
return { $type: 'Map', entries: Array.from(value, ([key, item]) => [
|
|
391
|
+
serializeExpressionValue(key, ancestors), serializeExpressionValue(item, ancestors),
|
|
392
|
+
]) };
|
|
393
|
+
}
|
|
394
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
|
|
395
|
+
throw new TypeError('Cannot describe unsupported expression value object');
|
|
396
|
+
}
|
|
397
|
+
if (Object.getOwnPropertySymbols(value).some(key => Object.prototype.propertyIsEnumerable.call(value, key))) {
|
|
398
|
+
throw new TypeError('Cannot describe expression value with symbol keys');
|
|
399
|
+
}
|
|
400
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
401
|
+
key, serializeExpressionValue(item, ancestors),
|
|
402
|
+
]));
|
|
403
|
+
}
|
|
404
|
+
finally {
|
|
405
|
+
ancestors.delete(value);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
359
408
|
class DynamoDBExpression {
|
|
360
409
|
expressionAttributeNameMap;
|
|
361
410
|
expressionAttributeValueMap;
|
|
@@ -369,6 +418,27 @@ class DynamoDBExpression {
|
|
|
369
418
|
this.expression = expression;
|
|
370
419
|
this.updateExpressionGroup = updateExpressionGroup;
|
|
371
420
|
}
|
|
421
|
+
/**
|
|
422
|
+
* Detached, JSON-serializable description of the expression. Intended for logging,
|
|
423
|
+
* debugging, and unit tests that need to assert on a built expression
|
|
424
|
+
* without reaching into the internal Maps.
|
|
425
|
+
* Sets, bigint, binary, Maps, NumberValue, undefined and non-finite numbers
|
|
426
|
+
* use explicit `$type` tags. Circular and unsupported values throw TypeError.
|
|
427
|
+
*/
|
|
428
|
+
describe() {
|
|
429
|
+
return {
|
|
430
|
+
expression: this.expression,
|
|
431
|
+
expressionAttributeNames: Object.fromEntries(this.expressionAttributeNameMap),
|
|
432
|
+
expressionAttributeValues: this.expressionAttributeValueMap
|
|
433
|
+
? Object.fromEntries(Array.from(this.expressionAttributeValueMap, ([key, value]) => [
|
|
434
|
+
key, serializeExpressionValue(value),
|
|
435
|
+
]))
|
|
436
|
+
: {},
|
|
437
|
+
...(this.updateExpressionGroup !== undefined
|
|
438
|
+
? { updateExpressionGroup: this.updateExpressionGroup }
|
|
439
|
+
: {}),
|
|
440
|
+
};
|
|
441
|
+
}
|
|
372
442
|
}
|
|
373
443
|
exports.DynamoDBExpression = DynamoDBExpression;
|
|
374
444
|
var DynamoDBTransactionMode;
|