@model-ts/dynamodb 3.0.3 → 3.1.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/src/provider.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Client, Key, PaginationParams } from "./client"
1
+ import { Client, Key, PaginationParams, QueryParams } from "./client"
2
2
  import {
3
3
  DynamoDBModelInstance,
4
4
  DynamoDBModelConstructor,
@@ -375,8 +375,20 @@ export const getProvider = (client: Client) => {
375
375
 
376
376
  return {
377
377
  classProps: {
378
+ /**
379
+ * The DynamoDB document client.
380
+ */
378
381
  dynamodb: client,
382
+
383
+ /**
384
+ * Creates operation objects for batch processing and transactions.
385
+ * Supports get, put, update, updateRaw, delete, softDelete, and condition operations.
386
+ */
379
387
  operation,
388
+
389
+ /**
390
+ * @internal
391
+ */
380
392
  __dynamoDBDecode<M extends DynamoDBModelConstructor<any>>(
381
393
  this: M,
382
394
  value: unknown
@@ -391,6 +403,10 @@ export const getProvider = (client: Client) => {
391
403
  return decoded
392
404
  }
393
405
  },
406
+
407
+ /**
408
+ * @internal
409
+ */
394
410
  __dynamoDBEncode<
395
411
  T extends DynamoDBModelInstance,
396
412
  M extends DynamoDBModelConstructor<T>
@@ -403,6 +419,12 @@ export const getProvider = (client: Client) => {
403
419
  })
404
420
  },
405
421
 
422
+ /**
423
+ * Retrieves a single item from DynamoDB by its primary key.
424
+ * Prefer `load()` for built-in batching.
425
+ *
426
+ * @throws ItemNotFoundError if the item doesn't exist.
427
+ */
406
428
  get<M extends DynamoDBModelConstructor<any>>(
407
429
  this: M,
408
430
  key: Key,
@@ -416,6 +438,12 @@ export const getProvider = (client: Client) => {
416
438
  })
417
439
  },
418
440
 
441
+ /**
442
+ * Retrieves a single item from DynamoDB by its primary key.
443
+ * Uses built-in batching for usage in e.g. `Promise.all()`.
444
+ *
445
+ * @throws ItemNotFoundError if the item doesn't exist and `null` is not true.
446
+ */
419
447
  load<
420
448
  M extends DynamoDBModelConstructor<any>,
421
449
  Null extends boolean = false,
@@ -439,6 +467,10 @@ export const getProvider = (client: Client) => {
439
467
  )
440
468
  },
441
469
 
470
+ /**
471
+ * Loads multiple items from DynamoDB by their primary keys.
472
+ * Returns an array of items or errors.
473
+ */
442
474
  loadMany<M extends DynamoDBModelConstructor<any>>(
443
475
  this: M,
444
476
  keys: Key[],
@@ -454,6 +486,9 @@ export const getProvider = (client: Client) => {
454
486
  )
455
487
  },
456
488
 
489
+ /**
490
+ * Returns a page of query results using cursor-based pagination.
491
+ */
457
492
  paginate<M extends DynamoDBModelConstructor<any>>(
458
493
  this: M,
459
494
  args: PaginationInput,
@@ -462,6 +497,23 @@ export const getProvider = (client: Client) => {
462
497
  return client.paginate(this, args, params)
463
498
  },
464
499
 
500
+ /**
501
+ * Performs a DynamoDB query operation and returns matching items.
502
+ * Use `FetchAllPages: true` to automatically fetch all pages of results.
503
+ */
504
+ async query<M extends DynamoDBModelConstructor<any>>(
505
+ this: M,
506
+ params: QueryParams
507
+ ) {
508
+ const { items, meta } = await client.query(params, { items: this })
509
+ return Object.assign(items, { meta })
510
+ },
511
+
512
+ /**
513
+ * Stores an item in DynamoDB.
514
+ *
515
+ * @throws KeyExistsError if the item already exists and `IgnoreExistence` is not true.
516
+ */
465
517
  put<M extends DynamoDBModelConstructor<any>>(
466
518
  this: M,
467
519
  item: TypeOf<M>,
@@ -478,6 +530,10 @@ export const getProvider = (client: Client) => {
478
530
  })
479
531
  },
480
532
 
533
+ /**
534
+ * Performs a raw DynamoDB update operation using update expressions.
535
+ * Provides low-level access to DynamoDB's native update functionality.
536
+ */
481
537
  updateRaw<M extends DynamoDBModelConstructor<any>>(
482
538
  this: M,
483
539
  key: Key,
@@ -496,6 +552,10 @@ export const getProvider = (client: Client) => {
496
552
  })
