@squiz/db-lib 1.71.2 → 1.71.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/lib/AbstractRepository.d.ts +2 -0
  3. package/lib/AbstractRepository.d.ts.map +1 -0
  4. package/lib/AbstractRepository.integration.spec.d.ts +1 -0
  5. package/lib/AbstractRepository.integration.spec.d.ts.map +1 -0
  6. package/lib/AbstractRepository.integration.spec.js +118 -0
  7. package/lib/AbstractRepository.integration.spec.js.map +1 -0
  8. package/lib/AbstractRepository.js +187 -0
  9. package/lib/AbstractRepository.js.map +1 -0
  10. package/lib/ConnectionManager.d.ts +1 -0
  11. package/lib/ConnectionManager.d.ts.map +1 -0
  12. package/lib/ConnectionManager.js +58 -0
  13. package/lib/ConnectionManager.js.map +1 -0
  14. package/lib/Migrator.d.ts +1 -0
  15. package/lib/Migrator.d.ts.map +1 -0
  16. package/lib/Migrator.js +160 -0
  17. package/lib/Migrator.js.map +1 -0
  18. package/lib/PostgresErrorCodes.d.ts +1 -0
  19. package/lib/PostgresErrorCodes.d.ts.map +1 -0
  20. package/lib/PostgresErrorCodes.js +274 -0
  21. package/lib/PostgresErrorCodes.js.map +1 -0
  22. package/lib/Repositories.d.ts +1 -0
  23. package/lib/Repositories.d.ts.map +1 -0
  24. package/lib/Repositories.js +3 -0
  25. package/lib/Repositories.js.map +1 -0
  26. package/lib/dynamodb/AbstractDynamoDbRepository.d.ts +1 -0
  27. package/lib/dynamodb/AbstractDynamoDbRepository.d.ts.map +1 -0
  28. package/lib/dynamodb/AbstractDynamoDbRepository.js +367 -0
  29. package/lib/dynamodb/AbstractDynamoDbRepository.js.map +1 -0
  30. package/lib/dynamodb/AbstractDynamoDbRepository.spec.d.ts +1 -0
  31. package/lib/dynamodb/AbstractDynamoDbRepository.spec.d.ts.map +1 -0
  32. package/lib/dynamodb/AbstractDynamoDbRepository.spec.js +698 -0
  33. package/lib/dynamodb/AbstractDynamoDbRepository.spec.js.map +1 -0
  34. package/lib/dynamodb/DynamoDbManager.d.ts +1 -0
  35. package/lib/dynamodb/DynamoDbManager.d.ts.map +1 -0
  36. package/lib/dynamodb/DynamoDbManager.js +66 -0
  37. package/lib/dynamodb/DynamoDbManager.js.map +1 -0
  38. package/lib/dynamodb/getDynamoDbOptions.d.ts +1 -0
  39. package/lib/dynamodb/getDynamoDbOptions.d.ts.map +1 -0
  40. package/lib/dynamodb/getDynamoDbOptions.js +15 -0
  41. package/lib/dynamodb/getDynamoDbOptions.js.map +1 -0
  42. package/lib/error/DuplicateItemError.d.ts +1 -0
  43. package/lib/error/DuplicateItemError.d.ts.map +1 -0
  44. package/lib/error/DuplicateItemError.js +12 -0
  45. package/lib/error/DuplicateItemError.js.map +1 -0
  46. package/lib/error/InvalidDataFormatError.d.ts +1 -0
  47. package/lib/error/InvalidDataFormatError.d.ts.map +1 -0
  48. package/lib/error/InvalidDataFormatError.js +12 -0
  49. package/lib/error/InvalidDataFormatError.js.map +1 -0
  50. package/lib/error/InvalidDbSchemaError.d.ts +1 -0
  51. package/lib/error/InvalidDbSchemaError.d.ts.map +1 -0
  52. package/lib/error/InvalidDbSchemaError.js +12 -0
  53. package/lib/error/InvalidDbSchemaError.js.map +1 -0
  54. package/lib/error/MissingKeyValuesError.d.ts +1 -0
  55. package/lib/error/MissingKeyValuesError.d.ts.map +1 -0
  56. package/lib/error/MissingKeyValuesError.js +12 -0
  57. package/lib/error/MissingKeyValuesError.js.map +1 -0
  58. package/lib/error/TransactionError.d.ts +1 -0
  59. package/lib/error/TransactionError.d.ts.map +1 -0
  60. package/lib/error/TransactionError.js +12 -0
  61. package/lib/error/TransactionError.js.map +1 -0
  62. package/lib/getConnectionInfo.d.ts +1 -0
  63. package/lib/getConnectionInfo.d.ts.map +1 -0
  64. package/lib/getConnectionInfo.js +30 -0
  65. package/lib/getConnectionInfo.js.map +1 -0
  66. package/lib/index.d.ts +1 -0
  67. package/lib/index.d.ts.map +1 -0
  68. package/lib/index.js +33 -70416
  69. package/lib/index.js.map +1 -7
  70. package/package.json +5 -5
  71. package/src/AbstractRepository.ts +26 -20
  72. package/src/dynamodb/AbstractDynamoDbRepository.ts +1 -1
  73. package/src/dynamodb/getDynamoDbOptions.ts +1 -1
  74. package/tsconfig.json +5 -2
  75. package/tsconfig.tsbuildinfo +1 -1
  76. package/build.js +0 -31
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squiz/db-lib",
3
- "version": "1.71.2",
3
+ "version": "1.71.3",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "private": false,
@@ -8,7 +8,7 @@
8
8
  "access": "public"
