@digitraffic/common 2025.2.4-3 → 2025.2.28-1
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
|
25
|
-
export declare function inDatabase<T>(fn: (db: DTDatabase) => Promise<T
|
26
|
-
export declare function inDatabaseReadonly<T>(fn: (db: DTDatabase) => 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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
}
|
22
|
-
|
23
|
-
|
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
|
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.
|
3
|
+
"version": "2025.2.28-1",
|
4
4
|
"description": "",
|
5
5
|
"type": "module",
|
6
6
|
"repository": {
|
@@ -126,32 +126,32 @@
|
|
126
126
|
"zod": "^3.24.1"
|
127
127
|
},
|
128
128
|
"devDependencies": {
|
129
|
-
"@aws-sdk/client-api-gateway": "^3.
|
130
|
-
"@aws-sdk/client-s3": "^3.
|
131
|
-
"@aws-sdk/client-secrets-manager": "^3.
|
132
|
-
"@aws-sdk/client-sns": "^3.
|
133
|
-
"@aws-sdk/lib-storage": "^3.
|
129
|
+
"@aws-sdk/client-api-gateway": "^3.758.0",
|
130
|
+
"@aws-sdk/client-s3": "^3.758.0",
|
131
|
+
"@aws-sdk/client-secrets-manager": "^3.758.0",
|
132
|
+
"@aws-sdk/client-sns": "^3.758.0",
|
133
|
+
"@aws-sdk/lib-storage": "^3.758.0",
|
134
134
|
"@date-fns/tz": "1.2.0",
|
135
135
|
"@digitraffic/eslint-config": "^3.1.1",
|
136
136
|
"@jest/globals": "^29.7.0",
|
137
137
|
"@rushstack/eslint-config": "^3.7.1",
|
138
|
-
"@rushstack/heft": "^0.
|
139
|
-
"@rushstack/heft-jest-plugin": "^0.14.
|
140
|
-
"@rushstack/heft-lint-plugin": "^0.5.
|
141
|
-
"@rushstack/heft-typescript-plugin": "^0.6.
|
142
|
-
"@smithy/fetch-http-handler": "
|
143
|
-
"@smithy/types": "^
|
138
|
+
"@rushstack/heft": "^0.69.1",
|
139
|
+
"@rushstack/heft-jest-plugin": "^0.14.11",
|
140
|
+
"@rushstack/heft-lint-plugin": "^0.5.20",
|
141
|
+
"@rushstack/heft-typescript-plugin": "^0.6.13",
|
142
|
+
"@smithy/fetch-http-handler": "5.0.1",
|
143
|
+
"@smithy/types": "^4.1.0",
|
144
144
|
"@types/aws-lambda": "8.10.147",
|
145
145
|
"@types/etag": "^1.8.3",
|
146
|
-
"@types/geojson": "7946.0.
|
146
|
+
"@types/geojson": "7946.0.16",
|
147
147
|
"@types/geojson-validation": "^1.0.3",
|
148
148
|
"@types/jest": "29.5.14",
|
149
149
|
"@types/lodash-es": "4.17.12",
|
150
150
|
"@types/madge": "5.0.3",
|
151
|
-
"@types/node": "
|
151
|
+
"@types/node": "22.13.5",
|
152
152
|
"@typescript-eslint/eslint-plugin": "~7.14.1",
|
153
|
-
"@typescript-eslint/parser": "^7.
|
154
|
-
"aws-cdk-lib": "^2.
|
153
|
+
"@typescript-eslint/parser": "^7.0.0",
|
154
|
+
"aws-cdk-lib": "^2.181.1",
|
155
155
|
"aws-sdk": "^2.1692.0",
|
156
156
|
"change-case": "^5.4.4",
|
157
157
|
"constructs": "~10.4.2",
|
@@ -163,20 +163,20 @@
|
|
163
163
|
"geojson-validation": "^1.0.2",
|
164
164
|
"jest": "^29.7.0",
|
165
165
|
"jest-junit": "^16.0.0",
|
166
|
-
"ky": "^1.7.
|
167
|
-
"lefthook": "^1.
|
166
|
+
"ky": "^1.7.5",
|
167
|
+
"lefthook": "^1.11.2",
|
168
168
|
"lodash": "^4.17.21",
|
169
169
|
"lodash-es": "~4.17.21",
|
170
170
|
"madge": "^8.0.0",
|
171
171
|
"node-ttl": "^0.2.0",
|
172
|
-
"pg-native": "^3.2.
|
172
|
+
"pg-native": "^3.2.2",
|
173
173
|
"pg-promise": "^11.10.2",
|
174
174
|
"pg-query-stream": "4.7.1",
|
175
175
|
"rimraf": "^6.0.1",
|
176
|
-
"ts-jest": "^29.2.
|
176
|
+
"ts-jest": "^29.2.6",
|
177
177
|
"typescript": "~5.6.3",
|
178
178
|
"velocityjs": "^2.0.6",
|
179
|
-
"zod": "~3.24.
|
179
|
+
"zod": "~3.24.2"
|
180
180
|
},
|
181
181
|
"scripts": {
|
182
182
|
"build": "heft build --clean",
|