electrodb 2.1.0 → 2.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 +43 -34
- package/index.d.ts +2 -2
- package/index.js +8 -1
- package/package.json +1 -1
- package/src/clauses.js +5 -0
- package/src/entity.js +6 -6
- package/src/operations.js +4 -2
- package/src/schema.js +10 -0
package/README.md
CHANGED
|
@@ -3401,7 +3401,7 @@ await StoreLocations
|
|
|
3401
3401
|
o.add(a.tenant, newTenant); // electrodb "set" -> dynamodb "set"
|
|
3402
3402
|
o.add(a.rent, 100); // electrodb "number" -> dynamodb "number"
|
|
3403
3403
|
o.subtract(a.deposit, 200); // electrodb "number" -> dynamodb "number"
|
|
3404
|
-
o.remove(
|
|
3404
|
+
o.remove(attr.discount); // electrodb "number" -> dynamodb "number"
|
|
3405
3405
|
o.append(a.rentalAgreement, [{ // electrodb "list" -> dynamodb "list"
|
|
3406
3406
|
type: "ammendment", // electrodb "map" -> dynamodb "map"
|
|
3407
3407
|
detail: "no soup for you"
|
|
@@ -3425,40 +3425,49 @@ Response Format:
|
|
|
3425
3425
|
Equivalent DocClient Parameters:
|
|
3426
3426
|
```json
|
|
3427
3427
|
{
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
":tenant_u0": ["larry"],
|
|
3447
|
-
":rent_u0": 100,
|
|
3448
|
-
":deposit_u0": 200,
|
|
3449
|
-
":rentalAgreement_u0": [{
|
|
3450
|
-
"type": "amendment",
|
|
3451
|
-
"detail": "no soup for you"
|
|
3452
|
-
}],
|
|
3453
|
-
":tags_u0": ["coffee"], // <- DynamoDB Set
|
|
3454
|
-
":contact_u0": ["555-345-2222"], // <- DynamoDB Set
|
|
3428
|
+
"UpdateExpression": "SET #category = :category_u0, #deposit = #deposit - :deposit_u0, #rentalAgreement = list_append(#rentalAgreement, :rentalAgreement_u0), #totalFees = #totalFees + #petFee, #cityId = :cityId_u0, #mallId = :mallId_u0, #buildingId = :buildingId_u0, #storeId = :storeId_u0, #__edb_e__ = :__edb_e___u0, #__edb_v__ = :__edb_v___u0 REMOVE #discount ADD #tenant :tenant_u0, #rent :rent_u0, #leaseHolders :tenant_u0 DELETE #tags :tags_u0, #contact :contact_u0",
|
|
3429
|
+
"ExpressionAttributeNames": {
|
|
3430
|
+
"#category": "category",
|
|
3431
|
+
"#tenant": "tenant",
|
|
3432
|
+
"#rent": "rent",
|
|
3433
|
+
"#deposit": "deposit",
|
|
3434
|
+
"#discount": "discount",
|
|
3435
|
+
"#rentalAgreement": "rentalAgreement",
|
|
3436
|
+
"#tags": "tags",
|
|
3437
|
+
"#contact": "contact",
|
|
3438
|
+
"#totalFees": "totalFees",
|
|
3439
|
+
"#petFee": "petFee",
|
|
3440
|
+
"#leaseHolders": "leaseHolders",
|
|
3441
|
+
"#buildingId": "buildingId",
|
|
3442
|
+
"#cityId": "cityId",
|
|
3443
|
+
"#mallId": "mallId",
|
|
3444
|
+
"#storeId": "storeId",
|
|
3445
|
+
"#__edb_e__": "__edb_e__", "#__edb_v__": "__edb_v__",
|
|
3455
3446
|
},
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3447
|
+
"ExpressionAttributeValues": {
|
|
3448
|
+
":buildingId_u0": "A34",
|
|
3449
|
+
":cityId_u0": "portland",
|
|
3450
|
+
":category0": "food/coffee",
|
|
3451
|
+
":category_u0": "food/meal",
|
|
3452
|
+
":tenant_u0": ["larry"],
|
|
3453
|
+
":rent_u0": 100,
|
|
3454
|
+
":deposit_u0": 200,
|
|
3455
|
+
":rentalAgreement_u0": [{
|
|
3456
|
+
"type": "amendment",
|
|
3457
|
+
"detail": "no soup for you"
|
|
3458
|
+
}],
|
|
3459
|
+
":tags_u0": ["coffee"],
|
|
3460
|
+
":contact_u0": ["555-345-2222"],
|
|
3461
|
+
":mallId_u0": "EastPointe",
|
|
3462
|
+
":storeId_u0": "LatteLarrys",
|
|
3463
|
+
":__edb_e___u0": "MallStore", ":__edb_v___u0": "1",
|
|
3464
|
+
},
|
|
3465
|
+
"TableName": "electro",
|
|
3466
|
+
"Key": {
|
|
3467
|
+
"pk": "$mallstoredirectory#cityid_portland#mallid_eastpointe",
|
|
3468
|
+
"sk": "$mallstore_1#buildingid_a34#storeid_lattelarrys"
|
|
3469
|
+
},
|
|
3470
|
+
"ConditionExpression": "#category = :category0"
|
|
3462
3471
|
}
|
|
3463
3472
|
```
|
|
3464
3473
|
|
package/index.d.ts
CHANGED
|
@@ -698,7 +698,7 @@ export type BatchWriteGo<ResponseType> = <O extends BulkOptions>(options?: O) =>
|
|
|
698
698
|
|
|
699
699
|
export type ParamRecord<Options = ParamOptions> = <P>(options?: Options) => P;
|
|
700
700
|
|
|
701
|
-
export
|
|
701
|
+
export class ElectroError extends Error {
|
|
702
702
|
readonly name: 'ElectroError';
|
|
703
703
|
readonly code: number;
|
|
704
704
|
readonly date: number;
|
|
@@ -733,7 +733,7 @@ export interface ElectroValidationErrorFieldReference<T extends Error = Error> {
|
|
|
733
733
|
readonly cause: T | undefined;
|
|
734
734
|
}
|
|
735
735
|
|
|
736
|
-
export
|
|
736
|
+
export class ElectroValidationError<T extends Error = Error> extends ElectroError {
|
|
737
737
|
readonly fields: ReadonlyArray<ElectroValidationErrorFieldReference<T>>;
|
|
738
738
|
}
|
|
739
739
|
|
package/index.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
const { Entity } = require("./src/entity");
|
|
2
2
|
const { Service } = require("./src/service");
|
|
3
3
|
const { createCustomAttribute } = require('./src/schema');
|
|
4
|
+
const { ElectroError, ElectroValidationError, ElectroUserValidationError, ElectroAttributeValidationError } = require('./src/errors');
|
|
4
5
|
|
|
5
|
-
module.exports = {
|
|
6
|
+
module.exports = {
|
|
7
|
+
Entity,
|
|
8
|
+
Service,
|
|
9
|
+
createCustomAttribute,
|
|
10
|
+
ElectroError,
|
|
11
|
+
ElectroValidationError,
|
|
12
|
+
};
|
package/package.json
CHANGED
package/src/clauses.js
CHANGED
|
@@ -277,6 +277,11 @@ let clauses = {
|
|
|
277
277
|
}
|
|
278
278
|
try {
|
|
279
279
|
state.query.updateProxy.invokeCallback(cb);
|
|
280
|
+
for (const path of Object.keys(state.query.update.refs)) {
|
|
281
|
+
const operation = state.query.update.impacted[path];
|
|
282
|
+
const attribute = state.query.update.refs[path];
|
|
283
|
+
entity.model.schema.checkOperation(attribute, operation);
|
|
284
|
+
}
|
|
280
285
|
return state;
|
|
281
286
|
} catch(err) {
|
|
282
287
|
state.setError(err);
|
package/src/entity.js
CHANGED
|
@@ -624,7 +624,7 @@ class Entity {
|
|
|
624
624
|
|
|
625
625
|
if (config._isPagination || response.LastEvaluatedKey) {
|
|
626
626
|
const nextPage = this._formatReturnPager(config, response.LastEvaluatedKey);
|
|
627
|
-
return { cursor: nextPage
|
|
627
|
+
return { cursor: nextPage || null, data: results };
|
|
628
628
|
}
|
|
629
629
|
|
|
630
630
|
return { data: results };
|
|
@@ -652,19 +652,19 @@ class Entity {
|
|
|
652
652
|
}
|
|
653
653
|
|
|
654
654
|
_formatReturnPager(config, lastEvaluatedKey) {
|
|
655
|
-
let page = lastEvaluatedKey
|
|
655
|
+
let page = lastEvaluatedKey || null;
|
|
656
656
|
if (config.raw || config.pager === Pager.raw) {
|
|
657
657
|
return page;
|
|
658
658
|
}
|
|
659
|
-
return config.formatCursor.serialize(page)
|
|
659
|
+
return config.formatCursor.serialize(page) || null;
|
|
660
660
|
}
|
|
661
661
|
|
|
662
662
|
_formatExclusiveStartKey(config) {
|
|
663
663
|
let exclusiveStartKey = config.cursor;
|
|
664
664
|
if (config.raw || config.pager === Pager.raw) {
|
|
665
|
-
return exclusiveStartKey
|
|
665
|
+
return exclusiveStartKey || null;
|
|
666
666
|
}
|
|
667
|
-
return config.formatCursor.deserialize(exclusiveStartKey)
|
|
667
|
+
return config.formatCursor.deserialize(exclusiveStartKey) || null;
|
|
668
668
|
}
|
|
669
669
|
|
|
670
670
|
_getTableName() {
|
|
@@ -1972,7 +1972,7 @@ class Entity {
|
|
|
1972
1972
|
_buildQueryFacets(facets, skFacets) {
|
|
1973
1973
|
let queryFacets = this._findProperties(facets, skFacets).reduce(
|
|
1974
1974
|
(result, [name, value]) => {
|
|
1975
|
-
if (value) {
|
|
1975
|
+
if (value !== undefined) {
|
|
1976
1976
|
result[name] = value;
|
|
1977
1977
|
}
|
|
1978
1978
|
return result;
|
package/src/operations.js
CHANGED
|
@@ -256,6 +256,7 @@ class ExpressionState {
|
|
|
256
256
|
this.impacted = {};
|
|
257
257
|
this.expression = "";
|
|
258
258
|
this.prefix = prefix || "";
|
|
259
|
+
this.refs = {};
|
|
259
260
|
}
|
|
260
261
|
|
|
261
262
|
incrementName(name) {
|
|
@@ -316,8 +317,9 @@ class ExpressionState {
|
|
|
316
317
|
return this.expression;
|
|
317
318
|
}
|
|
318
319
|
|
|
319
|
-
setImpacted(operation, path) {
|
|
320
|
+
setImpacted(operation, path, ref) {
|
|
320
321
|
this.impacted[path] = operation;
|
|
322
|
+
this.refs[path] = ref;
|
|
321
323
|
}
|
|
322
324
|
}
|
|
323
325
|
|
|
@@ -407,7 +409,7 @@ class AttributeOperationProxy {
|
|
|
407
409
|
}
|
|
408
410
|
|
|
409
411
|
const formatted = template(options, target, paths.expression, ...attributeValues);
|
|
410
|
-
builder.setImpacted(operation, paths.json);
|
|
412
|
+
builder.setImpacted(operation, paths.json, target);
|
|
411
413
|
if (canNest) {
|
|
412
414
|
seen.add(paths.expression);
|
|
413
415
|
seen.add(formatted);
|
package/src/schema.js
CHANGED
|
@@ -1361,6 +1361,16 @@ class Schema {
|
|
|
1361
1361
|
return record;
|
|
1362
1362
|
}
|
|
1363
1363
|
|
|
1364
|
+
checkOperation(attribute, operation) {
|
|
1365
|
+
if (!attribute) {
|
|
1366
|
+
throw new e.ElectroAttributeValidationError(path, `Attribute "${path}" does not exist on model.`);
|
|
1367
|
+
} else if (attribute.required && operation === 'remove') {
|
|
1368
|
+
throw new e.ElectroAttributeValidationError(attribute.path, `Attribute "${attribute.path}" is Required and cannot be removed`);
|
|
1369
|
+
} else if (attribute.readOnly) {
|
|
1370
|
+
throw new e.ElectroAttributeValidationError(attribute.path, `Attribute "${attribute.path}" is Read-Only and cannot be updated`);
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1364
1374
|
checkRemove(paths = []) {
|
|
1365
1375
|
for (const path of paths) {
|
|
1366
1376
|
const attribute = this.traverser.getPath(path);
|