9
9
  },
10
10
  "scripts": {
11
- "compile": "node build.js && tsc",
11
+ "compile": "tsc -b",
12
12
  "test": "jest -c jest.config.ts --testMatch=\"**/*.spec.ts\" --testMatch=\"!**/*.integration.spec.ts\" --passWithNoTests",
13
13
  "test:integration": "jest --testMatch=\"**/*.integration.spec.ts\"",
14
14
  "test:update-snapshots": "jest -c jest.config.ts --updateSnapshot",
@@ -19,7 +19,7 @@
19
19
  "devDependencies": {
20
20
  "@types/jest": "28.1.8",
21
21
  "@types/node": "20.12.4",
22
- "@types/pg": "8.6.6",
22
+ "@types/pg": "^8.11.8",
23
23
  "aws-sdk-client-mock": "^4.0.0",
24
24
  "aws-sdk-client-mock-jest": "4.0.0",
25
25
  "eslint": "8.33.0",
@@ -36,9 +36,9 @@
36
36
  "@aws-sdk/client-secrets-manager": "3.651.1",
37
37
  "@aws-sdk/lib-dynamodb": "^3.651.1",
38
38
  "@opentelemetry/api": "^1.6.0",
39
- "@squiz/dx-common-lib": "^1.66.4",
39
+ "@squiz/dx-common-lib": "^1.68.3",
40
40
  "@squiz/dx-logger-lib": "^1.64.0",
41
41
  "dotenv": "16.0.3",
42
- "pg": "8.9.0"
42
+ "pg": "^8.12.0"
43
43
  }
44
44
  }
@@ -1,4 +1,4 @@
1
- import { PoolClient, Pool } from 'pg';
1
+ import { PoolClient, Pool, escapeIdentifier } from 'pg';
2
2
  import { Repositories } from './Repositories';
3
3
  import { InvalidUpdateValueError } from '@squiz/dx-common-lib';
4
4
 
@@ -56,19 +56,29 @@ export abstract class AbstractRepository<SHAPE extends object, DATA_CLASS extend
56
56
  return await this.pool.connect();
57
57
  }
58
58
 
