@devopsplaybook.io/common-utils 1.10.1 → 1.11.0-beta.24.d8f9aef
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/README.md +73 -27
- package/dist/src/ConfigBase.d.ts +31 -0
- package/dist/src/ConfigBase.js +58 -16
- package/dist/src/DbUtils.d.ts +20 -3
- package/dist/src/DbUtils.js +93 -2
- package/dist/src/DbUtilsNoTelemetry.d.ts +4 -1
- package/dist/src/DbUtilsNoTelemetry.js +62 -6
- package/dist/src/PostgresDbUtils.d.ts +41 -10
- package/dist/src/PostgresDbUtils.js +357 -304
- package/dist/src/SqlDbUtils.d.ts +12 -4
- package/dist/src/SqlDbUtils.js +76 -30
- package/dist/src/users/Auth.d.ts +11 -1
- package/dist/src/users/Auth.js +160 -44
- package/dist/src/users/User.d.ts +10 -0
- package/dist/src/users/User.js +30 -10
- package/dist/src/users/UserApiToken.d.ts +4 -0
- package/dist/src/users/UserApiToken.js +11 -0
- package/dist/src/users/UsersApiTokensData.d.ts +12 -0
- package/dist/src/users/UsersApiTokensData.js +130 -33
- package/dist/src/users/UsersData.d.ts +20 -1
- package/dist/src/users/UsersData.js +150 -52
- package/dist/src/users/UsersRoutes.js +178 -61
- package/dist/src/users/index.d.ts +8 -0
- package/dist/src/users/index.js +24 -0
- package/package.json +58 -1
- package/.github/workflows/main-build.yml +0 -18
- package/.github/workflows/pr-check.yml +0 -27
- package/.github/workflows/reusable-merge-build.yml +0 -197
- package/.github/workflows/reusable-npm-merge.yml +0 -135
- package/.github/workflows/reusable-npm-pr.yml +0 -183
- package/.github/workflows/reusable-npm-upgrade.yml +0 -92
- package/.github/workflows/reusable-pr-verify.yml +0 -181
- package/AGENTS.md +0 -105
- package/index.ts +0 -18
- package/jest.config.js +0 -17
- package/prettierrc.json +0 -5
- package/src/ConfigBase.spec.ts +0 -108
- package/src/ConfigBase.ts +0 -297
- package/src/DbUtils.spec.ts +0 -23
- package/src/DbUtils.ts +0 -116
- package/src/DbUtilsNoTelemetry.spec.ts +0 -168
- package/src/DbUtilsNoTelemetry.ts +0 -117
- package/src/LLM.spec.ts +0 -303
- package/src/LLM.ts +0 -204
- package/src/Notifications.spec.ts +0 -265
- package/src/Notifications.ts +0 -201
- package/src/OTelContext.spec.ts +0 -58
- package/src/OTelContext.ts +0 -63
- package/src/PostgresDbUtils.spec.ts +0 -153
- package/src/PostgresDbUtils.ts +0 -666
- package/src/SqlDbUtils.spec.ts +0 -108
- package/src/SqlDbUtils.ts +0 -152
- package/src/SystemCommand.spec.ts +0 -18
- package/src/SystemCommand.ts +0 -23
- package/src/Timeout.spec.ts +0 -18
- package/src/Timeout.ts +0 -12
- package/src/users/Auth.spec.ts +0 -268
- package/src/users/Auth.ts +0 -202
- package/src/users/User.ts +0 -75
- package/src/users/UserApiToken.ts +0 -55
- package/src/users/UserPassword.spec.ts +0 -28
- package/src/users/UserPassword.ts +0 -20
- package/src/users/UserSession.ts +0 -9
- package/src/users/UsersApiTokensData.spec.ts +0 -158
- package/src/users/UsersApiTokensData.ts +0 -125
- package/src/users/UsersData.ts +0 -141
- package/src/users/UsersRoutes.ts +0 -374
- package/tsconfig.json +0 -15
- package/tsconfig.spec.json +0 -8
|
@@ -6,6 +6,33 @@ exports.DbUtilsNoTelemetryExecSQL = DbUtilsNoTelemetryExecSQL;
|
|
|
6
6
|
exports.DbUtilsNoTelemetryQuerySQL = DbUtilsNoTelemetryQuerySQL;
|
|
7
7
|
const DbUtils_1 = require("./DbUtils");
|
|
8
8
|
let logger;
|
|
9
|
+
/**
|
|
10
|
+
* Compiled SQLite statements are cached per database handle: `better-sqlite3`
|
|
11
|
+
* has no internal cache and `prepare()` dominates the ingestion hot path.
|
|
12
|
+
*/
|
|
13
|
+
const PREPARED_STATEMENT_CACHE_MAX = 100;
|
|
14
|
+
const statementCaches = new WeakMap();
|
|
15
|
+
function prepareCached(db, sql) {
|
|
16
|
+
let cache = statementCaches.get(db);
|
|
17
|
+
if (!cache) {
|
|
18
|
+
cache = new Map();
|
|
19
|
+
statementCaches.set(db, cache);
|
|
20
|
+
}
|
|
21
|
+
let statement = cache.get(sql);
|
|
22
|
+
if (!statement) {
|
|
23
|
+
if (cache.size >= PREPARED_STATEMENT_CACHE_MAX) {
|
|
24
|
+
const oldest = cache.keys().next().value;
|
|
25
|
+
if (oldest !== undefined) {
|
|
26
|
+
cache.delete(oldest);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
statement = db.prepare(sql);
|
|
30
|
+
cache.set(sql, statement);
|
|
31
|
+
}
|
|
32
|
+
return statement;
|
|
33
|
+
}
|
|
34
|
+
/** Maximum number of bound parameters per statement on each backend. */
|
|
35
|
+
const PARAMS_PER_STATEMENT = { postgres: 65535, sqlite: 32766 };
|
|
9
36
|
/**
|
|
10
37
|
* Injects the OTel logger instance used by no-telemetry DB operations.
|
|
11
38
|
* Must be called once at startup.
|
|
@@ -17,15 +44,43 @@ function DbUtilsNoTelemetrySetLogger(loggerIn) {
|
|
|
17
44
|
* Execute a multi-row INSERT with a flat parameter array.
|
|
18
45
|
* Builds: INSERT INTO <tableCols> VALUES (?,?...),(?,?...),...
|
|
19
46
|
*
|
|
20
|
-
*
|
|
47
|
+
* Large inputs are chunked so the statement never exceeds the backend's
|
|
48
|
+
* bound-parameter limit (65535 on Postgres, 32766 on SQLite).
|
|
49
|
+
*
|
|
50
|
+
* @returns Number of rows inserted (summed across chunks).
|
|
21
51
|
*/
|
|
22
52
|
function DbUtilsNoTelemetryBatchInsert(tableCols, numCols, rows) {
|
|
23
53
|
if (rows.length === 0)
|
|
24
54
|
return 0;
|
|
55
|
+
const dbType = (0, DbUtils_1.DbUtilsGetType)();
|
|
56
|
+
const maxRowsPerChunk = Math.max(1, Math.floor(PARAMS_PER_STATEMENT[dbType] / Math.max(1, numCols)));
|
|
57
|
+
if (rows.length <= maxRowsPerChunk) {
|
|
58
|
+
return DbUtilsNoTelemetryExecSQL(buildBatchInsertSQL(tableCols, numCols, rows.length), rows.flat());
|
|
59
|
+
}
|
|
60
|
+
const chunks = [];
|
|
61
|
+
for (let i = 0; i < rows.length; i += maxRowsPerChunk) {
|
|
62
|
+
chunks.push(rows.slice(i, i + maxRowsPerChunk));
|
|
63
|
+
}
|
|
64
|
+
if (dbType === "postgres") {
|
|
65
|
+
return execChunksSequentially(chunks, tableCols, numCols);
|
|
66
|
+
}
|
|
67
|
+
let total = 0;
|
|
68
|
+
for (const chunk of chunks) {
|
|
69
|
+
total += DbUtilsNoTelemetryExecSQL(buildBatchInsertSQL(tableCols, numCols, chunk.length), chunk.flat());
|
|
70
|
+
}
|
|
71
|
+
return total;
|
|
72
|
+
}
|
|
73
|
+
function buildBatchInsertSQL(tableCols, numCols, rowCount) {
|
|
25
74
|
const rowSQL = `(${Array.from({ length: numCols }, () => "?").join(",")})`;
|
|
26
|
-
const multiValues = Array.from({ length:
|
|
27
|
-
|
|
28
|
-
|
|
75
|
+
const multiValues = Array.from({ length: rowCount }, () => rowSQL).join(",");
|
|
76
|
+
return `INSERT ${tableCols} VALUES ${multiValues}`;
|
|
77
|
+
}
|
|
78
|
+
async function execChunksSequentially(chunks, tableCols, numCols) {
|
|
79
|
+
let total = 0;
|
|
80
|
+
for (const chunk of chunks) {
|
|
81
|
+
total += (await DbUtilsNoTelemetryExecSQL(buildBatchInsertSQL(tableCols, numCols, chunk.length), chunk.flat()));
|
|
82
|
+
}
|
|
83
|
+
return total;
|
|
29
84
|
}
|
|
30
85
|
/**
|
|
31
86
|
* Execute a write SQL statement **without** creating an OTel span.
|
|
@@ -50,7 +105,8 @@ function DbUtilsNoTelemetryExecSQL(sql, params = []) {
|
|
|
50
105
|
});
|
|
51
106
|
}
|
|
52
107
|
// SQLite (better-sqlite3) – synchronous
|
|
53
|
-
const
|
|
108
|
+
const db = (0, DbUtils_1.DbUtilsGetDatabase)();
|
|
109
|
+
const stmt = prepareCached(db, sql);
|
|
54
110
|
const result = stmt.run(params);
|
|
55
111
|
return result.changes;
|
|
56
112
|
}
|
|
@@ -80,6 +136,6 @@ function DbUtilsNoTelemetryQuerySQL(sql, params = [], debug = false) {
|
|
|
80
136
|
});
|
|
81
137
|
}
|
|
82
138
|
// SQLite (better-sqlite3) – synchronous
|
|
83
|
-
const stmt = (0, DbUtils_1.DbUtilsGetDatabase)()
|
|
139
|
+
const stmt = prepareCached((0, DbUtils_1.DbUtilsGetDatabase)(), sql);
|
|
84
140
|
return stmt.all(params);
|
|
85
141
|
}
|
|
@@ -10,7 +10,24 @@ export interface PostgresDbConfig {
|
|
|
10
10
|
DATABASE_POSTGRES_USER: string;
|
|
11
11
|
DATABASE_POSTGRES_PASSWORD: string;
|
|
12
12
|
DATABASE_POSTGRES_DATABASE: string;
|
|
13
|
+
/**
|
|
14
|
+
* Optional per-session `statement_timeout` (milliseconds) applied to every
|
|
15
|
+
* pool. Disabled when absent or 0 (backward-compatible default).
|
|
16
|
+
*/
|
|
17
|
+
DATABASE_POSTGRES_STATEMENT_TIMEOUT_MS?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Optional per-session `idle_in_transaction_session_timeout` (milliseconds)
|
|
20
|
+
* applied to every pool. Disabled when absent or 0.
|
|
21
|
+
*/
|
|
22
|
+
DATABASE_POSTGRES_IDLE_IN_TRANSACTION_TIMEOUT_MS?: number;
|
|
13
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Named advisory-lock purposes. Each name maps to a fixed 32-bit key (the
|
|
26
|
+
* first four ASCII characters of the purpose) so that every replica of every
|
|
27
|
+
* service booting against the same database serialises the same operation.
|
|
28
|
+
*/
|
|
29
|
+
export type PostgresLockName = "migration" | "auth_token" | "users_bootstrap";
|
|
30
|
+
export declare const POSTGRES_LOCK_KEYS: Record<PostgresLockName, number>;
|
|
14
31
|
/**
|
|
15
32
|
* Class-based PostgreSQL utility that manages a schema-specific pool (used
|
|
16
33
|
* during migrations) and an optional shared runtime pool (used for
|
|
@@ -45,7 +62,10 @@ export declare class PostgresSchemaDbUtils {
|
|
|
45
62
|
* @returns Number of rows changed.
|
|
46
63
|
*/
|
|
47
64
|
execSQL(context: Span, sql: string, params?: any[], useSchemaPool?: boolean): Promise<number>;
|
|
48
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Execute an entire SQL file (used for migrations).
|
|
67
|
+
* Migration files must not contain their own transaction control statements.
|
|
68
|
+
*/
|
|
49
69
|
execSQLFile(context: Span, filename: string, useSchemaPool?: boolean): Promise<void>;
|
|
50
70
|
/**
|
|
51
71
|
* Execute a read SQL query with OTel tracing.
|
|
@@ -58,9 +78,6 @@ export declare class PostgresSchemaDbUtils {
|
|
|
58
78
|
transaction(context: Span, callback: (client: any) => Promise<void>, useSchemaPool?: boolean): Promise<void>;
|
|
59
79
|
/** Close both the schema pool and the runtime pool. */
|
|
60
80
|
closeAll(): Promise<void>;
|
|
61
|
-
private execSQLForSchema;
|
|
62
|
-
private execSQLFileForSchema;
|
|
63
|
-
private querySQLForSchema;
|
|
64
81
|
}
|
|
65
82
|
/**
|
|
66
83
|
* Injects the OTel tracer and logger instances used by all Postgres operations.
|
|
@@ -70,23 +87,37 @@ export declare function PostgresDbUtilsSetOTel(tracerIn: StandardTracer, loggerI
|
|
|
70
87
|
/**
|
|
71
88
|
* Creates the Postgres connection pool and applies pending migration files
|
|
72
89
|
* from `sqlDir`.
|
|
90
|
+
*
|
|
91
|
+
* Migrations are applied under a session-level advisory lock (concurrently
|
|
92
|
+
* booting replicas serialise instead of double-applying) and each file plus
|
|
93
|
+
* its `db_version` row runs in its own transaction: a failing migration is
|
|
94
|
+
* rolled back and never recorded.
|
|
73
95
|
*/
|
|
74
96
|
export declare function PostgresDbUtilsInit(context: Span, config: PostgresDbConfig, sqlDir: string): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Run a callback while holding a Postgres advisory lock, serialising the
|
|
99
|
+
* callback across every replica of every service booting against the same
|
|
100
|
+
* database (used for the `auth_token` and first-user bootstrap races).
|
|
101
|
+
*/
|
|
102
|
+
export declare function PostgresDbUtilsWithAdvisoryLock<T>(lock: PostgresLockName, callback: () => Promise<T>): Promise<T>;
|
|
75
103
|
/** Returns the underlying `pg.Pool` instance. */
|
|
76
104
|
export declare function PostgresDbUtilsGetPool(): Pool;
|
|
77
105
|
/**
|
|
78
106
|
* Execute a write SQL statement with OTel tracing.
|
|
79
107
|
* @returns Number of rows changed.
|
|
80
108
|
*/
|
|
81
|
-
export declare function PostgresDbUtilsExecSQL(context: Span, sql: string, params?: unknown[]): Promise<number>;
|
|
82
|
-
/**
|
|
83
|
-
|
|
109
|
+
export declare function PostgresDbUtilsExecSQL(context: Span | undefined, sql: string, params?: unknown[]): Promise<number>;
|
|
110
|
+
/**
|
|
111
|
+
* Execute an entire SQL file (used for migrations).
|
|
112
|
+
* Migration files must not contain their own transaction control statements.
|
|
113
|
+
*/
|
|
114
|
+
export declare function PostgresDbUtilsExecSQLFile(context: Span | undefined, filename: string): Promise<void>;
|
|
84
115
|
/**
|
|
85
116
|
* Execute a read SQL query with OTel tracing.
|
|
86
117
|
* @returns Array of row objects.
|
|
87
118
|
*/
|
|
88
|
-
export declare function PostgresDbUtilsQuerySQL(context: Span, sql: string, params?: unknown[], debug?: boolean): Promise<any[]>;
|
|
119
|
+
export declare function PostgresDbUtilsQuerySQL(context: Span | undefined, sql: string, params?: unknown[], debug?: boolean): Promise<any[]>;
|
|
89
120
|
/** Start a transaction. */
|
|
90
|
-
export declare function PostgresDbUtilsTransactionStart(context: Span): Promise<void>;
|
|
121
|
+
export declare function PostgresDbUtilsTransactionStart(context: Span | undefined): Promise<void>;
|
|
91
122
|
/** Commit a transaction. */
|
|
92
|
-
export declare function PostgresDbUtilsTransactionCommit(context: Span): Promise<void>;
|
|
123
|
+
export declare function PostgresDbUtilsTransactionCommit(context: Span | undefined): Promise<void>;
|