@kici-dev/shared 0.1.26 → 0.2.0
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/dist/agent-platform.d.ts +32 -0
- package/dist/agent-platform.js +27 -0
- package/dist/agent-platform.test.d.ts +2 -0
- package/dist/ci-env.d.ts +2 -0
- package/dist/ci-env.js +3 -0
- package/dist/cold-store/bucket.d.ts +1 -1
- package/dist/cold-store/cold-store.d.ts +24 -1
- package/dist/cold-store/cold-store.js +17 -5
- package/dist/cold-store/index.js +1 -1
- package/dist/db-admin.d.ts +206 -65
- package/dist/db-admin.js +236 -122
- package/dist/db-collation.d.ts +49 -0
- package/dist/db-collation.js +68 -1
- package/dist/db.d.ts +34 -0
- package/dist/db.js +30 -1
- package/dist/diagnostics/bundle-archive.js +5 -5
- package/dist/env/allowlist.d.ts +5 -0
- package/dist/env/allowlist.js +6 -1
- package/dist/env/define-env.d.ts +19 -2
- package/dist/env/define-env.js +18 -3
- package/dist/env/logger-env.d.ts +11 -9
- package/dist/env/logger-env.js +25 -9
- package/dist/idempotency-files.d.ts +7 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -4
- package/dist/telemetry/init.d.ts +18 -7
- package/dist/telemetry/init.js +36 -11
- package/dist/tmp-dir.d.ts +14 -0
- package/dist/tmp-dir.js +13 -0
- package/dist/tmp-dir.test.d.ts +2 -0
- package/dist/tmp.d.ts +2 -0
- package/dist/tmp.js +3 -0
- package/package.json +26 -17
- package/sbom.spdx.json +1222 -1618
package/dist/db-admin.js
CHANGED
|
@@ -2,6 +2,7 @@ import "./rolldown-runtime-ClRpJifh.js";
|
|
|
2
2
|
import { createPool } from "./db.js";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import pg from "pg";
|
|
5
|
+
import { HoldType, unknownContributorHoldReason } from "@kici-dev/engine";
|
|
5
6
|
//#region src/db-admin.ts
|
|
6
7
|
/**
|
|
7
8
|
* Admin/DB-operations helpers shared between `kici-admin` (orchestrator DB)
|
|
@@ -341,18 +342,18 @@ async function purgeScopedSecretsDirect(databaseUrl, orgId) {
|
|
|
341
342
|
}
|
|
342
343
|
}
|
|
343
344
|
/**
|
|
344
|
-
* Bulk-delete `
|
|
345
|
-
* every org when `orgId` is omitted. `
|
|
346
|
-
* `
|
|
345
|
+
* Bulk-delete `contexts` (and their FK-dependent rows) for an org, or for
|
|
346
|
+
* every org when `orgId` is omitted. `context_bindings` /
|
|
347
|
+
* `context_variables` / `context_source_overrides` cascade
|
|
347
348
|
* automatically (ON DELETE CASCADE). `held_runs` and `execution_runs` reference
|
|
348
|
-
* `
|
|
349
|
-
* would leave orphaned `held_runs` rows carrying a null
|
|
349
|
+
* `contexts(id)` with ON DELETE SET NULL, so deleting contexts alone
|
|
350
|
+
* would leave orphaned `held_runs` rows carrying a null context reference;
|
|
350
351
|
* this helper deletes the org's `held_runs` too so a warm-start reset gets a
|
|
351
352
|
* clean slate. Runs in a transaction so both deletes commit atomically. Used by
|
|
352
|
-
* the E2E warm-start reset (so seeded
|
|
353
|
-
* categories) and exposed via `kici-admin
|
|
353
|
+
* the E2E warm-start reset (so seeded contexts don't leak between
|
|
354
|
+
* categories) and exposed via `kici-admin context purge`.
|
|
354
355
|
*/
|
|
355
|
-
async function
|
|
356
|
+
async function purgeContextsDirect(databaseUrl, orgId) {
|
|
356
357
|
const pool = createPool(databaseUrl);
|
|
357
358
|
const client = await pool.connect();
|
|
358
359
|
try {
|
|
@@ -360,10 +361,10 @@ async function purgeEnvironmentsDirect(databaseUrl, orgId) {
|
|
|
360
361
|
const where = orgId ? "WHERE org_id = $1" : "";
|
|
361
362
|
const params = orgId ? [orgId] : [];
|
|
362
363
|
const held = await client.query(`DELETE FROM held_runs ${where}`, params);
|
|
363
|
-
const envs = await client.query(`DELETE FROM
|
|
364
|
+
const envs = await client.query(`DELETE FROM contexts ${where}`, params);
|
|
364
365
|
await client.query("COMMIT");
|
|
365
366
|
return {
|
|
366
|
-
|
|
367
|
+
contextsDeleted: envs.rowCount ?? 0,
|
|
367
368
|
heldRunsDeleted: held.rowCount ?? 0
|
|
368
369
|
};
|
|
369
370
|
} catch (err) {
|
|
@@ -375,7 +376,7 @@ async function purgeEnvironmentsDirect(databaseUrl, orgId) {
|
|
|
375
376
|
}
|
|
376
377
|
}
|
|
377
378
|
/**
|
|
378
|
-
* Allowed policy field names for `
|
|
379
|
+
* Allowed policy field names for `setContextPolicyDirect`. Kept as an
|
|
379
380
|
* explicit allowlist so the column-name interpolation in the UPDATE string
|
|
380
381
|
* can never be driven by unsanitised caller input.
|
|
381
382
|
*/
|
|
@@ -389,13 +390,19 @@ const ENV_POLICY_COLUMNS = /* @__PURE__ */ new Set([
|
|
|
389
390
|
"allow_local_execution"
|
|
390
391
|
]);
|
|
391
392
|
/**
|
|
392
|
-
* Upsert
|
|
393
|
+
* Upsert a context row keyed by (org_id, name). Returns the env id and
|
|
393
394
|
* whether the row was newly inserted. `branchRestrictions` / `requiredReviewers`
|
|
394
395
|
* are JSON-serialised server-side; pass them as plain arrays or objects.
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
396
|
+
*
|
|
397
|
+
* An omitted `holdExpirySeconds` is written as NULL rather than a literal
|
|
398
|
+
* window: the column carries no DDL default, so "never set" and "cleared" both
|
|
399
|
+
* land on NULL and resolve through the one `DEFAULT_HOLD_EXPIRY_SECONDS`
|
|
400
|
+
* fallback on read. Writing a literal here would give this path a second,
|
|
401
|
+
* longer default that no read-side code knows about.
|
|
402
|
+
*/
|
|
403
|
+
async function seedContextDirect(databaseUrl, opts) {
|
|
404
|
+
if (opts.waitTimerSeconds != null && opts.waitTimerSeconds < 0) throw new Error(`context: waitTimerSeconds must be >= 0 (got ${opts.waitTimerSeconds})`);
|
|
405
|
+
if (opts.holdExpirySeconds != null && opts.holdExpirySeconds < 1) throw new Error(`context: holdExpirySeconds must be >= 1 (got ${opts.holdExpirySeconds})`);
|
|
399
406
|
const pool = new pg.Pool({
|
|
400
407
|
connectionString: databaseUrl,
|
|
401
408
|
max: 1
|
|
@@ -403,20 +410,20 @@ async function seedEnvironmentDirect(databaseUrl, opts) {
|
|
|
403
410
|
try {
|
|
404
411
|
const branchJson = JSON.stringify(opts.branchRestrictions ?? []);
|
|
405
412
|
const reviewersJson = opts.requiredReviewers === void 0 ? null : JSON.stringify(opts.requiredReviewers);
|
|
406
|
-
const row = (await pool.query(`INSERT INTO
|
|
413
|
+
const row = (await pool.query(`INSERT INTO contexts
|
|
407
414
|
(org_id, name, type, enabled, branch_restrictions, required_reviewers,
|
|
408
415
|
wait_timer_seconds, hold_expiry_seconds, minimum_trust, glob_pattern)
|
|
409
416
|
VALUES ($1, $2, COALESCE($3, 'fixed'), COALESCE($4, true), $5::jsonb, $6::jsonb,
|
|
410
|
-
$7,
|
|
417
|
+
$7, $8, $9, $10)
|
|
411
418
|
ON CONFLICT (org_id, name) DO UPDATE SET
|
|
412
|
-
type = COALESCE(EXCLUDED.type,
|
|
419
|
+
type = COALESCE(EXCLUDED.type, contexts.type),
|
|
413
420
|
enabled = EXCLUDED.enabled,
|
|
414
421
|
branch_restrictions = EXCLUDED.branch_restrictions,
|
|
415
422
|
required_reviewers = EXCLUDED.required_reviewers,
|
|
416
423
|
wait_timer_seconds = EXCLUDED.wait_timer_seconds,
|
|
417
424
|
hold_expiry_seconds = EXCLUDED.hold_expiry_seconds,
|
|
418
425
|
minimum_trust = EXCLUDED.minimum_trust,
|
|
419
|
-
glob_pattern = COALESCE(EXCLUDED.glob_pattern,
|
|
426
|
+
glob_pattern = COALESCE(EXCLUDED.glob_pattern, contexts.glob_pattern),
|
|
420
427
|
updated_at = now()
|
|
421
428
|
RETURNING id, (xmax = 0) AS inserted`, [
|
|
422
429
|
opts.orgId,
|
|
@@ -430,7 +437,7 @@ async function seedEnvironmentDirect(databaseUrl, opts) {
|
|
|
430
437
|
opts.minimumTrust ?? null,
|
|
431
438
|
opts.globPattern ?? null
|
|
432
439
|
])).rows[0];
|
|
433
|
-
if (!row) throw new Error(`
|
|
440
|
+
if (!row) throw new Error(`context: upsert returned no row for ${opts.name}`);
|
|
434
441
|
return {
|
|
435
442
|
envId: row.id,
|
|
436
443
|
created: row.inserted
|
|
@@ -440,47 +447,47 @@ async function seedEnvironmentDirect(databaseUrl, opts) {
|
|
|
440
447
|
}
|
|
441
448
|
}
|
|
442
449
|
/**
|
|
443
|
-
* Delete
|
|
444
|
-
* removed. The `
|
|
445
|
-
* `
|
|
446
|
-
* `FOREIGN KEY (
|
|
447
|
-
* so a single DELETE on `
|
|
450
|
+
* Delete a context keyed by (org_id, name). Returns whether a row was
|
|
451
|
+
* removed. The `context_bindings`, `context_variables`, and
|
|
452
|
+
* `context_source_overrides` children all carry
|
|
453
|
+
* `FOREIGN KEY (context_id) REFERENCES contexts(id) ON DELETE CASCADE`,
|
|
454
|
+
* so a single DELETE on `contexts` cascades to those children. The
|
|
448
455
|
* `held_runs` FK uses `ON DELETE SET NULL`, so terminal held-run history
|
|
449
|
-
* survives the delete with a null
|
|
450
|
-
* still reference the
|
|
456
|
+
* survives the delete with a null context reference. Pending held runs
|
|
457
|
+
* still reference the context, so this helper pre-checks their count and
|
|
451
458
|
* throws before issuing the DELETE — approve or reject them first.
|
|
452
459
|
*/
|
|
453
|
-
async function
|
|
460
|
+
async function deleteContextDirect(databaseUrl, opts) {
|
|
454
461
|
const pool = new pg.Pool({
|
|
455
462
|
connectionString: databaseUrl,
|
|
456
463
|
max: 1
|
|
457
464
|
});
|
|
458
465
|
try {
|
|
459
466
|
const pending = await pool.query(`SELECT count(*)::text AS count FROM held_runs hr
|
|
460
|
-
JOIN
|
|
467
|
+
JOIN contexts e ON e.id = hr.context_id
|
|
461
468
|
WHERE e.org_id = $1 AND e.name = $2 AND hr.status = 'pending'`, [opts.orgId, opts.name]);
|
|
462
469
|
const pendingCount = Number(pending.rows[0]?.count ?? 0);
|
|
463
|
-
if (pendingCount > 0) throw new Error(`
|
|
464
|
-
return { deleted: (await pool.query(`DELETE FROM
|
|
470
|
+
if (pendingCount > 0) throw new Error(`context has ${pendingCount} pending held run(s) — approve or reject them first`);
|
|
471
|
+
return { deleted: (await pool.query(`DELETE FROM contexts WHERE org_id = $1 AND name = $2 RETURNING id`, [opts.orgId, opts.name])).rows.length > 0 };
|
|
465
472
|
} finally {
|
|
466
473
|
await pool.end();
|
|
467
474
|
}
|
|
468
475
|
}
|
|
469
476
|
/**
|
|
470
|
-
* Upsert an `
|
|
471
|
-
* (scoped to `hostPattern`, default `'**'`). Throws if the
|
|
477
|
+
* Upsert an `context_bindings` row connecting `contextName` to `scopePattern`
|
|
478
|
+
* (scoped to `hostPattern`, default `'**'`). Throws if the context does
|
|
472
479
|
* not exist.
|
|
473
480
|
*/
|
|
474
|
-
async function
|
|
481
|
+
async function seedContextBindingDirect(databaseUrl, opts) {
|
|
475
482
|
const pool = new pg.Pool({
|
|
476
483
|
connectionString: databaseUrl,
|
|
477
484
|
max: 1
|
|
478
485
|
});
|
|
479
486
|
try {
|
|
480
|
-
const envRow = await pool.query(`SELECT id FROM
|
|
481
|
-
if (envRow.rows.length === 0) throw new Error(`
|
|
487
|
+
const envRow = await pool.query(`SELECT id FROM contexts WHERE org_id = $1 AND name = $2`, [opts.orgId, opts.contextName]);
|
|
488
|
+
if (envRow.rows.length === 0) throw new Error(`context: not found (org=${opts.orgId}, name=${opts.contextName})`);
|
|
482
489
|
const envId = envRow.rows[0].id;
|
|
483
|
-
return { created: (await pool.query(`INSERT INTO
|
|
490
|
+
return { created: (await pool.query(`INSERT INTO context_bindings (org_id, context_id, scope_pattern, host_pattern)
|
|
484
491
|
VALUES ($1, $2, $3, $4)
|
|
485
492
|
ON CONFLICT DO NOTHING
|
|
486
493
|
RETURNING (xmax = 0) AS inserted`, [
|
|
@@ -495,16 +502,16 @@ async function seedEnvironmentBindingDirect(databaseUrl, opts) {
|
|
|
495
502
|
}
|
|
496
503
|
/**
|
|
497
504
|
* UPDATE only the policy fields that were explicitly provided. Columns that
|
|
498
|
-
* were NOT in `opts` are left untouched. Throws if the
|
|
505
|
+
* were NOT in `opts` are left untouched. Throws if the context is missing.
|
|
499
506
|
*/
|
|
500
|
-
async function
|
|
501
|
-
if (opts.waitTimerSeconds != null && opts.waitTimerSeconds < 0) throw new Error(`
|
|
502
|
-
if (opts.holdExpirySeconds != null && opts.holdExpirySeconds <
|
|
507
|
+
async function setContextPolicyDirect(databaseUrl, opts) {
|
|
508
|
+
if (opts.waitTimerSeconds != null && opts.waitTimerSeconds < 0) throw new Error(`context: waitTimerSeconds must be >= 0 (got ${opts.waitTimerSeconds})`);
|
|
509
|
+
if (opts.holdExpirySeconds != null && opts.holdExpirySeconds < 1) throw new Error(`context: holdExpirySeconds must be >= 1 (got ${opts.holdExpirySeconds})`);
|
|
503
510
|
const setClauses = [];
|
|
504
511
|
const params = [];
|
|
505
512
|
let idx = 1;
|
|
506
513
|
const addSet = (column, value, cast) => {
|
|
507
|
-
if (!ENV_POLICY_COLUMNS.has(column)) throw new Error(`
|
|
514
|
+
if (!ENV_POLICY_COLUMNS.has(column)) throw new Error(`context: unknown policy column ${column}`);
|
|
508
515
|
setClauses.push(`${column} = $${idx}${cast ? `::${cast}` : ""}`);
|
|
509
516
|
params.push(value);
|
|
510
517
|
idx += 1;
|
|
@@ -516,36 +523,36 @@ async function setEnvironmentPolicyDirect(databaseUrl, opts) {
|
|
|
516
523
|
if (opts.minimumTrust !== void 0) addSet("minimum_trust", opts.minimumTrust);
|
|
517
524
|
if (opts.enabled !== void 0) addSet("enabled", opts.enabled);
|
|
518
525
|
if (opts.allowLocalExecution !== void 0) addSet("allow_local_execution", opts.allowLocalExecution);
|
|
519
|
-
if (setClauses.length === 0) throw new Error("
|
|
526
|
+
if (setClauses.length === 0) throw new Error("context: setContextPolicy requires at least one policy field");
|
|
520
527
|
const pool = new pg.Pool({
|
|
521
528
|
connectionString: databaseUrl,
|
|
522
529
|
max: 1
|
|
523
530
|
});
|
|
524
531
|
try {
|
|
525
|
-
params.push(opts.orgId, opts.
|
|
532
|
+
params.push(opts.orgId, opts.contextName);
|
|
526
533
|
const orgParam = `$${idx}`;
|
|
527
534
|
const nameParam = `$${idx + 1}`;
|
|
528
|
-
const sql = `UPDATE
|
|
535
|
+
const sql = `UPDATE contexts
|
|
529
536
|
SET ${setClauses.join(", ")}, updated_at = now()
|
|
530
537
|
WHERE org_id = ${orgParam} AND name = ${nameParam}`;
|
|
531
|
-
if (((await pool.query(sql, params)).rowCount ?? 0) === 0) throw new Error(`
|
|
538
|
+
if (((await pool.query(sql, params)).rowCount ?? 0) === 0) throw new Error(`context: not found (org=${opts.orgId}, name=${opts.contextName})`);
|
|
532
539
|
} finally {
|
|
533
540
|
await pool.end();
|
|
534
541
|
}
|
|
535
542
|
}
|
|
536
543
|
/**
|
|
537
|
-
* SELECT * FROM
|
|
544
|
+
* SELECT * FROM contexts WHERE org_id = $1, ordered by name.
|
|
538
545
|
*/
|
|
539
|
-
async function
|
|
546
|
+
async function listContextsDirect(databaseUrl, opts) {
|
|
540
547
|
const pool = new pg.Pool({
|
|
541
548
|
connectionString: databaseUrl,
|
|
542
549
|
max: 1
|
|
543
550
|
});
|
|
544
551
|
try {
|
|
545
|
-
return {
|
|
552
|
+
return { contexts: (await pool.query(`SELECT id, org_id, name, type, enabled, branch_restrictions, required_reviewers,
|
|
546
553
|
wait_timer_seconds, hold_expiry_seconds, minimum_trust,
|
|
547
554
|
created_at, updated_at
|
|
548
|
-
FROM
|
|
555
|
+
FROM contexts
|
|
549
556
|
WHERE org_id = $1
|
|
550
557
|
ORDER BY name`, [opts.orgId])).rows };
|
|
551
558
|
} finally {
|
|
@@ -553,10 +560,10 @@ async function listEnvironmentsDirect(databaseUrl, opts) {
|
|
|
553
560
|
}
|
|
554
561
|
}
|
|
555
562
|
/**
|
|
556
|
-
* Fetch a single
|
|
557
|
-
* Throws if the
|
|
563
|
+
* Fetch a single context row joined with its variables and bindings.
|
|
564
|
+
* Throws if the context does not exist.
|
|
558
565
|
*/
|
|
559
|
-
async function
|
|
566
|
+
async function showContextDirect(databaseUrl, opts) {
|
|
560
567
|
const pool = new pg.Pool({
|
|
561
568
|
connectionString: databaseUrl,
|
|
562
569
|
max: 1
|
|
@@ -565,20 +572,20 @@ async function showEnvironmentDirect(databaseUrl, opts) {
|
|
|
565
572
|
const envResult = await pool.query(`SELECT id, org_id, name, type, enabled, branch_restrictions, required_reviewers,
|
|
566
573
|
wait_timer_seconds, hold_expiry_seconds, minimum_trust,
|
|
567
574
|
created_at, updated_at
|
|
568
|
-
FROM
|
|
575
|
+
FROM contexts
|
|
569
576
|
WHERE org_id = $1 AND name = $2`, [opts.orgId, opts.name]);
|
|
570
|
-
if (envResult.rows.length === 0) throw new Error(`
|
|
577
|
+
if (envResult.rows.length === 0) throw new Error(`context: not found (org=${opts.orgId}, name=${opts.name})`);
|
|
571
578
|
const env = envResult.rows[0];
|
|
572
579
|
const variables = await pool.query(`SELECT key, value, locked, updated_at
|
|
573
|
-
FROM
|
|
574
|
-
WHERE
|
|
580
|
+
FROM context_variables
|
|
581
|
+
WHERE context_id = $1
|
|
575
582
|
ORDER BY key`, [env.id]);
|
|
576
583
|
const bindings = await pool.query(`SELECT scope_pattern, host_pattern, created_at
|
|
577
|
-
FROM
|
|
578
|
-
WHERE
|
|
584
|
+
FROM context_bindings
|
|
585
|
+
WHERE context_id = $1
|
|
579
586
|
ORDER BY scope_pattern, host_pattern`, [env.id]);
|
|
580
587
|
return {
|
|
581
|
-
|
|
588
|
+
context: env,
|
|
582
589
|
variables: variables.rows,
|
|
583
590
|
bindings: bindings.rows
|
|
584
591
|
};
|
|
@@ -587,11 +594,16 @@ async function showEnvironmentDirect(databaseUrl, opts) {
|
|
|
587
594
|
}
|
|
588
595
|
}
|
|
589
596
|
/**
|
|
590
|
-
* Create (or update)
|
|
591
|
-
* transaction. Templates are represented as
|
|
597
|
+
* Create (or update) a context template + its seed variables in one
|
|
598
|
+
* transaction. Templates are represented as contexts with `type='template'`
|
|
592
599
|
* by convention. Returns `{ envId, variablesSet }`.
|
|
600
|
+
*
|
|
601
|
+
* An omitted `holdExpirySeconds` is written as NULL rather than a literal
|
|
602
|
+
* window, for the same reason as `seedContextDirect`: the column has no DDL
|
|
603
|
+
* default and every read resolves NULL through `DEFAULT_HOLD_EXPIRY_SECONDS`.
|
|
593
604
|
*/
|
|
594
|
-
async function
|
|
605
|
+
async function createContextTemplateDirect(databaseUrl, opts) {
|
|
606
|
+
if (opts.holdExpirySeconds != null && opts.holdExpirySeconds < 1) throw new Error(`context: holdExpirySeconds must be >= 1 (got ${opts.holdExpirySeconds})`);
|
|
595
607
|
const pool = new pg.Pool({
|
|
596
608
|
connectionString: databaseUrl,
|
|
597
609
|
max: 1
|
|
@@ -599,12 +611,12 @@ async function createEnvironmentTemplateDirect(databaseUrl, opts) {
|
|
|
599
611
|
const client = await pool.connect();
|
|
600
612
|
try {
|
|
601
613
|
await client.query("BEGIN");
|
|
602
|
-
const row = (await client.query(`INSERT INTO
|
|
614
|
+
const row = (await client.query(`INSERT INTO contexts
|
|
603
615
|
(org_id, name, type, enabled, branch_restrictions, required_reviewers,
|
|
604
616
|
wait_timer_seconds, hold_expiry_seconds, minimum_trust)
|
|
605
|
-
VALUES ($1, $2, COALESCE($3, 'template'), true, $4::jsonb, $5::jsonb, $6,
|
|
617
|
+
VALUES ($1, $2, COALESCE($3, 'template'), true, $4::jsonb, $5::jsonb, $6, $7, $8)
|
|
606
618
|
ON CONFLICT (org_id, name) DO UPDATE SET
|
|
607
|
-
type = COALESCE(EXCLUDED.type,
|
|
619
|
+
type = COALESCE(EXCLUDED.type, contexts.type),
|
|
608
620
|
branch_restrictions = EXCLUDED.branch_restrictions,
|
|
609
621
|
required_reviewers = EXCLUDED.required_reviewers,
|
|
610
622
|
wait_timer_seconds = EXCLUDED.wait_timer_seconds,
|
|
@@ -621,12 +633,12 @@ async function createEnvironmentTemplateDirect(databaseUrl, opts) {
|
|
|
621
633
|
opts.holdExpirySeconds ?? null,
|
|
622
634
|
opts.minimumTrust ?? null
|
|
623
635
|
])).rows[0];
|
|
624
|
-
if (!row) throw new Error(`
|
|
636
|
+
if (!row) throw new Error(`context: template upsert returned no row`);
|
|
625
637
|
let variablesSet = 0;
|
|
626
638
|
if (opts.variables) for (const [key, value] of Object.entries(opts.variables)) {
|
|
627
|
-
await client.query(`INSERT INTO
|
|
639
|
+
await client.query(`INSERT INTO context_variables (org_id, context_id, key, value, locked)
|
|
628
640
|
VALUES ($1, $2, $3, $4, false)
|
|
629
|
-
ON CONFLICT (org_id,
|
|
641
|
+
ON CONFLICT (org_id, context_id, key) DO UPDATE SET
|
|
630
642
|
value = EXCLUDED.value,
|
|
631
643
|
updated_at = now()`, [
|
|
632
644
|
opts.orgId,
|
|
@@ -651,14 +663,14 @@ async function createEnvironmentTemplateDirect(databaseUrl, opts) {
|
|
|
651
663
|
}
|
|
652
664
|
}
|
|
653
665
|
/**
|
|
654
|
-
* UPSERT a scoped_secrets row keyed by (org_id, scope=
|
|
666
|
+
* UPSERT a scoped_secrets row keyed by (org_id, scope=context, key).
|
|
655
667
|
* Writes the value verbatim — the caller is responsible for encryption
|
|
656
668
|
* (matches the stage-4 deferral noted in the plan).
|
|
657
669
|
*/
|
|
658
|
-
async function
|
|
659
|
-
if (!opts.orgId) throw new Error("
|
|
660
|
-
if (!opts.
|
|
661
|
-
if (!opts.key) throw new Error("
|
|
670
|
+
async function setContextSecretDirect(databaseUrl, opts) {
|
|
671
|
+
if (!opts.orgId) throw new Error("context: orgId required");
|
|
672
|
+
if (!opts.context) throw new Error("context: context name required");
|
|
673
|
+
if (!opts.key) throw new Error("context: key required");
|
|
662
674
|
const pool = new pg.Pool({
|
|
663
675
|
connectionString: databaseUrl,
|
|
664
676
|
max: 1
|
|
@@ -671,7 +683,7 @@ async function setEnvironmentSecretDirect(databaseUrl, opts) {
|
|
|
671
683
|
updated_at = now()
|
|
672
684
|
RETURNING (xmax = 0) AS inserted`, [
|
|
673
685
|
opts.orgId,
|
|
674
|
-
opts.
|
|
686
|
+
opts.context,
|
|
675
687
|
opts.key,
|
|
676
688
|
opts.encryptedValue
|
|
677
689
|
])).rows[0]?.inserted ?? false };
|
|
@@ -789,7 +801,7 @@ async function listExecutionRunsDirect(databaseUrl, opts = {}) {
|
|
|
789
801
|
const limit = Math.max(1, Math.min(1e3, opts.limit ?? 100));
|
|
790
802
|
const where = clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
791
803
|
return { runs: (await pool.query(`SELECT id, run_id, workflow_name, status, provider, repo_identifier,
|
|
792
|
-
ref, sha, routing_key,
|
|
804
|
+
ref, sha, routing_key, context, trust_tier, created_at,
|
|
793
805
|
started_at, completed_at, duration_ms
|
|
794
806
|
FROM execution_runs
|
|
795
807
|
${where}
|
|
@@ -800,6 +812,38 @@ async function listExecutionRunsDirect(databaseUrl, opts = {}) {
|
|
|
800
812
|
}
|
|
801
813
|
}
|
|
802
814
|
/**
|
|
815
|
+
* READ-ONLY: SELECT check_run_tracking rows for a commit. One row per
|
|
816
|
+
* `(provider, owner, repo, sha, check_name)`, ordered by check_name.
|
|
817
|
+
*
|
|
818
|
+
* Each column answers a different question. `check_run_id` is written once,
|
|
819
|
+
* when the check run is created in the `queued` state, so it answers "did we
|
|
820
|
+
* create it?". `terminal_sent_at` is stamped only after the provider accepts
|
|
821
|
+
* the terminal `completed` PATCH, so it answers "did we complete it?". Every
|
|
822
|
+
* write here is best-effort, so a null column is "no record", never proof of
|
|
823
|
+
* failure — see the per-field notes for what each one does and does not prove.
|
|
824
|
+
*/
|
|
825
|
+
async function listCheckRunTrackingDirect(databaseUrl, opts) {
|
|
826
|
+
const pool = createPool(databaseUrl);
|
|
827
|
+
try {
|
|
828
|
+
const clauses = ["sha = $1"];
|
|
829
|
+
const params = [opts.sha];
|
|
830
|
+
if (opts.checkName !== void 0) {
|
|
831
|
+
clauses.push(`check_name = $2`);
|
|
832
|
+
params.push(opts.checkName);
|
|
833
|
+
}
|
|
834
|
+
const limit = Math.max(1, Math.min(1e3, opts.limit ?? 50));
|
|
835
|
+
return { rows: (await pool.query(`SELECT provider, owner, repo, sha, check_name,
|
|
836
|
+
check_run_id::text AS check_run_id,
|
|
837
|
+
build_creation_state, run_id, in_progress_sent_at, terminal_sent_at
|
|
838
|
+
FROM check_run_tracking
|
|
839
|
+
WHERE ${clauses.join(" AND ")}
|
|
840
|
+
ORDER BY check_name
|
|
841
|
+
LIMIT ${limit}`, params)).rows };
|
|
842
|
+
} finally {
|
|
843
|
+
await pool.end();
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
803
847
|
* READ-ONLY: fetch a single run by run_id AND its jobs. Throws if no run
|
|
804
848
|
* matches the run_id. Jobs list may be empty for pending runs.
|
|
805
849
|
*/
|
|
@@ -807,7 +851,7 @@ async function showExecutionRunDirect(databaseUrl, opts) {
|
|
|
807
851
|
const pool = createPool(databaseUrl);
|
|
808
852
|
try {
|
|
809
853
|
const runResult = await pool.query(`SELECT id, run_id, workflow_name, status, provider, repo_identifier,
|
|
810
|
-
ref, sha, routing_key,
|
|
854
|
+
ref, sha, routing_key, context, trust_tier, created_at,
|
|
811
855
|
started_at, completed_at, duration_ms
|
|
812
856
|
FROM execution_runs
|
|
813
857
|
WHERE run_id = $1`, [opts.runId]);
|
|
@@ -816,7 +860,7 @@ async function showExecutionRunDirect(databaseUrl, opts) {
|
|
|
816
860
|
return {
|
|
817
861
|
run,
|
|
818
862
|
jobs: (await pool.query(`SELECT id, run_id, job_id, job_name, status, agent_id,
|
|
819
|
-
started_at, completed_at, duration_ms, created_at, error_message,
|
|
863
|
+
started_at, completed_at, duration_ms, created_at, error_message, contexts
|
|
820
864
|
FROM execution_jobs
|
|
821
865
|
WHERE run_id = $1
|
|
822
866
|
ORDER BY created_at ASC`, [run.run_id])).rows
|
|
@@ -834,7 +878,7 @@ async function listExecutionJobsDirect(databaseUrl, opts) {
|
|
|
834
878
|
try {
|
|
835
879
|
return { jobs: (await pool.query(`SELECT j.id, j.run_id, j.job_id, j.job_name, j.status, j.agent_id,
|
|
836
880
|
j.started_at, j.completed_at, j.duration_ms, j.created_at, j.error_message,
|
|
837
|
-
j.
|
|
881
|
+
j.contexts
|
|
838
882
|
FROM execution_jobs j
|
|
839
883
|
INNER JOIN execution_runs r ON r.run_id = j.run_id
|
|
840
884
|
WHERE r.run_id::text = $1 OR r.id::text = $1
|
|
@@ -1648,8 +1692,10 @@ async function seedUniversalGitSourceDirect(databaseUrl, opts) {
|
|
|
1648
1692
|
await pool.end();
|
|
1649
1693
|
}
|
|
1650
1694
|
}
|
|
1695
|
+
/** repo_identifier used for the different-repo isolation hold. */
|
|
1696
|
+
const CI_SECURITY_OTHER_REPO = "other/repo";
|
|
1651
1697
|
async function seedCiSecurityFixturesDirect(databaseUrl, opts) {
|
|
1652
|
-
const
|
|
1698
|
+
const contextName = opts.contextName ?? "ci-security-env";
|
|
1653
1699
|
const sourceName = opts.sourceName ?? "ci-security-dashboard-resolver";
|
|
1654
1700
|
const sourceRoutingKey = opts.sourceRoutingKey ?? `generic:${opts.orgId}:ci-security-dashboard`;
|
|
1655
1701
|
const pool = createPool(databaseUrl);
|
|
@@ -1661,37 +1707,89 @@ async function seedCiSecurityFixturesDirect(databaseUrl, opts) {
|
|
|
1661
1707
|
sourceRoutingKey,
|
|
1662
1708
|
opts.orgId
|
|
1663
1709
|
]);
|
|
1664
|
-
const envId = (await pool.query(`INSERT INTO
|
|
1710
|
+
const envId = (await pool.query(`INSERT INTO contexts (org_id, name, type, enabled)
|
|
1665
1711
|
VALUES ($1, $2, \'fixed\', true)
|
|
1666
1712
|
ON CONFLICT (org_id, name) DO UPDATE SET enabled = true
|
|
1667
|
-
RETURNING id`, [opts.orgId,
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1713
|
+
RETURNING id`, [opts.orgId, contextName])).rows[0].id;
|
|
1714
|
+
async function seedPrHold(args) {
|
|
1715
|
+
await pool.query(`INSERT INTO execution_runs (
|
|
1716
|
+
run_id, workflow_name, provider, repo_identifier,
|
|
1717
|
+
ref, sha, delivery_id, status, trust_tier, lock_file_source,
|
|
1718
|
+
contributor_username, routing_key, pr_number
|
|
1719
|
+
) VALUES ($1, \'e2e-security-wf\', \'internal\', $4, \'refs/heads/feature\',
|
|
1720
|
+
$5, $2, \'pending\', \'unknown\', \'base\', \'unknown-dev\', $3, $6)`, [
|
|
1721
|
+
args.runId,
|
|
1722
|
+
args.deliveryId,
|
|
1723
|
+
opts.runsRoutingKey,
|
|
1724
|
+
args.repoIdentifier,
|
|
1725
|
+
args.sha,
|
|
1726
|
+
args.prNumber
|
|
1727
|
+
]);
|
|
1728
|
+
await pool.query(`INSERT INTO execution_jobs (job_id, run_id, job_name, status)
|
|
1729
|
+
VALUES ($1, $2, \'security-test-job\', \'pending\')`, [args.jobId, args.runId]);
|
|
1730
|
+
return (await pool.query(`INSERT INTO held_runs (org_id, run_id, job_id, context_id, hold_type, queue_type, reason, expires_at)
|
|
1731
|
+
VALUES ($1, $2, $3, $4, $5, \'security\', $6, NOW() + INTERVAL \'72 hours\')
|
|
1732
|
+
RETURNING id`, [
|
|
1733
|
+
opts.orgId,
|
|
1734
|
+
args.runId,
|
|
1735
|
+
args.jobId,
|
|
1736
|
+
args.contextId === void 0 ? envId : args.contextId,
|
|
1737
|
+
args.holdType ?? HoldType.enum.security,
|
|
1738
|
+
args.reason ?? unknownContributorHoldReason(contextName)
|
|
1739
|
+
])).rows[0].id;
|
|
1740
|
+
}
|
|
1741
|
+
const heldRunId = await seedPrHold({
|
|
1742
|
+
runId: opts.unknownRunId,
|
|
1743
|
+
deliveryId: opts.unknownDeliveryId,
|
|
1744
|
+
jobId: opts.unknownJobId,
|
|
1745
|
+
repoIdentifier: ".",
|
|
1746
|
+
prNumber: 1,
|
|
1747
|
+
sha: "abc123"
|
|
1748
|
+
});
|
|
1749
|
+
const secondHeldRunId = await seedPrHold({
|
|
1750
|
+
runId: opts.secondPrRunId,
|
|
1751
|
+
deliveryId: opts.secondPrDeliveryId,
|
|
1752
|
+
jobId: opts.secondPrJobId,
|
|
1753
|
+
repoIdentifier: ".",
|
|
1754
|
+
prNumber: 2,
|
|
1755
|
+
sha: "bbb222"
|
|
1756
|
+
});
|
|
1757
|
+
const otherRepoHeldRunId = await seedPrHold({
|
|
1758
|
+
runId: opts.otherRepoRunId,
|
|
1759
|
+
deliveryId: opts.otherRepoDeliveryId,
|
|
1760
|
+
jobId: opts.otherRepoJobId,
|
|
1761
|
+
repoIdentifier: CI_SECURITY_OTHER_REPO,
|
|
1762
|
+
prNumber: 1,
|
|
1763
|
+
sha: "ccc333"
|
|
1764
|
+
});
|
|
1765
|
+
const wfModHeldRunId = await seedPrHold({
|
|
1766
|
+
runId: opts.wfModRunId,
|
|
1767
|
+
deliveryId: opts.wfModDeliveryId,
|
|
1768
|
+
jobId: opts.wfModJobId,
|
|
1769
|
+
repoIdentifier: ".",
|
|
1770
|
+
prNumber: 3,
|
|
1771
|
+
sha: "ddd444",
|
|
1772
|
+
holdType: HoldType.enum.security,
|
|
1773
|
+
reason: "workflow_modification",
|
|
1774
|
+
contextId: null
|
|
1775
|
+
});
|
|
1776
|
+
const forkPrHeldRunId = await seedPrHold({
|
|
1777
|
+
runId: opts.forkPrRunId,
|
|
1778
|
+
deliveryId: opts.forkPrDeliveryId,
|
|
1779
|
+
jobId: opts.forkPrJobId,
|
|
1780
|
+
repoIdentifier: ".",
|
|
1781
|
+
prNumber: 4,
|
|
1782
|
+
sha: "eee555",
|
|
1783
|
+
holdType: HoldType.enum.security,
|
|
1784
|
+
reason: "fork_pr",
|
|
1785
|
+
contextId: null
|
|
1786
|
+
});
|
|
1689
1787
|
await pool.query(`INSERT INTO execution_runs (
|
|
1690
1788
|
run_id, workflow_name, provider, repo_identifier,
|
|
1691
1789
|
ref, sha, delivery_id, status, trust_tier, lock_file_source,
|
|
1692
|
-
contributor_username, routing_key
|
|
1790
|
+
contributor_username, routing_key, pr_number
|
|
1693
1791
|
) VALUES ($1, \'e2e-security-wf\', \'internal\', \'.\', \'refs/heads/feature\',
|
|
1694
|
-
\'def456\', $2, \'running\', \'trusted\', \'head\', \'trusted-dev\', $3)`, [
|
|
1792
|
+
\'def456\', $2, \'running\', \'trusted\', \'head\', \'trusted-dev\', $3, 1)`, [
|
|
1695
1793
|
opts.trustedRunId,
|
|
1696
1794
|
opts.trustedDeliveryId,
|
|
1697
1795
|
opts.runsRoutingKey
|
|
@@ -1699,31 +1797,43 @@ async function seedCiSecurityFixturesDirect(databaseUrl, opts) {
|
|
|
1699
1797
|
await pool.query(`INSERT INTO execution_jobs (job_id, run_id, job_name, status)
|
|
1700
1798
|
VALUES ($1, $2, \'security-test-job\', \'running\')`, [opts.trustedJobId, opts.trustedRunId]);
|
|
1701
1799
|
return {
|
|
1800
|
+
contextName,
|
|
1702
1801
|
envId,
|
|
1703
|
-
heldRunId
|
|
1802
|
+
heldRunId,
|
|
1803
|
+
secondHeldRunId,
|
|
1804
|
+
otherRepoHeldRunId,
|
|
1805
|
+
wfModHeldRunId,
|
|
1806
|
+
forkPrHeldRunId
|
|
1704
1807
|
};
|
|
1705
1808
|
} finally {
|
|
1706
1809
|
await pool.end();
|
|
1707
1810
|
}
|
|
1708
1811
|
}
|
|
1709
1812
|
/**
|
|
1710
|
-
* Poll `execution_runs` for
|
|
1711
|
-
* `
|
|
1712
|
-
*
|
|
1813
|
+
* Poll `execution_runs` for the newest run started since `since` whose status
|
|
1814
|
+
* is in `statuses`, returning that status. Resolves `{ status: null }` if the
|
|
1815
|
+
* deadline passes before any run reaches a target status.
|
|
1816
|
+
*
|
|
1817
|
+
* Callers wanting "did the run finish?" pass the terminal status set and read
|
|
1818
|
+
* the landed status — a terminal failure is reported immediately rather than
|
|
1819
|
+
* indistinguishable from a timeout. Used by the cluster reroute tests to gate
|
|
1820
|
+
* on a workflow reaching a terminal state after a webhook trigger.
|
|
1713
1821
|
*/
|
|
1714
|
-
async function
|
|
1715
|
-
const timeoutMs = opts.timeoutMs ??
|
|
1822
|
+
async function waitForExecutionRunReachesStatusSinceDirect(databaseUrl, opts) {
|
|
1823
|
+
const timeoutMs = opts.timeoutMs ?? 24e4;
|
|
1716
1824
|
const intervalMs = opts.intervalMs ?? 5e3;
|
|
1717
1825
|
const deadline = Date.now() + timeoutMs;
|
|
1718
1826
|
const pool = createPool(databaseUrl);
|
|
1719
1827
|
try {
|
|
1720
1828
|
while (Date.now() < deadline) {
|
|
1721
|
-
|
|
1722
|
-
WHERE started_at > $1 AND status = $2
|
|
1723
|
-
|
|
1829
|
+
const result = await pool.query(`SELECT status FROM execution_runs
|
|
1830
|
+
WHERE started_at > $1 AND status = ANY($2)
|
|
1831
|
+
ORDER BY started_at DESC
|
|
1832
|
+
LIMIT 1`, [opts.since, [...opts.statuses]]);
|
|
1833
|
+
if (result.rows.length > 0) return { status: result.rows[0].status };
|
|
1724
1834
|
await new Promise((r) => setTimeout(r, intervalMs));
|
|
1725
1835
|
}
|
|
1726
|
-
return {
|
|
1836
|
+
return { status: null };
|
|
1727
1837
|
} finally {
|
|
1728
1838
|
await pool.end();
|
|
1729
1839
|
}
|
|
@@ -2269,11 +2379,15 @@ async function bumpRegistryVersionSimpleDirect(databaseUrl, opts = {}) {
|
|
|
2269
2379
|
async function upsertCronLastFiredDirect(databaseUrl, opts) {
|
|
2270
2380
|
const pool = createPool(databaseUrl);
|
|
2271
2381
|
try {
|
|
2272
|
-
await pool.query(`INSERT INTO cron_last_fired (registration_id, last_fired_at)
|
|
2273
|
-
VALUES ($1, NOW() - ($2)::interval)
|
|
2274
|
-
ON CONFLICT (registration_id) DO UPDATE SET
|
|
2382
|
+
await pool.query(`INSERT INTO cron_last_fired (registration_id, schedule_key, last_fired_at)
|
|
2383
|
+
VALUES ($1, $3, NOW() - ($2)::interval)
|
|
2384
|
+
ON CONFLICT (registration_id, schedule_key) DO UPDATE SET
|
|
2275
2385
|
last_fired_at = NOW() - ($2)::interval,
|
|
2276
|
-
updated_at = NOW()`, [
|
|
2386
|
+
updated_at = NOW()`, [
|
|
2387
|
+
opts.registrationId,
|
|
2388
|
+
opts.agoInterval,
|
|
2389
|
+
opts.scheduleKey
|
|
2390
|
+
]);
|
|
2277
2391
|
} finally {
|
|
2278
2392
|
await pool.end();
|
|
2279
2393
|
}
|
|
@@ -2297,7 +2411,7 @@ async function countCronLastFiredDirect(databaseUrl, opts) {
|
|
|
2297
2411
|
async function insertCronLastFiredNowDirect(databaseUrl, opts) {
|
|
2298
2412
|
const pool = createPool(databaseUrl);
|
|
2299
2413
|
try {
|
|
2300
|
-
await pool.query(`INSERT INTO cron_last_fired (registration_id, last_fired_at) VALUES ($1, NOW())`, [opts.registrationId]);
|
|
2414
|
+
await pool.query(`INSERT INTO cron_last_fired (registration_id, schedule_key, last_fired_at) VALUES ($1, $2, NOW())`, [opts.registrationId, opts.scheduleKey]);
|
|
2301
2415
|
} finally {
|
|
2302
2416
|
await pool.end();
|
|
2303
2417
|
}
|
|
@@ -2754,6 +2868,6 @@ async function terminateIdleDbBackendsDirect(databaseUrl) {
|
|
|
2754
2868
|
}
|
|
2755
2869
|
}
|
|
2756
2870
|
//#endregion
|
|
2757
|
-
export { MIGRATION_HASH_TABLE, PROVIDER_HASH_KEY, REGISTERABLE_TRIGGER_TYPES, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect,
|
|
2871
|
+
export { CI_SECURITY_OTHER_REPO, MIGRATION_HASH_TABLE, PROVIDER_HASH_KEY, REGISTERABLE_TRIGGER_TYPES, apiKeyExistsDirect, bumpRegistryVersionDirect, bumpRegistryVersionSimpleDirect, cleanupExecutionRowsDirect, clearDispatchQueueDirect, clearPeerCredentialsRevokedAtByIdsDirect, computeMigrationsHash, countActivePeerCredentialsByInstanceDirect, countCronLastFiredDirect, countHeldRunsByRunIdDirect, countWebhookSourcesByConnectionIdDirect, createContextTemplateDirect, createDbRole, createJoinTokenDirect, createReadOnlyDbUser, deleteContextDirect, deleteCronLastFiredDirect, deleteCrossRepoTrustDirect, deleteExecutionRunsByWorkflowNameDirect, deleteGenericWebhookSourcesByNameDirect, deleteJoinTokensByCreatedByDirect, deleteKiciEventsDirect, deleteOrgSettingsByCustomerIdDirect, deletePeerCredentialsByInstanceIdLikeDirect, deleteWorkflowRegistrationsDirect, describeTableColumnsDirect, dropAndCreateDatabase, dropDatabaseDirect, emitKiciEventDirect, ensureDatabase, ensureOrgOwnerMemberDirect, findAnyUserApiKeyIdDirect, getExecutionRunSecurityDirect, getGenericWebhookSourceByRoutingKeyDirect, getHeldRunByIdDirect, getPeerCredentialRevokedAtDirect, getRegistryVersionDirect, getWebhookSourceByRoutingKeyDirect, getWorkflowRegistrationByIdDirect, insertCronLastFiredNowDirect, insertCrossRepoTrustStrictDirect, insertKiciEventAtDirect, insertKiciEventRawDirect, insertPeerCredentialExpiredDirect, insertWorkflowRegistrationRawDirect, insertWorkflowRegistrationStrictDirect, isSchemaCurrent, isSchemaCurrentFromFilesDirect, latestExecutionRunByStatusDirect, listActiveGenericWebhookSourcesDirect, listActivePeerCredentialsExcludingDirect, listCheckRunTrackingDirect, listContextsDirect, listCrossRepoTrustBySourceRoutingKeyDirect, listExecutionJobsDirect, listExecutionRunsDirect, listHeldRunApprovalsDirect, listKiciEventsDirect, listQueueDirect, listRegistrationsByRoutingKeyDirect, listRegistrationsDirect, maskDatabaseUrl, paginateUnprocessedEventsKeysetDirect, parseDatabaseUrl, platformConnectionExistsDirect, pollKiciEventsDirect, prunePeerCredentialsDirect, purgeContextsDirect, purgeScopedSecretsDirect, purgeSecretBackendsDirect, purgeStaleExecutionDirect, purgeStaleSourcesDirect, readStoredMigrationContentHash, registerWorkflowManualDirect, resetRaftStateDirect, resolvePlatformWebhookSourceRoutingKeyDirect, restoreSoftDeletedGenericWebhookSourceDirect, seedApiKeyInlineDirect, seedCiSecurityFixturesDirect, seedContextBindingDirect, seedContextDirect, seedCrossRepoTrustDirect, seedGenericWebhookSourceDirect, seedSourcePrivateKeyDirect, seedSyntheticGithubSourceDirect, seedUniversalGitSourceDirect, seedWebhookSecretDirect, setContextPolicyDirect, setContextSecretDirect, showContextDirect, showExecutionRunDirect, showKiciEventDirect, showQueueEntryDirect, showRegistrationDirect, storeMigrationContentHash, storeMigrationContentHashInTableDirect, tableExistsDirect, terminateIdleDbBackendsDirect, updateGenericWebhookVerificationConfigDirect, updateOrgSettingsDeniedReposDirect, updateSourceRoutingKeyDirect, updateWorkflowRegistrationCommitShaDirect, upsertCronLastFiredDirect, upsertOrgSettingsGlobalWorkflowsDirect, verifyKiciEventNotifyDirect, waitForEventLogRowByDeliveryIdDirect, waitForExecutionRunReachesStatusSinceDirect, waitForLatestExecutionJobStatusDirect, waitForPlatformEventLogDistinctRoutedDirect, waitForPlatformExecutionRunStatusDirect, waitForPlatformRegistrationsDirect, waitForPostgresDirect, waitForRegistrationsByRoutingKeyDirect, waitForRegistrationsUpdatedAtAdvanceDirect, waitForRunCompletionDirect };
|
|
2758
2872
|
|
|
2759
2873
|
//# sourceMappingURL=db-admin.js.map
|