electrodb 2.6.0 → 2.7.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/docker/dynamodb/shared-local-instance.db +0 -0
- package/index.d.ts +65 -22
- package/package.json +1 -1
- package/src/clauses.js +38 -13
- package/src/entity.js +36 -28
- package/src/schema.js +2 -3
- package/src/types.js +1 -0
- package/src/update.js +13 -5
|
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
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
|
@@ -576,8 +576,7 @@ class Entity {
|
|
|
576
576
|
let results = config._isCollectionQuery
|
|
577
577
|
? {}
|
|
578
578
|
: [];
|
|
579
|
-
|
|
580
|
-
let ExclusiveStartKey = this._formatExclusiveStartKey(config);
|
|
579
|
+
let ExclusiveStartKey = this._formatExclusiveStartKey({config, indexName: parameters.IndexName });
|
|
581
580
|
if (ExclusiveStartKey === null) {
|
|
582
581
|
ExclusiveStartKey = undefined;
|
|
583
582
|
}
|
|
@@ -674,7 +673,7 @@ class Entity {
|
|
|
674
673
|
case MethodTypes.delete:
|
|
675
674
|
case MethodTypes.remove:
|
|
676
675
|
case MethodTypes.upsert:
|
|
677
|
-
return this.formatResponse(response, index, {...config, _objectOnEmpty: true});
|
|
676
|
+
return this.formatResponse(response, index, { ...config, _objectOnEmpty: true });
|
|
678
677
|
default:
|
|
679
678
|
return this.formatResponse(response, index, config);
|
|
680
679
|
}
|
|
@@ -815,7 +814,11 @@ class Entity {
|
|
|
815
814
|
results = null;
|
|
816
815
|
}
|
|
817
816
|
} else if (config._objectOnEmpty) {
|
|
818
|
-
return {
|
|
817
|
+
return {
|
|
818
|
+
data: {
|
|
819
|
+
...config._includeOnResponseItem,
|
|
820
|
+
}
|
|
821
|
+
};
|
|
819
822
|
} else {
|
|
820
823
|
results = null;
|
|
821
824
|
}
|
|
@@ -1067,30 +1070,22 @@ class Entity {
|
|
|
1067
1070
|
return config.formatCursor.serialize(page) || null;
|
|
1068
1071
|
}
|
|
1069
1072
|
|
|
1070
|
-
|
|
1071
|
-
// let exclusiveStartKey = config.cursor;
|
|
1072
|
-
// if (config.raw || config.pager === Pager.raw) {
|
|
1073
|
-
// return this._trimKeysToIndex({ provided: exclusiveStartKey, indexName }) || null;
|
|
1074
|
-
// }
|
|
1075
|
-
// let keys;
|
|
1076
|
-
// if (config.pager === Pager.item) {
|
|
1077
|
-
// keys = this._fromCompositeToKeysByIndex({indexName, provided: exclusiveStartKey});
|
|
1078
|
-
// } else {
|
|
1079
|
-
// keys = config.formatCursor.deserialize(exclusiveStartKey);
|
|
1080
|
-
// }
|
|
1081
|
-
// if (!keys) {
|
|
1082
|
-
// return null;
|
|
1083
|
-
// }
|
|
1084
|
-
//
|
|
1085
|
-
// return this._trimKeysToIndex({provided: keys, indexName}) || null;
|
|
1086
|
-
// }
|
|
1087
|
-
|
|
1088
|
-
_formatExclusiveStartKey(config) {
|
|
1073
|
+
_formatExclusiveStartKey({config, indexName = TableIndex}) {
|
|
1089
1074
|
let exclusiveStartKey = config.cursor;
|
|
1090
1075
|
if (config.raw || config.pager === Pager.raw) {
|
|
1091
|
-
return exclusiveStartKey || null;
|
|
1076
|
+
return this._trimKeysToIndex({ provided: exclusiveStartKey, indexName }) || null;
|
|
1077
|
+
}
|
|
1078
|
+
let keys;
|
|
1079
|
+
if (config.pager === Pager.item) {
|
|
1080
|
+
keys = this._fromCompositeToKeysByIndex({indexName, provided: exclusiveStartKey});
|
|
1081
|
+
} else {
|
|
1082
|
+
keys = config.formatCursor.deserialize(exclusiveStartKey);
|
|
1092
1083
|
}
|
|
1093
|
-
|
|
1084
|
+
if (!keys) {
|
|
1085
|
+
return null;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
return this._trimKeysToIndex({provided: keys, indexName}) || null;
|
|
1094
1089
|
}
|
|
1095
1090
|
|
|
1096
1091
|
setClient(client) {
|
|
@@ -1351,6 +1346,7 @@ class Entity {
|
|
|
1351
1346
|
order: undefined,
|
|
1352
1347
|
hydrate: false,
|
|
1353
1348
|
hydrator: (_entity, _indexName, items) => items,
|
|
1349
|
+
_includeOnResponseItem: {},
|
|
1354
1350
|
};
|
|
1355
1351
|
|
|
1356
1352
|
return provided.filter(Boolean).reduce((config, option) => {
|
|
@@ -1512,6 +1508,13 @@ class Entity {
|
|
|
1512
1508
|
config.hydrator = option.hydrator;
|
|
1513
1509
|
}
|
|
1514
1510
|
|
|
1511
|
+
if (option._includeOnResponseItem) {
|
|
1512
|
+
config._includeOnResponseItem = {
|
|
1513
|
+
...config._includeOnResponseItem,
|
|
1514
|
+
...option._includeOnResponseItem,
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1515
1518
|
config.page = Object.assign({}, config.page, option.page);
|
|
1516
1519
|
config.params = Object.assign({}, config.params, option.params);
|
|
1517
1520
|
return config;
|
|
@@ -1960,12 +1963,17 @@ class Entity {
|
|
|
1960
1963
|
const { updatedKeys, setAttributes, indexKey } = this._getPutKeys(pk, sk && sk.facets, upsert.data);
|
|
1961
1964
|
const upsertAttributes = this.model.schema.translateToFields(setAttributes);
|
|
1962
1965
|
const keyNames = Object.keys(indexKey);
|
|
1963
|
-
// update.set(this.identifiers.entity, this.getName());
|
|
1964
|
-
// update.set(this.identifiers.version, this.getVersion());
|
|
1965
1966
|
for (const field of [...Object.keys(upsertAttributes), ...Object.keys(updatedKeys)]) {
|
|
1966
1967
|
const value = u.getFirstDefined(upsertAttributes[field], updatedKeys[field]);
|
|
1967
1968
|
if (!keyNames.includes(field)) {
|
|
1968
|
-
|
|
1969
|
+
let operation = ItemOperations.set;
|
|
1970
|
+
const name = this.model.schema.translationForRetrieval[field];
|
|
1971
|
+
if (name) {
|
|
1972
|
+
if (this.model.schema.readOnlyAttributes.has(name)) {
|
|
1973
|
+
operation = ItemOperations.ifNotExists;
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
update.set(field, value, operation);
|
|
1969
1977
|
}
|
|
1970
1978
|
}
|
|
1971
1979
|
|
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) {
|