497
553
  },
498
554
 
555
+ /**
556
+ * Deletes an item from DynamoDB by its primary key.
557
+ * The item will be permanently removed from the table.
558
+ */
499
559
  delete<M extends DynamoDBModelConstructor<any>>(this: M, key: Key) {
500
560
  return client.delete<M>({
501
561
  _model: this,
@@ -504,6 +564,10 @@ export const getProvider = (client: Client) => {
504
564
  })
505
565
  },
506
566
 
567
+ /**
568
+ * Performs a soft delete by moving the item to a deleted state.
569
+ * The original item is deleted and a new item with a $$DELETED$$ prefix is created.
570
+ */
507
571
  softDelete<M extends DynamoDBModelConstructor<any>>(
508
572
  this: M,
509
573
  item: TypeOf<M>
@@ -512,7 +576,15 @@ export const getProvider = (client: Client) => {
512
576
  },
513
577
  },
514
578
  instanceProps: {
579
+ /**
580
+ * The DynamoDB document client instance.
581
+ */
515
582
  dynamodb: client,
583
+
584
+ /**
585
+ * Returns all key attributes for this instance, including primary keys and GSI keys.
586
+ * Used for cursor generation and key-based operations.
587
+ */
516
588
  keys<T extends DynamoDBModelInstance>(
517
589
  this: T
518
590
  ): { PK: string; SK: string } & { [key in GSIPK]?: string } &
@@ -526,9 +598,19 @@ export const getProvider = (client: Client) => {
526
598
  })).reduce((acc, cur) => Object.assign(acc, cur), {}),
527
599
  }
528
600
  },
601
+
602
+ /**
603
+ * Generates an (optionally encrypted) cursor for this instance.
604
+ * Cursors are used for pagination and must be treated as opaque tokens.
605
+ */
529
606
  cursor<T extends DynamoDBModelInstance>(this: T) {
530
607
  return encodeDDBCursor(this.keys(), client.cursorEncryptionKey)
531
608
  },
609
+
610
+ /**
611
+ * Stores this instance in DynamoDB.
612
+ * @throws KeyExistsError if the item already exists and `IgnoreExistence` is not true.
613
+ */
532
614
  put<T extends DynamoDBModelInstance>(
533
615
  this: T,
534
616
  params?: Omit<
@@ -543,6 +625,12 @@ export const getProvider = (client: Client) => {
543
625
  ...params,
544
626
  })
545
627
  },
628
+
629
+ /**
630
+ * Updates this instance with new attribute values and persists the changes to DynamoDB.
631
+ * Handles version conflicts and automatically manages key changes if primary keys are updated.
632
+ * @throws RaceConditionError if the instance is out of sync with the stored value.
633
+ */
546
634
  async update<T extends DynamoDBModelInstance>(
547
635
  this: T,
548
636
  attributes: Partial<ModelOf<T>["_codec"]["_A"]>
@@ -556,8 +644,8 @@ export const getProvider = (client: Client) => {
556
644
  // Update in place
557
645
  try {
558
646
  return await client.put(op)
559
- } catch (error) {
560
- if (error.code === "ConditionalCheckFailedException")
647
+ } catch (error: any) {
648
+ if (error?.code === "ConditionalCheckFailedException")
561
649
  throw new RaceConditionError(
562
650
  "The instance you are attempting to update is out of sync with the stored value."
563
651
  )
@@ -577,6 +665,11 @@ export const getProvider = (client: Client) => {
577
665
  }
578
666
  }
579
667
  },
668
+
669
+ /**
670
+ * Applies updates to this instance and returns the updated instance along with the operations to persist.
671
+ * Does not automatically persist the changes - use the returned operations with bulk() or individual operations.
672
+ */
580
673
  applyUpdate<T extends DynamoDBModelInstance>(
581
674
  this: T,
582
675
  attributes: Partial<ModelOf<T>["_codec"]["_A"]>
@@ -590,6 +683,11 @@ export const getProvider = (client: Client) => {
590
683
 
591
684
  return [updatedItem, op]
592
685
  },
686
+
687
+ /**
688
+ * Deletes this instance from DynamoDB.
689
+ * The item will be permanently removed from the table.
690
+ */
593
691
  delete<T extends DynamoDBModelInstance>(this: T): Promise<null> {
594
692
  const { PK, SK } = this.keys()
595
693
 
@@ -599,14 +697,31 @@ export const getProvider = (client: Client) => {
599
697
  key: { PK, SK },
600
698
  })
601
699
  },
700
+
701
+ /**
702
+ * Performs a soft delete on this instance.
703
+ * The original item is deleted and a new item with a $$DELETED$$ prefix is created.
704
+ */
602
705
  softDelete<T extends DynamoDBModelInstance>(this: T) {
603
706
  return client.softDelete<T>(this)
604
707
  },
708
+
709
+ /**
710
+ * Creates operation objects for this instance for batch processing and transactions.
711
+ * Supports put, update, updateRaw, delete, softDelete, and condition operations.
712
+ */
605
713
  operation: instanceOperation,
606
714
  },
