@vigilbase/cli 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLOUDFLARE.md +2 -0
- package/COMMANDS.md +43 -6
- package/LOCAL.md +731 -0
- package/README.md +58 -6
- package/dist/auth/device-auth.d.ts.map +1 -1
- package/dist/auth/device-auth.js +7 -3
- package/dist/auth/device-auth.js.map +1 -1
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/provider.d.ts +18 -0
- package/dist/auth/provider.d.ts.map +1 -0
- package/dist/auth/provider.js +62 -0
- package/dist/auth/provider.js.map +1 -0
- package/dist/auth/refresh.d.ts +10 -0
- package/dist/auth/refresh.d.ts.map +1 -0
- package/dist/auth/refresh.js +143 -0
- package/dist/auth/refresh.js.map +1 -0
- package/dist/auth/store.d.ts +27 -2
- package/dist/auth/store.d.ts.map +1 -1
- package/dist/auth/store.js +23 -8
- package/dist/auth/store.js.map +1 -1
- package/dist/auth/token-metadata.d.ts +10 -0
- package/dist/auth/token-metadata.d.ts.map +1 -0
- package/dist/auth/token-metadata.js +22 -0
- package/dist/auth/token-metadata.js.map +1 -0
- package/dist/auth/types.d.ts +8 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +40 -9
- package/dist/cli.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +20 -8
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/helpers.d.ts +15 -0
- package/dist/commands/helpers.d.ts.map +1 -1
- package/dist/commands/helpers.js +2 -2
- package/dist/commands/helpers.js.map +1 -1
- package/dist/commands/index.d.ts +3 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +6 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/local.d.ts +30 -0
- package/dist/commands/local.d.ts.map +1 -0
- package/dist/commands/local.js +1520 -0
- package/dist/commands/local.js.map +1 -0
- package/dist/commands/public-tools.d.ts.map +1 -1
- package/dist/commands/public-tools.js +8 -4
- package/dist/commands/public-tools.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +16 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +36 -4
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/format.d.ts.map +1 -1
- package/dist/lib/format.js +9 -0
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/help.d.ts +1 -1
- package/dist/lib/help.d.ts.map +1 -1
- package/dist/lib/help.js +9 -0
- package/dist/lib/help.js.map +1 -1
- package/dist/lib/network.d.ts.map +1 -1
- package/dist/lib/network.js +2 -1
- package/dist/lib/network.js.map +1 -1
- package/dist/lib/one-client.d.ts +3 -2
- package/dist/lib/one-client.d.ts.map +1 -1
- package/dist/lib/one-client.js +46 -2
- package/dist/lib/one-client.js.map +1 -1
- package/dist/lib/security-client.d.ts +1 -1
- package/dist/lib/tui.d.ts +309 -0
- package/dist/lib/tui.d.ts.map +1 -0
- package/dist/lib/tui.js +847 -0
- package/dist/lib/tui.js.map +1 -0
- package/dist/local/cloudflare-checkup/cf/allowlist.d.ts +95 -0
- package/dist/local/cloudflare-checkup/cf/allowlist.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/cf/allowlist.js +184 -0
- package/dist/local/cloudflare-checkup/cf/allowlist.js.map +1 -0
- package/dist/local/cloudflare-checkup/cf/auth-lifecycle.d.ts +113 -0
- package/dist/local/cloudflare-checkup/cf/auth-lifecycle.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/cf/auth-lifecycle.js +313 -0
- package/dist/local/cloudflare-checkup/cf/auth-lifecycle.js.map +1 -0
- package/dist/local/cloudflare-checkup/cf/child-env.d.ts +32 -0
- package/dist/local/cloudflare-checkup/cf/child-env.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/cf/child-env.js +81 -0
- package/dist/local/cloudflare-checkup/cf/child-env.js.map +1 -0
- package/dist/local/cloudflare-checkup/cf/install.d.ts +106 -0
- package/dist/local/cloudflare-checkup/cf/install.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/cf/install.js +309 -0
- package/dist/local/cloudflare-checkup/cf/install.js.map +1 -0
- package/dist/local/cloudflare-checkup/cf/locate.d.ts +44 -0
- package/dist/local/cloudflare-checkup/cf/locate.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/cf/locate.js +228 -0
- package/dist/local/cloudflare-checkup/cf/locate.js.map +1 -0
- package/dist/local/cloudflare-checkup/cf/run-cf.d.ts +89 -0
- package/dist/local/cloudflare-checkup/cf/run-cf.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/cf/run-cf.js +275 -0
- package/dist/local/cloudflare-checkup/cf/run-cf.js.map +1 -0
- package/dist/local/cloudflare-checkup/collector.d.ts +48 -0
- package/dist/local/cloudflare-checkup/collector.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/collector.js +296 -0
- package/dist/local/cloudflare-checkup/collector.js.map +1 -0
- package/dist/local/cloudflare-checkup/contract.d.ts +2793 -0
- package/dist/local/cloudflare-checkup/contract.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/contract.js +1614 -0
- package/dist/local/cloudflare-checkup/contract.js.map +1 -0
- package/dist/local/cloudflare-checkup/email-verification.d.ts +125 -0
- package/dist/local/cloudflare-checkup/email-verification.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/email-verification.js +212 -0
- package/dist/local/cloudflare-checkup/email-verification.js.map +1 -0
- package/dist/local/cloudflare-checkup/errors.d.ts +28 -0
- package/dist/local/cloudflare-checkup/errors.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/errors.js +99 -0
- package/dist/local/cloudflare-checkup/errors.js.map +1 -0
- package/dist/local/cloudflare-checkup/output.d.ts +24 -0
- package/dist/local/cloudflare-checkup/output.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/output.js +89 -0
- package/dist/local/cloudflare-checkup/output.js.map +1 -0
- package/dist/local/cloudflare-checkup/prompts.d.ts +41 -0
- package/dist/local/cloudflare-checkup/prompts.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/prompts.js +140 -0
- package/dist/local/cloudflare-checkup/prompts.js.map +1 -0
- package/dist/local/cloudflare-checkup/rate-budget.d.ts +42 -0
- package/dist/local/cloudflare-checkup/rate-budget.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/rate-budget.js +80 -0
- package/dist/local/cloudflare-checkup/rate-budget.js.map +1 -0
- package/dist/local/cloudflare-checkup/snapshot-file.d.ts +53 -0
- package/dist/local/cloudflare-checkup/snapshot-file.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/snapshot-file.js +186 -0
- package/dist/local/cloudflare-checkup/snapshot-file.js.map +1 -0
- package/dist/local/cloudflare-checkup/submit-client.d.ts +98 -0
- package/dist/local/cloudflare-checkup/submit-client.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/submit-client.js +349 -0
- package/dist/local/cloudflare-checkup/submit-client.js.map +1 -0
- package/dist/local/cloudflare-checkup/terminal-ui.d.ts +171 -0
- package/dist/local/cloudflare-checkup/terminal-ui.d.ts.map +1 -0
- package/dist/local/cloudflare-checkup/terminal-ui.js +404 -0
- package/dist/local/cloudflare-checkup/terminal-ui.js.map +1 -0
- package/package.json +8 -4
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export declare const CF_CALL_TIMEOUT_MS = 45000;
|
|
2
|
+
export declare const STDOUT_CAP_BYTES: number;
|
|
3
|
+
/** `rulesets get` bodies can be large managed rulesets. */
|
|
4
|
+
export declare const RULESET_STDOUT_CAP_BYTES: number;
|
|
5
|
+
export declare const STDERR_CAP_BYTES: number;
|
|
6
|
+
/**
|
|
7
|
+
* Flags that skip confirmations, switch cf to local simulation or project
|
|
8
|
+
* config, or send a request body. No allowlisted argv contains them; the
|
|
9
|
+
* runner refuses to spawn one that does.
|
|
10
|
+
*/
|
|
11
|
+
export declare const FORBIDDEN_CF_FLAGS: readonly string[];
|
|
12
|
+
export declare function assertSafeCfArgv(argv: readonly string[]): void;
|
|
13
|
+
export type CfProcessResult = {
|
|
14
|
+
exitCode: number | null;
|
|
15
|
+
stdout: string;
|
|
16
|
+
stderr: string;
|
|
17
|
+
timedOut: boolean;
|
|
18
|
+
stdoutTooLarge: boolean;
|
|
19
|
+
/** Set when the process could not be started at all. */
|
|
20
|
+
spawnFailed: boolean;
|
|
21
|
+
};
|
|
22
|
+
export type CfRunOptions = {
|
|
23
|
+
env: Record<string, string>;
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
stdoutCapBytes?: number;
|
|
26
|
+
};
|
|
27
|
+
/** Owns the private working directory and every live cf child. */
|
|
28
|
+
export declare class CfProcessRunner {
|
|
29
|
+
readonly entry: string;
|
|
30
|
+
readonly privateDir: string;
|
|
31
|
+
private readonly active;
|
|
32
|
+
private disposed;
|
|
33
|
+
/** Set once the runner kills its children (abort or shutdown), so those kills are not read as timeouts. */
|
|
34
|
+
private terminating;
|
|
35
|
+
private constructor();
|
|
36
|
+
static create(entry: string): Promise<CfProcessRunner>;
|
|
37
|
+
run(argv: readonly string[], options: CfRunOptions): Promise<CfProcessResult>;
|
|
38
|
+
/**
|
|
39
|
+
* The only interactive cf passthroughs: `cf auth create` (sign-in) and
|
|
40
|
+
* `cf auth delete` (logout). With `stdoutToStderr` (`--json`), cf's stdout
|
|
41
|
+
* is sent to stderr so the CLI's stdout stays a single JSON object.
|
|
42
|
+
*/
|
|
43
|
+
runInteractive(argv: readonly string[], env: Record<string, string>, options?: {
|
|
44
|
+
stdoutToStderr?: boolean;
|
|
45
|
+
}): Promise<number>;
|
|
46
|
+
get activeCount(): number;
|
|
47
|
+
/** SIGTERM every live child, then SIGKILL whatever is still running after 2 s. */
|
|
48
|
+
terminateAll(): Promise<void>;
|
|
49
|
+
dispose(): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Run `work` with a private cf runner; the directory is removed afterwards and
|
|
53
|
+
* on SIGINT, when live children get SIGTERM and then SIGKILL.
|
|
54
|
+
*/
|
|
55
|
+
export declare function withCfRunner<T>(entry: string, work: (runner: CfProcessRunner) => Promise<T>): Promise<T>;
|
|
56
|
+
export type CfFailure = {
|
|
57
|
+
kind: 'node_unsupported';
|
|
58
|
+
} | {
|
|
59
|
+
kind: 'command_unavailable';
|
|
60
|
+
} | {
|
|
61
|
+
kind: 'auth';
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'http';
|
|
64
|
+
status: number;
|
|
65
|
+
} | {
|
|
66
|
+
kind: 'network';
|
|
67
|
+
} | {
|
|
68
|
+
kind: 'cf_error';
|
|
69
|
+
};
|
|
70
|
+
/** ANSI and box-drawing characters removed; lines kept. */
|
|
71
|
+
export declare function cleanCfStderr(stderr: string): string;
|
|
72
|
+
/**
|
|
73
|
+
* Classify a failed cf call from its stderr, in order: Node version, unknown
|
|
74
|
+
* command, auth without an HTTP status, the HTTP status line
|
|
75
|
+
* (`${status} ${text}[ · HTTP <path>]`), network, anything else. cf wraps
|
|
76
|
+
* messages at the terminal width, so word patterns run over collapsed text.
|
|
77
|
+
*/
|
|
78
|
+
export declare function classifyCfStderr(stderr: string): CfFailure;
|
|
79
|
+
/**
|
|
80
|
+
* Parse cf stdout: lists print a bare JSON array, gets a bare object. cf prints
|
|
81
|
+
* nothing for a `null` result, so an empty get is `null` (the projectors decide).
|
|
82
|
+
*/
|
|
83
|
+
export declare function parseCfJson(stdout: string, shape: 'array' | 'object'): {
|
|
84
|
+
ok: true;
|
|
85
|
+
value: unknown;
|
|
86
|
+
} | {
|
|
87
|
+
ok: false;
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=run-cf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-cf.d.ts","sourceRoot":"","sources":["../../../../src/local/cloudflare-checkup/cf/run-cf.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawning cf (spec §F3, §F6).
|
|
3
|
+
*
|
|
4
|
+
* cf always runs as `process.execPath <cf entry> …argv` with no shell (and so
|
|
5
|
+
* no `.cmd` shim on Windows), from a private, empty 0700 working directory, so
|
|
6
|
+
* a project's `.env`, `.env.local`, `cloudflare.config.ts`, directory profile
|
|
7
|
+
* bindings and account cache never apply. Output is capped, stderr is never
|
|
8
|
+
* echoed, and every failure is reduced to a small classification.
|
|
9
|
+
*/
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import { chmod, mkdtemp, rm } from 'node:fs/promises';
|
|
12
|
+
import { tmpdir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { stripVTControlCharacters } from 'node:util';
|
|
15
|
+
import { CF_TOKEN_ENV } from './child-env.js';
|
|
16
|
+
export const CF_CALL_TIMEOUT_MS = 45_000;
|
|
17
|
+
export const STDOUT_CAP_BYTES = 8 * 1024 * 1024;
|
|
18
|
+
/** `rulesets get` bodies can be large managed rulesets. */
|
|
19
|
+
export const RULESET_STDOUT_CAP_BYTES = 16 * 1024 * 1024;
|
|
20
|
+
export const STDERR_CAP_BYTES = 64 * 1024;
|
|
21
|
+
const KILL_GRACE_MS = 2_000;
|
|
22
|
+
/**
|
|
23
|
+
* Flags that skip confirmations, switch cf to local simulation or project
|
|
24
|
+
* config, or send a request body. No allowlisted argv contains them; the
|
|
25
|
+
* runner refuses to spawn one that does.
|
|
26
|
+
*/
|
|
27
|
+
export const FORBIDDEN_CF_FLAGS = Object.freeze(['--force', '-f', '--yes', '-y', '--local', '--mode', '-m', '--body', '--persist-to']);
|
|
28
|
+
export function assertSafeCfArgv(argv) {
|
|
29
|
+
for (const arg of argv) {
|
|
30
|
+
const flag = arg.split('=')[0];
|
|
31
|
+
if (FORBIDDEN_CF_FLAGS.includes(flag))
|
|
32
|
+
throw new Error(`Refusing to run cf with ${flag}.`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Owns the private working directory and every live cf child. */
|
|
36
|
+
export class CfProcessRunner {
|
|
37
|
+
entry;
|
|
38
|
+
privateDir;
|
|
39
|
+
active = new Set();
|
|
40
|
+
disposed = false;
|
|
41
|
+
/** Set once the runner kills its children (abort or shutdown), so those kills are not read as timeouts. */
|
|
42
|
+
terminating = false;
|
|
43
|
+
constructor(entry, privateDir) {
|
|
44
|
+
this.entry = entry;
|
|
45
|
+
this.privateDir = privateDir;
|
|
46
|
+
}
|
|
47
|
+
static async create(entry) {
|
|
48
|
+
const privateDir = await mkdtemp(join(tmpdir(), 'vigilbase-cf-'));
|
|
49
|
+
await chmod(privateDir, 0o700);
|
|
50
|
+
return new CfProcessRunner(entry, privateDir);
|
|
51
|
+
}
|
|
52
|
+
run(argv, options) {
|
|
53
|
+
assertSafeCfArgv(argv);
|
|
54
|
+
if (this.disposed)
|
|
55
|
+
return Promise.resolve(failedToStart());
|
|
56
|
+
const timeoutMs = options.timeoutMs ?? CF_CALL_TIMEOUT_MS;
|
|
57
|
+
const stdoutCap = options.stdoutCapBytes ?? STDOUT_CAP_BYTES;
|
|
58
|
+
return new Promise((resolve) => {
|
|
59
|
+
let child;
|
|
60
|
+
try {
|
|
61
|
+
child = spawn(process.execPath, [this.entry, ...argv], {
|
|
62
|
+
shell: false,
|
|
63
|
+
cwd: this.privateDir,
|
|
64
|
+
env: options.env,
|
|
65
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
66
|
+
windowsHide: true,
|
|
67
|
+
timeout: timeoutMs,
|
|
68
|
+
killSignal: 'SIGKILL',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
resolve(failedToStart());
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this.active.add(child);
|
|
76
|
+
const stdout = [];
|
|
77
|
+
const stderr = [];
|
|
78
|
+
let stdoutBytes = 0;
|
|
79
|
+
let stderrBytes = 0;
|
|
80
|
+
let timedOut = false;
|
|
81
|
+
let stdoutTooLarge = false;
|
|
82
|
+
let settled = false;
|
|
83
|
+
// Node's own `timeout` option kills the child too; this timer only makes
|
|
84
|
+
// the cause observable when it wins the race.
|
|
85
|
+
const timer = setTimeout(() => {
|
|
86
|
+
timedOut = true;
|
|
87
|
+
child.kill('SIGKILL');
|
|
88
|
+
}, timeoutMs);
|
|
89
|
+
timer.unref?.();
|
|
90
|
+
child.stdout?.on('data', (chunk) => {
|
|
91
|
+
if (stdoutTooLarge)
|
|
92
|
+
return;
|
|
93
|
+
stdoutBytes += chunk.byteLength;
|
|
94
|
+
if (stdoutBytes > stdoutCap) {
|
|
95
|
+
stdoutTooLarge = true;
|
|
96
|
+
stdout.length = 0;
|
|
97
|
+
child.kill('SIGKILL');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
stdout.push(chunk);
|
|
101
|
+
});
|
|
102
|
+
child.stderr?.on('data', (chunk) => {
|
|
103
|
+
if (stderrBytes >= STDERR_CAP_BYTES)
|
|
104
|
+
return;
|
|
105
|
+
const room = STDERR_CAP_BYTES - stderrBytes;
|
|
106
|
+
stderr.push(chunk.byteLength > room ? chunk.subarray(0, room) : chunk);
|
|
107
|
+
stderrBytes += Math.min(chunk.byteLength, room);
|
|
108
|
+
});
|
|
109
|
+
const finish = (exitCode, signal, spawnFailed) => {
|
|
110
|
+
if (settled)
|
|
111
|
+
return;
|
|
112
|
+
settled = true;
|
|
113
|
+
clearTimeout(timer);
|
|
114
|
+
this.active.delete(child);
|
|
115
|
+
// A child killed by a signal we did not send for the stdout cap or a
|
|
116
|
+
// shutdown was killed by the spawn timeout.
|
|
117
|
+
if (signal !== null && !stdoutTooLarge && !this.terminating)
|
|
118
|
+
timedOut = true;
|
|
119
|
+
resolve({
|
|
120
|
+
exitCode,
|
|
121
|
+
stdout: Buffer.concat(stdout).toString('utf8'),
|
|
122
|
+
stderr: Buffer.concat(stderr).toString('utf8'),
|
|
123
|
+
timedOut,
|
|
124
|
+
stdoutTooLarge,
|
|
125
|
+
spawnFailed,
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
child.once('error', () => finish(null, null, true));
|
|
129
|
+
child.once('close', (code, signal) => finish(typeof code === 'number' ? code : null, signal ?? null, false));
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* The only interactive cf passthroughs: `cf auth create` (sign-in) and
|
|
134
|
+
* `cf auth delete` (logout). With `stdoutToStderr` (`--json`), cf's stdout
|
|
135
|
+
* is sent to stderr so the CLI's stdout stays a single JSON object.
|
|
136
|
+
*/
|
|
137
|
+
runInteractive(argv, env, options = {}) {
|
|
138
|
+
assertSafeCfArgv(argv);
|
|
139
|
+
return new Promise((resolve, reject) => {
|
|
140
|
+
const child = spawn(process.execPath, [this.entry, ...argv], {
|
|
141
|
+
shell: false, cwd: this.privateDir, env, stdio: ['inherit', options.stdoutToStderr ? 2 : 'inherit', 'inherit'], windowsHide: true,
|
|
142
|
+
});
|
|
143
|
+
this.active.add(child);
|
|
144
|
+
child.once('error', (error) => {
|
|
145
|
+
this.active.delete(child);
|
|
146
|
+
reject(error);
|
|
147
|
+
});
|
|
148
|
+
child.once('close', (code) => {
|
|
149
|
+
this.active.delete(child);
|
|
150
|
+
resolve(typeof code === 'number' ? code : 1);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
get activeCount() {
|
|
155
|
+
return this.active.size;
|
|
156
|
+
}
|
|
157
|
+
/** SIGTERM every live child, then SIGKILL whatever is still running after 2 s. */
|
|
158
|
+
async terminateAll() {
|
|
159
|
+
this.terminating = true;
|
|
160
|
+
if (this.active.size === 0)
|
|
161
|
+
return;
|
|
162
|
+
const children = [...this.active];
|
|
163
|
+
for (const child of children)
|
|
164
|
+
child.kill('SIGTERM');
|
|
165
|
+
await new Promise((resolve) => {
|
|
166
|
+
const timer = setTimeout(() => {
|
|
167
|
+
for (const child of children)
|
|
168
|
+
if (child.exitCode === null && child.signalCode === null)
|
|
169
|
+
child.kill('SIGKILL');
|
|
170
|
+
resolve();
|
|
171
|
+
}, KILL_GRACE_MS);
|
|
172
|
+
timer.unref?.();
|
|
173
|
+
Promise.all(children.map((child) => child.exitCode !== null || child.signalCode !== null
|
|
174
|
+
? Promise.resolve()
|
|
175
|
+
: new Promise((done) => child.once('close', () => done())))).then(() => {
|
|
176
|
+
clearTimeout(timer);
|
|
177
|
+
resolve();
|
|
178
|
+
}, () => undefined);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
async dispose() {
|
|
182
|
+
if (this.disposed)
|
|
183
|
+
return;
|
|
184
|
+
this.disposed = true;
|
|
185
|
+
await this.terminateAll();
|
|
186
|
+
await rm(this.privateDir, { recursive: true, force: true });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function failedToStart() {
|
|
190
|
+
return { exitCode: null, stdout: '', stderr: '', timedOut: false, stdoutTooLarge: false, spawnFailed: true };
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Run `work` with a private cf runner; the directory is removed afterwards and
|
|
194
|
+
* on SIGINT, when live children get SIGTERM and then SIGKILL.
|
|
195
|
+
*/
|
|
196
|
+
export async function withCfRunner(entry, work) {
|
|
197
|
+
const runner = await CfProcessRunner.create(entry);
|
|
198
|
+
const onSignal = () => {
|
|
199
|
+
void runner.dispose().finally(() => process.exit(130));
|
|
200
|
+
};
|
|
201
|
+
process.once('SIGINT', onSignal);
|
|
202
|
+
try {
|
|
203
|
+
return await work(runner);
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
process.removeListener('SIGINT', onSignal);
|
|
207
|
+
await runner.dispose();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const BOX_DRAWING = /[\u2500-\u257f]/g;
|
|
211
|
+
// cf's API error header: `${status} ${statusText}`, where statusText is empty
|
|
212
|
+
// outside 400-504, optionally followed by ` · HTTP <path>` (absent when the
|
|
213
|
+
// response URL is unknown). Body lines (`[code] message`, notes) never match:
|
|
214
|
+
// after the status only a known status text, whitespace or the `·` suffix may follow.
|
|
215
|
+
const STATUS_TEXT = '(?:Bad Request|Unauthorized|Forbidden|Not Found|Method Not Allowed|Conflict|Unprocessable Entity|' +
|
|
216
|
+
'Too Many Requests|Internal Server Error|Bad Gateway|Service Unavailable|Gateway Timeout)';
|
|
217
|
+
const STATUS_LINE = new RegExp(`^\\s*([1-5]\\d\\d)(?: ${STATUS_TEXT})?\\s*(?:\u00b7.*)?$`, 'gm');
|
|
218
|
+
// Node/undici network failures and the cf SDK's own client timeout ("Timeout exceeded when calling …").
|
|
219
|
+
const NETWORK = /ENOTFOUND|ECONNRESET|ETIMEDOUT|ECONNREFUSED|EAI_AGAIN|UND_ERR|fetch failed|socket hang up|Timeout exceeded|Request timed out/i;
|
|
220
|
+
/** ANSI and box-drawing characters removed; lines kept. */
|
|
221
|
+
export function cleanCfStderr(stderr) {
|
|
222
|
+
return stripVTControlCharacters(stderr).replace(BOX_DRAWING, ' ').replace(/\r\n?/g, '\n');
|
|
223
|
+
}
|
|
224
|
+
// cf's non-interactive no-credential / expired-token message names the token variable.
|
|
225
|
+
const AUTH = new RegExp(`not logged in|cf auth (login|create)|expired|does not exist|necessary to set a ${CF_TOKEN_ENV}`, 'i');
|
|
226
|
+
/** The last status header line in cleaned stderr, if any. */
|
|
227
|
+
function statusFromLines(lines) {
|
|
228
|
+
let status = null;
|
|
229
|
+
for (const match of lines.matchAll(STATUS_LINE))
|
|
230
|
+
status = Number(match[1]);
|
|
231
|
+
return status;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Classify a failed cf call from its stderr, in order: Node version, unknown
|
|
235
|
+
* command, auth without an HTTP status, the HTTP status line
|
|
236
|
+
* (`${status} ${text}[ · HTTP <path>]`), network, anything else. cf wraps
|
|
237
|
+
* messages at the terminal width, so word patterns run over collapsed text.
|
|
238
|
+
*/
|
|
239
|
+
export function classifyCfStderr(stderr) {
|
|
240
|
+
const lines = cleanCfStderr(stderr);
|
|
241
|
+
const flat = lines.replace(/\s+/g, ' ');
|
|
242
|
+
if (/cf requires Node\.js/.test(flat))
|
|
243
|
+
return { kind: 'node_unsupported' };
|
|
244
|
+
if (/Did you mean|Unknown (argument|command)/.test(flat))
|
|
245
|
+
return { kind: 'command_unavailable' };
|
|
246
|
+
const status = statusFromLines(lines);
|
|
247
|
+
if (status === null && AUTH.test(flat))
|
|
248
|
+
return { kind: 'auth' };
|
|
249
|
+
if (status !== null)
|
|
250
|
+
return { kind: 'http', status };
|
|
251
|
+
if (NETWORK.test(flat))
|
|
252
|
+
return { kind: 'network' };
|
|
253
|
+
return { kind: 'cf_error' };
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Parse cf stdout: lists print a bare JSON array, gets a bare object. cf prints
|
|
257
|
+
* nothing for a `null` result, so an empty get is `null` (the projectors decide).
|
|
258
|
+
*/
|
|
259
|
+
export function parseCfJson(stdout, shape) {
|
|
260
|
+
if (shape === 'object' && stdout.trim() === '')
|
|
261
|
+
return { ok: true, value: null };
|
|
262
|
+
let value;
|
|
263
|
+
try {
|
|
264
|
+
value = JSON.parse(stdout);
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
return { ok: false };
|
|
268
|
+
}
|
|
269
|
+
if (shape === 'array')
|
|
270
|
+
return Array.isArray(value) ? { ok: true, value } : { ok: false };
|
|
271
|
+
if (value === null || (typeof value === 'object' && !Array.isArray(value)))
|
|
272
|
+
return { ok: true, value };
|
|
273
|
+
return { ok: false };
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=run-cf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-cf.js","sourceRoot":"","sources":["../../../../src/local/cloudflare-checkup/cf/run-cf.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collecting a Cloudflare account through cf (spec §F5, §D3).
|
|
3
|
+
*
|
|
4
|
+
* Every read goes through the frozen allowlist and the shared scheduler (four
|
|
5
|
+
* workers, the request budget, auth pauses and retries). Each response is
|
|
6
|
+
* projected immediately by the vendored contract and the raw text discarded.
|
|
7
|
+
* Lists are paged with `--page N` until an empty page, because cf strips
|
|
8
|
+
* `result_info`: a final page and a server-clamped page look the same.
|
|
9
|
+
*/
|
|
10
|
+
import { type CollectedEntry, type CloudflareCheckupSnapshotV1, type SnapshotCollector, type ZoneData } from './contract.js';
|
|
11
|
+
import { type ProfileArgs } from './cf/allowlist.js';
|
|
12
|
+
import { type CfScheduler } from './cf/auth-lifecycle.js';
|
|
13
|
+
export declare const WORKER_COUNT = 4;
|
|
14
|
+
export type CollectEnv = {
|
|
15
|
+
scheduler: CfScheduler;
|
|
16
|
+
auth: ProfileArgs;
|
|
17
|
+
/** Template IDs, or `zone_setting:<id>`, whose dry-run mapping did not match. */
|
|
18
|
+
unavailable: ReadonlySet<string>;
|
|
19
|
+
concurrency?: number;
|
|
20
|
+
onProgress?: (progress: CollectProgress) => void;
|
|
21
|
+
};
|
|
22
|
+
export type CollectProgress = {
|
|
23
|
+
zonesDone: number;
|
|
24
|
+
zonesTotal: number;
|
|
25
|
+
requests: number;
|
|
26
|
+
};
|
|
27
|
+
export type AccountSummary = {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
};
|
|
31
|
+
/** `accounts list --per-page 50 --page N` until an empty page. */
|
|
32
|
+
export declare function listAccounts(env: CollectEnv): Promise<AccountSummary[]>;
|
|
33
|
+
/** Requests for N zones: about 19 + extra pages + N × (33 + rulesets per zone). */
|
|
34
|
+
export declare function estimateRequests(zoneCount: number, rulesetsPerZone?: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Collect every snapshot entry for one account. Aborts (no file) when the
|
|
37
|
+
* account read fails other than 400/403/404, when the zone list fails, when it
|
|
38
|
+
* holds more than 100 zones, or when the account is invisible and has no zones.
|
|
39
|
+
*/
|
|
40
|
+
export declare function collectAccount(env: CollectEnv, accountId: string, hooks?: {
|
|
41
|
+
onZones?: (zones: readonly ZoneData[]) => void;
|
|
42
|
+
}): Promise<CollectedEntry[]>;
|
|
43
|
+
/** Assemble, validate and serialise; the returned text is exactly what is written and uploaded. */
|
|
44
|
+
export declare function buildSnapshot(accountId: string, collector: SnapshotCollector, entries: readonly CollectedEntry[]): {
|
|
45
|
+
snapshot: CloudflareCheckupSnapshotV1;
|
|
46
|
+
text: string;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=collector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../../src/local/cloudflare-checkup/collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAgBL,KAAK,cAAc,EAInB,KAAK,2BAA2B,EAGhC,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EAEd,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAwB,KAAK,WAAW,EAAqC,MAAM,mBAAmB,CAAA;AAC7G,OAAO,EAAyC,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAGhG,eAAO,MAAM,YAAY,IAAI,CAAA;AAI7B,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,WAAW,CAAA;IACtB,IAAI,EAAE,WAAW,CAAA;IACjB,iFAAiF;IACjF,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAChC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAA;CACjD,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzF,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAuFzD,kEAAkE;AAClE,wBAAsB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAW7E;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,SAA8B,GAAG,MAAM,CAEzG;AAkDD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,KAAK,IAAI,CAAA;CAAO,GAC7D,OAAO,CAAC,cAAc,EAAE,CAAC,CA2F3B;AAcD,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG;IAAE,QAAQ,EAAE,2BAA2B,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAS1K"}
|