@apexops/kernel 0.10.0-next.5 → 0.11.0-next.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/.tsbuildinfo +1 -1
- package/dist/directory-lock.d.ts +118 -0
- package/dist/directory-lock.d.ts.map +1 -0
- package/dist/directory-lock.js +587 -0
- package/dist/directory-lock.js.map +1 -0
- package/dist/files.d.ts +63 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +158 -2
- package/dist/files.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/object-store.js +2 -2
- package/dist/object-store.js.map +1 -1
- package/dist/project-store.d.ts +2 -1
- package/dist/project-store.d.ts.map +1 -1
- package/dist/project-store.js +1 -0
- package/dist/project-store.js.map +1 -1
- package/dist/repeat-files.d.ts +66 -0
- package/dist/repeat-files.d.ts.map +1 -0
- package/dist/repeat-files.js +214 -0
- package/dist/repeat-files.js.map +1 -0
- package/dist/repeat-guard.d.ts +197 -0
- package/dist/repeat-guard.d.ts.map +1 -0
- package/dist/repeat-guard.js +462 -0
- package/dist/repeat-guard.js.map +1 -0
- package/dist/review-capture.d.ts +170 -0
- package/dist/review-capture.d.ts.map +1 -0
- package/dist/review-capture.js +570 -0
- package/dist/review-capture.js.map +1 -0
- package/dist/run-repository.d.ts +52 -2
- package/dist/run-repository.d.ts.map +1 -1
- package/dist/run-repository.js +198 -52
- package/dist/run-repository.js.map +1 -1
- package/dist/tasks.d.ts.map +1 -1
- package/dist/tasks.js +16 -2
- package/dist/tasks.js.map +1 -1
- package/dist/test/files.test.d.ts +2 -0
- package/dist/test/files.test.d.ts.map +1 -0
- package/dist/test/files.test.js +140 -0
- package/dist/test/files.test.js.map +1 -0
- package/dist/test/policies.test.js +1 -1
- package/dist/test/policies.test.js.map +1 -1
- package/dist/test/repeat-guard.test.d.ts +2 -0
- package/dist/test/repeat-guard.test.d.ts.map +1 -0
- package/dist/test/repeat-guard.test.js +1106 -0
- package/dist/test/repeat-guard.test.js.map +1 -0
- package/dist/test/review-capture.test.d.ts +2 -0
- package/dist/test/review-capture.test.d.ts.map +1 -0
- package/dist/test/review-capture.test.js +291 -0
- package/dist/test/review-capture.test.js.map +1 -0
- package/dist/test/run-repository.test.js +451 -7
- package/dist/test/run-repository.test.js.map +1 -1
- package/dist/test/workflow.test.js +30 -1
- package/dist/test/workflow.test.js.map +1 -1
- package/dist/test/writer-transfer.test.js +6 -1
- package/dist/test/writer-transfer.test.js.map +1 -1
- package/dist/validator-registry.d.ts.map +1 -1
- package/dist/validator-registry.js +10 -1
- package/dist/validator-registry.js.map +1 -1
- package/dist/workflow-validator-ownership.d.ts.map +1 -1
- package/dist/workflow-validator-ownership.js +2 -1
- package/dist/workflow-validator-ownership.js.map +1 -1
- package/package.json +3 -3
package/dist/run-repository.d.ts
CHANGED
|
@@ -16,23 +16,73 @@ export interface RunRepositoryOptions {
|
|
|
16
16
|
clock?: () => Date;
|
|
17
17
|
idSource?: () => string;
|
|
18
18
|
lockTtlMs?: number;
|
|
19
|
+
writerLeaseTtlMs?: number;
|
|
20
|
+
/** How long a writer lease acquisition waits for the run mutation lock; defaults to 10 seconds. */
|
|
21
|
+
writerLeaseLockWaitMs?: number;
|
|
22
|
+
/** Selects Windows transient file-sharing handling; defaults to `process.platform`. */
|
|
23
|
+
platform?: NodeJS.Platform;
|
|
19
24
|
faultInjector?: (stage: RunTransactionStage) => void | Promise<void>;
|
|
20
25
|
}
|
|
26
|
+
export interface RunWriterLeaseOwner {
|
|
27
|
+
workspacePath: string;
|
|
28
|
+
sessionId?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface RunWriterLease {
|
|
31
|
+
version: 1;
|
|
32
|
+
workspacePath: string;
|
|
33
|
+
host: string;
|
|
34
|
+
pid: number;
|
|
35
|
+
sessionId: string;
|
|
36
|
+
createdAt: string;
|
|
37
|
+
expiresAt: string;
|
|
38
|
+
}
|
|
39
|
+
export declare class RunWriterConflictError extends Error {
|
|
40
|
+
readonly ownerWorktree: string;
|
|
41
|
+
readonly expiresAt: string;
|
|
42
|
+
readonly code = "APEX_WRITER_CONFLICT";
|
|
43
|
+
constructor(ownerWorktree: string, expiresAt: string, options?: ErrorOptions);
|
|
44
|
+
}
|
|
45
|
+
export declare class RunMutationBusyError extends Error {
|
|
46
|
+
constructor();
|
|
47
|
+
}
|
|
48
|
+
export interface RunRepeatState {
|
|
49
|
+
runHash: string;
|
|
50
|
+
journalHead: string | null;
|
|
51
|
+
ownerEpoch: number;
|
|
52
|
+
writer: string | null;
|
|
53
|
+
}
|
|
54
|
+
/** Resolves a worktree path to the form used for ownership and repeat comparisons (case-folded on Windows). */
|
|
55
|
+
export declare function canonicalWorktreePath(path: string): string;
|
|
21
56
|
export declare class RunRepository {
|
|
22
57
|
private readonly runPath;
|
|
23
|
-
private readonly
|
|
58
|
+
private readonly mutationLock;
|
|
24
59
|
private readonly intentPath;
|
|
60
|
+
private readonly writerLeasePath;
|
|
25
61
|
private readonly clock;
|
|
26
62
|
private readonly idSource;
|
|
27
|
-
private readonly
|
|
63
|
+
private readonly writerLeaseTtlMs;
|
|
64
|
+
private readonly writerLeaseLockWaitMs;
|
|
65
|
+
private readonly platform;
|
|
28
66
|
private readonly faultInjector?;
|
|
29
67
|
readonly journal: EventJournal;
|
|
30
68
|
constructor(runDirectory: string, options?: RunRepositoryOptions);
|
|
31
69
|
hash(): Promise<string>;
|
|
32
70
|
read(): Promise<RunConfigV1>;
|
|
33
71
|
mutate(input: RunMutation): Promise<RunMutationResult>;
|
|
72
|
+
acquireWriterLease(owner: RunWriterLeaseOwner): Promise<RunWriterLease>;
|
|
73
|
+
private contended;
|
|
74
|
+
/**
|
|
75
|
+
* Reads the run state that decides whether a repeated call may be answered from its original result: the run hash,
|
|
76
|
+
* the journal head and the writer lease holder's canonical worktree (expiry excluded). Pending transactions are
|
|
77
|
+
* recovered first, so the snapshot reflects committed state.
|
|
78
|
+
*/
|
|
79
|
+
repeatState(): Promise<RunRepeatState>;
|
|
80
|
+
/** Rejects with the writer conflict when another worktree holds a live lease; never writes the lease. */
|
|
81
|
+
assertWriterAvailable(owner: RunWriterLeaseOwner): Promise<void>;
|
|
82
|
+
releaseWriterLease(owner: RunWriterLeaseOwner): Promise<boolean>;
|
|
34
83
|
private recover;
|
|
35
84
|
private readRaw;
|
|
85
|
+
private readWriterLease;
|
|
36
86
|
private withLock;
|
|
37
87
|
}
|
|
38
88
|
//# sourceMappingURL=run-repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-repository.d.ts","sourceRoot":"","sources":["../src/run-repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMtD,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"run-repository.d.ts","sourceRoot":"","sources":["../src/run-repository.ts"],"names":[],"mappings":"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"}
|
package/dist/run-repository.js
CHANGED
|
@@ -1,28 +1,101 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
2
|
+
import { readFile, rm } from "node:fs/promises";
|
|
3
3
|
import { hostname } from "node:os";
|
|
4
|
-
import {
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
5
|
import { sha256Json } from "./canonical.js";
|
|
6
6
|
import { EventJournal } from "./event-journal.js";
|
|
7
|
-
import {
|
|
7
|
+
import { DirectoryLock } from "./directory-lock.js";
|
|
8
|
+
import { atomicWriteJson, readPublishedFile } from "./files.js";
|
|
9
|
+
export class RunWriterConflictError extends Error {
|
|
10
|
+
ownerWorktree;
|
|
11
|
+
expiresAt;
|
|
12
|
+
code = "APEX_WRITER_CONFLICT";
|
|
13
|
+
constructor(ownerWorktree, expiresAt, options) {
|
|
14
|
+
super(`Run writer lease is held by ${ownerWorktree} until ${expiresAt}`, options);
|
|
15
|
+
this.ownerWorktree = ownerWorktree;
|
|
16
|
+
this.expiresAt = expiresAt;
|
|
17
|
+
this.name = "RunWriterConflictError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class RunMutationBusyError extends Error {
|
|
21
|
+
constructor() {
|
|
22
|
+
super("Run mutation is already in progress");
|
|
23
|
+
this.name = "RunMutationBusyError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const WRITER_LEASE_FILE = ".run-writer-lease.json";
|
|
27
|
+
const MAX_WRITER_LEASE_BYTES = 64 * 1024;
|
|
28
|
+
// Same-workspace renewals cannot fail fast with a conflict, so they queue on the run mutation lock. The budget must
|
|
29
|
+
// cover a serialized queue of lock cycles on slow file systems (Windows cycles are an order of magnitude slower).
|
|
30
|
+
const WRITER_LEASE_LOCK_WAIT_MS = 10_000;
|
|
31
|
+
const TRANSIENT_LOCK_RENAME_CODES = new Set(["EPERM", "EACCES", "EBUSY"]);
|
|
32
|
+
function writerLeaseExpiry(value) {
|
|
33
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
34
|
+
return undefined;
|
|
35
|
+
const lease = value;
|
|
36
|
+
const createdAt = Date.parse(lease.createdAt ?? "");
|
|
37
|
+
const expiresAt = Date.parse(lease.expiresAt ?? "");
|
|
38
|
+
return lease.version === 1 &&
|
|
39
|
+
typeof lease.workspacePath === "string" &&
|
|
40
|
+
lease.workspacePath.length > 0 &&
|
|
41
|
+
Number.isInteger(lease.pid) &&
|
|
42
|
+
Number(lease.pid) > 0 &&
|
|
43
|
+
typeof lease.host === "string" &&
|
|
44
|
+
lease.host.length > 0 &&
|
|
45
|
+
typeof lease.sessionId === "string" &&
|
|
46
|
+
lease.sessionId.length > 0 &&
|
|
47
|
+
Number.isFinite(createdAt) &&
|
|
48
|
+
Number.isFinite(expiresAt) &&
|
|
49
|
+
expiresAt >= createdAt
|
|
50
|
+
? expiresAt
|
|
51
|
+
: undefined;
|
|
52
|
+
}
|
|
53
|
+
/** Resolves a worktree path to the form used for ownership and repeat comparisons (case-folded on Windows). */
|
|
54
|
+
export function canonicalWorktreePath(path) {
|
|
55
|
+
let canonical = resolve(path);
|
|
56
|
+
try {
|
|
57
|
+
canonical = realpathSync(canonical);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error.code !== "ENOENT")
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
return process.platform === "win32" ? canonical.toLocaleLowerCase() : canonical;
|
|
64
|
+
}
|
|
65
|
+
function sameWorkspace(left, right) {
|
|
66
|
+
return canonicalWorktreePath(left) === canonicalWorktreePath(right);
|
|
67
|
+
}
|
|
8
68
|
export class RunRepository {
|
|
9
69
|
runPath;
|
|
10
|
-
|
|
70
|
+
mutationLock;
|
|
11
71
|
intentPath;
|
|
72
|
+
writerLeasePath;
|
|
12
73
|
clock;
|
|
13
74
|
idSource;
|
|
14
|
-
|
|
75
|
+
writerLeaseTtlMs;
|
|
76
|
+
writerLeaseLockWaitMs;
|
|
77
|
+
platform;
|
|
15
78
|
faultInjector;
|
|
16
79
|
journal;
|
|
17
80
|
constructor(runDirectory, options = {}) {
|
|
18
81
|
const directory = resolve(runDirectory);
|
|
19
82
|
this.runPath = join(directory, "run.json");
|
|
20
|
-
this.lockPath = join(directory, ".run-mutation.lock");
|
|
21
83
|
this.intentPath = join(directory, ".run-transaction.json");
|
|
84
|
+
this.writerLeasePath = join(directory, WRITER_LEASE_FILE);
|
|
22
85
|
this.clock = options.clock ?? (() => new Date());
|
|
23
86
|
this.idSource = options.idSource ?? (() => crypto.randomUUID());
|
|
24
|
-
this.
|
|
87
|
+
this.writerLeaseTtlMs = options.writerLeaseTtlMs ?? 120_000;
|
|
88
|
+
this.writerLeaseLockWaitMs = options.writerLeaseLockWaitMs ?? WRITER_LEASE_LOCK_WAIT_MS;
|
|
89
|
+
this.platform = options.platform ?? process.platform;
|
|
25
90
|
this.faultInjector = options.faultInjector;
|
|
91
|
+
this.mutationLock = new DirectoryLock(join(directory, ".run-mutation.lock"), {
|
|
92
|
+
label: "Run mutation lock",
|
|
93
|
+
clock: this.clock,
|
|
94
|
+
idSource: this.idSource,
|
|
95
|
+
ttlMs: options.lockTtlMs ?? 30_000,
|
|
96
|
+
platform: this.platform,
|
|
97
|
+
busyError: () => new RunMutationBusyError(),
|
|
98
|
+
});
|
|
26
99
|
this.journal = new EventJournal(join(directory, "journal"));
|
|
27
100
|
}
|
|
28
101
|
async hash() {
|
|
@@ -72,6 +145,105 @@ export class RunRepository {
|
|
|
72
145
|
return { run: next, runHash: afterHash, eventHash: event.hash };
|
|
73
146
|
});
|
|
74
147
|
}
|
|
148
|
+
async acquireWriterLease(owner) {
|
|
149
|
+
const workspacePath = resolve(owner.workspacePath);
|
|
150
|
+
const conflictFromPublishedLease = async () => {
|
|
151
|
+
const existing = await this.readWriterLease();
|
|
152
|
+
if (existing !== undefined &&
|
|
153
|
+
existing.expiresAt > this.clock().getTime() &&
|
|
154
|
+
!sameWorkspace(existing.metadata.workspacePath, workspacePath)) {
|
|
155
|
+
return new RunWriterConflictError(existing.metadata.workspacePath, existing.metadata.expiresAt);
|
|
156
|
+
}
|
|
157
|
+
return undefined;
|
|
158
|
+
};
|
|
159
|
+
try {
|
|
160
|
+
return await this.withLock(async () => {
|
|
161
|
+
const now = this.clock();
|
|
162
|
+
const existing = await this.readWriterLease();
|
|
163
|
+
if (existing !== undefined &&
|
|
164
|
+
existing.expiresAt > now.getTime() &&
|
|
165
|
+
!sameWorkspace(existing.metadata.workspacePath, workspacePath)) {
|
|
166
|
+
throw new RunWriterConflictError(existing.metadata.workspacePath, existing.metadata.expiresAt);
|
|
167
|
+
}
|
|
168
|
+
const lease = {
|
|
169
|
+
version: 1,
|
|
170
|
+
workspacePath,
|
|
171
|
+
host: hostname(),
|
|
172
|
+
pid: process.pid,
|
|
173
|
+
sessionId: owner.sessionId ?? this.idSource(),
|
|
174
|
+
createdAt: existing !== undefined && sameWorkspace(existing.metadata.workspacePath, workspacePath)
|
|
175
|
+
? existing.metadata.createdAt
|
|
176
|
+
: now.toISOString(),
|
|
177
|
+
expiresAt: new Date(now.getTime() + this.writerLeaseTtlMs).toISOString(),
|
|
178
|
+
};
|
|
179
|
+
await atomicWriteJson(this.writerLeasePath, lease);
|
|
180
|
+
return lease;
|
|
181
|
+
}, { onContention: conflictFromPublishedLease, waitMs: this.writerLeaseLockWaitMs });
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
if (error instanceof RunWriterConflictError || !this.contended(error))
|
|
185
|
+
throw error;
|
|
186
|
+
// A busy lock or a Windows sharing violation is a contended outcome, not a verdict. Report it as a writer
|
|
187
|
+
// conflict only when another worktree verifiably holds an unexpired lease; otherwise surface the original error.
|
|
188
|
+
let conflict;
|
|
189
|
+
try {
|
|
190
|
+
conflict = await conflictFromPublishedLease();
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
195
|
+
if (conflict === undefined)
|
|
196
|
+
throw error;
|
|
197
|
+
throw new RunWriterConflictError(conflict.ownerWorktree, conflict.expiresAt, { cause: error });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
contended(error) {
|
|
201
|
+
return (error instanceof RunMutationBusyError ||
|
|
202
|
+
(this.platform === "win32" && TRANSIENT_LOCK_RENAME_CODES.has(error.code ?? "")));
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Reads the run state that decides whether a repeated call may be answered from its original result: the run hash,
|
|
206
|
+
* the journal head and the writer lease holder's canonical worktree (expiry excluded). Pending transactions are
|
|
207
|
+
* recovered first, so the snapshot reflects committed state.
|
|
208
|
+
*/
|
|
209
|
+
async repeatState() {
|
|
210
|
+
return this.withLock(async () => {
|
|
211
|
+
await this.recover();
|
|
212
|
+
const run = await this.readRaw();
|
|
213
|
+
const lease = await this.readWriterLease();
|
|
214
|
+
return {
|
|
215
|
+
runHash: sha256Json(run),
|
|
216
|
+
journalHead: await this.journal.head(),
|
|
217
|
+
ownerEpoch: run.ownerEpoch,
|
|
218
|
+
writer: lease === undefined ? null : canonicalWorktreePath(lease.metadata.workspacePath),
|
|
219
|
+
};
|
|
220
|
+
},
|
|
221
|
+
// Concurrent guarded calls read this state at once; wait out a short mutation instead of failing on contention.
|
|
222
|
+
{ waitMs: this.writerLeaseLockWaitMs });
|
|
223
|
+
}
|
|
224
|
+
/** Rejects with the writer conflict when another worktree holds a live lease; never writes the lease. */
|
|
225
|
+
async assertWriterAvailable(owner) {
|
|
226
|
+
const existing = await this.readWriterLease();
|
|
227
|
+
if (existing !== undefined &&
|
|
228
|
+
existing.expiresAt > this.clock().getTime() &&
|
|
229
|
+
!sameWorkspace(existing.metadata.workspacePath, resolve(owner.workspacePath))) {
|
|
230
|
+
throw new RunWriterConflictError(existing.metadata.workspacePath, existing.metadata.expiresAt);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
async releaseWriterLease(owner) {
|
|
234
|
+
const workspacePath = resolve(owner.workspacePath);
|
|
235
|
+
return this.withLock(async () => {
|
|
236
|
+
const existing = await this.readWriterLease();
|
|
237
|
+
if (existing === undefined)
|
|
238
|
+
return false;
|
|
239
|
+
if (existing.expiresAt > this.clock().getTime() &&
|
|
240
|
+
!sameWorkspace(existing.metadata.workspacePath, workspacePath)) {
|
|
241
|
+
throw new RunWriterConflictError(existing.metadata.workspacePath, existing.metadata.expiresAt);
|
|
242
|
+
}
|
|
243
|
+
await rm(this.writerLeasePath, { force: true });
|
|
244
|
+
return true;
|
|
245
|
+
});
|
|
246
|
+
}
|
|
75
247
|
async recover() {
|
|
76
248
|
let intent;
|
|
77
249
|
try {
|
|
@@ -98,54 +270,28 @@ export class RunRepository {
|
|
|
98
270
|
async readRaw() {
|
|
99
271
|
return JSON.parse(await readFile(this.runPath, "utf8"));
|
|
100
272
|
}
|
|
101
|
-
async
|
|
102
|
-
await
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
expiresAt: new Date(createdAt.getTime() + this.lockTtlMs).toISOString(),
|
|
111
|
-
};
|
|
112
|
-
const acquire = async () => {
|
|
113
|
-
const handle = await open(this.lockPath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY, 0o600);
|
|
114
|
-
await handle.writeFile(JSON.stringify(metadata));
|
|
115
|
-
await handle.close();
|
|
116
|
-
};
|
|
273
|
+
async readWriterLease() {
|
|
274
|
+
const bytes = await readPublishedFile(this.writerLeasePath, {
|
|
275
|
+
maxBytes: MAX_WRITER_LEASE_BYTES,
|
|
276
|
+
label: "Run writer lease metadata",
|
|
277
|
+
platform: this.platform,
|
|
278
|
+
});
|
|
279
|
+
if (bytes === undefined)
|
|
280
|
+
return undefined;
|
|
281
|
+
let parsed;
|
|
117
282
|
try {
|
|
118
|
-
|
|
283
|
+
parsed = JSON.parse(bytes.toString("utf8"));
|
|
119
284
|
}
|
|
120
285
|
catch (error) {
|
|
121
|
-
|
|
122
|
-
throw error;
|
|
123
|
-
let existing;
|
|
124
|
-
try {
|
|
125
|
-
existing = JSON.parse(await readFile(this.lockPath, "utf8"));
|
|
126
|
-
}
|
|
127
|
-
catch {
|
|
128
|
-
throw new Error("Run mutation lock metadata is unreadable", { cause: error });
|
|
129
|
-
}
|
|
130
|
-
if (Date.parse(existing.expiresAt) > this.clock().getTime())
|
|
131
|
-
throw new Error("Run mutation is already in progress", { cause: error });
|
|
132
|
-
await rm(this.lockPath);
|
|
133
|
-
await acquire();
|
|
134
|
-
}
|
|
135
|
-
try {
|
|
136
|
-
return await operation();
|
|
137
|
-
}
|
|
138
|
-
finally {
|
|
139
|
-
try {
|
|
140
|
-
const current = JSON.parse(await readFile(this.lockPath, "utf8"));
|
|
141
|
-
if (current.token === token)
|
|
142
|
-
await rm(this.lockPath, { force: true });
|
|
143
|
-
}
|
|
144
|
-
catch (error) {
|
|
145
|
-
if (error.code !== "ENOENT")
|
|
146
|
-
throw error;
|
|
147
|
-
}
|
|
286
|
+
throw new Error("Run writer lease metadata is unreadable", { cause: error });
|
|
148
287
|
}
|
|
288
|
+
const expiresAt = writerLeaseExpiry(parsed);
|
|
289
|
+
if (expiresAt === undefined)
|
|
290
|
+
throw new Error("Run writer lease metadata is unreadable");
|
|
291
|
+
return { metadata: parsed, expiresAt };
|
|
292
|
+
}
|
|
293
|
+
async withLock(operation, options = {}) {
|
|
294
|
+
return this.mutationLock.run(operation, options);
|
|
149
295
|
}
|
|
150
296
|
}
|
|
151
297
|
//# sourceMappingURL=run-repository.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-repository.js","sourceRoot":"","sources":["../src/run-repository.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run-repository.js","sourceRoot":"","sources":["../src/run-repository.ts"],"names":[],"mappings":"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"}
|
package/dist/tasks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,KAAK,EACL,cAAc,EACd,YAAY,EACb,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,KAAK,UAAU,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAOlD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,cAAc,EAAE,eAAe,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IACnH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAa3G;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAU5G;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,YAAY,CAKhF;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,KAAK,EACL,cAAc,EACd,YAAY,EACb,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,KAAK,UAAU,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAOlD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,cAAc,EAAE,eAAe,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IACnH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAa3G;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAU5G;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,YAAY,CAKhF;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CA8FzG;AAWD,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC"}
|
package/dist/tasks.js
CHANGED
|
@@ -39,19 +39,33 @@ export function validateInputAnswers(questions, submitted) {
|
|
|
39
39
|
for (const answer of submitted) {
|
|
40
40
|
if (answers.has(answer.questionId))
|
|
41
41
|
throw new Error(`Duplicate answer: ${answer.questionId}`);
|
|
42
|
+
const question = questions.find(({ id }) => id === answer.questionId);
|
|
43
|
+
if (question?.optional === true && typeof answer.value === "string" && answer.value.trim().length === 0) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
42
46
|
answers.set(answer.questionId, answer.value);
|
|
43
47
|
}
|
|
44
48
|
for (const answerId of answers.keys()) {
|
|
45
49
|
if (!questions.some(({ id }) => id === answerId))
|
|
46
50
|
throw new Error(`Unknown answer: ${answerId}`);
|
|
47
51
|
}
|
|
48
|
-
|
|
52
|
+
const requiredQuestions = questions.filter(({ optional }) => optional !== true);
|
|
53
|
+
if (answers.size < requiredQuestions.length || requiredQuestions.some(({ id }) => !answers.has(id))) {
|
|
49
54
|
throw new Error("Every requested question requires exactly one answer");
|
|
50
55
|
}
|
|
51
|
-
return questions.
|
|
56
|
+
return questions.flatMap((question) => {
|
|
57
|
+
if (!answers.has(question.id))
|
|
58
|
+
return [];
|
|
52
59
|
const value = answers.get(question.id);
|
|
53
60
|
if (isDeferredOrUnknown(value))
|
|
54
61
|
return { questionId: question.id, value };
|
|
62
|
+
const selections = Array.isArray(value)
|
|
63
|
+
? value
|
|
64
|
+
: typeof value === "object" && value !== null && value.kind === "compliance"
|
|
65
|
+
? value.scopes
|
|
66
|
+
: [];
|
|
67
|
+
if (new Set(selections).size !== selections.length)
|
|
68
|
+
throw new Error(`Answer repeats an option: ${question.id}`);
|
|
55
69
|
if (question.valueType !== undefined) {
|
|
56
70
|
if (question.valueType === "environment-set") {
|
|
57
71
|
if (!Array.isArray(value) || value.some((item) => !/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(item))) {
|
package/dist/tasks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAOtD,MAAM,qBAAqB,GAAqC;IAC9D,qBAAqB,EAAE,mCAAmC;IAC1D,uBAAuB,EAAE,sDAAsD;CAChF,CAAC;AAMF,MAAM,UAAU,kBAAkB,CAAC,KAAsB,EAAE,KAAY,EAAE,QAAkB;IACzF,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;IACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IACjC,OAAO;QACL,aAAa,EAAE,gBAAgB;QAC/B,GAAG,IAAI;QACP,MAAM,EAAE,QAAQ,EAAE;QAClB,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE;QAC5B,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,WAAW,EAAE;KACzD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAoB,EAAE,IAAY,EAAE,UAAkB,EAAE,KAAY;IACpG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,SAAuB;IAChE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,SAAuB,EAAE,SAA0B;IACtF,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC1D,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9F,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC;IACD,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,QAAQ,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IACnG,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.test.d.ts","sourceRoot":"","sources":["../../src/test/files.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { readPublishedFile, renameWithRetry, retrySharingViolations } from "../index.js";
|
|
4
|
+
function flakyRename(failures) {
|
|
5
|
+
const calls = [];
|
|
6
|
+
return {
|
|
7
|
+
calls,
|
|
8
|
+
rename: async (from, to) => {
|
|
9
|
+
calls.push([from, to]);
|
|
10
|
+
const code = failures.shift();
|
|
11
|
+
if (code !== undefined)
|
|
12
|
+
throw Object.assign(new Error(code), { code });
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
test("renameWithRetry retries transient Windows sharing violations with bounded backoff", async () => {
|
|
17
|
+
const flaky = flakyRename(["EPERM", "EBUSY", "EACCES"]);
|
|
18
|
+
const sleeps = [];
|
|
19
|
+
await renameWithRetry("a.tmp", "a", {
|
|
20
|
+
platform: "win32",
|
|
21
|
+
rename: flaky.rename,
|
|
22
|
+
sleep: async (milliseconds) => void sleeps.push(milliseconds),
|
|
23
|
+
});
|
|
24
|
+
assert.equal(flaky.calls.length, 4);
|
|
25
|
+
assert.deepEqual(sleeps, [10, 20, 40]);
|
|
26
|
+
});
|
|
27
|
+
test("renameWithRetry gives up after the attempt budget and never retries other errors or platforms", async () => {
|
|
28
|
+
const exhausted = flakyRename(Array(5).fill("EPERM"));
|
|
29
|
+
await assert.rejects(renameWithRetry("a.tmp", "a", { platform: "win32", attempts: 3, rename: exhausted.rename, sleep: async () => { } }), { code: "EPERM" });
|
|
30
|
+
assert.equal(exhausted.calls.length, 3);
|
|
31
|
+
const missing = flakyRename(["ENOENT"]);
|
|
32
|
+
await assert.rejects(renameWithRetry("a.tmp", "a", { platform: "win32", rename: missing.rename, sleep: async () => { } }), { code: "ENOENT" });
|
|
33
|
+
assert.equal(missing.calls.length, 1);
|
|
34
|
+
const linux = flakyRename(["EPERM"]);
|
|
35
|
+
await assert.rejects(renameWithRetry("a.tmp", "a", { platform: "linux", rename: linux.rename }), { code: "EPERM" });
|
|
36
|
+
assert.equal(linux.calls.length, 1);
|
|
37
|
+
});
|
|
38
|
+
test("retrySharingViolations returns the operation's value after transient Windows sharing violations", async () => {
|
|
39
|
+
const failures = ["EBUSY", "EACCES"];
|
|
40
|
+
const value = await retrySharingViolations(async () => {
|
|
41
|
+
const code = failures.shift();
|
|
42
|
+
if (code !== undefined)
|
|
43
|
+
throw Object.assign(new Error(code), { code });
|
|
44
|
+
return "read";
|
|
45
|
+
}, { platform: "win32", sleep: async () => { } });
|
|
46
|
+
assert.equal(value, "read");
|
|
47
|
+
assert.deepEqual(failures, []);
|
|
48
|
+
await assert.rejects(retrySharingViolations(async () => undefined, { platform: "win32", attempts: 0 }), RangeError);
|
|
49
|
+
});
|
|
50
|
+
test("renameWithRetry rejects attempt budgets outside 1 to 10", async () => {
|
|
51
|
+
for (const attempts of [0, 11, 1.5, Number.NaN, Number.POSITIVE_INFINITY]) {
|
|
52
|
+
await assert.rejects(renameWithRetry("a.tmp", "a", { platform: "win32", attempts, rename: async () => { }, sleep: async () => { } }), RangeError);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
function flakyPublishedFile(failures, contents = "{}") {
|
|
56
|
+
const calls = [];
|
|
57
|
+
const fail = (at) => {
|
|
58
|
+
calls.push(at);
|
|
59
|
+
if (failures[0]?.at !== at)
|
|
60
|
+
return;
|
|
61
|
+
const { code } = failures.shift();
|
|
62
|
+
throw Object.assign(new Error(code), { code });
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
calls,
|
|
66
|
+
lstat: async () => {
|
|
67
|
+
fail("lstat");
|
|
68
|
+
return { isFile: () => true, isSymbolicLink: () => false, size: Buffer.byteLength(contents) };
|
|
69
|
+
},
|
|
70
|
+
readFile: async () => {
|
|
71
|
+
fail("readFile");
|
|
72
|
+
return Buffer.from(contents);
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
test("readPublishedFile retries Windows sharing violations and a file replaced mid-read", async () => {
|
|
77
|
+
const flaky = flakyPublishedFile([
|
|
78
|
+
{ at: "lstat", code: "EBUSY" },
|
|
79
|
+
{ at: "readFile", code: "EPERM" },
|
|
80
|
+
{ at: "readFile", code: "ENOENT" },
|
|
81
|
+
{ at: "readFile", code: "EACCES" },
|
|
82
|
+
]);
|
|
83
|
+
const sleeps = [];
|
|
84
|
+
const bytes = await readPublishedFile("lease.json", {
|
|
85
|
+
maxBytes: 64,
|
|
86
|
+
label: "Lease",
|
|
87
|
+
platform: "win32",
|
|
88
|
+
lstat: flaky.lstat,
|
|
89
|
+
readFile: flaky.readFile,
|
|
90
|
+
sleep: async (milliseconds) => void sleeps.push(milliseconds),
|
|
91
|
+
});
|
|
92
|
+
assert.equal(bytes?.toString("utf8"), "{}");
|
|
93
|
+
assert.deepEqual(sleeps, [10, 20, 40, 80]);
|
|
94
|
+
assert.deepEqual(flaky.calls, [
|
|
95
|
+
"lstat",
|
|
96
|
+
"lstat",
|
|
97
|
+
"readFile",
|
|
98
|
+
"lstat",
|
|
99
|
+
"readFile",
|
|
100
|
+
"lstat",
|
|
101
|
+
"readFile",
|
|
102
|
+
"lstat",
|
|
103
|
+
"readFile",
|
|
104
|
+
]);
|
|
105
|
+
});
|
|
106
|
+
test("readPublishedFile reports absence only from lstat and never turns a transient failure into absence", async () => {
|
|
107
|
+
const absent = flakyPublishedFile([{ at: "lstat", code: "ENOENT" }]);
|
|
108
|
+
assert.equal(await readPublishedFile("lease.json", { maxBytes: 64, label: "Lease", platform: "win32", ...absent }), undefined);
|
|
109
|
+
assert.deepEqual(absent.calls, ["lstat"]);
|
|
110
|
+
const exhausted = flakyPublishedFile(Array.from({ length: 5 }, () => ({ at: "readFile", code: "EPERM" })));
|
|
111
|
+
await assert.rejects(readPublishedFile("lease.json", {
|
|
112
|
+
maxBytes: 64,
|
|
113
|
+
label: "Lease",
|
|
114
|
+
platform: "win32",
|
|
115
|
+
attempts: 3,
|
|
116
|
+
...exhausted,
|
|
117
|
+
sleep: async () => { },
|
|
118
|
+
}), { code: "EPERM" });
|
|
119
|
+
assert.equal(exhausted.calls.filter((call) => call === "readFile").length, 3);
|
|
120
|
+
const linux = flakyPublishedFile([{ at: "readFile", code: "EPERM" }]);
|
|
121
|
+
await assert.rejects(readPublishedFile("lease.json", { maxBytes: 64, label: "Lease", platform: "linux", ...linux }), {
|
|
122
|
+
code: "EPERM",
|
|
123
|
+
});
|
|
124
|
+
assert.deepEqual(linux.calls, ["lstat", "readFile"]);
|
|
125
|
+
const replaced = flakyPublishedFile([{ at: "readFile", code: "ENOENT" }]);
|
|
126
|
+
assert.equal((await readPublishedFile("lease.json", {
|
|
127
|
+
maxBytes: 64,
|
|
128
|
+
label: "Lease",
|
|
129
|
+
platform: "linux",
|
|
130
|
+
...replaced,
|
|
131
|
+
sleep: async () => { },
|
|
132
|
+
}))?.toString("utf8"), "{}");
|
|
133
|
+
const oversized = flakyPublishedFile([], "x".repeat(65));
|
|
134
|
+
await assert.rejects(readPublishedFile("lease.json", { maxBytes: 64, label: "Lease", platform: "win32", ...oversized }), /Lease is unsafe/u);
|
|
135
|
+
assert.deepEqual(oversized.calls, ["lstat"]);
|
|
136
|
+
for (const attempts of [0, 11, 1.5]) {
|
|
137
|
+
await assert.rejects(readPublishedFile("lease.json", { maxBytes: 64, label: "Lease", attempts }), RangeError);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=files.test.js.map
|