electrodb 2.6.1 → 2.7.1
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/docker/dynamodb/shared-local-instance.db +0 -0
- package/index.d.ts +65 -22
- package/package.json +3 -2
- package/src/clauses.js +38 -13
- package/src/entity.js +23 -5
- package/src/schema.js +2 -3
- package/src/types.js +1 -0
- package/src/update.js +13 -5
- package/.travis.yml +0 -15
|
Binary file
|
package/index.d.ts
CHANGED
|
@@ -156,8 +156,8 @@ export interface CollectionWhereOperations {
|
|
|
156
156
|
begins: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
157
157
|
exists: <T, A extends WhereAttributeSymbol<T>>(attr: A) => string;
|
|
158
158
|
notExists: <T, A extends WhereAttributeSymbol<T>>(attr: A) => string;
|
|
159
|
-
contains: <T, A extends WhereAttributeSymbol<T>>(attr: A, value:
|
|
160
|
-
notContains: <T, A extends WhereAttributeSymbol<T>>(attr: A, value:
|
|
159
|
+
contains: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: A extends WhereAttributeSymbol<infer V> ? V extends Array<infer I> ? I : V : never) => string;
|
|
160
|
+
notContains: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: A extends WhereAttributeSymbol<infer V> ? V extends Array<infer I> ? I : V : never) => string;
|
|
161
161
|
value: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
162
162
|
name: <T, A extends WhereAttributeSymbol<T>>(attr: A) => string;
|
|
163
163
|
size: <T, A extends WhereAttributeSymbol<T>>(attr: A) => string;
|
|
@@ -601,6 +601,11 @@ export type ElectroEventListener = (event: ElectroEvent) => void;
|
|
|
601
601
|
// details: any;
|
|
602
602
|
// };
|
|
603
603
|
|
|
604
|
+
export type EntityIdentifiers<E extends Entity<any, any, any, any>> =
|
|
605
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
606
|
+
? AllTableIndexCompositeAttributes<A, F, C, S>
|
|
607
|
+
: never;
|
|
608
|
+
|
|
604
609
|
export type EntityItem<E extends Entity<any, any, any, any>> =
|
|
605
610
|
E extends Entity<infer A, infer F, infer C, infer S>
|
|
606
611
|
? ResponseItem<A, F, C, S>
|
|
@@ -621,9 +626,14 @@ export type BatchGetEntityItem<E extends Entity<any, any, any, any>> =
|
|
|
621
626
|
? ResponseItem<A, F, C, S>[]
|
|
622
627
|
: never;
|
|
623
628
|
|
|
629
|
+
export type UpdateEntityResponseItem<E extends Entity<any, any, any, any>> =
|
|
630
|
+
E extends Entity<infer A, infer F, infer C, infer S>
|
|
631
|
+
? AllTableIndexCompositeAttributes<A,F,C,S>
|
|
632
|
+
: never;
|
|
633
|
+
|
|
624
634
|
export type UpdateEntityItem<E extends Entity<any, any, any, any>> =
|
|
625
635
|
E extends Entity<infer A, infer F, infer C, infer S>
|
|
626
|
-
?
|
|
636
|
+
? SetItem<A,F,C,S>
|
|
627
637
|
: never;
|
|
628
638
|
|
|
629
639
|
export type UpdateAddEntityItem<E extends Entity<any, any, any, any>> =
|
|
@@ -692,7 +702,7 @@ export type BatchGetResponse<E extends Entity<any, any, any, any>> =
|
|
|
692
702
|
} : never;
|
|
693
703
|
|
|
694
704
|
export type UpdateEntityResponse<E extends Entity<any, any, any, any>> = {
|
|
695
|
-
data:
|
|
705
|
+
data: UpdateEntityResponseItem<E>;
|
|
696
706
|
}
|
|
697
707
|
export type UpdateAddEntityResponse<E extends Entity<any, any, any, any>> = {
|
|
698
708
|
data: UpdateAddEntityItem<E>;
|
|
@@ -793,7 +803,7 @@ export type UpdateRecordGoTransaction<ResponseType> = <T = ResponseType, Options
|
|
|
793
803
|
export interface SetRecordActionOptionsTransaction<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, SetAttr,IndexCompositeAttributes,TableItem> {
|
|
794
804
|
commit: UpdateRecordGoTransaction<TableItem>;
|
|
795
805
|
params: ParamRecord<UpdateQueryParams>;
|
|
796
|
-
set: SetRecordTransaction<A,F,C,S, SetItem<A,F,C,S>,IndexCompositeAttributes,TableItem>;
|
|
806
|
+
set: SetRecordTransaction<A,F,C,S, SetItem<A,F,C,S>, IndexCompositeAttributes, TableItem>;
|
|
797
807
|
remove: RemoveRecordTransaction<A,F,C,S, Array<keyof SetItem<A,F,C,S>>,IndexCompositeAttributes,TableItem>;
|
|
798
808
|
add: SetRecordTransaction<A,F,C,S, AddItem<A,F,C,S>,IndexCompositeAttributes,TableItem>;
|
|
799
809
|
subtract: SetRecordTransaction<A,F,C,S, SubtractItem<A,F,C,S>,IndexCompositeAttributes,TableItem>;
|
|
@@ -818,19 +828,19 @@ export interface BatchGetRecordOperationOptions<A extends string, F extends stri
|
|
|
818
828
|
}
|
|
819
829
|
|
|
820
830
|
export interface PutRecordOperationOptions<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, ResponseType> {
|
|
821
|
-
go: PutRecordGo<ResponseType
|
|
831
|
+
go: PutRecordGo<ResponseType>;
|
|
822
832
|
params: ParamRecord<PutQueryOptions>;
|
|
823
833
|
where: WhereClause<A, F, C, S, Item<A, F, C, S, S["attributes"]>, PutRecordOperationOptions<A, F, C, S, ResponseType>>;
|
|
824
834
|
}
|
|
825
835
|
|
|
826
836
|
export interface UpsertRecordOperationOptions<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, ResponseType> {
|
|
827
|
-
go:
|
|
837
|
+
go: UpsertRecordGo<ResponseType, AllTableIndexCompositeAttributes<A,F,C,S>>;
|
|
828
838
|
params: ParamRecord<UpdateQueryParams>;
|
|
829
839
|
where: WhereClause<A, F, C, S, Item<A, F, C, S, S["attributes"]>, UpsertRecordOperationOptions<A, F, C, S, ResponseType>>;
|
|
830
840
|
}
|
|
831
841
|
|
|
832
842
|
export interface DeleteRecordOperationOptions<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, ResponseType> {
|
|
833
|
-
go: DeleteRecordOperationGo<ResponseType,
|
|
843
|
+
go: DeleteRecordOperationGo<ResponseType, AllTableIndexCompositeAttributes<A,F,C,S>>;
|
|
834
844
|
params: ParamRecord<DeleteQueryOptions>;
|
|
835
845
|
where: WhereClause<A,F,C,S,Item<A,F,C,S,S["attributes"]>,DeleteRecordOperationOptions<A,F,C,S,ResponseType>>;
|
|
836
846
|
}
|
|
@@ -841,9 +851,10 @@ export interface BatchWriteOperationOptions<A extends string, F extends string,
|
|
|
841
851
|
}
|
|
842
852
|
|
|
843
853
|
export interface SetRecordActionOptions<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, SetAttr,IndexCompositeAttributes,TableItem> {
|
|
844
|
-
go: UpdateRecordGo<TableItem
|
|
854
|
+
go: UpdateRecordGo<TableItem, AllTableIndexCompositeAttributes<A,F,C,S>>;
|
|
845
855
|
params: ParamRecord<UpdateQueryParams>;
|
|
846
|
-
set: SetRecord<A,F,C,S, SetItem<A,F,C,S>,IndexCompositeAttributes,TableItem>;
|
|
856
|
+
set: SetRecord<A,F,C,S, SetItem<A,F,C,S>,IndexCompositeAttributes, TableItem>;
|
|
857
|
+
// ifNotExists: SetRecord<A,F,C,S, SetItem<A,F,C,S>,IndexCompositeAttributes,TableItem>;
|
|
847
858
|
remove: SetRecord<A,F,C,S, Array<keyof SetItem<A,F,C,S>>,IndexCompositeAttributes,TableItem>;
|
|
848
859
|
add: SetRecord<A,F,C,S, AddItem<A,F,C,S>,IndexCompositeAttributes,TableItem>;
|
|
849
860
|
subtract: SetRecord<A,F,C,S, SubtractItem<A,F,C,S>,IndexCompositeAttributes,TableItem>;
|
|
@@ -1005,7 +1016,7 @@ export interface DeleteQueryOptions extends QueryOptions {
|
|
|
1005
1016
|
}
|
|
1006
1017
|
|
|
1007
1018
|
export interface PutQueryOptions extends QueryOptions {
|
|
1008
|
-
response?: "default" | "none" | 'all_old';
|
|
1019
|
+
response?: "default" | "none" | 'all_old' | 'all_new';
|
|
1009
1020
|
}
|
|
1010
1021
|
|
|
1011
1022
|
export interface ParamOptions {
|
|
@@ -1206,20 +1217,52 @@ export type ServiceQueryRecordsGo<ResponseType, Options = ServiceQueryGoTerminal
|
|
|
1206
1217
|
|
|
1207
1218
|
export type QueryRecordsGo<ResponseType, Options = QueryOptions> = <T = ResponseType>(options?: Options) => Promise<{ data: T, cursor: string | null }>;
|
|
1208
1219
|
|
|
1209
|
-
export type UpdateRecordGo<ResponseType> = <T = ResponseType, Options extends UpdateQueryOptions = UpdateQueryOptions>(options?: Options) =>
|
|
1220
|
+
export type UpdateRecordGo<ResponseType, Keys> = <T = ResponseType, Options extends UpdateQueryOptions = UpdateQueryOptions>(options?: Options) =>
|
|
1210
1221
|
Options extends infer O
|
|
1211
1222
|
? 'response' extends keyof O
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1223
|
+
? O['response'] extends 'all_new'
|
|
1224
|
+
? Promise<{ data: T }>
|
|
1225
|
+
: O['response'] extends 'all_old'
|
|
1226
|
+
? Promise<{ data: T }>
|
|
1227
|
+
: O['response'] extends 'default'
|
|
1228
|
+
? Promise<{ data: Keys }>
|
|
1229
|
+
: O['response'] extends 'none'
|
|
1230
|
+
? Promise<{ data: null }>
|
|
1231
|
+
: Promise<{ data: Partial<T> }>
|
|
1232
|
+
: Promise<{ data: Keys }>
|
|
1218
1233
|
: never;
|
|
1219
1234
|
|
|
1220
|
-
export type
|
|
1235
|
+
export type UpsertRecordGo<ResponseType, Keys> = <T = ResponseType, Options extends UpdateQueryOptions = UpdateQueryOptions>(options?: Options) =>
|
|
1236
|
+
Options extends infer O
|
|
1237
|
+
? 'response' extends keyof O
|
|
1238
|
+
? O['response'] extends 'all_new'
|
|
1239
|
+
? Promise<{ data: T }>
|
|
1240
|
+
: O['response'] extends 'all_old'
|
|
1241
|
+
? Promise<{ data: T }>
|
|
1242
|
+
: O['response'] extends 'default'
|
|
1243
|
+
? Promise<{ data: Keys }>
|
|
1244
|
+
: O['response'] extends 'none'
|
|
1245
|
+
? Promise<{ data: null }>
|
|
1246
|
+
: Promise<{ data: Partial<T> }>
|
|
1247
|
+
: Promise<{ data: Keys }>
|
|
1248
|
+
: never;
|
|
1221
1249
|
|
|
1222
|
-
export type
|
|
1250
|
+
export type PutRecordGo<ResponseType> = <T = ResponseType, Options extends PutQueryOptions = PutQueryOptions>(options?: Options) => Promise<{ data: T }>
|
|
1251
|
+
|
|
1252
|
+
export type DeleteRecordOperationGo<ResponseType, Keys> = <T = ResponseType, Options extends DeleteQueryOptions = DeleteQueryOptions>(options?: Options) =>
|
|
1253
|
+
Options extends infer O
|
|
1254
|
+
? 'response' extends keyof O
|
|
1255
|
+
? O['response'] extends 'all_new'
|
|
1256
|
+
? Promise<{ data: T }>
|
|
1257
|
+
: O['response'] extends 'all_old'
|
|
1258
|
+
? Promise<{ data: T }>
|
|
1259
|
+
: O['response'] extends 'default'
|
|
1260
|
+
? Promise<{ data: Keys }>
|
|
1261
|
+
: O['response'] extends 'none'
|
|
1262
|
+
? Promise<{ data: null }>
|
|
1263
|
+
: Promise<{ data: Partial<T> }>
|
|
1264
|
+
: Promise<{ data: Keys }>
|
|
1265
|
+
: never;
|
|
1223
1266
|
|
|
1224
1267
|
export type BatchWriteGo<ResponseType> = <O extends BulkOptions>(options?: O) =>
|
|
1225
1268
|
Promise<{ unprocessed: ResponseType }>
|
|
@@ -2419,8 +2462,8 @@ export interface WhereOperations<A extends string, F extends string, C extends s
|
|
|
2419
2462
|
begins: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
|
|
2420
2463
|
exists: <A extends WhereAttributeSymbol<any>>(attr: A) => string;
|
|
2421
2464
|
notExists: <A extends WhereAttributeSymbol<any>>(attr: A) => string;
|
|
2422
|
-
contains: <T, A extends WhereAttributeSymbol<T>>(attr: A, value:
|
|
2423
|
-
notContains: <T, A extends WhereAttributeSymbol<T>>(attr: A, value:
|
|
2465
|
+
contains: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: A extends WhereAttributeSymbol<infer V> ? V extends Array<infer I> ? I : V : never) => string;
|
|
2466
|
+
notContains: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: A extends WhereAttributeSymbol<infer V> ? V extends Array<infer I> ? I : V : never) => string;
|
|
2424
2467
|
value: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: A extends WhereAttributeSymbol<infer V> ? V : never) => A extends WhereAttributeSymbol<infer V> ? V : never;
|
|
2425
2468
|
name: <A extends WhereAttributeSymbol<any>>(attr: A) => string;
|
|
2426
2469
|
size: <T, A extends WhereAttributeSymbol<T>>(attr: A) => number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "electrodb",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.1",
|
|
4
4
|
"description": "A library to more easily create and interact with multiple entities and heretical relationships in dynamodb",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"coverage:local:coveralls": "npm run test:init && nyc npm run test:unit && nyc report --reporter=text-lcov | coveralls",
|
|
13
13
|
"coverage:local:html": "npm run test:init && nyc npm run test:unit && nyc report --reporter=html",
|
|
14
14
|
"build:browser": "browserify playground/browser.js -o playground/bundle.js",
|
|
15
|
-
"build": "sh buildbrowser.sh"
|
|
15
|
+
"build": "sh buildbrowser.sh",
|
|
16
|
+
"start:containers": "docker compose up -d"
|
|
16
17
|
},
|
|
17
18
|
"repository": {
|
|
18
19
|
"type": "git",
|
package/src/clauses.js
CHANGED
|
@@ -185,13 +185,17 @@ let clauses = {
|
|
|
185
185
|
}
|
|
186
186
|
try {
|
|
187
187
|
const {pk, sk} = state.getCompositeAttributes();
|
|
188
|
+
const pkComposite = entity._expectFacets(facets, pk);
|
|
189
|
+
state.addOption('_includeOnResponseItem', pkComposite);
|
|
188
190
|
return state
|
|
189
191
|
.setMethod(MethodTypes.delete)
|
|
190
192
|
.setType(QueryTypes.eq)
|
|
191
|
-
.setPK(
|
|
193
|
+
.setPK(pkComposite)
|
|
192
194
|
.ifSK(() => {
|
|
193
195
|
entity._expectFacets(facets, sk);
|
|
194
|
-
state.
|
|
196
|
+
const skComposite = state.buildQueryComposites(facets, sk);
|
|
197
|
+
state.setSK(skComposite);
|
|
198
|
+
state.addOption('_includeOnResponseItem', {...skComposite, ...pkComposite});
|
|
195
199
|
});
|
|
196
200
|
} catch(err) {
|
|
197
201
|
state.setError(err);
|
|
@@ -215,13 +219,17 @@ let clauses = {
|
|
|
215
219
|
if (sk) {
|
|
216
220
|
filter.unsafeSet(FilterOperationNames.exists, sk);
|
|
217
221
|
}
|
|
222
|
+
const pkComposite = entity._expectFacets(facets, attributes.pk);
|
|
223
|
+
state.addOption('_includeOnResponseItem', pkComposite);
|
|
218
224
|
return state
|
|
219
225
|
.setMethod(MethodTypes.delete)
|
|
220
226
|
.setType(QueryTypes.eq)
|
|
221
|
-
.setPK(
|
|
227
|
+
.setPK(pkComposite)
|
|
222
228
|
.ifSK(() => {
|
|
223
229
|
entity._expectFacets(facets, attributes.sk);
|
|
224
|
-
state.
|
|
230
|
+
const skComposite = state.buildQueryComposites(facets, attributes.sk);
|
|
231
|
+
state.setSK(skComposite);
|
|
232
|
+
state.addOption('_includeOnResponseItem', {...skComposite, ...pkComposite});
|
|
225
233
|
});
|
|
226
234
|
} catch(err) {
|
|
227
235
|
state.setError(err);
|
|
@@ -239,14 +247,18 @@ let clauses = {
|
|
|
239
247
|
try {
|
|
240
248
|
let record = entity.model.schema.checkCreate({...payload});
|
|
241
249
|
const attributes = state.getCompositeAttributes();
|
|
250
|
+
const pkComposite = entity._expectFacets(record, attributes.pk);
|
|
251
|
+
state.addOption('_includeOnResponseItem', pkComposite);
|
|
242
252
|
return state
|
|
243
253
|
.setMethod(MethodTypes.upsert)
|
|
244
254
|
.setType(QueryTypes.eq)
|
|
245
255
|
.applyUpsert(record)
|
|
246
|
-
.setPK(
|
|
256
|
+
.setPK(pkComposite)
|
|
247
257
|
.ifSK(() => {
|
|
248
258
|
entity._expectFacets(record, attributes.sk);
|
|
249
|
-
|
|
259
|
+
const skComposite = entity._buildQueryFacets(record, attributes.sk);
|
|
260
|
+
state.setSK(skComposite);
|
|
261
|
+
state.addOption('_includeOnResponseItem', {...skComposite, ...pkComposite});
|
|
250
262
|
})
|
|
251
263
|
.whenOptions(({ state, options }) => {
|
|
252
264
|
if (!state.getParams()) {
|
|
@@ -337,13 +349,17 @@ let clauses = {
|
|
|
337
349
|
if (sk) {
|
|
338
350
|
filter.unsafeSet(FilterOperationNames.exists, sk);
|
|
339
351
|
}
|
|
352
|
+
const pkComposite = entity._expectFacets(facets, attributes.pk);
|
|
353
|
+
state.addOption('_includeOnResponseItem', pkComposite);
|
|
340
354
|
return state
|
|
341
355
|
.setMethod(MethodTypes.update)
|
|
342
356
|
.setType(QueryTypes.eq)
|
|
343
|
-
.setPK(
|
|
357
|
+
.setPK(pkComposite)
|
|
344
358
|
.ifSK(() => {
|
|
345
359
|
entity._expectFacets(facets, attributes.sk);
|
|
346
|
-
state.
|
|
360
|
+
const skComposite = state.buildQueryComposites(facets, attributes.sk);
|
|
361
|
+
state.setSK(skComposite);
|
|
362
|
+
state.addOption('_includeOnResponseItem', {...skComposite, ...pkComposite});
|
|
347
363
|
});
|
|
348
364
|
} catch(err) {
|
|
349
365
|
state.setError(err);
|
|
@@ -360,13 +376,17 @@ let clauses = {
|
|
|
360
376
|
}
|
|
361
377
|
try {
|
|
362
378
|
const attributes = state.getCompositeAttributes();
|
|
379
|
+
const pkComposite = entity._expectFacets(facets, attributes.pk);
|
|
380
|
+
state.addOption('_includeOnResponseItem', pkComposite);
|
|
363
381
|
return state
|
|
364
382
|
.setMethod(MethodTypes.update)
|
|
365
383
|
.setType(QueryTypes.eq)
|
|
366
|
-
.setPK(
|
|
384
|
+
.setPK(pkComposite)
|
|
367
385
|
.ifSK(() => {
|
|
368
386
|
entity._expectFacets(facets, attributes.sk);
|
|
369
|
-
state.
|
|
387
|
+
const skComposite = state.buildQueryComposites(facets, attributes.sk);
|
|
388
|
+
state.setSK(skComposite);
|
|
389
|
+
state.addOption('_includeOnResponseItem', {...pkComposite, ...skComposite});
|
|
370
390
|
});
|
|
371
391
|
} catch(err) {
|
|
372
392
|
state.setError(err);
|
|
@@ -808,7 +828,8 @@ class ChainState {
|
|
|
808
828
|
data: {},
|
|
809
829
|
},
|
|
810
830
|
upsert: {
|
|
811
|
-
data: {}
|
|
831
|
+
data: {},
|
|
832
|
+
ifNotExists: {},
|
|
812
833
|
},
|
|
813
834
|
keys: {
|
|
814
835
|
provided: [],
|
|
@@ -1018,8 +1039,12 @@ class ChainState {
|
|
|
1018
1039
|
}
|
|
1019
1040
|
}
|
|
1020
1041
|
|
|
1021
|
-
applyUpsert(data = {}) {
|
|
1022
|
-
|
|
1042
|
+
applyUpsert(data = {}, { ifNotExists } = {}) {
|
|
1043
|
+
if (ifNotExists) {
|
|
1044
|
+
this.query.upsert.ifNotExists = {...this.query.upsert.ifNotExists, ...data};
|
|
1045
|
+
} else {
|
|
1046
|
+
this.query.upsert.data = {...this.query.upsert.data, ...data};
|
|
1047
|
+
}
|
|
1023
1048
|
return this;
|
|
1024
1049
|
}
|
|
1025
1050
|
|
package/src/entity.js
CHANGED
|
@@ -673,7 +673,7 @@ class Entity {
|
|
|
673
673
|
case MethodTypes.delete:
|
|
674
674
|
case MethodTypes.remove:
|
|
675
675
|
case MethodTypes.upsert:
|
|
676
|
-
return this.formatResponse(response, index, {...config, _objectOnEmpty: true});
|
|
676
|
+
return this.formatResponse(response, index, { ...config, _objectOnEmpty: true });
|
|
677
677
|
default:
|
|
678
678
|
return this.formatResponse(response, index, config);
|
|
679
679
|
}
|
|
@@ -814,7 +814,11 @@ class Entity {
|
|
|
814
814
|
results = null;
|
|
815
815
|
}
|
|
816
816
|
} else if (config._objectOnEmpty) {
|
|
817
|
-
return {
|
|
817
|
+
return {
|
|
818
|
+
data: {
|
|
819
|
+
...config._includeOnResponseItem,
|
|
820
|
+
}
|
|
821
|
+
};
|
|
818
822
|
} else {
|
|
819
823
|
results = null;
|
|
820
824
|
}
|
|
@@ -1342,6 +1346,7 @@ class Entity {
|
|
|
1342
1346
|
order: undefined,
|
|
1343
1347
|
hydrate: false,
|
|
1344
1348
|
hydrator: (_entity, _indexName, items) => items,
|
|
1349
|
+
_includeOnResponseItem: {},
|
|
1345
1350
|
};
|
|
1346
1351
|
|
|
1347
1352
|
return provided.filter(Boolean).reduce((config, option) => {
|
|
@@ -1503,6 +1508,13 @@ class Entity {
|
|
|
1503
1508
|
config.hydrator = option.hydrator;
|
|
1504
1509
|
}
|
|
1505
1510
|
|
|
1511
|
+
if (option._includeOnResponseItem) {
|
|
1512
|
+
config._includeOnResponseItem = {
|
|
1513
|
+
...config._includeOnResponseItem,
|
|
1514
|
+
...option._includeOnResponseItem,
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1506
1518
|
config.page = Object.assign({}, config.page, option.page);
|
|
1507
1519
|
config.params = Object.assign({}, config.params, option.params);
|
|
1508
1520
|
return config;
|
|
@@ -1951,12 +1963,18 @@ class Entity {
|
|
|
1951
1963
|
const { updatedKeys, setAttributes, indexKey } = this._getPutKeys(pk, sk && sk.facets, upsert.data);
|
|
1952
1964
|
const upsertAttributes = this.model.schema.translateToFields(setAttributes);
|
|
1953
1965
|
const keyNames = Object.keys(indexKey);
|
|
1954
|
-
// update.set(this.identifiers.entity, this.getName());
|
|
1955
|
-
// update.set(this.identifiers.version, this.getVersion());
|
|
1956
1966
|
for (const field of [...Object.keys(upsertAttributes), ...Object.keys(updatedKeys)]) {
|
|
1957
1967
|
const value = u.getFirstDefined(upsertAttributes[field], updatedKeys[field]);
|
|
1958
1968
|
if (!keyNames.includes(field)) {
|
|
1959
|
-
|
|
1969
|
+
let operation = ItemOperations.set;
|
|
1970
|
+
const name = this.model.schema.translationForRetrieval[field];
|
|
1971
|
+
if (name) {
|
|
1972
|
+
const attribute = this.model.schema.attributes[name];
|
|
1973
|
+
if (this.model.schema.readOnlyAttributes.has(name) && (!attribute || !attribute.indexes || attribute.indexes.length === 0)) {
|
|
1974
|
+
operation = ItemOperations.ifNotExists;
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
update.set(field, value, operation);
|
|
1960
1978
|
}
|
|
1961
1979
|
}
|
|
1962
1980
|
|
package/src/schema.js
CHANGED
|
@@ -1429,15 +1429,14 @@ class Schema {
|
|
|
1429
1429
|
: attribute.getValidate(value);
|
|
1430
1430
|
}
|
|
1431
1431
|
|
|
1432
|
-
checkUpdate(payload = {}) {
|
|
1432
|
+
checkUpdate(payload = {}, { allowReadOnly } = {}) {
|
|
1433
1433
|
let record = {};
|
|
1434
1434
|
for (let [path, attribute] of this.traverser.getAll()) {
|
|
1435
1435
|
let value = payload[path];
|
|
1436
1436
|
if (value === undefined) {
|
|
1437
1437
|
continue;
|
|
1438
1438
|
}
|
|
1439
|
-
if (attribute.readOnly) {
|
|
1440
|
-
// todo: #electroerror
|
|
1439
|
+
if (attribute.readOnly && !allowReadOnly) {
|
|
1441
1440
|
throw new e.ElectroAttributeValidationError(attribute.path, `Attribute "${attribute.path}" is Read-Only and cannot be updated`);
|
|
1442
1441
|
} else {
|
|
1443
1442
|
record[path] = attribute.getValidate(value);
|
package/src/types.js
CHANGED
package/src/update.js
CHANGED
|
@@ -9,7 +9,7 @@ class UpdateExpression extends ExpressionState {
|
|
|
9
9
|
remove: new Set(),
|
|
10
10
|
add: new Set(),
|
|
11
11
|
subtract: new Set(),
|
|
12
|
-
delete: new Set()
|
|
12
|
+
delete: new Set(),
|
|
13
13
|
};
|
|
14
14
|
this.seen = new Map();
|
|
15
15
|
this.type = BuilderTypes.update;
|
|
@@ -23,25 +23,33 @@ class UpdateExpression extends ExpressionState {
|
|
|
23
23
|
this.operations[type].delete(expression);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
set(name, value, operation) {
|
|
26
|
+
set(name, value, operation = ItemOperations.set) {
|
|
27
|
+
let operationToApply = operation;
|
|
28
|
+
if (operation === ItemOperations.ifNotExists) {
|
|
29
|
+
operationToApply = ItemOperations.set;
|
|
30
|
+
}
|
|
27
31
|
const seen = this.seen.get(name);
|
|
28
32
|
let n;
|
|
29
33
|
let v;
|
|
30
34
|
if (seen) {
|
|
31
35
|
n = seen.name;
|
|
32
36
|
v = seen.value;
|
|
33
|
-
this.unadd(
|
|
37
|
+
this.unadd(operationToApply, seen.expression);
|
|
38
|
+
|
|
34
39
|
} else {
|
|
35
40
|
n = this.setName({}, name, name);
|
|
36
41
|
v = this.setValue(name, value);
|
|
37
42
|
}
|
|
38
|
-
|
|
43
|
+
let expression = `${n.prop} = ${v}`;
|
|
44
|
+
if (operation === ItemOperations.ifNotExists) {
|
|
45
|
+
expression = `${n.prop} = if_not_exists(${n.prop}, ${v})`;
|
|
46
|
+
}
|
|
39
47
|
this.seen.set(name, {
|
|
40
48
|
name: n,
|
|
41
49
|
value: v,
|
|
42
50
|
expression,
|
|
43
51
|
});
|
|
44
|
-
this.add(
|
|
52
|
+
this.add(operationToApply, expression);
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
remove(name) {
|
package/.travis.yml
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
language: node_js
|
|
2
|
-
|
|
3
|
-
services:
|
|
4
|
-
- docker
|
|
5
|
-
|
|
6
|
-
before_install:
|
|
7
|
-
- docker pull amazon/dynamodb-local
|
|
8
|
-
- docker run -p 8000:8000 --name dynamodb -d amazon/dynamodb-local
|
|
9
|
-
- docker ps -a
|
|
10
|
-
|
|
11
|
-
node_js:
|
|
12
|
-
- '16'
|
|
13
|
-
|
|
14
|
-
script:
|
|
15
|
-
- npm run coverage:local:coveralls
|