@digitraffic/common 2025.2.4-3 → 2025.2.28-2

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.
@@ -1,3 +1,3 @@
1
1
  import { type DTDatabase } from "../database/database.js";
2
2
  export declare function assertCount(db: DTDatabase, sql: string, count: number): Promise<void>;
3
- export declare function dbTestBase(fn: (db: DTDatabase) => void, truncateFn: (db: DTDatabase) => Promise<void>, dbUser: string, dbPass: string, dbUri: string): () => void;
3
+ export declare function dbTestBase(fn: (db: DTDatabase) => void, truncateFn: (db: DTDatabase) => Promise<void>, dbUser: string, dbPass: string, dbUri: string, convertNullsToUndefined?: boolean): () => void;
@@ -3,11 +3,11 @@ import { getEnvVariableOrElse } from "../utils/utils.js";
3
3
  export async function assertCount(db, sql, count) {
4
4
  await db.one(sql).then((x) => expect(x.count).toEqual(count));
5
5
  }
6
- export function dbTestBase(fn, truncateFn, dbUser, dbPass, dbUri) {
6
+ export function dbTestBase(fn, truncateFn, dbUser, dbPass, dbUri, convertNullsToUndefined = false) {
7
7
  const theDbUri = getEnvVariableOrElse("DB_URI", dbUri);
8
- console.log(`Test database URI: ${theDbUri}`);
8
+ console.log(`Test database URI: ${theDbUri}, convertNullsToUndefined: ${convertNullsToUndefined}`);
9
9
  return () => {
10
- const db = initDbConnection(dbUser, dbPass, "test", theDbUri, {
10
+ const db = initDbConnection(dbUser, dbPass, "test", theDbUri, convertNullsToUndefined, {
11
11
  noWarnings: true, // ignore duplicate connection warning for tests
12
12
  });
13
13
  beforeAll(async () => {
@@ -18,9 +18,10 @@ export type DTTransaction = ITask<unknown>;
18
18
  * @param password Password
19
19
  * @param applicationName name of application
20
20
  * @param url Connection URL
21
+ * @param convertNullsToUndefined if true null values in query results will be converted to undefined, Default false.
21
22
  * @param options pg-promise options
22
23
  */
23
- export declare function initDbConnection(username: string, password: string, applicationName: string, url: string, options?: object): DTDatabase;
24
- export declare function inTransaction<T>(fn: (db: DTTransaction) => Promise<T>): Promise<T>;
25
- export declare function inDatabase<T>(fn: (db: DTDatabase) => Promise<T>): Promise<T>;
26
- export declare function inDatabaseReadonly<T>(fn: (db: DTDatabase) => Promise<T>): Promise<T>;
24
+ export declare function initDbConnection(username: string, password: string, applicationName: string, url: string, convertNullsToUndefined: boolean, options?: object): DTDatabase;
25
+ export declare function inTransaction<T>(fn: (db: DTTransaction) => Promise<T>, convertNullsToUndefined?: boolean): Promise<T>;
26
+ export declare function inDatabase<T>(fn: (db: DTDatabase) => Promise<T>, convertNullsToUndefined?: boolean): Promise<T>;
27
+ export declare function inDatabaseReadonly<T>(fn: (db: DTDatabase) => Promise<T>, convertNullsToUndefined?: boolean): Promise<T>;
@@ -1,7 +1,7 @@
1
- import {} from "pg-promise";
2
- import { getEnvVariable, getEnvVariableOrElse } from "../utils/utils.js";
1
+ import pgpImport, {} from "pg-promise";
3
2
  import { logger } from "../aws/runtime/dt-logger-default.js";
4
3
  import { logException } from "../utils/logging.js";
4
+ import { getEnvVariable, getEnvVariableOrElse } from "../utils/utils.js";
5
5
  export var DatabaseEnvironmentKeys;
6
6
  (function (DatabaseEnvironmentKeys) {
7
7
  DatabaseEnvironmentKeys["DB_USER"] = "DB_USER";
@@ -10,18 +10,32 @@ export var DatabaseEnvironmentKeys;
10
10
  DatabaseEnvironmentKeys["DB_RO_URI"] = "DB_RO_URI";
11
11
  DatabaseEnvironmentKeys["DB_APPLICATION"] = "DB_APPLICATION";
12
12
  })(DatabaseEnvironmentKeys || (DatabaseEnvironmentKeys = {}));
13
- import pgpImport from "pg-promise";
14
- const pgp = pgpImport();
15
- // convert numeric types to number instead of string
16
- pgp.pg.types.setTypeParser(pgp.pg.types.builtins.INT8, (value) => {
17
- return parseInt(value);
18
- });
19
- pgp.pg.types.setTypeParser(pgp.pg.types.builtins.FLOAT8, (value) => {
20
- return parseFloat(value);
21
- });
22
- pgp.pg.types.setTypeParser(pgp.pg.types.builtins.NUMERIC, (value) => {
23
- return parseFloat(value);
24
- });
13
+ // pg-promise initialization options
14
+ // https://vitaly-t.github.io/pg-promise/global.html#event:receive
15
+ const pgpPromiseInitOptions = {
16
+ // eslint-disable-next-line
17
+ receive(e) {
18
+ if (e.data) {
19
+ convertNullColumnsToUndefined(e.data);
20
+ }
21
+ },
22
+ };
23
+ function initPgp(pgpPromiseInitOptions) {
24
+ const pgp = pgpPromiseInitOptions
25
+ ? pgpImport(pgpPromiseInitOptions)
26
+ : pgpImport();
27
+ // convert numeric types to number instead of string
28
+ pgp.pg.types.setTypeParser(pgp.pg.types.builtins.INT8, (value) => {
29
+ return parseInt(value);
30
+ });
31
+ pgp.pg.types.setTypeParser(pgp.pg.types.builtins.FLOAT8, (value) => {
32
+ return parseFloat(value);
33
+ });
34
+ pgp.pg.types.setTypeParser(pgp.pg.types.builtins.NUMERIC, (value) => {
35
+ return parseFloat(value);
36
+ });
37
+ return pgp;
38
+ }
25
39
  /**
26
40
  * Creates a non-pooling database connection primarily used by Lambdas.
27
41
  *
@@ -32,27 +46,28 @@ pgp.pg.types.setTypeParser(pgp.pg.types.builtins.NUMERIC, (value) => {
32
46
  * @param password Password
33
47
  * @param applicationName name of application
34
48
  * @param url Connection URL
49
+ * @param convertNullsToUndefined if true null values in query results will be converted to undefined, Default false.
35
50
  * @param options pg-promise options
36
51
  */
37
- export function initDbConnection(username, password, applicationName, url, options) {
52
+ export function initDbConnection(username, password, applicationName, url, convertNullsToUndefined, options) {
38
53
  const finalUrl = `postgresql://${username}:${password}@${url}?application_name=${applicationName}`;
39
- return pgp(finalUrl, options);
54
+ return initPgp(convertNullsToUndefined ? pgpPromiseInitOptions : undefined)(finalUrl, options);
40
55
  }
41
- export function inTransaction(fn) {
42
- return inDatabase((db) => db.tx((t) => fn(t)));
56
+ export function inTransaction(fn, convertNullsToUndefined = false) {
57
+ return inDatabase((db) => db.tx((t) => fn(t)), convertNullsToUndefined);
43
58
  }
44
- export function inDatabase(fn) {
45
- return doInDatabase(false, fn);
59
+ export function inDatabase(fn, convertNullsToUndefined = false) {
60
+ return doInDatabase(false, fn, convertNullsToUndefined);
46
61
  }
47
- export function inDatabaseReadonly(fn) {
48
- return doInDatabase(true, fn);
62
+ export function inDatabaseReadonly(fn, convertNullsToUndefined = false) {
63
+ return doInDatabase(true, fn, convertNullsToUndefined);
49
64
  }
50
- async function doInDatabase(readonly, fn) {
65
+ async function doInDatabase(readonly, fn, convertNullsToUndefined) {
51
66
  const db_application = getEnvVariableOrElse(DatabaseEnvironmentKeys.DB_APPLICATION, "unknown-cdk-application");
52
67
  const db_uri = readonly
53
68
  ? getEnvVariable(DatabaseEnvironmentKeys.DB_RO_URI)
54
69
  : getEnvVariable(DatabaseEnvironmentKeys.DB_URI);
55
- const db = initDbConnection(getEnvVariable(DatabaseEnvironmentKeys.DB_USER), getEnvVariable(DatabaseEnvironmentKeys.DB_PASS), db_application, db_uri);
70
+ const db = initDbConnection(getEnvVariable(DatabaseEnvironmentKeys.DB_USER), getEnvVariable(DatabaseEnvironmentKeys.DB_PASS), db_application, db_uri, convertNullsToUndefined);
56
71
  try {
57
72
  // deallocate all prepared statements to allow for connection pooling
58
73
  // DISCARD instead of DEALLOCATE as it didn't always clean all prepared statements
@@ -67,4 +82,18 @@ async function doInDatabase(readonly, fn) {
67
82
  await db.$pool.end();
68
83
  }
69
84
  }
85
+ // eslint-disable-next-line
86
+ function convertNullColumnsToUndefined(rows) {
87
+ rows.forEach((row) => {
88
+ // eslint-disable-next-line guard-for-in
89
+ for (const column in row) {
90
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
91
+ const columnValue = row[column];
92
+ if (columnValue === null) {
93
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
94
+ row[column] = undefined;
95
+ }
96
+ }
97
+ });
98
+ }
70
99
  //# sourceMappingURL=database.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitraffic/common",
3
- "version": "2025.2.4-3",
3
+ "version": "2025.2.28-2",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "repository": {
@@ -104,79 +104,79 @@
104
104
  "./dist/aws/runtime/digitraffic-integration-response": "./dist/aws/runtime/digitraffic-integration-response.js"
105
105
  },
106
106
  "peerDependencies": {
107
- "@aws-sdk/client-api-gateway": "^3.721.0",
108
- "@aws-sdk/client-s3": "^3.721.0",
109
- "@aws-sdk/client-secrets-manager": "^3.721.0",
110
- "@aws-sdk/client-sns": "^3.721.0",
111
- "@aws-sdk/lib-storage": "^3.721.0",
107
+ "@aws-sdk/client-api-gateway": "^3.758.0",
108
+ "@aws-sdk/client-s3": "^3.758.0",
109
+ "@aws-sdk/client-secrets-manager": "^3.758.0",
110
+ "@aws-sdk/client-sns": "^3.758.0",
111
+ "@aws-sdk/lib-storage": "^3.758.0",
112
112
  "@date-fns/tz": "1.2.0",
113
- "@smithy/fetch-http-handler": "4.1.3",
114
- "aws-cdk-lib": "^2.177.0",
113
+ "@smithy/fetch-http-handler": "5.0.1",
114
+ "aws-cdk-lib": "^2.181.1",
115
115
  "change-case": "^5.4.4",
116
116
  "constructs": "~10.4.2",
117
117
  "date-fns": "~4.1.0",
118
118
  "etag": "^1.8.1",
119
119
  "geojson-validation": "^1.0.2",
120
- "ky": "^1.7.4",
120
+ "ky": "^1.7.5",
121
121
  "lodash-es": "^4.17.21",
122
122
  "node-ttl": "^0.2.0",
123
- "pg-native": "^3.2.0",
123
+ "pg-native": "^3.2.2",
124
124
  "pg-promise": "^11.10.2",
125
125
  "pg-query-stream": "4.7.1",
126
- "zod": "^3.24.1"
126
+ "zod": "^3.24.2"
127
127
  },
128
128
  "devDependencies": {
129
- "@aws-sdk/client-api-gateway": "^3.738.0",
130
- "@aws-sdk/client-s3": "^3.738.0",
131
- "@aws-sdk/client-secrets-manager": "^3.738.0",
132
- "@aws-sdk/client-sns": "^3.738.0",
133
- "@aws-sdk/lib-storage": "^3.738.0",
134
- "@date-fns/tz": "1.2.0",
135
129
  "@digitraffic/eslint-config": "^3.1.1",
136
130
  "@jest/globals": "^29.7.0",
137
131
  "@rushstack/eslint-config": "^3.7.1",
138
- "@rushstack/heft": "^0.68.15",
139
- "@rushstack/heft-jest-plugin": "^0.14.5",
140
- "@rushstack/heft-lint-plugin": "^0.5.14",
141
- "@rushstack/heft-typescript-plugin": "^0.6.8",
142
- "@smithy/fetch-http-handler": "4.1.3",
143
- "@smithy/types": "^3.7.2",
132
+ "@rushstack/heft": "^0.69.1",
133
+ "@rushstack/heft-jest-plugin": "^0.14.11",
134
+ "@rushstack/heft-lint-plugin": "^0.5.20",
135
+ "@rushstack/heft-typescript-plugin": "^0.6.13",
136
+ "@smithy/types": "^4.1.0",
144
137
  "@types/aws-lambda": "8.10.147",
145
138
  "@types/etag": "^1.8.3",
146
- "@types/geojson": "7946.0.15",
139
+ "@types/geojson": "7946.0.16",
147
140
  "@types/geojson-validation": "^1.0.3",
148
141
  "@types/jest": "29.5.14",
149
142
  "@types/lodash-es": "4.17.12",
150
143
  "@types/madge": "5.0.3",
151
- "@types/node": "20.17.6",
144
+ "@types/node": "22.13.5",
152
145
  "@typescript-eslint/eslint-plugin": "~7.14.1",
153
- "@typescript-eslint/parser": "^7.18.0",
154
- "aws-cdk-lib": "^2.177.0",
146
+ "@typescript-eslint/parser": "^7.0.0",
155
147
  "aws-sdk": "^2.1692.0",
156
- "change-case": "^5.4.4",
157
- "constructs": "~10.4.2",
158
- "date-fns": "~4.1.0",
159
148
  "eslint": "^8.57.1",
160
149
  "eslint-config-prettier": "^9.1.0",
161
150
  "eslint-plugin-deprecation": "~3.0.0",
162
- "etag": "^1.8.1",
163
- "geojson-validation": "^1.0.2",
164
151
  "jest": "^29.7.0",
165
152
  "jest-junit": "^16.0.0",
166
- "ky": "^1.7.4",
167
- "lefthook": "^1.10.10",
153
+ "lefthook": "^1.11.2",
168
154
  "lodash": "^4.17.21",
169
- "lodash-es": "~4.17.21",
170
155
  "madge": "^8.0.0",
171
- "node-ttl": "^0.2.0",
172
- "pg-native": "^3.2.0",
173
- "pg-promise": "^11.10.2",
174
- "pg-query-stream": "4.7.1",
175
156
  "rimraf": "^6.0.1",
176
- "ts-jest": "^29.2.5",
157
+ "ts-jest": "^29.2.6",
177
158
  "typescript": "~5.6.3",
178
159
  "velocityjs": "^2.0.6",
179
- "zod": "~3.24.1"
160
+ "@aws-sdk/client-api-gateway": "^3.758.0",
161
+ "@aws-sdk/client-s3": "^3.758.0",
162
+ "@aws-sdk/client-secrets-manager": "^3.758.0",
163
+ "@aws-sdk/client-sns": "^3.758.0",
164
+ "@aws-sdk/lib-storage": "^3.758.0",
165
+ "@date-fns/tz": "1.2.0",
166
+ "@smithy/fetch-http-handler": "5.0.1",
167
+ "aws-cdk-lib": "^2.181.1",
168
+ "change-case": "^5.4.4",
169
+ "constructs": "~10.4.2",
170
+ "date-fns": "~4.1.0",
171
+ "etag": "^1.8.1",
172
+ "geojson-validation": "^1.0.2",
173
+ "ky": "^1.7.5",
174
+ "lodash-es": "^4.17.21",
175
+ "node-ttl": "^0.2.0",
176
+ "pg-native": "^3.2.2",
177
+ "pg-promise": "^11.10.2",
178
+ "pg-query-stream": "4.7.1",
179
+ "zod": "^3.24.2"
180
180
  },
181
181
  "scripts": {
182
182
  "build": "heft build --clean",