@untestutils/core 0.5.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/LICENSE +21 -0
- package/dist/artifact-store.d.mts +19 -0
- package/dist/artifact-store.d.ts +20 -0
- package/dist/artifact-store.d.ts.map +1 -0
- package/dist/artifact-store.mjs +52 -0
- package/dist/debug.d.mts +5 -0
- package/dist/debug.d.ts +6 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.mjs +22 -0
- package/dist/drivers/cli-framework.d.mts +57 -0
- package/dist/drivers/cli-framework.d.ts +64 -0
- package/dist/drivers/cli-framework.d.ts.map +1 -0
- package/dist/drivers/cli-framework.mjs +138 -0
- package/dist/drivers/command.d.mts +15 -0
- package/dist/drivers/command.d.ts +16 -0
- package/dist/drivers/command.d.ts.map +1 -0
- package/dist/drivers/command.mjs +70 -0
- package/dist/drivers/define-driver.d.mts +4 -0
- package/dist/drivers/define-driver.d.ts +5 -0
- package/dist/drivers/define-driver.d.ts.map +1 -0
- package/dist/drivers/define-driver.mjs +3 -0
- package/dist/drivers/host.d.mts +18 -0
- package/dist/drivers/host.d.ts +19 -0
- package/dist/drivers/host.d.ts.map +1 -0
- package/dist/drivers/host.mjs +31 -0
- package/dist/drivers/index.d.mts +12 -0
- package/dist/drivers/index.d.ts +13 -0
- package/dist/drivers/index.d.ts.map +1 -0
- package/dist/drivers/index.mjs +6 -0
- package/dist/drivers/node-entry.d.mts +13 -0
- package/dist/drivers/node-entry.d.ts +14 -0
- package/dist/drivers/node-entry.d.ts.map +1 -0
- package/dist/drivers/node-entry.mjs +55 -0
- package/dist/drivers/static-dir.d.mts +9 -0
- package/dist/drivers/static-dir.d.ts +10 -0
- package/dist/drivers/static-dir.d.ts.map +1 -0
- package/dist/drivers/static-dir.mjs +90 -0
- package/dist/harness.d.mts +4 -0
- package/dist/harness.d.ts +5 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/harness.mjs +18 -0
- package/dist/hash.d.mts +6 -0
- package/dist/hash.d.ts +7 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.mjs +76 -0
- package/dist/identity.d.mts +9 -0
- package/dist/identity.d.ts +10 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.mjs +44 -0
- package/dist/index.d.mts +29 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +22 -0
- package/dist/lock.d.mts +26 -0
- package/dist/lock.d.ts +27 -0
- package/dist/lock.d.ts.map +1 -0
- package/dist/lock.mjs +145 -0
- package/dist/orchestrator.d.mts +19 -0
- package/dist/orchestrator.d.ts +22 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.mjs +343 -0
- package/dist/paths.d.mts +20 -0
- package/dist/paths.d.ts +21 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.mjs +124 -0
- package/dist/ports.d.mts +2 -0
- package/dist/ports.d.ts +8 -0
- package/dist/ports.d.ts.map +1 -0
- package/dist/ports.mjs +38 -0
- package/dist/process.d.mts +31 -0
- package/dist/process.d.ts +36 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.mjs +191 -0
- package/dist/progress.d.mts +45 -0
- package/dist/progress.d.ts +66 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.mjs +205 -0
- package/dist/ready.d.mts +11 -0
- package/dist/ready.d.ts +12 -0
- package/dist/ready.d.ts.map +1 -0
- package/dist/ready.mjs +142 -0
- package/dist/recipes.d.mts +23 -0
- package/dist/recipes.d.ts +24 -0
- package/dist/recipes.d.ts.map +1 -0
- package/dist/recipes.mjs +94 -0
- package/dist/run-helper.d.mts +6 -0
- package/dist/run-helper.d.ts +7 -0
- package/dist/run-helper.d.ts.map +1 -0
- package/dist/run-helper.mjs +79 -0
- package/dist/target-registry.d.mts +27 -0
- package/dist/target-registry.d.ts +28 -0
- package/dist/target-registry.d.ts.map +1 -0
- package/dist/target-registry.mjs +103 -0
- package/dist/types.d.mts +92 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.mjs +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { defineDriver } from "./define-driver.mjs";
|
|
2
|
+
export { command } from "./command.mjs";
|
|
3
|
+
export { staticDir } from "./static-dir.mjs";
|
|
4
|
+
export { nodeEntry } from "./node-entry.mjs";
|
|
5
|
+
export { host } from "./host.mjs";
|
|
6
|
+
export { resolveBin, assertAppRoot, cliFrameworkRecipe, frameworkRoots, _cliInternals } from "./cli-framework.mjs";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Recipe } from "../index.mjs";
|
|
2
|
+
export interface NodeEntryOptions {
|
|
3
|
+
id: string;
|
|
4
|
+
entry: string;
|
|
5
|
+
cwd?: string;
|
|
6
|
+
prepare?: string;
|
|
7
|
+
hashInputs?: string[];
|
|
8
|
+
readyPath?: string;
|
|
9
|
+
readyTimeoutMs?: number;
|
|
10
|
+
env?: Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
export declare function nodeEntry(opts: NodeEntryOptions): Recipe;
|
|
13
|
+
export default nodeEntry;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Recipe } from '..';
|
|
2
|
+
export interface NodeEntryOptions {
|
|
3
|
+
id: string;
|
|
4
|
+
entry: string;
|
|
5
|
+
cwd?: string;
|
|
6
|
+
prepare?: string;
|
|
7
|
+
hashInputs?: string[];
|
|
8
|
+
readyPath?: string;
|
|
9
|
+
readyTimeoutMs?: number;
|
|
10
|
+
env?: Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
export declare function nodeEntry(opts: NodeEntryOptions): Recipe;
|
|
13
|
+
export default nodeEntry;
|
|
14
|
+
//# sourceMappingURL=node-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-entry.d.ts","sourceRoot":"","sources":["../../src/drivers/node-entry.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,MAAM,EACZ,MAAM,IAAI,CAAC;AAEZ,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAoDxD;AAED,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { resolve } from "pathe";
|
|
3
|
+
import { defineRecipe, loopbackUrl, waitForHttpReady, spawnManaged } from "../index.mjs";
|
|
4
|
+
export function nodeEntry(opts) {
|
|
5
|
+
const entry = resolve(opts.entry);
|
|
6
|
+
const cwd = opts.cwd ? resolve(opts.cwd) : undefined;
|
|
7
|
+
const ensureEntry = () => {
|
|
8
|
+
if (!existsSync(entry)) {
|
|
9
|
+
throw new Error(`[untestutils/nodeEntry] entry not found: ${entry}`);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
return defineRecipe({
|
|
13
|
+
id: opts.id,
|
|
14
|
+
share: "always",
|
|
15
|
+
hashInputs: async () => opts.hashInputs?.map((p) => resolve(p)) ?? [entry, ...cwd ? [cwd] : []],
|
|
16
|
+
ready: async () => {},
|
|
17
|
+
prepare: opts.prepare ? async ({ run }) => {
|
|
18
|
+
ensureEntry();
|
|
19
|
+
const result = await run.command(opts.prepare, { cwd });
|
|
20
|
+
if (result.exitCode !== 0) {
|
|
21
|
+
throw new Error(`[untestutils/nodeEntry] prepare failed:\n${result.stderr.slice(-2e3)}`);
|
|
22
|
+
}
|
|
23
|
+
} : undefined,
|
|
24
|
+
start: async ({ port, host }) => {
|
|
25
|
+
ensureEntry();
|
|
26
|
+
const managed = spawnManaged(process.execPath, [entry], {
|
|
27
|
+
cwd,
|
|
28
|
+
env: {
|
|
29
|
+
...process.env,
|
|
30
|
+
...opts.env,
|
|
31
|
+
PORT: String(port),
|
|
32
|
+
HOST: host
|
|
33
|
+
},
|
|
34
|
+
captureLogs: true
|
|
35
|
+
});
|
|
36
|
+
const url = loopbackUrl(port, "/", host);
|
|
37
|
+
try {
|
|
38
|
+
await waitForHttpReady(url, {
|
|
39
|
+
path: opts.readyPath ?? "/",
|
|
40
|
+
timeoutMs: opts.readyTimeoutMs
|
|
41
|
+
});
|
|
42
|
+
} catch (e) {
|
|
43
|
+
await managed.stop();
|
|
44
|
+
throw new Error(`[untestutils/nodeEntry] ready failed:\n${e}\n--- server logs ---\n${managed.logs().slice(-4e3)}`);
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
kind: "url",
|
|
48
|
+
url,
|
|
49
|
+
stop: managed.stop,
|
|
50
|
+
pid: managed.pid
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
export default nodeEntry;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Recipe } from '..';
|
|
2
|
+
export interface StaticDirOptions {
|
|
3
|
+
id: string;
|
|
4
|
+
root: string;
|
|
5
|
+
hashInputs?: string[];
|
|
6
|
+
readyPath?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function staticDir(opts: StaticDirOptions): Recipe;
|
|
9
|
+
export default staticDir;
|
|
10
|
+
//# sourceMappingURL=static-dir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-dir.d.ts","sourceRoot":"","sources":["../../src/drivers/static-dir.ts"],"names":[],"mappings":"AAIA,OAAO,EAA+C,KAAK,MAAM,EAAE,MAAM,IAAI,CAAC;AAgB9E,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CA8ExD;AAED,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { readFile, stat } from "node:fs/promises";
|
|
4
|
+
import { extname, join, normalize, resolve, sep } from "pathe";
|
|
5
|
+
import { defineRecipe, loopbackUrl, waitForHttpReady } from "../index.mjs";
|
|
6
|
+
const MIME = {
|
|
7
|
+
".html": "text/html; charset=utf-8",
|
|
8
|
+
".js": "text/javascript; charset=utf-8",
|
|
9
|
+
".css": "text/css; charset=utf-8",
|
|
10
|
+
".json": "application/json",
|
|
11
|
+
".svg": "image/svg+xml",
|
|
12
|
+
".png": "image/png",
|
|
13
|
+
".jpg": "image/jpeg",
|
|
14
|
+
".jpeg": "image/jpeg",
|
|
15
|
+
".ico": "image/x-icon",
|
|
16
|
+
".txt": "text/plain; charset=utf-8",
|
|
17
|
+
".wasm": "application/wasm"
|
|
18
|
+
};
|
|
19
|
+
export function staticDir(opts) {
|
|
20
|
+
const root = resolve(opts.root);
|
|
21
|
+
return defineRecipe({
|
|
22
|
+
id: opts.id,
|
|
23
|
+
share: "always",
|
|
24
|
+
hashInputs: async () => opts.hashInputs?.map((p) => resolve(p)) ?? [root],
|
|
25
|
+
|
|
26
|
+
ready: async () => {},
|
|
27
|
+
start: async ({ port, host }) => {
|
|
28
|
+
if (!existsSync(root)) {
|
|
29
|
+
throw new Error(`[untestutils/staticDir] root not found: ${root}`);
|
|
30
|
+
}
|
|
31
|
+
const server = createServer(async (req, res) => {
|
|
32
|
+
try {
|
|
33
|
+
const urlPath = decodeURIComponent((req.url ?? "/").split("?")[0] || "/");
|
|
34
|
+
let filePath = join(root, urlPath === "/" ? "index.html" : urlPath);
|
|
35
|
+
|
|
36
|
+
const normalized = normalize(filePath);
|
|
37
|
+
if (!normalized.startsWith(normalize(root) + sep) && normalized !== normalize(root)) {
|
|
38
|
+
res.statusCode = 403;
|
|
39
|
+
res.end("Forbidden");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
let st = await stat(normalized).catch(() => null);
|
|
43
|
+
if (st?.isDirectory()) {
|
|
44
|
+
filePath = join(normalized, "index.html");
|
|
45
|
+
st = await stat(filePath).catch(() => null);
|
|
46
|
+
} else {
|
|
47
|
+
filePath = normalized;
|
|
48
|
+
}
|
|
49
|
+
if (!st?.isFile()) {
|
|
50
|
+
|
|
51
|
+
const fallback = join(root, "index.html");
|
|
52
|
+
const fb = await stat(fallback).catch(() => null);
|
|
53
|
+
if (fb?.isFile()) {
|
|
54
|
+
const body = await readFile(fallback);
|
|
55
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
56
|
+
res.end(body);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
res.statusCode = 404;
|
|
60
|
+
res.end("Not Found");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const body = await readFile(filePath);
|
|
64
|
+
res.setHeader("Content-Type", MIME[extname(filePath)] ?? "application/octet-stream");
|
|
65
|
+
res.end(body);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
res.statusCode = 500;
|
|
68
|
+
res.end(String(e));
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
await new Promise((resolvePromise, reject) => {
|
|
72
|
+
server.listen(port, host, () => resolvePromise());
|
|
73
|
+
server.once("error", (err) => {
|
|
74
|
+
reject(new Error(`[untestutils/staticDir] listen failed on ${host}:${port}: ${err.message}`, { cause: err }));
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
const url = loopbackUrl(port, "/", host);
|
|
78
|
+
await waitForHttpReady(url, { path: opts.readyPath ?? "/" });
|
|
79
|
+
return {
|
|
80
|
+
kind: "url+dir",
|
|
81
|
+
url,
|
|
82
|
+
dir: root,
|
|
83
|
+
stop: async () => new Promise((resolvePromise) => {
|
|
84
|
+
server.close(() => resolvePromise());
|
|
85
|
+
})
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
export default staticDir;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HarnessHandle, Recipe, UseHarnessOptions } from "./types.mjs";
|
|
2
|
+
export declare function useHarness(recipe: string | Recipe, _opts?: UseHarnessOptions): Promise<HarnessHandle>;
|
|
3
|
+
export declare function getCurrentHarness(): HarnessHandle | undefined;
|
|
4
|
+
export declare function getHarness(id: string): HarnessHandle | undefined;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { HarnessHandle, Recipe, UseHarnessOptions } from './types';
|
|
2
|
+
export declare function useHarness(recipe: string | Recipe, _opts?: UseHarnessOptions): Promise<HarnessHandle>;
|
|
3
|
+
export declare function getCurrentHarness(): HarnessHandle | undefined;
|
|
4
|
+
export declare function getHarness(id: string): HarnessHandle | undefined;
|
|
5
|
+
//# sourceMappingURL=harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAOxE,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,KAAK,GAAE,iBAAsB,GAC5B,OAAO,CAAC,aAAa,CAAC,CAQxB;AAED,wBAAgB,iBAAiB,IAAI,aAAa,GAAG,SAAS,CAE7D;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEhE"}
|
package/dist/harness.mjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import { createHarnessHandle, ensurePrepared } from "./orchestrator.mjs";
|
|
3
|
+
import { resolveArtifactsRoot } from "./paths.mjs";
|
|
4
|
+
const storage = new AsyncLocalStorage();
|
|
5
|
+
const handles = new Map();
|
|
6
|
+
export async function useHarness(recipe, _opts = {}) {
|
|
7
|
+
const prepared = await ensurePrepared(recipe, { artifactsRoot: resolveArtifactsRoot() });
|
|
8
|
+
const handle = createHarnessHandle(prepared);
|
|
9
|
+
handles.set(handle.id, handle);
|
|
10
|
+
storage.enterWith(handle);
|
|
11
|
+
return handle;
|
|
12
|
+
}
|
|
13
|
+
export function getCurrentHarness() {
|
|
14
|
+
return storage.getStore();
|
|
15
|
+
}
|
|
16
|
+
export function getHarness(id) {
|
|
17
|
+
return handles.get(id);
|
|
18
|
+
}
|
package/dist/hash.d.mts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function sha1(content: Buffer | string): string;
|
|
2
|
+
export declare function hashFile(path: string): Promise<string>;
|
|
3
|
+
export declare function collectFileHashes(dir: string, lines: string[], root?: string): Promise<void>;
|
|
4
|
+
export declare function contentHash(inputs: string[]): Promise<string>;
|
|
5
|
+
export declare function hashString(value: string): string;
|
|
6
|
+
export declare function streamSha1(path: string): Promise<string>;
|
package/dist/hash.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function sha1(content: Buffer | string): string;
|
|
2
|
+
export declare function hashFile(path: string): Promise<string>;
|
|
3
|
+
export declare function collectFileHashes(dir: string, lines: string[], root?: string): Promise<void>;
|
|
4
|
+
export declare function contentHash(inputs: string[]): Promise<string>;
|
|
5
|
+
export declare function hashString(value: string): string;
|
|
6
|
+
export declare function streamSha1(path: string): Promise<string>;
|
|
7
|
+
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAqBA,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAErD;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG5D;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,GAAE,MAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAenE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ9D"}
|
package/dist/hash.mjs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { createReadStream, existsSync } from "node:fs";
|
|
3
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
4
|
+
import { join, relative } from "pathe";
|
|
5
|
+
const SKIP_DIRS = new Set([
|
|
6
|
+
"node_modules",
|
|
7
|
+
".git",
|
|
8
|
+
".nuxt",
|
|
9
|
+
".output",
|
|
10
|
+
".untestutils",
|
|
11
|
+
"dist",
|
|
12
|
+
"coverage",
|
|
13
|
+
"test-results",
|
|
14
|
+
".data",
|
|
15
|
+
".turbo",
|
|
16
|
+
".next"
|
|
17
|
+
]);
|
|
18
|
+
const SKIP_FILES = new Set([
|
|
19
|
+
".DS_Store",
|
|
20
|
+
"pnpm-lock.yaml",
|
|
21
|
+
"package-lock.json",
|
|
22
|
+
"yarn.lock"
|
|
23
|
+
]);
|
|
24
|
+
export function sha1(content) {
|
|
25
|
+
return createHash("sha1").update(content).digest("hex");
|
|
26
|
+
}
|
|
27
|
+
export async function hashFile(path) {
|
|
28
|
+
const buf = await readFile(path);
|
|
29
|
+
return sha1(buf);
|
|
30
|
+
}
|
|
31
|
+
export async function collectFileHashes(dir, lines, root = dir) {
|
|
32
|
+
if (!existsSync(dir)) return;
|
|
33
|
+
let entries;
|
|
34
|
+
try {
|
|
35
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
36
|
+
} catch {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
if (SKIP_DIRS.has(entry.name) || SKIP_FILES.has(entry.name)) continue;
|
|
41
|
+
const path = join(dir, entry.name);
|
|
42
|
+
if (entry.isDirectory()) {
|
|
43
|
+
await collectFileHashes(path, lines, root);
|
|
44
|
+
} else if (entry.isFile()) {
|
|
45
|
+
lines.push(`${relative(root, path)}|${await hashFile(path)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export async function contentHash(inputs) {
|
|
50
|
+
const lines = [];
|
|
51
|
+
for (const input of inputs) {
|
|
52
|
+
if (!existsSync(input)) {
|
|
53
|
+
lines.push(`missing:${input}`);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const s = await stat(input);
|
|
57
|
+
if (s.isDirectory()) {
|
|
58
|
+
await collectFileHashes(input, lines, input);
|
|
59
|
+
} else {
|
|
60
|
+
lines.push(`${input}|${await hashFile(input)}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return sha1(lines.sort().join("\n"));
|
|
64
|
+
}
|
|
65
|
+
export function hashString(value) {
|
|
66
|
+
return sha1(value);
|
|
67
|
+
}
|
|
68
|
+
export async function streamSha1(path) {
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
const hash = createHash("sha1");
|
|
71
|
+
const stream = createReadStream(path);
|
|
72
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
73
|
+
stream.on("end", () => resolve(hash.digest("hex")));
|
|
74
|
+
stream.on("error", reject);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Recipe } from "./types.mjs";
|
|
2
|
+
export declare function computeIdentity(recipe: Recipe, artifactsRoot: string, root?: string): Promise<{
|
|
3
|
+
identity: string;
|
|
4
|
+
hash: string;
|
|
5
|
+
id: string;
|
|
6
|
+
}>;
|
|
7
|
+
/** Detect colliding Recipe.id pointing at different identity hashes in-process. */
|
|
8
|
+
export declare function assertUniqueRecipeBinding(id: string, identity: string): void;
|
|
9
|
+
export declare function resetRecipeBindings(): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Recipe } from './types';
|
|
2
|
+
export declare function computeIdentity(recipe: Recipe, artifactsRoot: string, root?: string): Promise<{
|
|
3
|
+
identity: string;
|
|
4
|
+
hash: string;
|
|
5
|
+
id: string;
|
|
6
|
+
}>;
|
|
7
|
+
/** Detect colliding Recipe.id pointing at different identity hashes in-process. */
|
|
8
|
+
export declare function assertUniqueRecipeBinding(id: string, identity: string): void;
|
|
9
|
+
export declare function resetRecipeBindings(): void;
|
|
10
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAEpE,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC;IACT,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC,CAwBD;AAQD,mFAAmF;AACnF,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ5E;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { resolve } from "pathe";
|
|
2
|
+
import { contentHash, hashString } from "./hash.mjs";
|
|
3
|
+
import { SCHEMA_VERSION } from "./types.mjs";
|
|
4
|
+
export async function computeIdentity(recipe, artifactsRoot, root) {
|
|
5
|
+
const id = recipe.id;
|
|
6
|
+
if (!id) {
|
|
7
|
+
throw new Error("[untestutils] Recipe.id is required for sharing and registry");
|
|
8
|
+
}
|
|
9
|
+
const ctx = {
|
|
10
|
+
root: root ? resolve(root) : undefined,
|
|
11
|
+
outDir: "",
|
|
12
|
+
artifactsRoot
|
|
13
|
+
};
|
|
14
|
+
const inputParts = [];
|
|
15
|
+
if (recipe.hashInputs) {
|
|
16
|
+
const inputs = await recipe.hashInputs(ctx);
|
|
17
|
+
inputParts.push(...inputs.map((p) => resolve(p)));
|
|
18
|
+
} else if (root) {
|
|
19
|
+
inputParts.push(resolve(root));
|
|
20
|
+
}
|
|
21
|
+
const content = inputParts.length ? await contentHash(inputParts) : hashString(id);
|
|
22
|
+
const hash = hashString(`${SCHEMA_VERSION}|${id}|${content}|${recipe.share ?? "always"}`);
|
|
23
|
+
const identity = `${sanitize(id)}-${hash.slice(0, 12)}`;
|
|
24
|
+
return {
|
|
25
|
+
identity,
|
|
26
|
+
hash,
|
|
27
|
+
id
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function sanitize(id) {
|
|
31
|
+
return id.replace(/[^a-zA-Z0-9._-]+/g, "-").slice(0, 64);
|
|
32
|
+
}
|
|
33
|
+
const registryIds = new Map();
|
|
34
|
+
|
|
35
|
+
export function assertUniqueRecipeBinding(id, identity) {
|
|
36
|
+
const prev = registryIds.get(id);
|
|
37
|
+
if (prev && prev !== identity) {
|
|
38
|
+
throw new Error(`[untestutils] Recipe id "${id}" is bound to conflicting identities (${prev} vs ${identity}). Use distinct ids.`);
|
|
39
|
+
}
|
|
40
|
+
registryIds.set(id, identity);
|
|
41
|
+
}
|
|
42
|
+
export function resetRecipeBindings() {
|
|
43
|
+
registryIds.clear();
|
|
44
|
+
}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type { Recipe, RecipeFactory, RecipeRegistry, Running, HarnessHandle, SharePolicy, PrepareCtx, StartCtx, HashCtx, UseHarnessOptions } from "./types.mjs";
|
|
2
|
+
export { SCHEMA_VERSION } from "./types.mjs";
|
|
3
|
+
export { defineRecipe, defineRecipes, ensureRecipes, getRegisteredRecipe, getRecipesModulePath, listRegisteredRecipes, clearRegisteredRecipes } from "./recipes.mjs";
|
|
4
|
+
export { useHarness, getCurrentHarness, getHarness } from "./harness.mjs";
|
|
5
|
+
export { ensurePrepared, stopAllTargets, reclaimStaleTargets, resolveRecipe, detachLiveTargetsForTests } from "./orchestrator.mjs";
|
|
6
|
+
export { TargetRegistry, envKey, envDirKey } from "./target-registry.mjs";
|
|
7
|
+
export { ArtifactStore } from "./artifact-store.mjs";
|
|
8
|
+
export { FileLock, atomicWriteJson, atomicWriteText, lockPathFor } from "./lock.mjs";
|
|
9
|
+
export { contentHash, sha1, hashString, collectFileHashes } from "./hash.mjs";
|
|
10
|
+
export { getFreePort, waitForPort } from "./ports.mjs";
|
|
11
|
+
export { LOOPBACK_HOST, loopbackUrl, normalizeBaseUrl, resolveArtifactsRoot, resolveBindHost, resolveProbeHost, findRepoRoot } from "./paths.mjs";
|
|
12
|
+
export { waitForHttpReady, defaultReady } from "./ready.mjs";
|
|
13
|
+
export { scrubTestEnv, spawnManaged, runCommand, killProcessTree, killPidTree, isPidAlive } from "./process.mjs";
|
|
14
|
+
export { createRunHelper } from "./run-helper.mjs";
|
|
15
|
+
export { debug, isDebug, log, envFlag } from "./debug.mjs";
|
|
16
|
+
export { progress, isQuiet, isCi, isProgressEnabled, progressIo, withQuietLogger } from "./progress.mjs";
|
|
17
|
+
export { computeIdentity, assertUniqueRecipeBinding, resetRecipeBindings } from "./identity.mjs";
|
|
18
|
+
export type { Driver } from "./drivers/define-driver.mjs";
|
|
19
|
+
export { defineDriver } from "./drivers/define-driver.mjs";
|
|
20
|
+
export { command } from "./drivers/command.mjs";
|
|
21
|
+
export type { CommandOptions } from "./drivers/command.mjs";
|
|
22
|
+
export { staticDir } from "./drivers/static-dir.mjs";
|
|
23
|
+
export type { StaticDirOptions } from "./drivers/static-dir.mjs";
|
|
24
|
+
export { nodeEntry } from "./drivers/node-entry.mjs";
|
|
25
|
+
export type { NodeEntryOptions } from "./drivers/node-entry.mjs";
|
|
26
|
+
export { host } from "./drivers/host.mjs";
|
|
27
|
+
export type { HostOptions } from "./drivers/host.mjs";
|
|
28
|
+
export { resolveBin, assertAppRoot, cliFrameworkRecipe, frameworkRoots, _cliInternals } from "./drivers/cli-framework.mjs";
|
|
29
|
+
export type { ResolveBinOptions, SpawnSpec, CliFrameworkRecipeOptions, FrameworkBaseOptions } from "./drivers/cli-framework.mjs";
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type { Recipe, RecipeFactory, RecipeRegistry, Running, HarnessHandle, SharePolicy, PrepareCtx, StartCtx, HashCtx, UseHarnessOptions, } from './types';
|
|
2
|
+
export { SCHEMA_VERSION } from './types';
|
|
3
|
+
export { defineRecipe, defineRecipes, ensureRecipes, getRegisteredRecipe, getRecipesModulePath, listRegisteredRecipes, clearRegisteredRecipes, } from './recipes';
|
|
4
|
+
export { useHarness, getCurrentHarness, getHarness } from './harness';
|
|
5
|
+
export { ensurePrepared, stopAllTargets, reclaimStaleTargets, resolveRecipe, detachLiveTargetsForTests, } from './orchestrator';
|
|
6
|
+
export { TargetRegistry, envKey, envDirKey } from './target-registry';
|
|
7
|
+
export { ArtifactStore } from './artifact-store';
|
|
8
|
+
export { FileLock, atomicWriteJson, atomicWriteText, lockPathFor } from './lock';
|
|
9
|
+
export { contentHash, sha1, hashString, collectFileHashes } from './hash';
|
|
10
|
+
export { getFreePort, waitForPort } from './ports';
|
|
11
|
+
export { LOOPBACK_HOST, loopbackUrl, normalizeBaseUrl, resolveArtifactsRoot, resolveBindHost, resolveProbeHost, findRepoRoot, } from './paths';
|
|
12
|
+
export { waitForHttpReady, defaultReady } from './ready';
|
|
13
|
+
export { scrubTestEnv, spawnManaged, runCommand, killProcessTree, killPidTree, isPidAlive, } from './process';
|
|
14
|
+
export { createRunHelper } from './run-helper';
|
|
15
|
+
export { debug, isDebug, log, envFlag } from './debug';
|
|
16
|
+
export { progress, isQuiet, isCi, isProgressEnabled, progressIo, withQuietLogger, } from './progress';
|
|
17
|
+
export { computeIdentity, assertUniqueRecipeBinding, resetRecipeBindings } from './identity';
|
|
18
|
+
export type { Driver } from './drivers/define-driver';
|
|
19
|
+
export { defineDriver } from './drivers/define-driver';
|
|
20
|
+
export { command } from './drivers/command';
|
|
21
|
+
export type { CommandOptions } from './drivers/command';
|
|
22
|
+
export { staticDir } from './drivers/static-dir';
|
|
23
|
+
export type { StaticDirOptions } from './drivers/static-dir';
|
|
24
|
+
export { nodeEntry } from './drivers/node-entry';
|
|
25
|
+
export type { NodeEntryOptions } from './drivers/node-entry';
|
|
26
|
+
export { host } from './drivers/host';
|
|
27
|
+
export type { HostOptions } from './drivers/host';
|
|
28
|
+
export { resolveBin, assertAppRoot, cliFrameworkRecipe, frameworkRoots, _cliInternals, } from './drivers/cli-framework';
|
|
29
|
+
export type { ResolveBinOptions, SpawnSpec, CliFrameworkRecipeOptions, FrameworkBaseOptions, } from './drivers/cli-framework';
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,MAAM,EACN,aAAa,EACb,cAAc,EACd,OAAO,EACP,aAAa,EACb,WAAW,EACX,UAAU,EACV,QAAQ,EACR,OAAO,EACP,iBAAiB,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EACL,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EACL,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,eAAe,EACf,WAAW,EACX,UAAU,GACX,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EACL,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,iBAAiB,EACjB,UAAU,EACV,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAG7F,YAAY,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,aAAa,GACd,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,iBAAiB,EACjB,SAAS,EACT,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export { SCHEMA_VERSION } from "./types.mjs";
|
|
2
|
+
export { defineRecipe, defineRecipes, ensureRecipes, getRegisteredRecipe, getRecipesModulePath, listRegisteredRecipes, clearRegisteredRecipes } from "./recipes.mjs";
|
|
3
|
+
export { useHarness, getCurrentHarness, getHarness } from "./harness.mjs";
|
|
4
|
+
export { ensurePrepared, stopAllTargets, reclaimStaleTargets, resolveRecipe, detachLiveTargetsForTests } from "./orchestrator.mjs";
|
|
5
|
+
export { TargetRegistry, envKey, envDirKey } from "./target-registry.mjs";
|
|
6
|
+
export { ArtifactStore } from "./artifact-store.mjs";
|
|
7
|
+
export { FileLock, atomicWriteJson, atomicWriteText, lockPathFor } from "./lock.mjs";
|
|
8
|
+
export { contentHash, sha1, hashString, collectFileHashes } from "./hash.mjs";
|
|
9
|
+
export { getFreePort, waitForPort } from "./ports.mjs";
|
|
10
|
+
export { LOOPBACK_HOST, loopbackUrl, normalizeBaseUrl, resolveArtifactsRoot, resolveBindHost, resolveProbeHost, findRepoRoot } from "./paths.mjs";
|
|
11
|
+
export { waitForHttpReady, defaultReady } from "./ready.mjs";
|
|
12
|
+
export { scrubTestEnv, spawnManaged, runCommand, killProcessTree, killPidTree, isPidAlive } from "./process.mjs";
|
|
13
|
+
export { createRunHelper } from "./run-helper.mjs";
|
|
14
|
+
export { debug, isDebug, log, envFlag } from "./debug.mjs";
|
|
15
|
+
export { progress, isQuiet, isCi, isProgressEnabled, progressIo, withQuietLogger } from "./progress.mjs";
|
|
16
|
+
export { computeIdentity, assertUniqueRecipeBinding, resetRecipeBindings } from "./identity.mjs";
|
|
17
|
+
export { defineDriver } from "./drivers/define-driver.mjs";
|
|
18
|
+
export { command } from "./drivers/command.mjs";
|
|
19
|
+
export { staticDir } from "./drivers/static-dir.mjs";
|
|
20
|
+
export { nodeEntry } from "./drivers/node-entry.mjs";
|
|
21
|
+
export { host } from "./drivers/host.mjs";
|
|
22
|
+
export { resolveBin, assertAppRoot, cliFrameworkRecipe, frameworkRoots, _cliInternals } from "./drivers/cli-framework.mjs";
|
package/dist/lock.d.mts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface LockInfo {
|
|
2
|
+
pid: number;
|
|
3
|
+
startedAt: number;
|
|
4
|
+
heartbeatAt: number;
|
|
5
|
+
identity: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class FileLock {
|
|
8
|
+
private readonly lockPath;
|
|
9
|
+
private readonly identity;
|
|
10
|
+
private readonly staleMs;
|
|
11
|
+
private heartbeat?;
|
|
12
|
+
private held;
|
|
13
|
+
constructor(lockPath: string, identity: string, staleMs?: number);
|
|
14
|
+
acquire(timeoutMs?: number): Promise<void>;
|
|
15
|
+
release(): Promise<void>;
|
|
16
|
+
private startHeartbeat;
|
|
17
|
+
private stopHeartbeat;
|
|
18
|
+
private beat;
|
|
19
|
+
private tryStealStale;
|
|
20
|
+
}
|
|
21
|
+
export declare function atomicWriteJson(path: string, data: unknown): Promise<void>;
|
|
22
|
+
export declare function atomicWriteText(path: string, content: string): Promise<void>;
|
|
23
|
+
export declare function markReady(readyPath: string): Promise<void>;
|
|
24
|
+
export declare function isReady(readyPath: string): Promise<boolean>;
|
|
25
|
+
export declare function removePath(path: string): Promise<void>;
|
|
26
|
+
export declare function lockPathFor(artifactsRoot: string, identity: string): string;
|
package/dist/lock.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface LockInfo {
|
|
2
|
+
pid: number;
|
|
3
|
+
startedAt: number;
|
|
4
|
+
heartbeatAt: number;
|
|
5
|
+
identity: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class FileLock {
|
|
8
|
+
private readonly lockPath;
|
|
9
|
+
private readonly identity;
|
|
10
|
+
private readonly staleMs;
|
|
11
|
+
private heartbeat?;
|
|
12
|
+
private held;
|
|
13
|
+
constructor(lockPath: string, identity: string, staleMs?: number);
|
|
14
|
+
acquire(timeoutMs?: number): Promise<void>;
|
|
15
|
+
release(): Promise<void>;
|
|
16
|
+
private startHeartbeat;
|
|
17
|
+
private stopHeartbeat;
|
|
18
|
+
private beat;
|
|
19
|
+
private tryStealStale;
|
|
20
|
+
}
|
|
21
|
+
export declare function atomicWriteJson(path: string, data: unknown): Promise<void>;
|
|
22
|
+
export declare function atomicWriteText(path: string, content: string): Promise<void>;
|
|
23
|
+
export declare function markReady(readyPath: string): Promise<void>;
|
|
24
|
+
export declare function isReady(readyPath: string): Promise<boolean>;
|
|
25
|
+
export declare function removePath(path: string): Promise<void>;
|
|
26
|
+
export declare function lockPathFor(artifactsRoot: string, identity: string): string;
|
|
27
|
+
//# sourceMappingURL=lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAcD,qBAAa,QAAQ;IAKjB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,OAAO,CAAC,SAAS,CAAC,CAAiC;IACnD,OAAO,CAAC,IAAI,CAAS;gBAGF,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAyB;IAG/C,OAAO,CAAC,SAAS,GAAE,MAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BnD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB9B,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,aAAa;YAKP,IAAI;YAqBJ,aAAa;CAwB5B;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhF;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKlF;AAED,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;AAED,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEjE;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAMD,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3E"}
|