@travetto/model-dynamodb 7.0.0-rc.1 → 7.0.0-rc.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 +2 -2
- package/package.json +4 -4
- package/src/service.ts +42 -40
package/README.md
CHANGED
|
@@ -30,8 +30,8 @@ import { DynamoDBModelService, DynamoDBModelConfig } from '@travetto/model-dynam
|
|
|
30
30
|
|
|
31
31
|
export class Init {
|
|
32
32
|
@InjectableFactory({ primary: true })
|
|
33
|
-
static getModelService(
|
|
34
|
-
return new DynamoDBModelService(
|
|
33
|
+
static getModelService(config: DynamoDBModelConfig) {
|
|
34
|
+
return new DynamoDBModelService(config);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-dynamodb",
|
|
3
|
-
"version": "7.0.0-rc.
|
|
3
|
+
"version": "7.0.0-rc.2",
|
|
4
4
|
"description": "DynamoDB backing for the travetto model module.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@aws-sdk/client-dynamodb": "^3.940.0",
|
|
29
|
-
"@travetto/cli": "^7.0.0-rc.
|
|
30
|
-
"@travetto/config": "^7.0.0-rc.
|
|
31
|
-
"@travetto/model": "^7.0.0-rc.
|
|
29
|
+
"@travetto/cli": "^7.0.0-rc.2",
|
|
30
|
+
"@travetto/config": "^7.0.0-rc.2",
|
|
31
|
+
"@travetto/model": "^7.0.0-rc.2"
|
|
32
32
|
},
|
|
33
33
|
"travetto": {
|
|
34
34
|
"displayName": "DynamoDB Model Support"
|
package/src/service.ts
CHANGED
|
@@ -20,18 +20,18 @@ function simpleName(idx: string): string {
|
|
|
20
20
|
return idx.replace(/[^A-Za-z0-9]/g, '');
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function toValue(
|
|
24
|
-
function toValue(
|
|
25
|
-
if (
|
|
23
|
+
function toValue(value: string | number | boolean | Date | undefined | null): AttributeValue;
|
|
24
|
+
function toValue(value: unknown): AttributeValue | undefined {
|
|
25
|
+
if (value === undefined || value === null || value === '') {
|
|
26
26
|
return { NULL: true };
|
|
27
|
-
} else if (typeof
|
|
28
|
-
return { S:
|
|
29
|
-
} else if (typeof
|
|
30
|
-
return { N: `${
|
|
31
|
-
} else if (typeof
|
|
32
|
-
return { BOOL:
|
|
33
|
-
} else if (
|
|
34
|
-
return { N: `${
|
|
27
|
+
} else if (typeof value === 'string') {
|
|
28
|
+
return { S: value };
|
|
29
|
+
} else if (typeof value === 'number') {
|
|
30
|
+
return { N: `${value}` };
|
|
31
|
+
} else if (typeof value === 'boolean') {
|
|
32
|
+
return { BOOL: value };
|
|
33
|
+
} else if (value instanceof Date) {
|
|
34
|
+
return { N: `${value.getTime()}` };
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -84,10 +84,10 @@ export class DynamoDBModelService implements ModelCrudSupport, ModelExpirySuppor
|
|
|
84
84
|
const indices: Record<string, unknown> = {};
|
|
85
85
|
for (const idx of config.indices ?? []) {
|
|
86
86
|
const { key, sort } = ModelIndexedUtil.computeIndexKey(cls, idx, item);
|
|
87
|
-
const
|
|
88
|
-
indices[`${
|
|
87
|
+
const property = simpleName(idx.name);
|
|
88
|
+
indices[`${property}__`] = toValue(key);
|
|
89
89
|
if (sort) {
|
|
90
|
-
indices[`${
|
|
90
|
+
indices[`${property}_sort__`] = toValue(+sort);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
const query: PutItemCommandInput = {
|
|
@@ -108,12 +108,12 @@ export class DynamoDBModelService implements ModelCrudSupport, ModelExpirySuppor
|
|
|
108
108
|
const expr: string[] = [];
|
|
109
109
|
for (const idx of config.indices ?? []) {
|
|
110
110
|
const { key, sort } = ModelIndexedUtil.computeIndexKey(cls, idx, item);
|
|
111
|
-
const
|
|
112
|
-
indices[`:${
|
|
113
|
-
expr.push(`${
|
|
111
|
+
const property = simpleName(idx.name);
|
|
112
|
+
indices[`:${property}`] = toValue(key);
|
|
113
|
+
expr.push(`${property}__ = :${property}`);
|
|
114
114
|
if (sort) {
|
|
115
|
-
indices[`:${
|
|
116
|
-
expr.push(`${
|
|
115
|
+
indices[`:${property}_sort`] = toValue(+sort);
|
|
116
|
+
expr.push(`${property}_sort__ = :${property}_sort`);
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -125,7 +125,7 @@ export class DynamoDBModelService implements ModelCrudSupport, ModelExpirySuppor
|
|
|
125
125
|
'body=:body',
|
|
126
126
|
expiry !== undefined ? `${EXP_ATTR}=:expr` : undefined,
|
|
127
127
|
...expr
|
|
128
|
-
].filter(
|
|
128
|
+
].filter(part => !!part).join(', ')}`,
|
|
129
129
|
ExpressionAttributeValues: {
|
|
130
130
|
':body': toValue(JSON.stringify(item)),
|
|
131
131
|
...(expiry !== undefined ? { ':expr': toValue(expiry) } : {}),
|
|
@@ -134,15 +134,15 @@ export class DynamoDBModelService implements ModelCrudSupport, ModelExpirySuppor
|
|
|
134
134
|
ReturnValues: 'ALL_NEW'
|
|
135
135
|
});
|
|
136
136
|
}
|
|
137
|
-
} catch (
|
|
138
|
-
if (
|
|
137
|
+
} catch (error) {
|
|
138
|
+
if (error instanceof Error && error.name === 'ConditionalCheckFailedException') {
|
|
139
139
|
if (mode === 'create') {
|
|
140
140
|
throw new ExistsError(cls, id);
|
|
141
141
|
} else if (mode === 'update') {
|
|
142
142
|
throw new NotFoundError(cls, id);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
-
throw
|
|
145
|
+
throw error;
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
@@ -332,12 +332,12 @@ export class DynamoDBModelService implements ModelCrudSupport, ModelExpirySuppor
|
|
|
332
332
|
});
|
|
333
333
|
|
|
334
334
|
if (batch.Count && batch.Items) {
|
|
335
|
-
for (const
|
|
335
|
+
for (const item of batch.Items) {
|
|
336
336
|
try {
|
|
337
|
-
yield await loadAndCheckExpiry(cls,
|
|
338
|
-
} catch (
|
|
339
|
-
if (!(
|
|
340
|
-
throw
|
|
337
|
+
yield await loadAndCheckExpiry(cls, item.body.S!);
|
|
338
|
+
} catch (error) {
|
|
339
|
+
if (!(error instanceof NotFoundError)) {
|
|
340
|
+
throw error;
|
|
341
341
|
}
|
|
342
342
|
}
|
|
343
343
|
}
|
|
@@ -360,12 +360,12 @@ export class DynamoDBModelService implements ModelCrudSupport, ModelExpirySuppor
|
|
|
360
360
|
async #getIdByIndex<T extends ModelType>(cls: Class<T>, idx: string, body: DeepPartial<T>): Promise<string> {
|
|
361
361
|
ModelCrudUtil.ensureNotSubType(cls);
|
|
362
362
|
|
|
363
|
-
const
|
|
363
|
+
const idxConfig = ModelRegistryIndex.getIndex(cls, idx, ['sorted', 'unsorted']);
|
|
364
364
|
|
|
365
|
-
const { key, sort } = ModelIndexedUtil.computeIndexKey(cls,
|
|
365
|
+
const { key, sort } = ModelIndexedUtil.computeIndexKey(cls, idxConfig, body);
|
|
366
366
|
|
|
367
|
-
if (
|
|
368
|
-
throw new IndexNotSupported(cls,
|
|
367
|
+
if (idxConfig.type === 'sorted' && sort === undefined) {
|
|
368
|
+
throw new IndexNotSupported(cls, idxConfig, 'Sorted indices require the sort field');
|
|
369
369
|
}
|
|
370
370
|
|
|
371
371
|
const idxName = simpleName(idx);
|
|
@@ -374,7 +374,9 @@ export class DynamoDBModelService implements ModelCrudSupport, ModelExpirySuppor
|
|
|
374
374
|
TableName: this.#resolveTable(cls),
|
|
375
375
|
IndexName: idxName,
|
|
376
376
|
ProjectionExpression: 'id',
|
|
377
|
-
KeyConditionExpression: [sort ? `${idxName}_sort__ = :${idxName}_sort` : '', `${idxName}__ = :${idxName}`]
|
|
377
|
+
KeyConditionExpression: [sort ? `${idxName}_sort__ = :${idxName}_sort` : '', `${idxName}__ = :${idxName}`]
|
|
378
|
+
.filter(expr => !!expr)
|
|
379
|
+
.join(' and '),
|
|
378
380
|
ExpressionAttributeValues: {
|
|
379
381
|
[`:${idxName}`]: toValue(key),
|
|
380
382
|
...(sort ? { [`:${idxName}_sort`]: toValue(+sort) } : {})
|
|
@@ -405,8 +407,8 @@ export class DynamoDBModelService implements ModelCrudSupport, ModelExpirySuppor
|
|
|
405
407
|
async * listByIndex<T extends ModelType>(cls: Class<T>, idx: string, body?: DeepPartial<T>): AsyncIterable<T> {
|
|
406
408
|
ModelCrudUtil.ensureNotSubType(cls);
|
|
407
409
|
|
|
408
|
-
const
|
|
409
|
-
const { key } = ModelIndexedUtil.computeIndexKey(cls,
|
|
410
|
+
const config = ModelRegistryIndex.getIndex(cls, idx, ['sorted', 'unsorted']);
|
|
411
|
+
const { key } = ModelIndexedUtil.computeIndexKey(cls, config, body, { emptySortValue: null });
|
|
410
412
|
|
|
411
413
|
const idxName = simpleName(idx);
|
|
412
414
|
|
|
@@ -425,12 +427,12 @@ export class DynamoDBModelService implements ModelCrudSupport, ModelExpirySuppor
|
|
|
425
427
|
});
|
|
426
428
|
|
|
427
429
|
if (batch.Count && batch.Items) {
|
|
428
|
-
for (const
|
|
430
|
+
for (const item of batch.Items) {
|
|
429
431
|
try {
|
|
430
|
-
yield await loadAndCheckExpiry(cls,
|
|
431
|
-
} catch (
|
|
432
|
-
if (!(
|
|
433
|
-
throw
|
|
432
|
+
yield await loadAndCheckExpiry(cls, item.body.S!);
|
|
433
|
+
} catch (error) {
|
|
434
|
+
if (!(error instanceof NotFoundError)) {
|
|
435
|
+
throw error;
|
|
434
436
|
}
|
|
435
437
|
}
|
|
436
438
|
}
|