pipework 0.242.0 → 0.245.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/core/config/namespace.d.ts +1 -0
  3. package/dist/core/config/namespace.d.ts.map +1 -1
  4. package/dist/core/config/schema.d.ts +2 -0
  5. package/dist/core/config/schema.d.ts.map +1 -1
  6. package/dist/core/config/schema.js +1 -0
  7. package/dist/core/config/schema.js.map +1 -1
  8. package/dist/data/migrate/apply.d.ts +14 -0
  9. package/dist/data/migrate/apply.d.ts.map +1 -1
  10. package/dist/data/migrate/apply.js +10 -2
  11. package/dist/data/migrate/apply.js.map +1 -1
  12. package/dist/data/migrate/provision-framework.d.ts.map +1 -1
  13. package/dist/data/migrate/provision-framework.js +6 -2
  14. package/dist/data/migrate/provision-framework.js.map +1 -1
  15. package/dist/infra/alerts/handle.d.ts.map +1 -1
  16. package/dist/infra/alerts/handle.js +11 -10
  17. package/dist/infra/alerts/handle.js.map +1 -1
  18. package/dist/test/auto-setup.js +2 -2
  19. package/dist/test/auto-setup.js.map +1 -1
  20. package/dist/test/index.d.ts +1 -0
  21. package/dist/test/index.d.ts.map +1 -1
  22. package/dist/test/index.js +1 -0
  23. package/dist/test/index.js.map +1 -1
  24. package/dist/test/plugin.d.ts +6 -1
  25. package/dist/test/plugin.d.ts.map +1 -1
  26. package/dist/test/plugin.js +12 -1
  27. package/dist/test/plugin.js.map +1 -1
  28. package/dist/test/reset.d.ts +35 -0
  29. package/dist/test/reset.d.ts.map +1 -0
  30. package/dist/test/reset.js +179 -0
  31. package/dist/test/reset.js.map +1 -0
  32. package/dist/test/setup.d.ts.map +1 -1
  33. package/dist/test/setup.js +89 -7
  34. package/dist/test/setup.js.map +1 -1
  35. package/dist/test/vitest.js +2 -2
  36. package/dist/test/vitest.js.map +1 -1
  37. package/dist/test/watch.d.ts +21 -0
  38. package/dist/test/watch.d.ts.map +1 -0
  39. package/dist/test/watch.js +81 -0
  40. package/dist/test/watch.js.map +1 -0
  41. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
1
  export { setupTestDatabases, teardownTestDatabases, getTestDatabase, getTestDatabases, type TestDatabase, type SetupOptions } from './setup.js';
2
2
  export { flushPendingDrops, TEST_DROP_LOG_PREFIX, TEST_REAP_LOG_PREFIX } from './setup.js';
3
3
  export { SetupStalled, logSlowPhases, SETUP_PROGRESS_LOG_PREFIX, type SetupPhase, type SetupProgress, type SetupProgressListener, } from './progress.js';
4
+ export { armTestWatch, TEST_WATCH_LOG_PREFIX, type TestWatchTarget } from './watch.js';
4
5
  export { beginTestIsolation, endTestIsolation, type TestContext, type TestDatabaseConnections } from './plugin.js';
5
6
  export { setupPipeworkTests, useTestDb, useSetupDb, useTestInstance, useTestClient, type UseTestClientOptions, closeSetupConnections, SetupConnectionCloseError, teardownAfterAll, withFlow, type WithFlowOptions } from './vitest.js';
6
7
  export { mockAuth, asTenant } from './auth.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,eAAe,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAC/I,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAC1F,OAAO,EACL,YAAY,EACZ,aAAa,EACb,yBAAyB,EACzB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,qBAAqB,GAC3B,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AACtO,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACnF,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AACzF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACjF,OAAO,EAAE,GAAG,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACrF,OAAO,EAAE,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,eAAe,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAC/I,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAC1F,OAAO,EACL,YAAY,EACZ,aAAa,EACb,yBAAyB,EACzB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,qBAAqB,GAC3B,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAA;AACtF,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AACtO,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACnF,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AACzF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACjF,OAAO,EAAE,GAAG,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACrF,OAAO,EAAE,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAA"}
@@ -1,6 +1,7 @@
1
1
  export { setupTestDatabases, teardownTestDatabases, getTestDatabase, getTestDatabases } from './setup.js';
2
2
  export { flushPendingDrops, TEST_DROP_LOG_PREFIX, TEST_REAP_LOG_PREFIX } from './setup.js';
3
3
  export { SetupStalled, logSlowPhases, SETUP_PROGRESS_LOG_PREFIX, } from './progress.js';
4
+ export { armTestWatch, TEST_WATCH_LOG_PREFIX } from './watch.js';
4
5
  export { beginTestIsolation, endTestIsolation } from './plugin.js';
5
6
  export { setupPipeworkTests, useTestDb, useSetupDb, useTestInstance, useTestClient, closeSetupConnections, SetupConnectionCloseError, teardownAfterAll, withFlow } from './vitest.js';
