@squiz/db-lib 1.65.0 → 1.66.0

Sign up to get free protection for your applications and to get access to all the features.
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';