electrodb 2.9.2 → 2.10.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/index.d.ts CHANGED
@@ -158,8 +158,9 @@ export interface CollectionWhereOperations {
158
158
  notExists: <T, A extends WhereAttributeSymbol<T>>(attr: A) => string;
159
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
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
- value: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
161
+ field: (name: string) => string;
162
162
  name: <T, A extends WhereAttributeSymbol<T>>(attr: A) => string;
163
+ value: <T, A extends WhereAttributeSymbol<T>>(attr: A, value: T) => string;
163
164
  size: <T, A extends WhereAttributeSymbol<T>>(attr: A) => string;
164
165
  type: <T, A extends WhereAttributeSymbol<T>>(attr: A, type: DynamoDBAttributeType) => string;
165
166
  escape: <T extends string | number | boolean>(value: T) => T extends string ? string
@@ -834,12 +835,56 @@ export interface PutRecordOperationOptions<A extends string, F extends string, C
834
835
  where: WhereClause<A, F, C, S, Item<A, F, C, S, S["attributes"]>, PutRecordOperationOptions<A, F, C, S, ResponseType>>;
835
836
  }
836
837
 
837
- export interface UpsertRecordOperationOptions<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, ResponseType> {
838
- go: UpsertRecordGo<ResponseType, AllTableIndexCompositeAttributes<A,F,C,S>>;
839
- params: ParamRecord<UpdateQueryParams>;
840
- where: WhereClause<A, F, C, S, Item<A, F, C, S, S["attributes"]>, UpsertRecordOperationOptions<A, F, C, S, ResponseType>>;
838
+ type RequiredKeys<T> = Exclude<{ [K in keyof T]-?: {} extends Pick<T, K> ? never : K }[keyof T], symbol>;
839
+
840
+ type OverlappingProperties<T1, T2> = {
841
+ [Key in keyof T1 as Key extends keyof T2 ? Key : never]: Key extends keyof T2 ? T2[Key] : never;
842
+ }
843
+
844
+ type NonOverlappingProperties<T1, T2> = {
845
+ [Key in keyof T1 as Key extends keyof T2 ? never : Key]: T1[Key];
841
846
  }
842
847
 
848
+ // RequiredPutItems
849
+ export type UpsertRecordOperationOptions<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, ResponseType, FullExpectedItem, RemainingExpectedItem, ProvidedItem> =
850
+ // keyof Omit<ProvidedItem, RequiredKeys<RemainingExpectedItem>> extends RequiredKeys<RemainingExpectedItem>
851
+ [RequiredKeys<RemainingExpectedItem>] extends [never]
852
+ ? {
853
+ go: UpsertRecordGo<ResponseType, AllTableIndexCompositeAttributes<A,F,C,S>>;
854
+ params: ParamRecord<UpdateQueryParams>;
855
+
856
+ where: WhereClause<A, F, C, S, Item<A, F, C, S, S["attributes"]>, UpsertRecordOperationOptions<A,F,C,S, ResponseType, FullExpectedItem, RemainingExpectedItem, ProvidedItem>>;
857
+
858
+ set: <ReceivedItem extends Partial<OverlappingProperties<RemainingExpectedItem, PutItem<A,F,C,S>>>>(item: ReceivedItem) =>
859
+ UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem, NonOverlappingProperties<RemainingExpectedItem, ReceivedItem>, NonOverlappingProperties<ProvidedItem, ReceivedItem>>
860
+ ifNotExists: <ReceivedItem extends Partial<OverlappingProperties<RemainingExpectedItem, PutItem<A,F,C,S>>>>(item: ReceivedItem) =>
861
+ UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem, NonOverlappingProperties<RemainingExpectedItem, ReceivedItem>, NonOverlappingProperties<ProvidedItem, ReceivedItem>>
862
+ add: <ReceivedItem extends Partial<OverlappingProperties<RemainingExpectedItem, AddItem<A,F,C,S>>>>(item: ReceivedItem) =>
863
+ UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem, NonOverlappingProperties<RemainingExpectedItem, ReceivedItem>, NonOverlappingProperties<ProvidedItem, ReceivedItem>>
864
+ subtract: <ReceivedItem extends Partial<OverlappingProperties<RemainingExpectedItem, SubtractItem<A,F,C,S>>>>(item: ReceivedItem) =>
865
+ UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem, NonOverlappingProperties<RemainingExpectedItem, ReceivedItem>, NonOverlappingProperties<ProvidedItem, ReceivedItem>>
866
+ append: <ReceivedItem extends Partial<OverlappingProperties<RemainingExpectedItem, AppendItem<A,F,C,S>>>>(item: ReceivedItem) =>
867
+ UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem, NonOverlappingProperties<RemainingExpectedItem, ReceivedItem>, NonOverlappingProperties<ProvidedItem, ReceivedItem>>
868
+ }
869
+ : {
870
+ // these are strings to give context to the user this is a builder pattern
871
+ go: `Missing required attributes to perform upsert` | `Required: ${RequiredKeys<RemainingExpectedItem>}`;
872
+ params: `Missing required attributes to perform upsert` | `Required: ${RequiredKeys<RemainingExpectedItem>}`;
873
+
874
+ where: WhereClause<A, F, C, S, Item<A, F, C, S, S["attributes"]>, UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem,RemainingExpectedItem,ProvidedItem>>;
875
+
876
+ set: <ReceivedItem extends Partial<OverlappingProperties<RemainingExpectedItem, PutItem<A,F,C,S>>>>(item: ReceivedItem) =>
877
+ UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem, NonOverlappingProperties<RemainingExpectedItem, ReceivedItem>, NonOverlappingProperties<ProvidedItem, ReceivedItem>>
878
+ ifNotExists: <ReceivedItem extends Partial<OverlappingProperties<RemainingExpectedItem, PutItem<A,F,C,S>>>>(item: ReceivedItem) =>
879
+ UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem, NonOverlappingProperties<RemainingExpectedItem, ReceivedItem>, NonOverlappingProperties<ProvidedItem, ReceivedItem>>
880
+ add: <ReceivedItem extends Partial<OverlappingProperties<RemainingExpectedItem, AddItem<A,F,C,S>>>>(item: ReceivedItem) =>
881
+ UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem, NonOverlappingProperties<RemainingExpectedItem, ReceivedItem>, NonOverlappingProperties<ProvidedItem, ReceivedItem>>
882
+ subtract: <ReceivedItem extends Partial<OverlappingProperties<RemainingExpectedItem, SubtractItem<A,F,C,S>>>>(item: ReceivedItem) =>
883
+ UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem, NonOverlappingProperties<RemainingExpectedItem, ReceivedItem>, NonOverlappingProperties<ProvidedItem, ReceivedItem>>
884
+ append: <ReceivedItem extends Partial<OverlappingProperties<RemainingExpectedItem, AppendItem<A,F,C,S>>>>(item: ReceivedItem) =>
885
+ UpsertRecordOperationOptions<A,F,C,S,ResponseType,FullExpectedItem, NonOverlappingProperties<RemainingExpectedItem, ReceivedItem>, NonOverlappingProperties<ProvidedItem, ReceivedItem>>
886
+ }
887
+
843
888
  export interface DeleteRecordOperationOptions<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, ResponseType> {
844
889
  go: DeleteRecordOperationGo<ResponseType, AllTableIndexCompositeAttributes<A,F,C,S>>;
845
890
  params: ParamRecord<DeleteQueryOptions>;
@@ -2343,7 +2388,10 @@ export type RequiredPutItems<A extends string, F extends string, C extends strin
2343
2388
 
2344
2389
  export type PutItem<A extends string, F extends string, C extends string, S extends Schema<A,F,C>> =
2345
2390
  Pick<CreatedItem<A,F,C,S,S["attributes"]>, ExtractKeysOfValueType<RequiredPutItems<A,F,C,S>,true>>
2346
- & Partial<CreatedItem<A,F,C,S,S["attributes"]>>
2391
+ & Partial<CreatedItem<A,F,C,S,S["attributes"]>>;
2392
+
2393
+ export type UpsertItem<A extends string, F extends string, C extends string, S extends Schema<A,F,C>> =
2394
+ Partial<PutItem<A,F,C,S>>;
2347
2395
 
2348
2396
  export type UpdateData<A extends string, F extends string, C extends string, S extends Schema<A,F,C>> =
2349
2397
  Omit<{
@@ -2480,6 +2528,7 @@ export interface WhereOperations<A extends string, F extends string, C extends s
2480
2528
  name: <A extends WhereAttributeSymbol<any>>(attr: A) => string;
2481
2529
  size: <T, A extends WhereAttributeSymbol<T>>(attr: A) => number;
2482
2530
  type: <T, A extends WhereAttributeSymbol<T>>(attr: A, type: DynamoDBAttributeType) => string;
2531
+ field: (name: string) => string;
2483
2532
  escape: <T extends string | number | boolean>(value: T) =>
2484
2533
  T extends string ? string
2485
2534
  : T extends number ? number
@@ -2491,8 +2540,8 @@ export interface DataUpdateOperations<A extends string, F extends string, C exte
2491
2540
  set: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: DataUpdateAttributeValues<A>) => any;
2492
2541
  remove: <T, A extends DataUpdateAttributeSymbol<T>>(attr: [T] extends [never] ? never : A) => any;
2493
2542
  append: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: DataUpdateAttributeValues<A> extends Array<any> ? DataUpdateAttributeValues<A> : never) => any;
2494
- add: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: A extends DataUpdateAttributeSymbol<infer V> ? V extends number | Array<any> ? V : [V] extends [any] ? V : never : never ) => any;
2495
- subtract: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: A extends DataUpdateAttributeSymbol<infer V> ? V extends number ? V : [V] extends [any] ? V : never : never ) => any;
2543
+ add: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: A extends DataUpdateAttributeSymbol<infer V> ? V extends number | Array<any> ? V : [V] extends [any] ? V : never : never, defaultValue?: A extends DataUpdateAttributeSymbol<infer V> ? V extends number ? V : never : never) => any;
2544
+ subtract: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: A extends DataUpdateAttributeSymbol<infer V> ? V extends number ? V : [V] extends [any] ? V : never : never, defaultValue?: A extends DataUpdateAttributeSymbol<infer V> ? V extends number ? V : never : never) => any;
2496
2545
  delete: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: A extends DataUpdateAttributeSymbol<infer V> ? V extends Array<any> ? V : [V] extends [any] ? V : never : never ) => any;
