@kici-dev/shared 0.1.14 → 0.1.15
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 +13 -1
- package/dist/db-admin.d.ts +29 -0
- package/dist/db-admin.js +56 -5
- package/dist/db.d.ts +20 -1
- package/dist/db.js +34 -2
- package/dist/db.test.d.ts +2 -0
- package/dist/graceful-shutdown.d.ts +13 -1
- package/dist/graceful-shutdown.js +23 -9
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/s3-client.js +4 -1
- package/dist/s3-client.test.d.ts +2 -0
- package/package.json +11 -7
- package/sbom.spdx.json +15 -15
package/README.md
CHANGED
|
@@ -1 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
# @kici-dev/shared
|
|
2
|
+
|
|
3
|
+
Shared utilities for the KiCI CI/CD stack — logging, zx setup, crypto, telemetry, health and metrics routes. No business logic. Re-exports `@kici-dev/core`.
|
|
4
|
+
|
|
5
|
+
This is an internal support library — other `@kici-dev` packages depend on it; it is not meant to be installed directly.
|
|
6
|
+
|
|
7
|
+
Part of [KiCI](https://kici.dev) — CI/CD workflows as TypeScript code: author them with full language power, dry-run them locally, and run them on your own infrastructure.
|
|
8
|
+
|
|
9
|
+
## Links
|
|
10
|
+
|
|
11
|
+
- Documentation: <https://docs.kici.dev/architecture/overview/>
|
|
12
|
+
- Source: <https://github.com/kici-dev/kici-public/tree/main/packages/shared>
|
|
13
|
+
- License: Apache-2.0
|
package/dist/db-admin.d.ts
CHANGED
|
@@ -187,6 +187,7 @@ export interface SeedEnvironmentOpts {
|
|
|
187
187
|
waitTimerSeconds?: number | null;
|
|
188
188
|
holdExpirySeconds?: number | null;
|
|
189
189
|
minimumTrust?: string | null;
|
|
190
|
+
globPattern?: string | null;
|
|
190
191
|
}
|
|
191
192
|
export interface SeedEnvironmentResult {
|
|
192
193
|
envId: string;
|
|
@@ -198,6 +199,24 @@ export interface SeedEnvironmentResult {
|
|
|
198
199
|
* are JSON-serialised server-side; pass them as plain arrays or objects.
|
|
199
200
|
*/
|
|
200
201
|
export declare function seedEnvironmentDirect(databaseUrl: string, opts: SeedEnvironmentOpts): Promise<SeedEnvironmentResult>;
|
|
202
|
+
export interface DeleteEnvironmentOpts {
|
|
203
|
+
orgId: string;
|
|
204
|
+
name: string;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Delete an environment keyed by (org_id, name). Returns whether a row was
|
|
208
|
+
* removed. The `environment_bindings`, `environment_variables`, and
|
|
209
|
+
* `environment_source_overrides` children all carry
|
|
210
|
+
* `FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE CASCADE`,
|
|
211
|
+
* so a single DELETE on `environments` cascades to those children. The
|
|
212
|
+
* `held_runs` FK uses `ON DELETE SET NULL`, so terminal held-run history
|
|
213
|
+
* survives the delete with a null environment reference. Pending held runs
|
|
214
|
+
* still reference the environment, so this helper pre-checks their count and
|
|
215
|
+
* throws before issuing the DELETE — approve or reject them first.
|
|
216
|
+
*/
|
|
217
|
+
export declare function deleteEnvironmentDirect(databaseUrl: string, opts: DeleteEnvironmentOpts): Promise<{
|
|
218
|
+
deleted: boolean;
|
|
219
|
+
}>;
|
|
201
220
|
export interface SeedEnvironmentBindingOpts {
|
|
202
221
|
orgId: string;
|
|
203
222
|
envName: string;
|
|
@@ -219,6 +238,7 @@ export interface SetEnvironmentPolicyOpts {
|
|
|
219
238
|
holdExpirySeconds?: number | null;
|
|
220
239
|
minimumTrust?: string | null;
|
|
221
240
|
enabled?: boolean;
|
|
241
|
+
allowLocalExecution?: boolean;
|
|
222
242
|
}
|
|
223
243
|
/**
|
|
224
244
|
* UPDATE only the policy fields that were explicitly provided. Columns that
|
|
@@ -1462,5 +1482,14 @@ export declare function clearPeerCredentialsRevokedAtByIdsDirect(databaseUrl: st
|
|
|
1462
1482
|
export declare function countActivePeerCredentialsByInstanceDirect(databaseUrl: string, opts: {
|
|
1463
1483
|
instanceId: string;
|
|
1464
1484
|
}): Promise<number>;
|
|
1485
|
+
/**
|
|
1486
|
+
* Terminate every idle backend of the connecting user except our own
|
|
1487
|
+
* connection. Mirrors what a Postgres leader demotion does to idle pooled
|
|
1488
|
+
* connections — used by resilience tests to verify the pg pool error
|
|
1489
|
+
* handlers absorb the termination without a process restart.
|
|
1490
|
+
*
|
|
1491
|
+
* Returns the number of backends terminated.
|
|
1492
|
+
*/
|
|
1493
|
+
export declare function terminateIdleDbBackendsDirect(databaseUrl: string): Promise<number>;
|
|
1465
1494
|
export {};
|
|
1466
1495
|
//# sourceMappingURL=db-admin.d.ts.map
|
package/dist/db-admin.js
CHANGED
|
@@ -351,7 +351,8 @@ const ENV_POLICY_COLUMNS = new Set([
|
|
|
351
351
|
"wait_timer_seconds",
|
|
352
352
|
"hold_expiry_seconds",
|
|
353
353
|
"minimum_trust",
|
|
354
|
-
"enabled"
|
|
354
|
+
"enabled",
|
|
355
|
+
"allow_local_execution"
|
|
355
356
|
]);
|
|
356
357
|
/**
|
|
357
358
|
* Upsert an environment row keyed by (org_id, name). Returns the env id and
|
|
@@ -370,9 +371,9 @@ async function seedEnvironmentDirect(databaseUrl, opts) {
|
|
|
370
371
|
const reviewersJson = opts.requiredReviewers === void 0 ? null : JSON.stringify(opts.requiredReviewers);
|
|
371
372
|
const row = (await pool.query(`INSERT INTO environments
|
|
372
373
|
(org_id, name, type, enabled, branch_restrictions, required_reviewers,
|
|
373
|
-
wait_timer_seconds, hold_expiry_seconds, minimum_trust)
|
|
374
|
+
wait_timer_seconds, hold_expiry_seconds, minimum_trust, glob_pattern)
|
|
374
375
|
VALUES ($1, $2, COALESCE($3, 'fixed'), COALESCE($4, true), $5::jsonb, $6::jsonb,
|
|
375
|
-
$7, COALESCE($8, 86400), $9)
|
|
376
|
+
$7, COALESCE($8, 86400), $9, $10)
|
|
376
377
|
ON CONFLICT (org_id, name) DO UPDATE SET
|
|
377
378
|
type = COALESCE(EXCLUDED.type, environments.type),
|
|
378
379
|
enabled = EXCLUDED.enabled,
|
|
@@ -381,6 +382,7 @@ async function seedEnvironmentDirect(databaseUrl, opts) {
|
|
|
381
382
|
wait_timer_seconds = EXCLUDED.wait_timer_seconds,
|
|
382
383
|
hold_expiry_seconds = EXCLUDED.hold_expiry_seconds,
|
|
383
384
|
minimum_trust = EXCLUDED.minimum_trust,
|
|
385
|
+
glob_pattern = COALESCE(EXCLUDED.glob_pattern, environments.glob_pattern),
|
|
384
386
|
updated_at = now()
|
|
385
387
|
RETURNING id, (xmax = 0) AS inserted`, [
|
|
386
388
|
opts.orgId,
|
|
@@ -391,7 +393,8 @@ async function seedEnvironmentDirect(databaseUrl, opts) {
|
|
|
391
393
|
reviewersJson,
|
|
392
394
|
opts.waitTimerSeconds ?? null,
|
|
393
395
|
opts.holdExpirySeconds ?? null,
|
|
394
|
-
opts.minimumTrust ?? null
|
|
396
|
+
opts.minimumTrust ?? null,
|
|
397
|
+
opts.globPattern ?? null
|
|
395
398
|
])).rows[0];
|
|
396
399
|
if (!row) throw new Error(`environment: upsert returned no row for ${opts.name}`);
|
|
397
400
|
return {
|
|
@@ -403,6 +406,33 @@ async function seedEnvironmentDirect(databaseUrl, opts) {
|
|
|
403
406
|
}
|
|
404
407
|
}
|
|
405
408
|
/**
|
|
409
|
+
* Delete an environment keyed by (org_id, name). Returns whether a row was
|
|
410
|
+
* removed. The `environment_bindings`, `environment_variables`, and
|
|
411
|
+
* `environment_source_overrides` children all carry
|
|
412
|
+
* `FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE CASCADE`,
|
|
413
|
+
* so a single DELETE on `environments` cascades to those children. The
|
|
414
|
+
* `held_runs` FK uses `ON DELETE SET NULL`, so terminal held-run history
|
|
415
|
+
* survives the delete with a null environment reference. Pending held runs
|
|
416
|
+
* still reference the environment, so this helper pre-checks their count and
|
|
417
|
+
* throws before issuing the DELETE — approve or reject them first.
|
|
418
|
+
*/
|
|
419
|
+
async function deleteEnvironmentDirect(databaseUrl, opts) {
|
|
420
|
+
const pool = new pg.Pool({
|
|
421
|
+
connectionString: databaseUrl,
|
|
422
|
+
max: 1
|
|
423
|
+
});
|
|
424
|
+
try {
|
|
425
|
+
const pending = await pool.query(`SELECT count(*)::text AS count FROM held_runs hr
|
|
426
|
+
JOIN environments e ON e.id = hr.environment_id
|
|
427
|
+
WHERE e.org_id = $1 AND e.name = $2 AND hr.status = 'pending'`, [opts.orgId, opts.name]);
|
|
428
|
+
const pendingCount = Number(pending.rows[0]?.count ?? 0);
|
|
429
|
+
if (pendingCount > 0) throw new Error(`environment has ${pendingCount} pending held run(s) — approve or reject them first`);
|
|
430
|
+
return { deleted: (await pool.query(`DELETE FROM environments WHERE org_id = $1 AND name = $2 RETURNING id`, [opts.orgId, opts.name])).rows.length > 0 };
|
|
431
|
+
} finally {
|
|
432
|
+
await pool.end();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
406
436
|
* Upsert an `environment_bindings` row connecting `envName` to `scopePattern`.
|
|
407
437
|
* Throws if the environment does not exist.
|
|
408
438
|
*/
|
|
@@ -449,6 +479,7 @@ async function setEnvironmentPolicyDirect(databaseUrl, opts) {
|
|
|
449
479
|
if (opts.holdExpirySeconds !== void 0) addSet("hold_expiry_seconds", opts.holdExpirySeconds);
|
|
450
480
|
if (opts.minimumTrust !== void 0) addSet("minimum_trust", opts.minimumTrust);
|
|
451
481
|
if (opts.enabled !== void 0) addSet("enabled", opts.enabled);
|
|
482
|
+
if (opts.allowLocalExecution !== void 0) addSet("allow_local_execution", opts.allowLocalExecution);
|
|
452
483
|
if (setClauses.length === 0) throw new Error("environment: setEnvironmentPolicy requires at least one policy field");
|
|
453
484
|
const pool = new pg.Pool({
|
|
454
485
|
connectionString: databaseUrl,
|
|
@@ -2555,7 +2586,27 @@ async function countActivePeerCredentialsByInstanceDirect(databaseUrl, opts) {
|
|
|
2555
2586
|
await pool.end();
|
|
2556
2587
|
}
|
|
2557
2588
|
}
|
|
2589
|
+
/**
|
|
2590
|
+
* Terminate every idle backend of the connecting user except our own
|
|
2591
|
+
* connection. Mirrors what a Postgres leader demotion does to idle pooled
|
|
2592
|
+
* connections — used by resilience tests to verify the pg pool error
|
|
2593
|
+
* handlers absorb the termination without a process restart.
|
|
2594
|
+
*
|
|
2595
|
+
* Returns the number of backends terminated.
|
|
2596
|
+
*/
|
|
2597
|
+
async function terminateIdleDbBackendsDirect(databaseUrl) {
|
|
2598
|
+
const pool = createPool(databaseUrl);
|
|
2599
|
+
try {
|
|
2600
|
+
return (await pool.query(`SELECT pg_terminate_backend(pid)
|
|
2601
|
+
FROM pg_stat_activity
|
|
2602
|
+
WHERE pid <> pg_backend_pid()
|
|
2603
|
+
AND usename = current_user
|
|
2604
|
+
AND state = 'idle'`)).rowCount ?? 0;
|
|
2605
|
+
} finally {
|
|
2606
|
+
await pool.end();
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2558
2609
|
//#endregion
|
|
2559
|
-
export { MIGRATION_HASH_TABLE, PROVIDER_HASH_KEY, REGISTERABLE_TRIGGER_TYPES, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect, createDbRole, createEnvironmentTemplateDirect, createJoinTokenDirect, createReadOnlyDbUser, deleteCronLastFiredDirect, deleteCrossRepoTrustDirect, deleteExecutionRunsByWorkflowNameDirect, deleteGenericWebhookSourcesByNameDirect, deleteKiciEventsDirect, deleteOrgSettingsByCustomerIdDirect, deletePeerCredentialsByInstanceIdLikeDirect, deleteWorkflowRegistrationsDirect, describeTableColumnsDirect, dropAndCreateDatabase, dropDatabaseDirect, emitKiciEventDirect, ensureDatabase, ensureOrgOwnerMemberDirect, findAnyUserApiKeyIdDirect, getExecutionRunSecurityDirect, getGenericWebhookSourceByRoutingKeyDirect, getHeldRunByIdDirect, getPeerCredentialRevokedAtDirect, getRegistryVersionDirect, getWebhookSourceByRoutingKeyDirect, getWorkflowRegistrationByIdDirect, insertCronLastFiredNowDirect, insertCrossRepoTrustStrictDirect, insertKiciEventRawDirect, insertPeerCredentialExpiredDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, isSchemaCurrent, isSchemaCurrentFromFilesDirect, latestExecutionRunByStatusDirect, listActiveGenericWebhookSourcesDirect, listActivePeerCredentialsExcludingDirect, listCrossRepoTrustBySourceRoutingKeyDirect, listEnvironmentsDirect, listExecutionJobsDirect, listExecutionRunsDirect, listKiciEventsDirect, listQueueDirect, listRegistrationsByRoutingKeyDirect, listRegistrationsDirect, maskDatabaseUrl, parseDatabaseUrl, platformConnectionExistsDirect, pollKiciEventsDirect, prunePeerCredentialsDirect, purgeScopedSecretsDirect, purgeSecretBackendsDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, readStoredMigrationContentHash, registerWorkflowManualDirect, resetRaftStateDirect, resolvePlatformWebhookSourceRoutingKeyDirect, restoreSoftDeletedGenericWebhookSourceDirect, seedApiKeyInlineDirect, seedCiSecurityFixturesDirect, seedCrossRepoTrustDirect, seedEnvironmentBindingDirect, seedEnvironmentDirect, seedGenericWebhookSourceDirect, seedSourcePrivateKeyDirect, seedSyntheticGithubSourceDirect, seedUniversalGitSourceDirect, seedWebhookSecretDirect, setEnvironmentPolicyDirect, setEnvironmentSecretDirect, showEnvironmentDirect, showExecutionRunDirect, showKiciEventDirect, showQueueEntryDirect, showRegistrationDirect, storeMigrationContentHash, storeMigrationContentHashInTableDirect, tableExistsDirect, updateGenericWebhookVerificationConfigDirect, updateOrgSettingsDeniedReposDirect, updateSourceRoutingKeyDirect, updateWorkflowRegistrationCommitShaDirect, upsertCronLastFiredDirect, upsertOrgSettingsGlobalWorkflowsDirect, verifyKiciEventNotifyDirect, waitForEventLogRowByDeliveryIdDirect, waitForExecutionRunStatusSinceDirect, waitForLatestExecutionJobStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformRegistrationsDirect, waitForPostgresDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, waitForRunCompletionDirect };
|
|
2610
|
+
export { MIGRATION_HASH_TABLE, PROVIDER_HASH_KEY, REGISTERABLE_TRIGGER_TYPES, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect, createDbRole, createEnvironmentTemplateDirect, createJoinTokenDirect, createReadOnlyDbUser, deleteCronLastFiredDirect, deleteCrossRepoTrustDirect, deleteEnvironmentDirect, deleteExecutionRunsByWorkflowNameDirect, deleteGenericWebhookSourcesByNameDirect, deleteKiciEventsDirect, deleteOrgSettingsByCustomerIdDirect, deletePeerCredentialsByInstanceIdLikeDirect, deleteWorkflowRegistrationsDirect, describeTableColumnsDirect, dropAndCreateDatabase, dropDatabaseDirect, emitKiciEventDirect, ensureDatabase, ensureOrgOwnerMemberDirect, findAnyUserApiKeyIdDirect, getExecutionRunSecurityDirect, getGenericWebhookSourceByRoutingKeyDirect, getHeldRunByIdDirect, getPeerCredentialRevokedAtDirect, getRegistryVersionDirect, getWebhookSourceByRoutingKeyDirect, getWorkflowRegistrationByIdDirect, insertCronLastFiredNowDirect, insertCrossRepoTrustStrictDirect, insertKiciEventRawDirect, insertPeerCredentialExpiredDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, isSchemaCurrent, isSchemaCurrentFromFilesDirect, latestExecutionRunByStatusDirect, listActiveGenericWebhookSourcesDirect, listActivePeerCredentialsExcludingDirect, listCrossRepoTrustBySourceRoutingKeyDirect, listEnvironmentsDirect, listExecutionJobsDirect, listExecutionRunsDirect, listKiciEventsDirect, listQueueDirect, listRegistrationsByRoutingKeyDirect, listRegistrationsDirect, maskDatabaseUrl, parseDatabaseUrl, platformConnectionExistsDirect, pollKiciEventsDirect, prunePeerCredentialsDirect, purgeScopedSecretsDirect, purgeSecretBackendsDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, readStoredMigrationContentHash, registerWorkflowManualDirect, resetRaftStateDirect, resolvePlatformWebhookSourceRoutingKeyDirect, restoreSoftDeletedGenericWebhookSourceDirect, seedApiKeyInlineDirect, seedCiSecurityFixturesDirect, seedCrossRepoTrustDirect, seedEnvironmentBindingDirect, seedEnvironmentDirect, seedGenericWebhookSourceDirect, seedSourcePrivateKeyDirect, seedSyntheticGithubSourceDirect, seedUniversalGitSourceDirect, seedWebhookSecretDirect, setEnvironmentPolicyDirect, setEnvironmentSecretDirect, showEnvironmentDirect, showExecutionRunDirect, showKiciEventDirect, showQueueEntryDirect, showRegistrationDirect, storeMigrationContentHash, storeMigrationContentHashInTableDirect, tableExistsDirect, terminateIdleDbBackendsDirect, updateGenericWebhookVerificationConfigDirect, updateOrgSettingsDeniedReposDirect, updateSourceRoutingKeyDirect, updateWorkflowRegistrationCommitShaDirect, upsertCronLastFiredDirect, upsertOrgSettingsGlobalWorkflowsDirect, verifyKiciEventNotifyDirect, waitForEventLogRowByDeliveryIdDirect, waitForExecutionRunStatusSinceDirect, waitForLatestExecutionJobStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformRegistrationsDirect, waitForPostgresDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, waitForRunCompletionDirect };
|
|
2560
2611
|
|
|
2561
2612
|
//# sourceMappingURL=db-admin.js.map
|
package/dist/db.d.ts
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
import pg from 'pg';
|
|
2
2
|
import { Kysely } from 'kysely';
|
|
3
|
+
/** Where a pg connection error surfaced. */
|
|
4
|
+
export type PgPoolErrorSource = 'idle-pool' | 'client';
|
|
5
|
+
export interface CreatePoolOptions {
|
|
6
|
+
/** Extra pg.Pool config merged over the connection string (e.g. max, connectionTimeoutMillis). */
|
|
7
|
+
config?: Omit<pg.PoolConfig, 'connectionString'>;
|
|
8
|
+
/**
|
|
9
|
+
* Optional hook invoked after the built-in log line on every absorbed
|
|
10
|
+
* connection error (e.g. to increment a metrics counter). Additive — it
|
|
11
|
+
* never replaces the log.
|
|
12
|
+
*/
|
|
13
|
+
onError?: (err: Error, source: PgPoolErrorSource) => void;
|
|
14
|
+
}
|
|
3
15
|
/**
|
|
4
16
|
* Create PostgreSQL connection pool.
|
|
17
|
+
*
|
|
18
|
+
* Always attaches error handlers for both idle pooled clients (the pool's
|
|
19
|
+
* own 'error' event) and checked-out clients (per-client 'error' via the
|
|
20
|
+
* 'connect' hook). Without them, a terminated backend — e.g. a Postgres
|
|
21
|
+
* leader switchover — escalates to an uncaughtException and a full process
|
|
22
|
+
* restart. The broken connection is logged and discarded; pg replaces it on
|
|
23
|
+
* the next acquire. In-flight query failures still reject to their callers.
|
|
5
24
|
*/
|
|
6
|
-
export declare function createPool(databaseUrl: string): pg.Pool;
|
|
25
|
+
export declare function createPool(databaseUrl: string, options?: CreatePoolOptions): pg.Pool;
|
|
7
26
|
/**
|
|
8
27
|
* Create Kysely database instance (PostgreSQL only).
|
|
9
28
|
*
|
package/dist/db.js
CHANGED
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
import "./chunk-gOLHoazu.js";
|
|
2
2
|
import pg from "pg";
|
|
3
3
|
import { Kysely, PostgresDialect } from "kysely";
|
|
4
|
+
import { createLogger } from "@kici-dev/core";
|
|
4
5
|
//#region src/db.ts
|
|
6
|
+
let poolLogger;
|
|
7
|
+
function getPoolLogger() {
|
|
8
|
+
poolLogger ??= createLogger({ prefix: "pg-pool" });
|
|
9
|
+
return poolLogger;
|
|
10
|
+
}
|
|
5
11
|
/**
|
|
6
12
|
* Create PostgreSQL connection pool.
|
|
13
|
+
*
|
|
14
|
+
* Always attaches error handlers for both idle pooled clients (the pool's
|
|
15
|
+
* own 'error' event) and checked-out clients (per-client 'error' via the
|
|
16
|
+
* 'connect' hook). Without them, a terminated backend — e.g. a Postgres
|
|
17
|
+
* leader switchover — escalates to an uncaughtException and a full process
|
|
18
|
+
* restart. The broken connection is logged and discarded; pg replaces it on
|
|
19
|
+
* the next acquire. In-flight query failures still reject to their callers.
|
|
7
20
|
*/
|
|
8
|
-
function createPool(databaseUrl) {
|
|
9
|
-
|
|
21
|
+
function createPool(databaseUrl, options) {
|
|
22
|
+
const pool = new pg.Pool({
|
|
23
|
+
connectionString: databaseUrl,
|
|
24
|
+
...options?.config
|
|
25
|
+
});
|
|
26
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
27
|
+
const handle = (err, source) => {
|
|
28
|
+
if (seen.has(err)) return;
|
|
29
|
+
seen.add(err);
|
|
30
|
+
getPoolLogger().warn("Discarded broken pg connection", {
|
|
31
|
+
source,
|
|
32
|
+
error: err.message,
|
|
33
|
+
stack: err.stack
|
|
34
|
+
});
|
|
35
|
+
options?.onError?.(err, source);
|
|
36
|
+
};
|
|
37
|
+
pool.on("error", (err) => handle(err, "idle-pool"));
|
|
38
|
+
pool.on("connect", (client) => {
|
|
39
|
+
client.on("error", (err) => handle(err, "client"));
|
|
40
|
+
});
|
|
41
|
+
return pool;
|
|
10
42
|
}
|
|
11
43
|
/**
|
|
12
44
|
* Create Kysely database instance (PostgreSQL only).
|
|
@@ -50,9 +50,21 @@ export interface ShutdownHandle {
|
|
|
50
50
|
/**
|
|
51
51
|
* Wire up SIGTERM / SIGINT (and optionally uncaughtException /
|
|
52
52
|
* unhandledRejection) handlers that execute the provided teardown
|
|
53
|
-
* steps sequentially, then
|
|
53
|
+
* steps sequentially, then exit.
|
|
54
|
+
*
|
|
55
|
+
* Exit codes: signal-triggered and programmatic shutdowns exit 0;
|
|
56
|
+
* shutdowns triggered by uncaughtException / unhandledRejection exit 1 so
|
|
57
|
+
* `Restart=on-failure`-style supervisor policies and exit-code alerting
|
|
58
|
+
* see the fatal cause. Escalation is sticky — a fatal trigger arriving
|
|
59
|
+
* while a clean shutdown is already in progress still raises the final
|
|
60
|
+
* exit code to 1.
|
|
54
61
|
*
|
|
55
62
|
* A force-exit timer ensures the process terminates even if a step hangs.
|
|
63
|
+
* The force-exit honors the same sticky exit code as a clean completion: a
|
|
64
|
+
* slow SIGTERM/SIGINT stop that merely overran the grace period still exits 0,
|
|
65
|
+
* so systemd records an intentional stop rather than marking the unit `failed`
|
|
66
|
+
* (which would break `systemctl restart` recovery). Only a fatal trigger
|
|
67
|
+
* (uncaughtException / unhandledRejection) raises the force-exit code to 1.
|
|
56
68
|
*/
|
|
57
69
|
export declare function setupGracefulShutdown(options: GracefulShutdownOptions): ShutdownHandle;
|
|
58
70
|
//# sourceMappingURL=graceful-shutdown.d.ts.map
|
|
@@ -4,14 +4,28 @@ import { toErrorMessage } from "@kici-dev/core";
|
|
|
4
4
|
/**
|
|
5
5
|
* Wire up SIGTERM / SIGINT (and optionally uncaughtException /
|
|
6
6
|
* unhandledRejection) handlers that execute the provided teardown
|
|
7
|
-
* steps sequentially, then
|
|
7
|
+
* steps sequentially, then exit.
|
|
8
|
+
*
|
|
9
|
+
* Exit codes: signal-triggered and programmatic shutdowns exit 0;
|
|
10
|
+
* shutdowns triggered by uncaughtException / unhandledRejection exit 1 so
|
|
11
|
+
* `Restart=on-failure`-style supervisor policies and exit-code alerting
|
|
12
|
+
* see the fatal cause. Escalation is sticky — a fatal trigger arriving
|
|
13
|
+
* while a clean shutdown is already in progress still raises the final
|
|
14
|
+
* exit code to 1.
|
|
8
15
|
*
|
|
9
16
|
* A force-exit timer ensures the process terminates even if a step hangs.
|
|
17
|
+
* The force-exit honors the same sticky exit code as a clean completion: a
|
|
18
|
+
* slow SIGTERM/SIGINT stop that merely overran the grace period still exits 0,
|
|
19
|
+
* so systemd records an intentional stop rather than marking the unit `failed`
|
|
20
|
+
* (which would break `systemctl restart` recovery). Only a fatal trigger
|
|
21
|
+
* (uncaughtException / unhandledRejection) raises the force-exit code to 1.
|
|
10
22
|
*/
|
|
11
23
|
function setupGracefulShutdown(options) {
|
|
12
24
|
const { logger, steps, timeoutMs = 3e4, onForceExit, skipErrorHandlers = false } = options;
|
|
13
25
|
let isShuttingDown = false;
|
|
14
|
-
|
|
26
|
+
let exitCode = 0;
|
|
27
|
+
async function gracefulShutdown(signal, code = 0) {
|
|
28
|
+
exitCode = Math.max(exitCode, code);
|
|
15
29
|
if (isShuttingDown) {
|
|
16
30
|
logger.warn("Shutdown already in progress, ignoring signal", { signal });
|
|
17
31
|
return;
|
|
@@ -19,8 +33,8 @@ function setupGracefulShutdown(options) {
|
|
|
19
33
|
isShuttingDown = true;
|
|
20
34
|
logger.info(`Received ${signal}, starting graceful shutdown...`);
|
|
21
35
|
const forceExitTimeout = setTimeout(() => {
|
|
22
|
-
logger.error(`Graceful shutdown timed out after ${timeoutMs / 1e3}s, forcing exit
|
|
23
|
-
if (onForceExit?.() !== true) process.exit(
|
|
36
|
+
logger.error(`Graceful shutdown timed out after ${timeoutMs / 1e3}s, forcing exit`, { exitCode });
|
|
37
|
+
if (onForceExit?.() !== true) process.exit(exitCode);
|
|
24
38
|
}, timeoutMs);
|
|
25
39
|
try {
|
|
26
40
|
for (const step of steps) try {
|
|
@@ -34,8 +48,8 @@ function setupGracefulShutdown(options) {
|
|
|
34
48
|
});
|
|
35
49
|
}
|
|
36
50
|
clearTimeout(forceExitTimeout);
|
|
37
|
-
logger.info("Graceful shutdown complete");
|
|
38
|
-
process.exit(
|
|
51
|
+
logger.info("Graceful shutdown complete", { exitCode });
|
|
52
|
+
process.exit(exitCode);
|
|
39
53
|
} catch (error) {
|
|
40
54
|
logger.error("Error during graceful shutdown", {
|
|
41
55
|
error: toErrorMessage(error),
|
|
@@ -53,17 +67,17 @@ function setupGracefulShutdown(options) {
|
|
|
53
67
|
error: error.message,
|
|
54
68
|
stack: error.stack
|
|
55
69
|
});
|
|
56
|
-
gracefulShutdown("uncaughtException");
|
|
70
|
+
gracefulShutdown("uncaughtException", 1);
|
|
57
71
|
});
|
|
58
72
|
process.on("unhandledRejection", (reason) => {
|
|
59
73
|
logger.error("Unhandled rejection", {
|
|
60
74
|
reason: toErrorMessage(reason),
|
|
61
75
|
stack: reason instanceof Error ? reason.stack : void 0
|
|
62
76
|
});
|
|
63
|
-
gracefulShutdown("unhandledRejection");
|
|
77
|
+
gracefulShutdown("unhandledRejection", 1);
|
|
64
78
|
});
|
|
65
79
|
}
|
|
66
|
-
return { shutdown: gracefulShutdown };
|
|
80
|
+
return { shutdown: (signal) => gracefulShutdown(signal) };
|
|
67
81
|
}
|
|
68
82
|
//#endregion
|
|
69
83
|
export { setupGracefulShutdown };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from '@kici-dev/core';
|
|
2
2
|
export { RingBuffer } from './ring-buffer.js';
|
|
3
|
-
export { createPool, createDb } from './db.js';
|
|
4
|
-
export { parseDatabaseUrl, maskDatabaseUrl, dropAndCreateDatabase, dropDatabaseDirect, ensureDatabase, type EnsureDatabaseOpts, createDbRole, createReadOnlyDbUser, computeMigrationsHash, storeMigrationContentHash, readStoredMigrationContentHash, isSchemaCurrent, clearDispatchQueueDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, purgeScopedSecretsDirect, seedEnvironmentDirect, seedEnvironmentBindingDirect, setEnvironmentPolicyDirect, listEnvironmentsDirect, showEnvironmentDirect, createEnvironmentTemplateDirect, setEnvironmentSecretDirect, listQueueDirect, showQueueEntryDirect, listExecutionRunsDirect, showExecutionRunDirect, listExecutionJobsDirect, listRegistrationsDirect, showRegistrationDirect, registerWorkflowManualDirect, resetRaftStateDirect, emitKiciEventDirect, seedGenericWebhookSourceDirect, purgeSecretBackendsDirect, apiKeyExistsDirect, seedApiKeyInlineDirect, platformConnectionExistsDirect, countWebhookSourcesByConnectionIdDirect, getWebhookSourceByRoutingKeyDirect, findAnyUserApiKeyIdDirect, seedSyntheticGithubSourceDirect, seedWebhookSecretDirect, seedSourcePrivateKeyDirect, bumpRegistryVersionDirect, pollKiciEventsDirect, waitForPostgresDirect, waitForRunCompletionDirect, cleanupExecutionRowsDirect, isSchemaCurrentFromFilesDirect, storeMigrationContentHashInTableDirect, createJoinTokenDirect, updateSourceRoutingKeyDirect, prunePeerCredentialsDirect, waitForPlatformRegistrationsDirect, seedUniversalGitSourceDirect, seedCiSecurityFixturesDirect, waitForExecutionRunStatusSinceDirect, latestExecutionRunByStatusDirect, waitForLatestExecutionJobStatusDirect, describeTableColumnsDirect, tableExistsDirect, insertKiciEventRawDirect, showKiciEventDirect, listKiciEventsDirect, deleteKiciEventsDirect, verifyKiciEventNotifyDirect, seedCrossRepoTrustDirect, listCrossRepoTrustBySourceRoutingKeyDirect, deleteCrossRepoTrustDirect, insertCrossRepoTrustStrictDirect, deleteWorkflowRegistrationsDirect, getWorkflowRegistrationByIdDirect, listRegistrationsByRoutingKeyDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, updateWorkflowRegistrationCommitShaDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, getRegistryVersionDirect, bumpRegistryVersionSimpleDirect, upsertCronLastFiredDirect, countCronLastFiredDirect, insertCronLastFiredNowDirect, deleteCronLastFiredDirect, deleteExecutionRunsByWorkflowNameDirect, getGenericWebhookSourceByRoutingKeyDirect, listActiveGenericWebhookSourcesDirect, updateGenericWebhookVerificationConfigDirect, deleteGenericWebhookSourcesByNameDirect, restoreSoftDeletedGenericWebhookSourceDirect, upsertOrgSettingsGlobalWorkflowsDirect, updateOrgSettingsDeniedReposDirect, deleteOrgSettingsByCustomerIdDirect, getExecutionRunSecurityDirect, getHeldRunByIdDirect, countHeldRunsByRunIdDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForEventLogRowByDeliveryIdDirect, resolvePlatformWebhookSourceRoutingKeyDirect, ensureOrgOwnerMemberDirect, deletePeerCredentialsByInstanceIdLikeDirect, insertPeerCredentialExpiredDirect, getPeerCredentialRevokedAtDirect, listActivePeerCredentialsExcludingDirect, clearPeerCredentialsRevokedAtByIdsDirect, countActivePeerCredentialsByInstanceDirect, type ColumnInfo, type KiciEventRow, type CrossRepoTrustRow, type WorkflowRegistrationFullRow, type RegistrationsScopedResult, type LatestExecutionRunResult, type WaitForLatestJobResult, type ExecutionRunSecurityRow, type HeldRunSecurityRow, type EventLogRow as PlatformEventLogRow, type UpsertOrgSettingsOpts, type OrgSettingsRepoPatternEntry, type InsertKiciEventRawOpts, type EmitKiciEventOpts, type SeedGenericWebhookSourceOpts, REGISTERABLE_TRIGGER_TYPES, MIGRATION_HASH_TABLE, type PurgeStaleExecutionResult, type PurgeStaleSourcesResult, type SeedEnvironmentOpts, type SeedEnvironmentResult, type SeedEnvironmentBindingOpts, type SetEnvironmentPolicyOpts, type EnvironmentRow, type EnvironmentVariableRow, type EnvironmentBindingRow, type ShowEnvironmentResult, type CreateEnvironmentTemplateOpts, type SetEnvironmentSecretOpts, type DispatchQueueRow, type ListQueueOpts, type ExecutionRunRow, type ExecutionJobRow, type ListExecutionRunsOpts, type WorkflowRegistrationRow, type ListRegistrationsOpts, type ListRegistrationsResult, type ShowRegistrationResult, type RegisterWorkflowManualOpts, type RegisterWorkflowManualResult, } from './db-admin.js';
|
|
3
|
+
export { createPool, createDb, type CreatePoolOptions, type PgPoolErrorSource } from './db.js';
|
|
4
|
+
export { parseDatabaseUrl, maskDatabaseUrl, dropAndCreateDatabase, dropDatabaseDirect, ensureDatabase, type EnsureDatabaseOpts, createDbRole, createReadOnlyDbUser, computeMigrationsHash, storeMigrationContentHash, readStoredMigrationContentHash, isSchemaCurrent, clearDispatchQueueDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, purgeScopedSecretsDirect, seedEnvironmentDirect, deleteEnvironmentDirect, seedEnvironmentBindingDirect, setEnvironmentPolicyDirect, listEnvironmentsDirect, showEnvironmentDirect, createEnvironmentTemplateDirect, setEnvironmentSecretDirect, listQueueDirect, showQueueEntryDirect, listExecutionRunsDirect, showExecutionRunDirect, listExecutionJobsDirect, listRegistrationsDirect, showRegistrationDirect, registerWorkflowManualDirect, resetRaftStateDirect, emitKiciEventDirect, seedGenericWebhookSourceDirect, purgeSecretBackendsDirect, apiKeyExistsDirect, seedApiKeyInlineDirect, platformConnectionExistsDirect, countWebhookSourcesByConnectionIdDirect, getWebhookSourceByRoutingKeyDirect, findAnyUserApiKeyIdDirect, seedSyntheticGithubSourceDirect, seedWebhookSecretDirect, seedSourcePrivateKeyDirect, bumpRegistryVersionDirect, pollKiciEventsDirect, waitForPostgresDirect, waitForRunCompletionDirect, cleanupExecutionRowsDirect, isSchemaCurrentFromFilesDirect, storeMigrationContentHashInTableDirect, createJoinTokenDirect, updateSourceRoutingKeyDirect, prunePeerCredentialsDirect, waitForPlatformRegistrationsDirect, seedUniversalGitSourceDirect, seedCiSecurityFixturesDirect, waitForExecutionRunStatusSinceDirect, latestExecutionRunByStatusDirect, waitForLatestExecutionJobStatusDirect, describeTableColumnsDirect, tableExistsDirect, insertKiciEventRawDirect, showKiciEventDirect, listKiciEventsDirect, deleteKiciEventsDirect, verifyKiciEventNotifyDirect, seedCrossRepoTrustDirect, listCrossRepoTrustBySourceRoutingKeyDirect, deleteCrossRepoTrustDirect, insertCrossRepoTrustStrictDirect, deleteWorkflowRegistrationsDirect, getWorkflowRegistrationByIdDirect, listRegistrationsByRoutingKeyDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, updateWorkflowRegistrationCommitShaDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, getRegistryVersionDirect, bumpRegistryVersionSimpleDirect, upsertCronLastFiredDirect, countCronLastFiredDirect, insertCronLastFiredNowDirect, deleteCronLastFiredDirect, deleteExecutionRunsByWorkflowNameDirect, getGenericWebhookSourceByRoutingKeyDirect, listActiveGenericWebhookSourcesDirect, updateGenericWebhookVerificationConfigDirect, deleteGenericWebhookSourcesByNameDirect, restoreSoftDeletedGenericWebhookSourceDirect, upsertOrgSettingsGlobalWorkflowsDirect, updateOrgSettingsDeniedReposDirect, deleteOrgSettingsByCustomerIdDirect, getExecutionRunSecurityDirect, getHeldRunByIdDirect, countHeldRunsByRunIdDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForEventLogRowByDeliveryIdDirect, resolvePlatformWebhookSourceRoutingKeyDirect, ensureOrgOwnerMemberDirect, deletePeerCredentialsByInstanceIdLikeDirect, insertPeerCredentialExpiredDirect, getPeerCredentialRevokedAtDirect, listActivePeerCredentialsExcludingDirect, clearPeerCredentialsRevokedAtByIdsDirect, countActivePeerCredentialsByInstanceDirect, terminateIdleDbBackendsDirect, type ColumnInfo, type KiciEventRow, type CrossRepoTrustRow, type WorkflowRegistrationFullRow, type RegistrationsScopedResult, type LatestExecutionRunResult, type WaitForLatestJobResult, type ExecutionRunSecurityRow, type HeldRunSecurityRow, type EventLogRow as PlatformEventLogRow, type UpsertOrgSettingsOpts, type OrgSettingsRepoPatternEntry, type InsertKiciEventRawOpts, type EmitKiciEventOpts, type SeedGenericWebhookSourceOpts, REGISTERABLE_TRIGGER_TYPES, MIGRATION_HASH_TABLE, type PurgeStaleExecutionResult, type PurgeStaleSourcesResult, type SeedEnvironmentOpts, type SeedEnvironmentResult, type SeedEnvironmentBindingOpts, type SetEnvironmentPolicyOpts, type EnvironmentRow, type EnvironmentVariableRow, type EnvironmentBindingRow, type ShowEnvironmentResult, type CreateEnvironmentTemplateOpts, type SetEnvironmentSecretOpts, type DispatchQueueRow, type ListQueueOpts, type ExecutionRunRow, type ExecutionJobRow, type ListExecutionRunsOpts, type WorkflowRegistrationRow, type ListRegistrationsOpts, type ListRegistrationsResult, type ShowRegistrationResult, type RegisterWorkflowManualOpts, type RegisterWorkflowManualResult, } from './db-admin.js';
|
|
5
5
|
export { createMetricsRoutes, type MetricsRoutesDeps } from './routes/metrics.js';
|
|
6
6
|
export { createHealthRoutes, type HealthRoutesDeps } from './routes/health.js';
|
|
7
7
|
export { getReconnectDelay } from './reconnect-delay.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./chunk-gOLHoazu.js";
|
|
2
2
|
import { createDb, createPool } from "./db.js";
|
|
3
|
-
import { MIGRATION_HASH_TABLE, REGISTERABLE_TRIGGER_TYPES, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect, createDbRole, createEnvironmentTemplateDirect, createJoinTokenDirect, createReadOnlyDbUser, deleteCronLastFiredDirect, deleteCrossRepoTrustDirect, deleteExecutionRunsByWorkflowNameDirect, deleteGenericWebhookSourcesByNameDirect, deleteKiciEventsDirect, deleteOrgSettingsByCustomerIdDirect, deletePeerCredentialsByInstanceIdLikeDirect, deleteWorkflowRegistrationsDirect, describeTableColumnsDirect, dropAndCreateDatabase, dropDatabaseDirect, emitKiciEventDirect, ensureDatabase, ensureOrgOwnerMemberDirect, findAnyUserApiKeyIdDirect, getExecutionRunSecurityDirect, getGenericWebhookSourceByRoutingKeyDirect, getHeldRunByIdDirect, getPeerCredentialRevokedAtDirect, getRegistryVersionDirect, getWebhookSourceByRoutingKeyDirect, getWorkflowRegistrationByIdDirect, insertCronLastFiredNowDirect, insertCrossRepoTrustStrictDirect, insertKiciEventRawDirect, insertPeerCredentialExpiredDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, isSchemaCurrent, isSchemaCurrentFromFilesDirect, latestExecutionRunByStatusDirect, listActiveGenericWebhookSourcesDirect, listActivePeerCredentialsExcludingDirect, listCrossRepoTrustBySourceRoutingKeyDirect, listEnvironmentsDirect, listExecutionJobsDirect, listExecutionRunsDirect, listKiciEventsDirect, listQueueDirect, listRegistrationsByRoutingKeyDirect, listRegistrationsDirect, maskDatabaseUrl, parseDatabaseUrl, platformConnectionExistsDirect, pollKiciEventsDirect, prunePeerCredentialsDirect, purgeScopedSecretsDirect, purgeSecretBackendsDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, readStoredMigrationContentHash, registerWorkflowManualDirect, resetRaftStateDirect, resolvePlatformWebhookSourceRoutingKeyDirect, restoreSoftDeletedGenericWebhookSourceDirect, seedApiKeyInlineDirect, seedCiSecurityFixturesDirect, seedCrossRepoTrustDirect, seedEnvironmentBindingDirect, seedEnvironmentDirect, seedGenericWebhookSourceDirect, seedSourcePrivateKeyDirect, seedSyntheticGithubSourceDirect, seedUniversalGitSourceDirect, seedWebhookSecretDirect, setEnvironmentPolicyDirect, setEnvironmentSecretDirect, showEnvironmentDirect, showExecutionRunDirect, showKiciEventDirect, showQueueEntryDirect, showRegistrationDirect, storeMigrationContentHash, storeMigrationContentHashInTableDirect, tableExistsDirect, updateGenericWebhookVerificationConfigDirect, updateOrgSettingsDeniedReposDirect, updateSourceRoutingKeyDirect, updateWorkflowRegistrationCommitShaDirect, upsertCronLastFiredDirect, upsertOrgSettingsGlobalWorkflowsDirect, verifyKiciEventNotifyDirect, waitForEventLogRowByDeliveryIdDirect, waitForExecutionRunStatusSinceDirect, waitForLatestExecutionJobStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformRegistrationsDirect, waitForPostgresDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, waitForRunCompletionDirect } from "./db-admin.js";
|
|
3
|
+
import { MIGRATION_HASH_TABLE, REGISTERABLE_TRIGGER_TYPES, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect, createDbRole, createEnvironmentTemplateDirect, createJoinTokenDirect, createReadOnlyDbUser, deleteCronLastFiredDirect, deleteCrossRepoTrustDirect, deleteEnvironmentDirect, deleteExecutionRunsByWorkflowNameDirect, deleteGenericWebhookSourcesByNameDirect, deleteKiciEventsDirect, deleteOrgSettingsByCustomerIdDirect, deletePeerCredentialsByInstanceIdLikeDirect, deleteWorkflowRegistrationsDirect, describeTableColumnsDirect, dropAndCreateDatabase, dropDatabaseDirect, emitKiciEventDirect, ensureDatabase, ensureOrgOwnerMemberDirect, findAnyUserApiKeyIdDirect, getExecutionRunSecurityDirect, getGenericWebhookSourceByRoutingKeyDirect, getHeldRunByIdDirect, getPeerCredentialRevokedAtDirect, getRegistryVersionDirect, getWebhookSourceByRoutingKeyDirect, getWorkflowRegistrationByIdDirect, insertCronLastFiredNowDirect, insertCrossRepoTrustStrictDirect, insertKiciEventRawDirect, insertPeerCredentialExpiredDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, isSchemaCurrent, isSchemaCurrentFromFilesDirect, latestExecutionRunByStatusDirect, listActiveGenericWebhookSourcesDirect, listActivePeerCredentialsExcludingDirect, listCrossRepoTrustBySourceRoutingKeyDirect, listEnvironmentsDirect, listExecutionJobsDirect, listExecutionRunsDirect, listKiciEventsDirect, listQueueDirect, listRegistrationsByRoutingKeyDirect, listRegistrationsDirect, maskDatabaseUrl, parseDatabaseUrl, platformConnectionExistsDirect, pollKiciEventsDirect, prunePeerCredentialsDirect, purgeScopedSecretsDirect, purgeSecretBackendsDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, readStoredMigrationContentHash, registerWorkflowManualDirect, resetRaftStateDirect, resolvePlatformWebhookSourceRoutingKeyDirect, restoreSoftDeletedGenericWebhookSourceDirect, seedApiKeyInlineDirect, seedCiSecurityFixturesDirect, seedCrossRepoTrustDirect, seedEnvironmentBindingDirect, seedEnvironmentDirect, seedGenericWebhookSourceDirect, seedSourcePrivateKeyDirect, seedSyntheticGithubSourceDirect, seedUniversalGitSourceDirect, seedWebhookSecretDirect, setEnvironmentPolicyDirect, setEnvironmentSecretDirect, showEnvironmentDirect, showExecutionRunDirect, showKiciEventDirect, showQueueEntryDirect, showRegistrationDirect, storeMigrationContentHash, storeMigrationContentHashInTableDirect, tableExistsDirect, terminateIdleDbBackendsDirect, updateGenericWebhookVerificationConfigDirect, updateOrgSettingsDeniedReposDirect, updateSourceRoutingKeyDirect, updateWorkflowRegistrationCommitShaDirect, upsertCronLastFiredDirect, upsertOrgSettingsGlobalWorkflowsDirect, verifyKiciEventNotifyDirect, waitForEventLogRowByDeliveryIdDirect, waitForExecutionRunStatusSinceDirect, waitForLatestExecutionJobStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformRegistrationsDirect, waitForPostgresDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, waitForRunCompletionDirect } from "./db-admin.js";
|
|
4
4
|
import { setupGracefulShutdown } from "./graceful-shutdown.js";
|
|
5
5
|
import { RingBuffer } from "./ring-buffer.js";
|
|
6
6
|
import { createMetricsRoutes } from "./routes/metrics.js";
|
|
@@ -22,4 +22,4 @@ import { ChunkLru } from "./cold-store/lru.js";
|
|
|
22
22
|
import { DEFAULT_TABLE_CONFIG, resolveTableConfig } from "./cold-store/config.js";
|
|
23
23
|
import "./cold-store/index.js";
|
|
24
24
|
export * from "@kici-dev/core";
|
|
25
|
-
export { BaseColdStore, COLD_BUCKET_NAMES, ChunkLru, DEFAULT_TABLE_CONFIG, MIGRATION_HASH_TABLE, REGISTERABLE_TRIGGER_TYPES, RingBuffer, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, chunkObjectKey, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, coldDaysToBucket, coldStoreArchiveBytesTotal, coldStoreArchiveCyclesTotal, coldStoreArchiveDurationSeconds, coldStoreArchiveRowsTotal, coldStorePurgeBytesTotal, coldStorePurgeChunksTotal, coldStorePurgeDurationSeconds, coldStoreRehydrateBytesTotal, coldStoreRehydrateDurationSeconds, coldStoreRehydrateRequestsTotal, coldStoreReplayDurationSeconds, coldStoreReplayRowsTotal, coldStoreVerifyFailuresTotal, collectRuntimeMetricNames, computeChunkId, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect, createDb, createDbRole, createEnvironmentTemplateDirect, createHealthRoutes, createJoinTokenDirect, createMeter, createMetricsRoutes, createPool, createReadOnlyDbUser, createS3Client, decodeChunk, deleteCronLastFiredDirect, deleteCrossRepoTrustDirect, deleteExecutionRunsByWorkflowNameDirect, deleteGenericWebhookSourcesByNameDirect, deleteKiciEventsDirect, deleteOrgSettingsByCustomerIdDirect, deletePeerCredentialsByInstanceIdLikeDirect, deleteWorkflowRegistrationsDirect, describeTableColumnsDirect, dropAndCreateDatabase, dropDatabaseDirect, emitKiciEventDirect, encodeChunk, encodeKeySegment, ensureDatabase, ensureOrgOwnerMemberDirect, findAnyUserApiKeyIdDirect, getExecutionRunSecurityDirect, getGenericWebhookSourceByRoutingKeyDirect, getHeldRunByIdDirect, getPeerCredentialRevokedAtDirect, getPrometheusExporter, getReconnectDelay, getRegistryVersionDirect, getWebhookSourceByRoutingKeyDirect, getWorkflowRegistrationByIdDirect, initTelemetry, insertCronLastFiredNowDirect, insertCrossRepoTrustStrictDirect, insertKiciEventRawDirect, insertPeerCredentialExpiredDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, isLongerColdRetention, isSchemaCurrent, isSchemaCurrentFromFilesDirect, latestExecutionRunByStatusDirect, listActiveGenericWebhookSourcesDirect, listActivePeerCredentialsExcludingDirect, listCrossRepoTrustBySourceRoutingKeyDirect, listEnvironmentsDirect, listExecutionJobsDirect, listExecutionRunsDirect, listKiciEventsDirect, listQueueDirect, listRegistrationsByRoutingKeyDirect, listRegistrationsDirect, maskDatabaseUrl, parseDatabaseUrl, parseManifest, platformConnectionExistsDirect, pollKiciEventsDirect, prunePeerCredentialsDirect, purgeScopedSecretsDirect, purgeSecretBackendsDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, readStoredMigrationContentHash, registerWorkflowManualDirect, resetRaftStateDirect, resolvePlatformWebhookSourceRoutingKeyDirect, resolveTableConfig, restoreSoftDeletedGenericWebhookSourceDirect, seedApiKeyInlineDirect, seedCiSecurityFixturesDirect, seedCrossRepoTrustDirect, seedEnvironmentBindingDirect, seedEnvironmentDirect, seedGenericWebhookSourceDirect, seedSourcePrivateKeyDirect, seedSyntheticGithubSourceDirect, seedUniversalGitSourceDirect, seedWebhookSecretDirect, serializeManifest, setEnvironmentPolicyDirect, setEnvironmentSecretDirect, setupGracefulShutdown, showEnvironmentDirect, showExecutionRunDirect, showKiciEventDirect, showQueueEntryDirect, showRegistrationDirect, storeMigrationContentHash, storeMigrationContentHashInTableDirect, tableExistsDirect, tablePrefix, tenantDayBucketPrefix, tenantDayPrefix, updateGenericWebhookVerificationConfigDirect, updateOrgSettingsDeniedReposDirect, updateSourceRoutingKeyDirect, updateWorkflowRegistrationCommitShaDirect, upsertCronLastFiredDirect, upsertOrgSettingsGlobalWorkflowsDirect, validateRequiredTools, verifyKiciEventNotifyDirect, waitForEventLogRowByDeliveryIdDirect, waitForExecutionRunStatusSinceDirect, waitForLatestExecutionJobStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformRegistrationsDirect, waitForPostgresDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, waitForRunCompletionDirect };
|
|
25
|
+
export { BaseColdStore, COLD_BUCKET_NAMES, ChunkLru, DEFAULT_TABLE_CONFIG, MIGRATION_HASH_TABLE, REGISTERABLE_TRIGGER_TYPES, RingBuffer, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, chunkObjectKey, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, coldDaysToBucket, coldStoreArchiveBytesTotal, coldStoreArchiveCyclesTotal, coldStoreArchiveDurationSeconds, coldStoreArchiveRowsTotal, coldStorePurgeBytesTotal, coldStorePurgeChunksTotal, coldStorePurgeDurationSeconds, coldStoreRehydrateBytesTotal, coldStoreRehydrateDurationSeconds, coldStoreRehydrateRequestsTotal, coldStoreReplayDurationSeconds, coldStoreReplayRowsTotal, coldStoreVerifyFailuresTotal, collectRuntimeMetricNames, computeChunkId, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect, createDb, createDbRole, createEnvironmentTemplateDirect, createHealthRoutes, createJoinTokenDirect, createMeter, createMetricsRoutes, createPool, createReadOnlyDbUser, createS3Client, decodeChunk, deleteCronLastFiredDirect, deleteCrossRepoTrustDirect, deleteEnvironmentDirect, deleteExecutionRunsByWorkflowNameDirect, deleteGenericWebhookSourcesByNameDirect, deleteKiciEventsDirect, deleteOrgSettingsByCustomerIdDirect, deletePeerCredentialsByInstanceIdLikeDirect, deleteWorkflowRegistrationsDirect, describeTableColumnsDirect, dropAndCreateDatabase, dropDatabaseDirect, emitKiciEventDirect, encodeChunk, encodeKeySegment, ensureDatabase, ensureOrgOwnerMemberDirect, findAnyUserApiKeyIdDirect, getExecutionRunSecurityDirect, getGenericWebhookSourceByRoutingKeyDirect, getHeldRunByIdDirect, getPeerCredentialRevokedAtDirect, getPrometheusExporter, getReconnectDelay, getRegistryVersionDirect, getWebhookSourceByRoutingKeyDirect, getWorkflowRegistrationByIdDirect, initTelemetry, insertCronLastFiredNowDirect, insertCrossRepoTrustStrictDirect, insertKiciEventRawDirect, insertPeerCredentialExpiredDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, isLongerColdRetention, isSchemaCurrent, isSchemaCurrentFromFilesDirect, latestExecutionRunByStatusDirect, listActiveGenericWebhookSourcesDirect, listActivePeerCredentialsExcludingDirect, listCrossRepoTrustBySourceRoutingKeyDirect, listEnvironmentsDirect, listExecutionJobsDirect, listExecutionRunsDirect, listKiciEventsDirect, listQueueDirect, listRegistrationsByRoutingKeyDirect, listRegistrationsDirect, maskDatabaseUrl, parseDatabaseUrl, parseManifest, platformConnectionExistsDirect, pollKiciEventsDirect, prunePeerCredentialsDirect, purgeScopedSecretsDirect, purgeSecretBackendsDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, readStoredMigrationContentHash, registerWorkflowManualDirect, resetRaftStateDirect, resolvePlatformWebhookSourceRoutingKeyDirect, resolveTableConfig, restoreSoftDeletedGenericWebhookSourceDirect, seedApiKeyInlineDirect, seedCiSecurityFixturesDirect, seedCrossRepoTrustDirect, seedEnvironmentBindingDirect, seedEnvironmentDirect, seedGenericWebhookSourceDirect, seedSourcePrivateKeyDirect, seedSyntheticGithubSourceDirect, seedUniversalGitSourceDirect, seedWebhookSecretDirect, serializeManifest, setEnvironmentPolicyDirect, setEnvironmentSecretDirect, setupGracefulShutdown, showEnvironmentDirect, showExecutionRunDirect, showKiciEventDirect, showQueueEntryDirect, showRegistrationDirect, storeMigrationContentHash, storeMigrationContentHashInTableDirect, tableExistsDirect, tablePrefix, tenantDayBucketPrefix, tenantDayPrefix, terminateIdleDbBackendsDirect, updateGenericWebhookVerificationConfigDirect, updateOrgSettingsDeniedReposDirect, updateSourceRoutingKeyDirect, updateWorkflowRegistrationCommitShaDirect, upsertCronLastFiredDirect, upsertOrgSettingsGlobalWorkflowsDirect, validateRequiredTools, verifyKiciEventNotifyDirect, waitForEventLogRowByDeliveryIdDirect, waitForExecutionRunStatusSinceDirect, waitForLatestExecutionJobStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformRegistrationsDirect, waitForPostgresDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, waitForRunCompletionDirect };
|
package/dist/s3-client.js
CHANGED
|
@@ -13,7 +13,10 @@ import { S3Client } from "@aws-sdk/client-s3";
|
|
|
13
13
|
* for cache-storage variants).
|
|
14
14
|
*/
|
|
15
15
|
function createS3Client(options) {
|
|
16
|
-
const config = {
|
|
16
|
+
const config = {
|
|
17
|
+
requestChecksumCalculation: "WHEN_REQUIRED",
|
|
18
|
+
responseChecksumValidation: "WHEN_REQUIRED"
|
|
19
|
+
};
|
|
17
20
|
if (options.region) config.region = options.region;
|
|
18
21
|
if (options.endpoint) config.endpoint = options.endpoint;
|
|
19
22
|
if (options.forcePathStyle !== void 0) config.forcePathStyle = options.forcePathStyle;
|
package/package.json
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kici-dev/shared",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "Shared utilities for the KiCI CI/CD stack — logging, zx setup, crypto, telemetry, health and metrics routes. No business logic.",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"kici",
|
|
7
6
|
"ci",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
7
|
+
"cicd",
|
|
8
|
+
"continuous-integration",
|
|
10
9
|
"typescript",
|
|
11
|
-
"
|
|
12
|
-
"devops",
|
|
10
|
+
"workflow",
|
|
13
11
|
"utilities"
|
|
14
12
|
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/kici-dev/kici-public.git",
|
|
16
|
+
"directory": "packages/shared"
|
|
17
|
+
},
|
|
18
|
+
"bugs": "https://github.com/kici-dev/kici-public/issues",
|
|
15
19
|
"homepage": "https://kici.dev",
|
|
16
20
|
"author": {
|
|
17
21
|
"name": "KiCI",
|
|
@@ -96,7 +100,7 @@
|
|
|
96
100
|
"yaml": "^2.8.3",
|
|
97
101
|
"zod": "^4.3.6",
|
|
98
102
|
"zx": "^8.8.5",
|
|
99
|
-
"@kici-dev/core": "0.1.
|
|
103
|
+
"@kici-dev/core": "0.1.15"
|
|
100
104
|
},
|
|
101
105
|
"devDependencies": {
|
|
102
106
|
"@opentelemetry/sdk-trace-base": "^2.7.0",
|
package/sbom.spdx.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"spdxVersion": "SPDX-2.3",
|
|
3
3
|
"dataLicense": "CC0-1.0",
|
|
4
4
|
"SPDXID": "SPDXRef-DOCUMENT",
|
|
5
|
-
"name": "@kici-dev/shared@0.1.
|
|
6
|
-
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fshared/0.1.
|
|
5
|
+
"name": "@kici-dev/shared@0.1.15",
|
|
6
|
+
"documentNamespace": "https://kici.dev/sbom/%40kici-dev%2Fshared/0.1.15/16314d47-0e1a-4be8-bddc-5605b523d24d",
|
|
7
7
|
"creationInfo": {
|
|
8
|
-
"created": "2026-
|
|
8
|
+
"created": "2026-06-11T03:03:13Z",
|
|
9
9
|
"creators": [
|
|
10
10
|
"Tool: kici-sbom-generator"
|
|
11
11
|
]
|
|
@@ -945,9 +945,9 @@
|
|
|
945
945
|
"homepage": "https://js-sdsl.org"
|
|
946
946
|
},
|
|
947
947
|
{
|
|
948
|
-
"SPDXID": "SPDXRef-Package--kici-dev-core-0.1.
|
|
948
|
+
"SPDXID": "SPDXRef-Package--kici-dev-core-0.1.15",
|
|
949
949
|
"name": "@kici-dev/core",
|
|
950
|
-
"versionInfo": "0.1.
|
|
950
|
+
"versionInfo": "0.1.15",
|
|
951
951
|
"downloadLocation": "NOASSERTION",
|
|
952
952
|
"filesAnalyzed": false,
|
|
953
953
|
"licenseConcluded": "NOASSERTION",
|
|
@@ -958,7 +958,7 @@
|
|
|
958
958
|
{
|
|
959
959
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
960
960
|
"referenceType": "purl",
|
|
961
|
-
"referenceLocator": "pkg:npm/%40kici-dev/core@0.1.
|
|
961
|
+
"referenceLocator": "pkg:npm/%40kici-dev/core@0.1.15"
|
|
962
962
|
}
|
|
963
963
|
],
|
|
964
964
|
"description": "Light shared utilities for the KiCI stack (logging, errors, formatting, crypto, zx init, the TypeScript ESM loader hook). No server-side dependencies.",
|
|
@@ -967,7 +967,7 @@
|
|
|
967
967
|
{
|
|
968
968
|
"SPDXID": "SPDXRef-RootPackage",
|
|
969
969
|
"name": "@kici-dev/shared",
|
|
970
|
-
"versionInfo": "0.1.
|
|
970
|
+
"versionInfo": "0.1.15",
|
|
971
971
|
"downloadLocation": "NOASSERTION",
|
|
972
972
|
"filesAnalyzed": false,
|
|
973
973
|
"licenseConcluded": "NOASSERTION",
|
|
@@ -978,7 +978,7 @@
|
|
|
978
978
|
{
|
|
979
979
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
980
980
|
"referenceType": "purl",
|
|
981
|
-
"referenceLocator": "pkg:npm/%40kici-dev/shared@0.1.
|
|
981
|
+
"referenceLocator": "pkg:npm/%40kici-dev/shared@0.1.15"
|
|
982
982
|
}
|
|
983
983
|
],
|
|
984
984
|
"description": "Shared utilities for the KiCI CI/CD stack — logging, zx setup, crypto, telemetry, health and metrics routes. No business logic.",
|
|
@@ -6442,32 +6442,32 @@
|
|
|
6442
6442
|
"relationshipType": "DEPENDS_ON"
|
|
6443
6443
|
},
|
|
6444
6444
|
{
|
|
6445
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
6445
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.15",
|
|
6446
6446
|
"relatedSpdxElement": "SPDXRef-Package-oxc-transform-0.128.0",
|
|
6447
6447
|
"relationshipType": "DEPENDS_ON"
|
|
6448
6448
|
},
|
|
6449
6449
|
{
|
|
6450
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
6450
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.15",
|
|
6451
6451
|
"relatedSpdxElement": "SPDXRef-Package-picocolors-1.1.1",
|
|
6452
6452
|
"relationshipType": "DEPENDS_ON"
|
|
6453
6453
|
},
|
|
6454
6454
|
{
|
|
6455
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
6455
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.15",
|
|
6456
6456
|
"relatedSpdxElement": "SPDXRef-Package-winston-daily-rotate-file-5.0.0",
|
|
6457
6457
|
"relationshipType": "DEPENDS_ON"
|
|
6458
6458
|
},
|
|
6459
6459
|
{
|
|
6460
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
6460
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.15",
|
|
6461
6461
|
"relatedSpdxElement": "SPDXRef-Package-winston-3.19.0",
|
|
6462
6462
|
"relationshipType": "DEPENDS_ON"
|
|
6463
6463
|
},
|
|
6464
6464
|
{
|
|
6465
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
6465
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.15",
|
|
6466
6466
|
"relatedSpdxElement": "SPDXRef-Package-zod-4.3.6",
|
|
6467
6467
|
"relationshipType": "DEPENDS_ON"
|
|
6468
6468
|
},
|
|
6469
6469
|
{
|
|
6470
|
-
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.
|
|
6470
|
+
"spdxElementId": "SPDXRef-Package--kici-dev-core-0.1.15",
|
|
6471
6471
|
"relatedSpdxElement": "SPDXRef-Package-zx-8.8.5",
|
|
6472
6472
|
"relationshipType": "DEPENDS_ON"
|
|
6473
6473
|
},
|
|
@@ -6478,7 +6478,7 @@
|
|
|
6478
6478
|
},
|
|
6479
6479
|
{
|
|
6480
6480
|
"spdxElementId": "SPDXRef-RootPackage",
|
|
6481
|
-
"relatedSpdxElement": "SPDXRef-Package--kici-dev-core-0.1.
|
|
6481
|
+
"relatedSpdxElement": "SPDXRef-Package--kici-dev-core-0.1.15",
|
|
6482
6482
|
"relationshipType": "DEPENDS_ON"
|
|
6483
6483
|
},
|
|
6484
6484
|
{
|