59
+ private sanitiseValue(value: Partial<SHAPE>) {
60
+ const sanitisedValue = Object.entries(value)
61
+ .map(([key, value]) => [this.modelPropertyToSqlColumn[key as keyof SHAPE], value] as const)
62
+ .filter(([column, _v]) => !!column);
63
+
64
+ const columns = sanitisedValue.map(([column]) => escapeIdentifier(column));
65
+ const bindingParams = sanitisedValue.map((_, index) => `$${index + 1}`);
66
+ const values = sanitisedValue.map(([_column, value]) => value);
67
+
68
+ return {
69
+ columns,
70
+ bindingParams,
71
+ values,
72
+ };
73
+ }
74
+
59
75
  async create(value: SHAPE, transactionClient: PoolClient | null = null): Promise<SHAPE> {
60
76
  const valueAsClass = new this.classRef(value as Record<string, unknown>);
61
- const columns = Object.keys(valueAsClass)
62
- .map((a) => `"${this.modelPropertyToSqlColumn[a as keyof SHAPE]}"`)
63
- .join(', ');
64
-
65
- const values = Object.values(valueAsClass)
66
- .map((a, index) => `$${index + 1}`)
67
- .join(', ');
77
+ const { columns, bindingParams, values } = this.sanitiseValue(valueAsClass);
68
78
 
69
79
  const result = await this.executeQuery(
70
- `INSERT INTO ${this.tableName} (${columns}) VALUES (${values}) RETURNING *`,
71
- Object.values(valueAsClass),
80
+ `INSERT INTO ${this.tableName} (${columns.join(', ')}) VALUES (${bindingParams.join(', ')}) RETURNING *`,
81
+ values,
72
82
  transactionClient,
73
83
  );
74
84
 
@@ -84,20 +94,16 @@ export abstract class AbstractRepository<SHAPE extends object, DATA_CLASS extend
84
94
  throw new InvalidUpdateValueError('Failed updating the repository, update values cannot be empty');
85
95
  }
86
96
  const whereValues = Object.values(where);
87
- const newValues = Object.values(newValue);
88
-
89
- const setString = Object.keys(newValue)
90
- .map((a, index) => `"${this.modelPropertyToSqlColumn[a as keyof SHAPE]}" = $${index + 1}`)
91
- .join(', ');
92
-
93
- const whereString = this.createWhereStringFromPartialModel(where, newValues.length);
97
+ const newValues = this.sanitiseValue(newValue);
98
+ const setValues = newValues.columns.map((c, i) => `${c} = ${newValues.bindingParams[i]}`);
99
+ const whereString = this.createWhereStringFromPartialModel(where, setValues.length);
94
100
 
95
101
  const result = await this.executeQuery(
96
102
  `UPDATE ${this.tableName}
97
- SET ${setString}
103
+ SET ${setValues.join(', ')}
98
104
  WHERE ${whereString}
99
105
  RETURNING *`,
100
- [...Object.values(newValues), ...Object.values(whereValues)],
106
+ [...newValues.values, ...whereValues],
101
107
  transactionClient,
102
108
  );
103
109
 
@@ -112,7 +118,7 @@ export abstract class AbstractRepository<SHAPE extends object, DATA_CLASS extend
112
118
 
113
119
  const result = await client.query(`DELETE FROM ${this.tableName} WHERE ${whereString}`, Object.values(where));
114
120
 
115
- return result.rowCount;
121
+ return result.rowCount ?? 0;
116
122
  } finally {
117
123
  if (client && !transactionClient) {
118
124
  client.release();
@@ -191,7 +191,7 @@ export abstract class AbstractDynamoDbRepository<SHAPE extends object, DATA_CLAS
191
191
  updateExpression.push(`${propName} = ${propValue}`);
192
192
  expressionAttributeNames[propName] = modelProperty;
193
193
 
194
- expressionAttributeValues[propValue] = newValue[modelProperty as keyof SHAPE];
194
+ expressionAttributeValues[propValue] = newValue[modelProperty as keyof SHAPE] ?? null;
195
195
  }
196
196
 
197
197
  const updateCommandInput = {
@@ -4,6 +4,6 @@ export const getDynamoDbOptions = (awsRegion: string, nodeEnv: 'production' | 'd
4
4
  }
5
5
  return {
6
6
  credentials: { accessKeyId: 'key', secretAccessKey: 'key' },
7
- endpoint: process.env.CI ? 'http://dynamodb-local:8000' : 'http://localhost:8000',
7
+ endpoint: process.env.CI ? 'http://dynamodb-local:8000' : process.env.DYNAMO_DB_HOST ?? 'http://localhost:8000',
8
8
  };
9
9
  };
package/tsconfig.json CHANGED
@@ -3,9 +3,12 @@
3
3
  "compilerOptions": {
4
4
  "outDir": "lib/",
5
5
  "resolveJsonModule": false,
6
+ "module": "Node16",
7
+ "moduleResolution": "Node16",
6
8
  "composite": true,
7
- "emitDeclarationOnly": true,
8
- "rootDir": "./src"
9
+ "rootDir": "./src",
10
+ "declaration": true,
11
+ "declarationMap": true
9
12
  },
10
13
  "references": [
11
14
  {