6
7
  export { mockAuth, asTenant } from './auth.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,eAAe,EAAE,gBAAgB,EAAwC,MAAM,YAAY,CAAA;AAC/I,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAC1F,OAAO,EACL,YAAY,EACZ,aAAa,EACb,yBAAyB,GAI1B,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAkD,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAA6B,qBAAqB,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAA;AACtO,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,cAAc,EAA2B,MAAM,cAAc,CAAA;AACnF,OAAO,EAAE,QAAQ,IAAI,YAAY,EAA8B,MAAM,oBAAoB,CAAA;AACzF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACjF,OAAO,EAAE,GAAG,EAA+C,MAAM,oBAAoB,CAAA;AACrF,OAAO,EAAE,gBAAgB,EAAqG,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,eAAe,EAAE,gBAAgB,EAAwC,MAAM,YAAY,CAAA;AAC/I,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAC1F,OAAO,EACL,YAAY,EACZ,aAAa,EACb,yBAAyB,GAI1B,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAwB,MAAM,YAAY,CAAA;AACtF,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAkD,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAA6B,qBAAqB,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAA;AACtO,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,cAAc,EAA2B,MAAM,cAAc,CAAA;AACnF,OAAO,EAAE,QAAQ,IAAI,YAAY,EAA8B,MAAM,oBAAoB,CAAA;AACzF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACjF,OAAO,EAAE,GAAG,EAA+C,MAAM,oBAAoB,CAAA;AACrF,OAAO,EAAE,gBAAgB,EAAqG,MAAM,oBAAoB,CAAA"}
@@ -11,7 +11,12 @@ export interface TestContext {
11
11
  id: string;
12
12
  db: TestDatabaseConnections;
13
13
  }
14
- export declare function beginTestIsolation(instance: Manifold): Promise<TestContext>;
14
+ /** The slice of vitest's `task` the watch needs: `fullName` and the resolved `timeout`. */
15
+ export interface WatchedTask {
16
+ fullName: string;
17
+ timeout: number;
18
+ }
19
+ export declare function beginTestIsolation(instance: Manifold, task?: WatchedTask): Promise<TestContext>;
15
20
  export declare function endTestIsolation(instance: Manifold, ctx: TestContext): Promise<void>;
16
21
  export declare function createTestContext(instance: Manifold, testConnections: TestContext, auth?: unknown, tenant?: string | null): Flow;
17
22
  export declare function propagateTestSessionVars(instance: Manifold, testConnections: TestContext, tenant: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/test/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,kBAAkB,EAAE,MAAM,oCAAoC,CAAA;AAErF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAE/D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAIvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAMnE,MAAM,WAAW,uBAAuB;IACtC,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,uBAAuB,CAAA;CAC5B;AAaD,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAmCjF;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB1F;AAiCD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAMhI;AAED,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,WAAW,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,aAAa,CAAC,EAAE,qBAAqB,GACpC;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAM7D;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/test/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,kBAAkB,EAAE,MAAM,oCAAoC,CAAA;AAErF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAE/D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAIvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAOnE,MAAM,WAAW,uBAAuB;IACtC,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,uBAAuB,CAAA;CAC5B;AAcD,2FAA2F;AAC3F,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CA0CrG;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B1F;AAiCD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAMhI;AAED,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,WAAW,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,aAAa,CAAC,EAAE,qBAAqB,GACpC;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAM7D;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
@@ -11,8 +11,10 @@ import { collapseTransactionsToSavepoints } from './savepoints.js';
11
11
  import { splitLargeInserts } from '../data/db/insert-split.js';
12
12
  import { settleTraceWritesBounded } from '../trace/runtime/pending-writes.js';
13
13
  import { createSystemHandle } from './system-channel.js';
14
+ import { armTestWatch } from './watch.js';
14
15
  const contextConnections = new Map();
15
- export async function beginTestIsolation(instance) {
16
+ const contextWatches = new Map();
17
+ export async function beginTestIsolation(instance, task) {
16
18
  const dbConnections = {};
17
19
  const contextId = randomUUID();
18
20
  const connections = new Map();
@@ -37,10 +39,19 @@ export async function beginTestIsolation(instance) {
37
39
  });
38
40
  }
39
41
  contextConnections.set(contextId, connections);
42
+ if (task !== undefined) {
43
+ const databases = [...connections.keys()].flatMap(n => {
44
+ const d = getTestDatabase(n);
45
+ return d ? [{ database: d.database, url: d.url }] : [];
46
+ });
47
+ contextWatches.set(contextId, armTestWatch({ name: task.fullName, timeoutMs: task.timeout, databases }));
48
+ }
40
49
  instance.isolation.markBegin();
41
50
  return { id: contextId, db: dbConnections };
42
51
  }
