@squiz/db-lib 1.65.0 → 1.66.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.66.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8ce1826: Use DynamoDB in Content API service
8
+
3
9
  ## 1.65.0
4
10
 
5
11
  ### Minor Changes
@@ -0,0 +1,158 @@
1
+ import { DynamoDBDocument } from '@aws-sdk/lib-dynamodb';
2
+ import { Transaction, DynamoDbManager } from '..';
3
+ interface Reader<T> {
4
+ queryItems(partialItem: Partial<T>, useSortKey?: boolean, index?: keyof TableIndexes): Promise<T[]>;
5
+ getItem(id: string | Partial<T>): Promise<T | undefined>;
6
+ }
7
+ interface Writer<T> {
8
+ createItem(item: Partial<T>): Promise<T>;
9
+ updateItem(partialItem: Partial<T>, newValue: Partial<T>): Promise<T | undefined>;
10
+ deleteItem(partialItem: Partial<T>): Promise<number>;
11
+ }
12
+ type Repository<T> = Reader<T> & Writer<T>;
13
+ type Repositories = Record<string, Repository<any>>;
14
+ export type TableKeys = {
15
+ pk: {
16
+ attributeName: string;
17
+ format: string;
18
+ };
19
+ sk: {
20
+ attributeName: string;
21
+ format: string;
22
+ };
23
+ };
24
+ export type TableIndexes = Record<string, TableKeys>;
25
+ export type KeysFormat = Record<keyof TableKeys | keyof TableIndexes, string>;
26
+ export type EntityDefinition = {
27
+ keys: TableKeys;
28
+ indexes: TableIndexes;
29
+ };
30
+ export declare abstract class AbstractDynamoDbRepository<SHAPE extends object, DATA_CLASS extends SHAPE> implements Reader<SHAPE>, Writer<SHAPE> {
31
+ protected tableName: string;
32
+ protected dbManager: DynamoDbManager<Repositories>;
33
+ protected entityName: string;
34
+ protected entityDefinition: EntityDefinition;
35
+ protected classRef: {
36
+ new (data?: Record<string, unknown>): DATA_CLASS;
37
+ };
38
+ protected client: DynamoDBDocument;
39
+ protected keys: TableKeys;
40
+ protected indexes: TableIndexes;
41
+ protected keysFormat: KeysFormat;
42
+ constructor(tableName: string, dbManager: DynamoDbManager<Repositories>, entityName: string, entityDefinition: EntityDefinition, classRef: {
43
+ new (data?: Record<string, unknown>): DATA_CLASS;
44
+ });
45
+ /**
46
+ * Get the single item matching the key fields value in the given
47
+ * partial item. Will throw MissingKeyValuesError if key field values
48
+ * are missing
49
+ *
50
+ * @param item
51
+ *
52
+ * @throws MissingKeyValuesError
53
+ */
54
+ getItem(item: Partial<SHAPE>): Promise<DATA_CLASS | undefined>;
55
+ /**
56
+ * Finds all the items matching the partition key or
57
+ * the gsi key (when gsi index name is specified)
58
+ *
59
+ * @param item
60
+ * @param useSortKey
61
+ * @param index
62
+ * @throws MissingKeyValuesError
63
+ */
64
+ queryItems(item: Partial<SHAPE>, useSortKey?: boolean, index?: keyof TableIndexes): Promise<DATA_CLASS[]>;
65
+ /**
66
+ * Update the existing item matching the key fields value
67
+ * in the passed in partialItem
68
+ * @param partialItem
69
+ * @param newValue
70
+ * @param transaction
71
+ *
72
+ * @returns Promise<SHAPE | undefined>
73
+ * @throws MissingKeyValuesError
74
+ */
75
+ updateItem(partialItem: Partial<SHAPE>, newValue: Exclude<Partial<SHAPE>, Record<string, never>>, transaction?: Transaction): Promise<DATA_CLASS | undefined>;
76
+ /**
77
+ * Adds new item to the table
78
+ *
79
+ * @param value
80
+ * @param transaction
81
+ *
82
+ * @returns Promise<SHAPE>
83
+ * @throws DuplicateItemError
84
+ * @throws MissingKeyValuesError
85
+ */
86
+ createItem(value: DATA_CLASS, transaction?: Transaction): Promise<DATA_CLASS>;
87
+ /**
88
+ * Deletes an item from the table
89
+ *
90
+ * @param partialItem
91
+ * @param transaction
92
+ * @returns number
93
+ * @throw MissingKeyValuesError
94
+ */
95
+ deleteItem(partialItem: Partial<SHAPE>, transaction?: Transaction): Promise<number>;
96
+ /**
97
+ * Return repo model object from the db value
98
+ * @param item
99
+ * @returns
100
+ */
101
+ protected hydrateItem(item: Record<string, unknown>): DATA_CLASS;
102
+ /**
103
+ * Evaluate the partition key value from the partial item
104
+ * @param item
105
+ * @returns string
106
+ * @throw MissingKeyValuesError
107
+ */
108
+ protected getPk(item: Partial<SHAPE>): string;
109
+ /**
110
+ * Evaluate the sort key value from the partial item
111
+ * @param item
112
+ * @returns string
113
+ *
114
+ * @throw MissingKeyValuesError
115
+ */
116
+ protected getSk(item: Partial<SHAPE>): string;
117
+ /**
118
+ * Evaluate the key value from the
119
+ *
120
+ * Example 1:
121
+ * Input:
122
+ * - item: {id: foo, name: 'some-name' }
123
+ * - attributeName: pk
124
+ * - this.keysFormat = { pk: 'item#{id}', 'sk': '#meta', ... }
125
+ * Output:
126
+ * - 'item#foo'
127
+ *
128
+ * Example 2:
129
+ * Input:
130
+ * - item: {id: foo, name: 'some-name', itemType: 'A' }
131
+ * - attributeName: sk
132
+ * - this.keysFormat = { pk: 'item#{id}', 'sk': 'type#{itemType}', ... }
133
+ * Output:
134
+ * - 'type#A'
135
+ *
136
+ * Example 3:
137
+ * Input:
138
+ * - item: {id: foo, name: 'some-name' }
139
+ * - attributeName: sk
140
+ * - this.keysFormat = { pk: 'item#{id}', 'sk': 'name-type#{itemType}{name}', ... }
141
+ * Output:
142
+ * - Error: "Key field "itemType" must be specified in the input item"
143
+ *
144
+ * @param item
145
+ * @param attributeName
146
+ *
147
+ * @returns string
148
+ * @throw MissingKeyValuesError
149
+ */
150
+ protected getKey(item: Partial<SHAPE>, attributeName: keyof KeysFormat): string;
151
+ /**
152
+ * Validate the data matches with "DATA_MODEL"
153
+ * @param value
154
+ * @return void
155
+ */
156
+ private assertValueMatchesModel;
157
+ }
158
+ export {};
@@ -0,0 +1,24 @@
1
+ import { AbstractDynamoDbRepository } from './AbstractDynamoDbRepository';
2
+ import { DynamoDbManager } from './DynamoDbManager';
3
+ import 'aws-sdk-client-mock-jest';
4
+ interface ITestItem {
5
+ name: string;
6
+ age: number;
7
+ country: string;
8
+ data?: object;
9
+ }
10
+ declare class TestItem implements ITestItem {
11
+ name: string;
12
+ age: number;
13
+ country: string;
14
+ data: object;
15
+ constructor(data?: Partial<ITestItem>);
16
+ }
17
+ export type TestRepositories = {
18
+ testItem: TestItemRepository;
19
+ };
20
+ export type TestDbManager = DynamoDbManager<TestRepositories>;
21
+ declare class TestItemRepository extends AbstractDynamoDbRepository<ITestItem, TestItem> {
22
+ constructor(tableName: string, dbManager: TestDbManager);
23
+ }
24
+ export {};
@@ -0,0 +1,18 @@
1
+ import { DynamoDBDocument, TransactWriteCommandInput } from '@aws-sdk/lib-dynamodb';
2
+ export type Transaction = {
3
+ id?: string;
4
+ };
5
+ type TransactionItems = TransactWriteCommandInput['TransactItems'];
6
+ export type TransactionItem = NonNullable<TransactionItems>[number];
7
+ export declare class DynamoDbManager<TRepositories> {
8
+ client: DynamoDBDocument;
9
+ private transactionItems;
10
+ repositories: TRepositories;
11
+ constructor(client: DynamoDBDocument, repositoryCreator: (dbManager: DynamoDbManager<TRepositories>) => TRepositories);
12
+ executeInTransaction<T>(func: (transaction: Transaction) => Promise<T>): Promise<T>;
13
+ addWriteTransactionItem(transactionId: string, item: TransactionItem): void;
14
+ private executeTransaction;
15
+ private startTransaction;
16
+ private closeTransaction;
17
+ }
18
+ export {};
@@ -0,0 +1,5 @@
1
+ import { InternalServerError } from '@squiz/dx-common-lib';
2
+ export declare class DuplicateItemError extends InternalServerError {
3
+ name: string;
4
+ constructor(message: string);
5
+ }
@@ -0,0 +1,5 @@
1
+ import { BadRequestError } from '@squiz/dx-common-lib';
2
+ export declare class InvalidDbSchemaError extends BadRequestError {
3
+ name: string;
4
+ constructor(message: string);
5
+ }
@@ -0,0 +1,5 @@
1
+ import { InternalServerError } from '@squiz/dx-common-lib';
2
+ export declare class MissingKeyValuesError extends InternalServerError {
3
+ name: string;
4
+ constructor(message: string);
5
+ }
@@ -0,0 +1,5 @@
1
+ import { InternalServerError } from '@squiz/dx-common-lib';
2
+ export declare class TransactionError extends InternalServerError {
3
+ name: string;
4
+ constructor(message: string);
5
+ }
package/lib/index.d.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  export * from './AbstractRepository';
2
2
  export * from './ConnectionManager';
3
+ export * from './dynamodb/DynamoDbManager';
4
+ export * from './dynamodb/AbstractDynamoDbRepository';
3
5
  export * from './Migrator';
4
6
  export * from './Repositories';
5
7
  export * from './getConnectionInfo';
8
+ export * from './error/DuplicateItemError';
9
+ export * from './error/TransactionError';
10
+ export * from './error/MissingKeyValuesError';
11
+ export * from './error/InvalidDbSchemaError';
6
12
  export * from './PostgresErrorCodes';
7
13
  export { Pool, PoolClient } from 'pg';