2497
2546
  del: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: A extends DataUpdateAttributeSymbol<infer V> ? V extends Array<any> ? V : never : never ) => any;
2498
2547
  value: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: DataUpdateAttributeValues<A>) => Required<DataUpdateAttributeValues<A>>;
@@ -2500,16 +2549,29 @@ export interface DataUpdateOperations<A extends string, F extends string, C exte
2500
2549
  ifNotExists: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: DataUpdateAttributeValues<A>) => any;
2501
2550
  }
2502
2551
 
2552
+ export interface UpsertDataUpdateOperations<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, I extends UpdateData<A,F,C,S>> {
2553
+ set: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: DataUpdateAttributeValues<A>) => any;
2554
+ append: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: DataUpdateAttributeValues<A> extends Array<any> ? DataUpdateAttributeValues<A> : never) => any;
2555
+ add: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: A extends DataUpdateAttributeSymbol<infer V> ? V extends number | Array<any> ? V : [V] extends [any] ? V : never : never, defaultValue?: A extends DataUpdateAttributeSymbol<infer V> ? V extends number ? V : never : never) => any;
2556
+ subtract: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: A extends DataUpdateAttributeSymbol<infer V> ? V extends number ? V : [V] extends [any] ? V : never : never, defaultValue?: A extends DataUpdateAttributeSymbol<infer V> ? V extends number ? V : never : never) => any;
2557
+ ifNotExists: <T, A extends DataUpdateAttributeSymbol<T>>(attr: A, value: DataUpdateAttributeValues<A>) => any;
2558
+ }
2559
+
2503
2560
  export type WhereCallback<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, I extends Item<A,F,C,S,S["attributes"]>> =