607
715
 
608
716
  unionProps: {
717
+ /**
718
+ * The DynamoDB document client instance.
719
+ */
609
720
  dynamodb: client,
721
+
722
+ /**
723
+ * @internal
724
+ */
610
725
  __dynamoDBDecode<M extends DynamoDBUnion>(this: M, value: unknown) {
611
726
  const decoded = this.from(value)
612
727
 
@@ -618,6 +733,13 @@ export const getProvider = (client: Client) => {
618
733
  return decoded
619
734
  }
620
735
  },
736
+
737
+ /**
738
+ * Retrieves a single item from DynamoDB by its primary key.
739
+ * Prefer `load()` for built-in batching.
740
+ *
741
+ * @throws ItemNotFoundError if the item doesn't exist.
742
+ */
621
743
  async get<M extends DynamoDBUnion>(
622
744
  this: M,
623
745
  key: Key,
@@ -631,6 +753,12 @@ export const getProvider = (client: Client) => {
631
753
  })
632
754
  },
633
755
 
756
+ /**
757
+ * Retrieves a single item from DynamoDB by its primary key.
758
+ * Uses built-in batching for usage in e.g. `Promise.all()`.
759
+ *
760
+ * @throws ItemNotFoundError if the item doesn't exist and `null` is not true.
761
+ */
634
762
  load<
635
763
  M extends DynamoDBUnion,
636
764
  Null extends boolean = false,
@@ -654,6 +782,10 @@ export const getProvider = (client: Client) => {
654
782
  )
655
783
  },
656
784
 
785
+ /**
786
+ * Loads multiple items from DynamoDB by their primary keys.
787
+ * Returns an array of items or errors.
788
+ */
657
789
  loadMany<M extends DynamoDBUnion>(
658
790
  this: M,
659
791
  keys: Key[],
@@ -669,6 +801,9 @@ export const getProvider = (client: Client) => {
669
801
  )
670
802
  },
671
803
 
804
+ /**
805
+ * Returns a page of query results using cursor-based pagination.
806
+ */
672
807
  paginate<M extends DynamoDBUnion>(
673
808
  this: M,
674
809
  args: PaginationInput,
@@ -676,6 +811,15 @@ export const getProvider = (client: Client) => {
676
811
  ) {
677
812
  return client.paginate(this, args, params)
678
813
  },
814
+
815
+ /**
816
+ * Performs a DynamoDB query operation and returns matching items.
817
+ * Use `FetchAllPages: true` to automatically fetch all pages of results.
818
+ */
819
+ async query<M extends DynamoDBUnion>(this: M, params: QueryParams) {
820
+ const { items, meta } = await client.query(params, { items: this })
821
+ return Object.assign(items, { meta })
822
+ },
679
823
  },
680
824
  }
681
825
  }
package/src/sandbox.ts CHANGED
@@ -5,29 +5,17 @@ import diff from "snapshot-diff"
5
5
  import { Client } from "./client"
6
6
  import { GSI_NAMES } from "./gsi"
7
7
 
8
- /**
9
- * Returns a random endpoint from the LOCAL_ENDPOINT environment variable.
10
- */
11
- function getEndpoint() {
12
- if (!process.env.LOCAL_ENDPOINT) throw new Error("LOCAL_ENDPOINT is not set")
13
-
14
- const endpoints = process.env.LOCAL_ENDPOINT.split(",")
15
- return endpoints[Math.floor(Math.random() * endpoints.length)]
16
- }
17
-
18
- const endpoint = getEndpoint()
19
-
20
8
  const ddb = new DynamoDB({
21
9
  accessKeyId: "xxx",
22
10
  secretAccessKey: "xxx",
23
- endpoint,
11
+ endpoint: process.env.LOCAL_ENDPOINT,
24
12
  region: "local",
25
13
  })
26
14
 
27
15
  const docClient = new DynamoDB.DocumentClient({
28
16
  accessKeyId: "xxx",
29
17
  secretAccessKey: "xxx",
30
- endpoint,
18
+ endpoint: process.env.LOCAL_ENDPOINT,
31
19
  region: "local",
32
20
  })
33
21