43
52
  export async function endTestIsolation(instance, ctx) {
53
+ contextWatches.get(ctx.id)?.();
54
+ contextWatches.delete(ctx.id);
44
55
  await settleTraceWritesBounded();
45
56
  instance.pool.clearOverrides();
46
57
  const connections = contextConnections.get(ctx.id);
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/test/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAE,OAAO,EAA2B,MAAM,oCAAoC,CAAA;AACrF,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAA;AAE5C,OAAO,EAAE,eAAe,EAAqB,MAAM,YAAY,CAAA;AAC/D,OAAO,EAAE,iBAAiB,IAAI,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,oDAAoD,CAAA;AAE3F,OAAO,EAAE,gCAAgC,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAA;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAoBxD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA6C,CAAA;AAE/E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,QAAkB;IACzD,MAAM,aAAa,GAA4B,EAAE,CAAA;IACjD,MAAM,SAAS,GAAG,UAAU,EAAE,CAAA;IAC9B,MAAM,WAAW,GAAG,IAAI,GAAG,EAAgC,CAAA;IAE3D,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,4CAA4C,IAAI,kCAAkC,CAAC,CAAA;QACrG,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,wBAAwB,CACzC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,CAC3G,CAAA;QACD,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;QAE1B,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YAC3B,IAAI;YACJ,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,MAAM;YACrC,OAAO,EAAE,IAAI;YACb,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,MAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,IAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5F,aAAa;gBACX,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAC7B,0IAA0I;oBAC1I,iHAAiH,CAClH,CAAC,CAAA;YACJ,CAAC;YACD,KAAK,CAAC,KAAK,KAA0C,CAAC;SACvD,CAAC,CAAA;IACJ,CAAC;IAED,kBAAkB,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;IAC9C,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,CAAA;IAC9B,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,EAAE,CAAA;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,QAAkB,EAAE,GAAgB;IACzE,MAAM,wBAAwB,EAAE,CAAA;IAChC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,CAAA;IAE9B,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAClD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,CAAA;QAC5B,OAAM;IACR,CAAC;IAED,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAA;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAA;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;IAED,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACjC,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,CAAA;AAC9B,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,MAAoB,EACpB,WAA8C,EAC9C,IAAY,EACZ,aAAoC,EACpC,UAAmB;IAEnB,MAAM,KAAK,GAAG,aAAa,CAAC,aAAa,CAAC,CAAA;IAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAChG,IAAI,cAAc,CAAC,aAAa,CAAC;QAAE,sBAAsB,CAAC,MAAM,CAAC,CAAA;IACjE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAE1B,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IAClC,MAAM,IAAI,GAAG,gCAAgC,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACzD,iBAAiB,CAAC,EAAE,CAAC,CAAA;IACrB,IAAI,MAAsC,CAAA;IAC1C,IAAI,IAAwD,CAAA;IAC5D,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;QACnC,IAAI,CAAC,MAAM,CAAC,CAAA;QACZ,IAAI,GAAG,CAAC,QAAQ,EAAE,EAAE;YAClB,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;YACnD,IAAI,CAAC,MAAM,CAAC,CAAA;YACZ,OAAO,MAAM,CAAA;QACf,CAAC,CAAA;IACH,CAAC;IAED,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IACpI,OAAO,EAAE,CAAA;AACX,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAkB,EAAE,eAA4B,EAAE,IAAc,EAAE,MAAsB;IACxH,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IAC/D,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;IAC3F,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,QAAkB,EAClB,eAA4B,EAC5B,MAAc;IAEd,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAC/C,IAAI,QAAQ,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAA,qBAAqB,QAAQ,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM,SAAS,CAAC,CAAA;QACvF,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,MAAoB,EACpB,aAAqC;IAErC,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACtE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAChG,IAAI,aAAa,IAAI,cAAc,CAAC,aAAa,CAAC;QAAE,sBAAsB,CAAC,MAAM,CAAC,CAAA;IAClF,MAAM,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAC7C,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,CAAA;AACnD,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/test/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export declare const TEST_RESET_LOG_PREFIX = "pipework:test-reset";
2
+ export type FreshCloneReason = 'digest' | 'prepared-xact' | 'matview' | 'error';
3
+ export interface Baseline {
4
+ digest: string;
5
+ /** Main-fork bytes of every user table, partition and matview. */
6
+ sizes: Map<string, number>;
7
+ /** relfilenode of every matview: a refresh rewrites it. */
8
+ matviews: Map<string, string>;
9
+ /** Tables that already had storage at baseline: always cleared and reloaded. */
10
+ stored: Set<string>;
11
+ /** COPY text of every table that had rows. */
12
+ rows: Map<string, Buffer>;
13
+ /** last_value (null = not called) and start_value of every sequence. */
14
+ sequences: Map<string, {
15
+ last: string | null;
16
+ start: string;
17
+ }>;
18
+ }
19
+ export type ResetOutcome = {
20
+ ok: true;
21
+ cleared: number;
22
+ reloaded: number;
23
+ } | {
24
+ ok: false;
25
+ reason: FreshCloneReason;
26
+ };
27
+ /** Read the state a reset returns to. `url` is a superuser connection to the database. */
28
+ export declare function captureBaseline(url: string): Promise<Baseline>;
29
+ /**
30
+ * Return the database to its baseline. Call after the file's backends are gone.
31
+ * Refuses (ok: false) rather than reset a database whose state a reset cannot
32
+ * undo; nothing is changed in that case.
33
+ */
34
+ export declare function resetDatabase(url: string, baseline: Baseline, superuser?: boolean): Promise<ResetOutcome>;
35
+ //# sourceMappingURL=reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../src/test/reset.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,qBAAqB,wBAAwB,CAAA;AAE1D,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,eAAe,GAAG,SAAS,GAAG,OAAO,CAAA;AAE/E,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1B,2DAA2D;IAC3D,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,gFAAgF;IAChF,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACnB,8CAA8C;IAC9C,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzB,wEAAwE;IACxE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC/D;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAA;AAyE3C,0FAA0F;AAC1F,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CA0BpE;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,QAAQ,EAClB,SAAS,UAAO,GACf,OAAO,CAAC,YAAY,CAAC,CA6DvB"}
@@ -0,0 +1,179 @@
1
+ import postgres from 'postgres';
2
+ // A worker keeps each per-file database across files and returns it to the
3
+ // state it had right after the clone. The baseline is captured once, before
4
+ // any file runs on it; a reset either restores that state exactly or reports
5
+ // that it cannot, and the caller then takes a fresh clone instead.
6
+ export const TEST_RESET_LOG_PREFIX = 'pipework:test-reset';
7
+ const USER_NAMESPACE = `n.nspname !~ '^pg_(toast_)?temp_' AND n.nspname <> 'information_schema' AND n.nspname <> 'pg_catalog'`;
8
+ // One md5 over the user-relevant catalogs. Storage fields (relfilenode,
9
+ // relpages, reltuples, relfrozenxid, ...) are left out: they move without any
10
+ // schema change. Objects below oid 16384 are the cluster's own.
11
+ const DIGEST_QUERY = `
12
+ SELECT md5(concat_ws('|',
13
+ (SELECT md5(coalesce(string_agg(row(n.oid, n.nspname, n.nspowner, n.nspacl)::text, E'\\n' ORDER BY n.oid), ''))
14
+ FROM pg_namespace n WHERE (n.oid >= 16384 OR n.nspname = 'public') AND ${USER_NAMESPACE}),
15
+ (SELECT md5(coalesce(string_agg(row(c.oid, c.relname, c.relnamespace, c.relkind, c.relpersistence, c.relowner, c.relacl, c.relrowsecurity, c.relforcerowsecurity, c.reloptions, c.relispartition, c.relpartbound::text)::text, E'\\n' ORDER BY c.oid), ''))
16
+ FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.oid >= 16384 AND ${USER_NAMESPACE}),
17
+ (SELECT md5(coalesce(string_agg(row(a.attrelid, a.attnum, a.attname, a.atttypid, a.attnotnull, a.atthasdef, a.attisdropped, a.attidentity, a.attgenerated, a.attacl, a.atttypmod, a.attcollation)::text, E'\\n' ORDER BY a.attrelid, a.attnum), ''))
18
+ FROM pg_attribute a JOIN pg_class c ON c.oid = a.attrelid JOIN pg_namespace n ON n.oid = c.relnamespace
19
+ WHERE a.attnum > 0 AND c.oid >= 16384 AND ${USER_NAMESPACE}),
20
+ (SELECT md5(coalesce(string_agg(row(d.oid, d.adrelid, d.adnum, pg_get_expr(d.adbin, d.adrelid))::text, E'\\n' ORDER BY d.oid), '')) FROM pg_attrdef d WHERE d.adrelid >= 16384),
21
+ (SELECT md5(coalesce(string_agg(row(k.oid, k.conname, k.contype, k.conrelid, k.convalidated, k.conkey, k.confrelid, k.confkey, k.conbin, k.condeferrable, k.condeferred, k.connoinherit)::text, E'\\n' ORDER BY k.oid), '')) FROM pg_constraint k WHERE k.oid >= 16384),
22
+ (SELECT md5(coalesce(string_agg(row(i.indexrelid, i.indrelid, i.indkey, i.indisunique, i.indisvalid, i.indisready, i.indpred, i.indexprs)::text, E'\\n' ORDER BY i.indexrelid), '')) FROM pg_index i WHERE i.indexrelid >= 16384),
23
+ (SELECT md5(coalesce(string_agg(row(p.oid, p.proname, p.pronamespace, p.proowner, p.proacl, p.prokind, md5(p.prosrc), p.proargtypes, p.prorettype, p.provolatile, p.prosecdef, p.proconfig, p.proisstrict)::text, E'\\n' ORDER BY p.oid), '')) FROM pg_proc p WHERE p.oid >= 16384),
24
+ (SELECT md5(coalesce(string_agg(row(t.oid, t.tgname, t.tgrelid, t.tgenabled, t.tgfoid, t.tgtype, t.tgattr, t.tgqual::text)::text, E'\\n' ORDER BY t.oid), '')) FROM pg_trigger t WHERE t.tgrelid >= 16384),
25
+ (SELECT md5(coalesce(string_agg(row(o.oid, o.polname, o.polrelid, o.polcmd, o.polroles, o.polqual, o.polwithcheck)::text, E'\\n' ORDER BY o.oid), '')) FROM pg_policy o),
26
+ (SELECT md5(coalesce(string_agg(row(r.oid, r.rulename, r.ev_class, r.ev_action)::text, E'\\n' ORDER BY r.oid), '')) FROM pg_rewrite r WHERE r.oid >= 16384),
27
+ (SELECT md5(coalesce(string_agg(row(y.oid, y.typname, y.typnamespace, y.typtype)::text, E'\\n' ORDER BY y.oid), ''))
28
+ FROM pg_type y JOIN pg_namespace n ON n.oid = y.typnamespace WHERE y.oid >= 16384 AND ${USER_NAMESPACE}),
29
+ (SELECT md5(coalesce(string_agg(row(s.seqrelid, s.seqtypid, s.seqstart, s.seqincrement, s.seqmax, s.seqmin, s.seqcache, s.seqcycle)::text, E'\\n' ORDER BY s.seqrelid), '')) FROM pg_sequence s WHERE s.seqrelid >= 16384),
30
+ (SELECT md5(coalesce(string_agg(row(e.oid, e.extname, e.extversion, e.extnamespace)::text, E'\\n' ORDER BY e.oid), '')) FROM pg_extension e),
31
+ (SELECT md5(coalesce(string_agg(row(u.oid, u.pubname)::text, E'\\n' ORDER BY u.oid), '')) FROM pg_publication u),
32
+ (SELECT md5(coalesce(string_agg(row(v.oid, v.evtname, v.evtevent, v.evtfoid, v.evtenabled)::text, E'\\n' ORDER BY v.oid), '')) FROM pg_event_trigger v),
33
+ (SELECT md5(coalesce(string_agg(row(h.inhrelid, h.inhparent, h.inhseqno)::text, E'\\n' ORDER BY h.inhrelid, h.inhparent), '')) FROM pg_inherits h),
34
+ (SELECT md5(coalesce(string_agg(row(m.oid, m.enumtypid, m.enumlabel, m.enumsortorder)::text, E'\\n' ORDER BY m.oid), '')) FROM pg_enum m),
35
+ (SELECT md5(coalesce(string_agg(row(q.oid, q.oprname, q.oprnamespace, q.oprleft, q.oprright, q.oprresult, q.oprcode)::text, E'\\n' ORDER BY q.oid), '')) FROM pg_operator q WHERE q.oid >= 16384),
36
+ (SELECT md5(coalesce(string_agg(row(w.oid, w.castsource, w.casttarget, w.castfunc, w.castcontext, w.castmethod)::text, E'\\n' ORDER BY w.oid), '')) FROM pg_cast w WHERE w.oid >= 16384),
37
+ (SELECT md5(coalesce(string_agg(row(l.oid, l.collname, l.collnamespace, l.collprovider, l.collisdeterministic, l.collcollate, l.collctype)::text, E'\\n' ORDER BY l.oid), '')) FROM pg_collation l WHERE l.oid >= 16384),
38
+ (SELECT md5(coalesce(string_agg(row(z.oid, z.stxrelid, z.stxname, z.stxkeys, z.stxkind)::text, E'\\n' ORDER BY z.oid), '')) FROM pg_statistic_ext z WHERE z.oid >= 16384),
39
+ (SELECT count(*)::text FROM pg_largeobject_metadata),
40
+ (SELECT md5(coalesce(string_agg(row(x.objoid, x.classoid, x.objsubid, x.description)::text, E'\\n' ORDER BY x.objoid, x.classoid, x.objsubid), '')) FROM pg_description x WHERE x.objoid >= 16384),
41
+ (SELECT md5(coalesce(string_agg(row(f.oid, f.defaclrole, f.defaclnamespace, f.defaclobjtype, f.defaclacl)::text, E'\\n' ORDER BY f.oid), '')) FROM pg_default_acl f),
42
+ (SELECT md5(coalesce(string_agg(row(b.setrole, b.setconfig)::text, E'\\n' ORDER BY b.setrole), ''))
43
+ FROM pg_db_role_setting b WHERE b.setdatabase = (SELECT oid FROM pg_database WHERE datname = current_database())),
44
+ (SELECT datacl::text FROM pg_database WHERE datname = current_database())
45
+ )) AS digest`;
46
+ const STORAGE_QUERY = `
47
+ SELECT format('%I.%I', n.nspname, c.relname) AS name, c.relkind::text AS kind,
48
+ c.relfilenode::text AS filenode, pg_relation_size(c.oid, 'main')::text AS size
49
+ FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
50
+ WHERE c.relkind IN ('r', 'm') AND c.oid >= 16384 AND ${USER_NAMESPACE}`;
51
+ const SEQUENCE_QUERY = `
52
+ SELECT format('%I.%I', schemaname, sequencename) AS name, last_value::text AS last, start_value::text AS start
53
+ FROM pg_sequences WHERE schemaname !~ '^pg_(toast_)?temp_' AND schemaname NOT IN ('information_schema', 'pg_catalog')`;
54
+ function connect(url) {
55
+ return postgres(url, { max: 1, onnotice: () => { }, idle_timeout: 0, max_lifetime: 0 });
56
+ }
57
+ async function readCopy(sql, table) {
58
+ const stream = await sql.unsafe(`COPY ${table} TO STDOUT`).readable();
59
+ const chunks = [];
60
+ for await (const chunk of stream)
61
+ chunks.push(Buffer.from(chunk));
62
+ return Buffer.concat(chunks);
63
+ }
64
+ async function writeCopy(sql, table, data) {
65
+ const sink = await sql.unsafe(`COPY ${table} FROM STDIN`).writable();
66
+ await new Promise((resolve, reject) => {
67
+ sink.once('error', reject);
68
+ sink.once('finish', resolve);
69
+ sink.end(data);
70
+ });
71
+ }
72
+ /** Read the state a reset returns to. `url` is a superuser connection to the database. */
73
+ export async function captureBaseline(url) {
74
+ const sql = connect(url);
75
+ try {
76
+ const [digestRow] = await sql.unsafe(DIGEST_QUERY);
77
+ const storage = await sql.unsafe(STORAGE_QUERY);
78
+ const sizes = new Map();
79
+ const matviews = new Map();
80
+ const stored = new Set();
81
+ for (const row of storage) {
82
+ sizes.set(row.name, Number(row.size));
83
+ if (row.kind === 'm')
84
+ matviews.set(row.name, row.filenode);
85
+ else if (Number(row.size) > 0)
86
+ stored.add(row.name);
87
+ }
88
+ const rows = new Map();
89
+ for (const table of stored) {
90
+ const [has] = await sql.unsafe(`SELECT EXISTS (SELECT 1 FROM ${table}) AS has`);
91
+ if (has.has)
92
+ rows.set(table, await readCopy(sql, table));
93
+ }
94
+ const sequences = new Map();
95
+ for (const row of await sql.unsafe(SEQUENCE_QUERY)) {
96
+ sequences.set(row.name, { last: row.last, start: row.start });
97
+ }
98
+ return { digest: digestRow.digest, sizes, matviews, stored, rows, sequences };
99
+ }
100
+ finally {
101
+ await sql.end();
102
+ }
103
+ }
104
+ /**
105
+ * Return the database to its baseline. Call after the file's backends are gone.
106
+ * Refuses (ok: false) rather than reset a database whose state a reset cannot
107
+ * undo; nothing is changed in that case.
108
+ */
109
+ export async function resetDatabase(url, baseline, superuser = true) {
110
+ let sql = null;
111
+ try {
112
+ sql = connect(url);
113
+ const [prepared] = await sql.unsafe(`SELECT count(*)::int AS n FROM pg_prepared_xacts WHERE database = current_database()`);
114
+ if (prepared.n > 0)
115
+ return { ok: false, reason: 'prepared-xact' };
116
+ const [digestRow] = await sql.unsafe(DIGEST_QUERY);
117
+ if (digestRow.digest !== baseline.digest)
118
+ return { ok: false, reason: 'digest' };
119
+ const storage = await sql.unsafe(STORAGE_QUERY);
120
+ const dirty = [];
121
+ for (const row of storage) {
122
+ const base = baseline.sizes.get(row.name);
123
+ if (base === undefined)
124
+ return { ok: false, reason: 'digest' };
125
+ if (row.kind === 'm') {
126
+ if (Number(row.size) !== base || row.filenode !== baseline.matviews.get(row.name)) {
127
+ return { ok: false, reason: 'matview' };
128
+ }
129
+ }
130
+ else if (Number(row.size) > base || baseline.stored.has(row.name)) {
131
+ dirty.push(row.name);
132
+ }
133
+ }
134
+ if (dirty.length > 0) {
135
+ await sql.begin(async (tx) => {
136
+ // Superuser: reload without firing triggers or checking FKs. Otherwise
137
+ // reload plainly, then refuse if a trigger wrote into a table that
138
+ // should be empty.
139
+ if (superuser)
140
+ await tx.unsafe(`SET LOCAL session_replication_role = replica`);
141
+ await tx.unsafe(`TRUNCATE ${dirty.join(', ')} CASCADE`);
142
+ for (const [table, data] of baseline.rows)
143
+ await writeCopy(tx, table, data);
144
+ if (!superuser && baseline.rows.size > 0) {
145
+ for (const row of await tx.unsafe(STORAGE_QUERY)) {
146
+ if (baseline.stored.has(row.name) || baseline.matviews.has(row.name))
147
+ continue;
148
+ if (Number(row.size) > (baseline.sizes.get(row.name) ?? 0))
149
+ throw new Error(`reload wrote to ${row.name}`);
150
+ }
151
+ }
152
+ });
153
+ }
154
+ const current = await sql.unsafe(SEQUENCE_QUERY);
155
+ const fixes = [];
156
+ for (const row of current) {
157
+ const base = baseline.sequences.get(row.name);
158
+ if (base === undefined)
159
+ return { ok: false, reason: 'digest' };
160
+ if (row.last === base.last)
161
+ continue;
162
+ const literal = `'${row.name.replace(/'/g, "''")}'::regclass`;
163
+ fixes.push(base.last === null
164
+ ? `setval(${literal}, ${base.start}, false)`
165
+ : `setval(${literal}, ${base.last}, true)`);
166
+ }
167
+ if (fixes.length > 0)
168
+ await sql.unsafe(`SELECT ${fixes.join(', ')}`);
169
+ return { ok: true, cleared: dirty.length, reloaded: baseline.rows.size };
170
+ }
171
+ catch {
172
+ return { ok: false, reason: 'error' };
173
+ }
174
+ finally {
175
+ if (sql !== null)
176
+ await sql.end().catch(() => { });
177
+ }
178
+ }
179
+ //# sourceMappingURL=reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.js","sourceRoot":"","sources":["../../src/test/reset.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAG/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAUnD,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,eAAe,CAAA;AAItB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAA;CACjB;AA2ED,+DAA+D;AAC/D,eAAO,MAAM,oBAAoB,uBAAuB,CAAA;AAoBxD,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,UAAU,CAAC,EAAE,qBAAqB,CAAA;IAClC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAUpC;AA0TD,8DAA8D;AAC9D,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAI7C;AAID;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC7B,KAAK,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAyD,EAC5F,QAAQ,GAAE,SAAS,MAAM,EAA0B,GAClD,OAAO,CAAC,OAAO,CAAC,CAYlB;AAYD,yFAAyF;AACzF,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM;CAe1E;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,mEAAmE;IACnE,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/B,4DAA4D;IAC5D,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/B,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACxC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,gFAAgF;IAChF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACjC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,CAgC5F;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,QAAQ,CAAC,GAAkB,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAcxB;AAgND,UAAU,WAAW;IACnB,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,0BAA0B,EAAE,MAAM,CAAA;IAC3C,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAA;CACvC;AAcD,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CASnF;AAgGD,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;AAEhD,eAAO,MAAM,yBAAyB,4BAA4B,CAAA;AAClE,eAAO,MAAM,wBAAwB,2BAA2B,CAAA;AAEhE,MAAM,WAAW,oBAAoB;IACnC,4BAA4B;IAC5B,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B,4BAA4B;IAC5B,GAAG,CAAC,EAAE,QAAQ,CAAA;IACd,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,8DAA8D;IAC9D,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,CAAC,CAAC,CAoCZ;AAgND,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwC3D;AA6DD,eAAO,MAAM,oBAAoB,uBAAuB,CAAA;AAExD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,OAAO,GAAG,UAAU,EAC5B,GAAG,GAAE,QAA2C,EAChD,GAAG,GAAE,MAAM,MAAyB,GACnC,OAAO,CAAC,MAAM,CAAC,CA0BjB;AAED,+DAA+D;AAC/D,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAEtE;AAED,wBAAgB,gBAAgB,IAAI,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAGlD"}
@@ -12,11 +12,20 @@ import { testDbPrefix, appRolePrefix, templateDbPrefix } from './namespace.js';
12
12
  import { templateFingerprint, templateInputs } from './fingerprint.js';
13
13
  import { PhaseTracker, withStallWatchdog, DEFAULT_SETUP_STALL_MS, } from './progress.js';
14
14
  import { describeError } from '../core/logging/error-chain.js';
15
+ import { captureBaseline, resetDatabase, TEST_RESET_LOG_PREFIX } from './reset.js';
15
16
  // Marker table written inside a template as the last act of a successful build.
16
17
  // A template database that exists without this row is the wreckage of a builder
17
18
  // that died mid-migration: it must be rebuilt, never cloned.
18
19
  const TEMPLATE_MARKER_TABLE = 'pipework_test_template';
19
20
  const testDatabases = new Map();
21
+ const retained = new Map();
22
+ let databasePerFile = false;
23
+ let runAdminUrl = '';
24
+ let adminIsSuperuser = null;
25
+ async function readSuperuser() {
26
+ const rows = await adminClient `SELECT rolsuper FROM pg_roles WHERE rolname = current_user`;
27
+ return rows[0]?.['rolsuper'] === true;
28
+ }
20
29
  const templates = new Map();
21
30
  let adminClient = null;
22
31
  // A random per-process fingerprint, embedded in every database and role name
@@ -31,9 +40,8 @@ function templateDbName(baseName, fingerprint) {
31
40
  }
32
41
  /** Log prefix for what the orphan reaper left alone (#391). */
33
42
  export const TEST_REAP_LOG_PREFIX = 'pipework:test-reap';
34
- // One name per CLONE, not per process. A test file's database is no longer
35
- // dropped the instant the file ends (see `pendingDrops`), so the next file in
36
- // the same worker must not ask for the name still queued for drop.
43
+ // One name per CLONE, not per process. A finished database may still be queued
44
+ // for drop (see `pendingDrops`), so the next clone must not ask for its name.
37
45
  let cloneSeq = 0;
38
46
  function testDbName(baseName) {
39
47
  return `${testDbPrefix()}${baseName}_${cloneSeq++}_${process.pid}_${runNonce}`;
@@ -91,6 +99,7 @@ async function runSetup(instance, tracker) {
91
99
  };
92
100
  });