2504
2561
  <W extends WhereAttributes<A,F,C,S,I>>(attributes: W, operations: WhereOperations<A,F,C,S,I>) => string;
2505
2562
 
2506
2563
  export type DataUpdateCallback<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, I extends UpdateData<A,F,C,S>> =
2507
2564
  <W extends DataUpdateAttributes<A,F,C,S,I>>(attributes: W, operations: DataUpdateOperations<A,F,C,S,I>) => any;
2508
2565
 
2566
+ export type UpsertDataUpdateCallback<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, I extends UpdateData<A,F,C,S>> =
2567
+ <W extends DataUpdateAttributes<A,F,C,S,I>>(attributes: W, operations: UpsertDataUpdateOperations<A,F,C,S,I>) => any;
2568
+
2509
2569
  export type WhereClause<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, I extends Item<A,F,C,S,S["attributes"]>, T> = (where: WhereCallback<A,F,C,S,I>) => T;
2510
2570
 
2511
2571
  export type DataUpdateMethod<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, I extends UpdateData<A,F,C,S>, T> = (update: DataUpdateCallback<A,F,C,S,I>) => T;
2512
2572
 
2573
+ export type UpsertDataUpdateMethod<A extends string, F extends string, C extends string, S extends Schema<A,F,C>, I extends UpdateData<A,F,C,S>, T> = (update: UpsertDataUpdateCallback<A,F,C,S,I>) => T;
2574
+
2513
2575
  type Resolve<T> = T extends Function | string | number | boolean