93
101
  dropBatchSize = instance.config.raw.test?.dropBatchSize ?? DEFAULT_DROP_BATCH_SIZE;
102
+ databasePerFile = instance.config.raw.test?.databasePerFile ?? false;
94
103
  const cloneGuards = resolveCloneGuards(instance.config.raw);
95
104
  const firstDb = databases[0];
96
105
  if (firstDb !== undefined) {
@@ -99,9 +108,19 @@ async function runSetup(instance, tracker) {
99
108
  }
100
109
  for (const plan of plans) {
101
110
  const template = await ensureTemplate(instance, plan, tracker);
111
+ const key = JSON.stringify([plan.name, plan.dbConfig.url, template.templateDb, cloneGuards]);
112
+ const kept = databasePerFile ? undefined : await takeKept(key);
113
+ if (kept !== undefined) {
114
+ testDatabases.set(plan.name, kept.testDb);
115
+ continue;
116
+ }
102
117
  tracker.reached('clone-start', plan.name);
103
118
  const testDb = await cloneTestDatabase(plan.name, plan.dbConfig, template, cloneGuards, n => tracker.reached('clone-start', plan.name, `retry ${n}`));
104
119
  tracker.reached('clone-done', plan.name);
120
+ if (!databasePerFile) {
121
+ const baseline = await captureBaseline(withDatabase(runAdminUrl, testDb.database));
122
+ retained.set(testDb.database, { testDb, baseline, key, inUse: true, needsReset: false });
123
+ }
105
124
  testDatabases.set(plan.name, testDb);
106
125
  }
107
126
  tracker.reached('ready');
@@ -115,6 +134,7 @@ async function runSetup(instance, tracker) {
115
134
  // this process dies, and is never unlocked per file: the template outlives
116
135
  // every file's database, so the lock that protects it must outlive them too.
117
136
  async function prepareRun(adminUrl, liveTemplates, tracker) {
137
+ runAdminUrl = adminUrl;
118
138
  if (adminClient === null) {
119
139
  adminClient = postgres(adminUrl, { max: 1, onnotice: () => { } });
120
140
  }
@@ -450,8 +470,10 @@ async function buildTemplate(instance, plan, tracker) {
450
470
  const admin = drizzle(adminClient);
451
471
  // A template database that exists at this point failed its readiness check —
452
472
  // the leftovers of a builder that died. Drop and start over.
473
+ tracker.reached('template-build', plan.name, 'drop');
453
474
  await closeTemplateClients(admin, templateDb);
454
- await withTemplateRetry(() => admin.execute(sql.raw(`DROP DATABASE IF EXISTS ${templateIdent}`)), { prefix: TEMPLATE_DROP_LOG_PREFIX });
475
+ await withTemplateRetry(() => admin.execute(sql.raw(`DROP DATABASE IF EXISTS ${templateIdent}`)), { prefix: TEMPLATE_DROP_LOG_PREFIX, onRetry: n => tracker.reached('template-build', plan.name, `drop retry ${n}`) });
476
+ tracker.reached('template-build', plan.name, 'create');
455
477
  await admin.execute(sql.raw(`CREATE DATABASE ${templateIdent}`));
456
478
  // #325: a test database is dropped or rolled back — durable commits are pure
457
479
  // overhead. `synchronous_commit` is a per-database setting and does not copy
@@ -471,6 +493,7 @@ async function buildTemplate(instance, plan, tracker) {
471
493
  ? withDatabase(dbConfig.testOwnerUrl, templateDb)
472
494
  : undefined;
473
495
  if (migrateUrlStr !== undefined) {
496
+ tracker.reached('template-build', plan.name, 'owner');
474
497
  const ownerIdent = quoteIdentifier(new URL(migrateUrlStr).username, 'role');
475
498
  await admin.execute(sql.raw(`GRANT CONNECT ON DATABASE ${templateIdent} TO ${ownerIdent}`));
476
499
  // PG15+: `public` belongs to the database owner and grants CREATE to
@@ -480,6 +503,7 @@ async function buildTemplate(instance, plan, tracker) {
480
503
  // Door policies in the migrations say `TO <platform role>`, so the role must
481
504
  // exist before they run.
482
505
  if (dbConfig.rls?.platformRole !== undefined) {
506
+ tracker.reached('template-build', plan.name, 'platform role');
483
507
  await provisionPlatformRole(adminClient, dbConfig.rls.platformRole, new URL(templateUrlStr).username);
484
508
  }
485
509
  if (dbConfig.extensions.length > 0) {
@@ -489,6 +513,7 @@ async function buildTemplate(instance, plan, tracker) {
489
513
  }
490
514
  }
491
515
  if (dbConfig.migrations !== undefined) {
516
+ tracker.reached('template-migrate', plan.name, 'start');
492
517
  await applyMigrations({
493
518
  migrationsFolder: dbConfig.migrations,
494
519
  migrationsTable: dbConfig.migrationTable,
@@ -498,6 +523,10 @@ async function buildTemplate(instance, plan, tracker) {
498
523
  // A migration stack is the one step long enough to look like a stall.
499
524
  // Each file applied is an advance. Issue #380.
500
525
  onMigration: (tag, index, total) => tracker.reached('template-migrate', plan.name, `${index}/${total} ${tag}`),
526
+ // Statements inside a long file, and the steps before the first file,
527
+ // are advances too. Issue #871.
528
+ onStatement: (tag, statement, statements, index, total) => tracker.reached('template-migrate', plan.name, `${index}/${total} ${tag} stmt ${statement}/${statements}`),
529
+ onPrepare: detail => tracker.reached('template-migrate', plan.name, `prepare ${detail}`),
501
530
  });
502
531
  }
503
532
  // Framework-owned partitioned tables (trace family) are kept out of app
@@ -516,7 +545,7 @@ async function buildTemplate(instance, plan, tracker) {
516
545
  // of CREATEs, each of which can wait on the disk. Issue #806.
517
546
  onProgress: (step, detail) => step === 'partition'
518
547
  ? tracker.reached('template-partitions', plan.name, detail)
519
- : tracker.reached('template-framework', plan.name, step),
548
+ : tracker.reached('template-framework', plan.name, detail === undefined ? step : `${step} ${detail}`),
520
549
  });
521
550
  const grantBeat = (detail) => tracker.reached('template-grants', plan.name, detail);
522
551
  grantBeat('role');
@@ -863,6 +892,7 @@ async function closeRunConnections() {
863
892
  if (adminClient !== null) {
864
893
  await adminClient.end();
865
894
  adminClient = null;
895
+ adminIsSuperuser = null;
866
896
  }
867
897
  if (lockClient !== null) {
868
898
  await lockClient.end();
@@ -907,10 +937,22 @@ export async function teardownTestDatabases() {
907
937
  return;
908
938
  }
909
939
  const admin = drizzle(adminClient);
940
+ // Kept databases are reset by the next setup that takes them, not here: a
941
+ // process that ends after one file never pays for it. Without an IPC channel
942
+ // nothing follows this teardown (see below): drop instead.
943
+ const canReuse = typeof process.send === 'function';
910
944
  for (const [, testDb] of testDatabases) {
911
945
  try {
912
946
  await admin.execute(sql `SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = ${testDb.database} AND pid != pg_backend_pid()`);
913
- pendingDrops.push(testDb.database);
947
+ const keep = retained.get(testDb.database);
948
+ if (keep !== undefined && canReuse) {
949
+ keep.inUse = false;
950
+ keep.needsReset = true;
951
+ }
952
+ else {
953
+ retained.delete(testDb.database);
954
+ pendingDrops.push(testDb.database);
955
+ }
914
956
  }
915
957
  catch {
916
958
  // Best effort cleanup — a leftover clone is reaped by the next run.
@@ -927,7 +969,43 @@ export async function teardownTestDatabases() {
927
969
  await closeRunConnections();
928
970
  }
929
971
  }
930
- // Finished per-file databases, waiting to be dropped together.
972
+ /**
973
+ * An idle kept database for this key, reset and marked in use. One whose reset
974
+ * fails is queued for drop and the next candidate tried; none left means the
975
+ * caller clones.
976
+ */
977
+ async function takeKept(key) {
978
+ for (const keep of retained.values()) {
979
+ if (keep.key !== key || keep.inUse)
980
+ continue;
981
+ if (keep.needsReset && !await resetKept(keep)) {
982
+ retained.delete(keep.testDb.database);
983
+ pendingDrops.push(keep.testDb.database);
984
+ continue;
985
+ }
986
+ keep.needsReset = false;
987
+ keep.inUse = true;
988
+ return keep;
989
+ }
990
+ return undefined;
991
+ }
992
+ /** Reset a kept database to its baseline and say so. False: it needs a fresh clone. */
993
+ async function resetKept(keep) {
994
+ const start = Date.now();
995
+ adminIsSuperuser ??= await readSuperuser();
996
+ const outcome = await resetDatabase(withDatabase(runAdminUrl, keep.testDb.database), keep.baseline, adminIsSuperuser);
997
+ const db = keep.testDb.database;
998
+ console.warn(outcome.ok
999
+ ? `${TEST_RESET_LOG_PREFIX} db=${db} cleared=${outcome.cleared} reloaded=${outcome.reloaded} elapsed_ms=${Date.now() - start}`
1000
+ : `${TEST_RESET_LOG_PREFIX} db=${db} fresh-clone reason=${outcome.reason}`);
1001
+ return outcome.ok;
1002
+ }
1003
+ // Per-file databases that are done with, waiting to be dropped together.
1004
+ //
1005
+ // A worker keeps its databases across files (`test.databasePerFile` off), so
1006
+ // what reaches this queue is a database whose reset fell back to a fresh clone,
1007
+ // every kept database at worker shutdown, and every database with
1008
+ // `databasePerFile`.
931
1009
  //
932
1010
  // Every `DROP DATABASE` forces an IMMEDIATE cluster-wide checkpoint and waits
933
1011
  // for it — `RequestCheckpoint(CHECKPOINT_IMMEDIATE | FORCE | WAIT)` in
@@ -953,6 +1031,10 @@ export const TEST_DROP_LOG_PREFIX = 'pipework:test-drop';
953
1031
  * rather than failing the flush for the rest.
954
1032
  */
955
1033
  export async function flushPendingDrops(reason, log = message => console.warn(message), now = () => Date.now()) {
1034
+ if (reason === 'shutdown') {
1035
+ pendingDrops.push(...retained.keys());
1036
+ retained.clear();
1037
+ }
956
1038
  if (adminClient === null || pendingDrops.length === 0)
957
1039
  return 0;
958
1040
  const admin = drizzle(adminClient);