2514
2576
  ? T : {[Key in keyof T]: Resolve<T[Key]>}
2515
2577
 
@@ -2524,6 +2586,7 @@ export type EntityConfiguration = {
2524
2586
  },
2525
2587
  };
2526
2588
 
2589
+
2527
2590
  export class Entity<A extends string, F extends string, C extends string, S extends Schema<A,F,C>> {
2528
2591
  readonly schema: S;
2529
2592
  private config?: EntityConfiguration;
@@ -2536,13 +2599,21 @@ export class Entity<A extends string, F extends string, C extends string, S exte
2536
2599
  delete(key: AllTableIndexCompositeAttributes<A,F,C,S>[]): BatchWriteOperationOptions<A,F,C,S, AllTableIndexCompositeAttributes<A,F,C,S>[]>;
2537
2600
  remove(key: AllTableIndexCompositeAttributes<A,F,C,S>): DeleteRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>
2538
2601
 
2539
- upsert(record: PutItem<A,F,C,S>): UpsertRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>;
2540
2602
  put(record: PutItem<A,F,C,S>): PutRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>;
2541
2603
  put(record: PutItem<A,F,C,S>[]): BatchWriteOperationOptions<A,F,C,S, AllTableIndexCompositeAttributes<A,F,C,S>[]>;
2542
2604
  create(record: PutItem<A,F,C,S>): PutRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>
2543
2605
 
2606
+ upsert<InitialItem extends UpsertItem<A,F,C,S>>(record: InitialItem): UpsertRecordOperationOptions<
2607
+ A,F,C,S,
2608
+ ResponseItem<A,F,C,S>,
2609
+ PutItem<A,F,C,S>,
2610
+ [keyof InitialItem] extends [never] ? PutItem<A,F,C,S> : Omit<PutItem<A,F,C,S>, keyof InitialItem>,
2611
+ InitialItem
2612
+ >;
2613
+
2544
2614
  update(key: AllTableIndexCompositeAttributes<A,F,C,S>): {
2545
2615
  set: SetRecord<A,F,C,S, SetItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, Partial<ResponseItem<A,F,C,S>>>;
2616
+ ifNotExists: SetRecord<A,F,C,S, SetItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, Partial<ResponseItem<A,F,C,S>>>;
2546
2617
  remove: RemoveRecord<A,F,C,S, RemoveItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, Partial<ResponseItem<A,F,C,S>>>;
2547
2618
  add: SetRecord<A,F,C,S, AddItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, Partial<ResponseItem<A,F,C,S>>>;
2548
2619
  subtract: SetRecord<A,F,C,S, SubtractItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, Partial<ResponseItem<A,F,C,S>>>;
@@ -2554,6 +2625,7 @@ export class Entity<A extends string, F extends string, C extends string, S exte
2554
2625
  patch(key: AllTableIndexCompositeAttributes<A,F,C,S>): {
2555
2626
  set: SetRecord<A,F,C,S, SetItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
2556
2627
  remove: RemoveRecord<A,F,C,S, RemoveItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
2628
+ ifNotExists: SetRecord<A,F,C,S, SetItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, Partial<ResponseItem<A,F,C,S>>>;
2557
2629
  add: SetRecord<A,F,C,S, AddItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
2558
2630
  subtract: SetRecord<A,F,C,S, SubtractItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
2559
2631
  append: SetRecord<A,F,C,S, AppendItem<A,F,C,S>, TableIndexCompositeAttributes<A,F,C,S>, ResponseItem<A,F,C,S>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electrodb",
3
- "version": "2.9.2",
3
+ "version": "2.10.0",
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": {
@@ -18,9 +18,17 @@
18
18
  "ddb:start": "docker compose up -d",
19
19
  "ddb:load": "docker compose exec electro npm run test:init",
20
20
  "ddb:stop": "docker compose stop",
21
- "examples:load:library": "npm run ddb:start && ts-node ./examples/library/load.ts",
22
- "examples:load:taskmanager": "npm run ddb:start && ts-node ./examples/taskmanager/load.ts",
23
- "examples:load:versioncontrol": "npm run ddb:start && ts-node ./examples/versioncontrol/load.ts"
21
+ "examples:load:library": "npm run ddb:init && ts-node ./examples/library/load.ts",
22
+ "examples:query:library": "npm run ddb:init && ts-node ./examples/library/query.ts",
23
+ "examples:load:taskmanager": "npm run ddb:init && ts-node ./examples/taskmanager/load.ts",
24
+ "examples:query:taskmanager": "npm run ddb:init && ts-node ./examples/taskmanager/query.ts",
25
+ "examples:load:versioncontrol": "npm run ddb:init && ts-node ./examples/versioncontrol/load.ts",
26
+ "examples:query:versioncontrol": "npm run ddb:init && ts-node ./examples/versioncontrol/query.ts",
27
+ "local:init": "LOCAL_DYNAMO_ENDPOINT='http://localhost:8000' npm run test:init",
28
+ "local:start": "npm run ddb:start && npm run local:init",
29
+ "local:stop": "npm run ddb:stop",
30
+ "local:exec": "LOCAL_DYNAMO_ENDPOINT='http://localhost:8000' ts-node ./test/debug.ts",
31
+ "local:debug": "npm run local:start && npm run local:exec"
24
32
  },
25
33
  "repository": {
26
34
  "type": "git",
@@ -53,7 +61,7 @@
53
61
  "source-map-support": "^0.5.19",
54
62
  "ts-node": "^10.9.1",
55
63
  "tsd": "^0.28.1",
56
- "typescript": "^5.1.6",
64
+ "typescript": "^5.2.2",
57
65
  "uuid": "7.0.1"
58
66
  },
59
67
  "keywords": [