Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | 16x 16x 2x 2x 2x 39x 39x 39x 47x 47x 47x 47x 47x 8x 2x 6x 6x 6x 6x 39x 21x 21x 3x 18x 18x 18x 18x 18x 13x 13x 1x 12x 12x 5x 7x 7x 7x 7x 5x 23x | /**
* Legacy flag parser for `bin/ethercalc` (ยง13 Q6).
*
* The old CLI used `optimist` to accept `--key`, `--cors`, `--port`, etc.
* We preserve the flag surface verbatim so existing self-host users can
* swap binaries without changing their systemd/init scripts. This module
* is pure โ it consumes an argv array and produces a `ParsedFlags` result
* or throws `CliError` with a message suitable for stderr. No process
* interaction; the orchestrator in `index.ts` owns I/O and exit codes.
*/
/**
* Shape of the parsed command line after legacy flag normalization.
*
* Every field is optional. When a flag is absent, the downstream mapper
* (`map.ts`) either supplies a wrangler default or leaves the env var
* unset so the Worker can fall back to its own default. Boolean flags
* (`--cors`, `--help`) are present-or-absent; string flags carry their
* value directly.
*/
export interface ParsedFlags {
key?: string;
cors?: boolean;
port?: number;
host?: string;
expire?: number;
basepath?: string;
keyfile?: string;
certfile?: string;
persistTo?: string;
help?: boolean;
}
/**
* Raised when the argv contains a syntactic error (unknown flag, missing
* value, non-numeric value where numeric required). Callers should print
* `err.message` to stderr and exit non-zero.
*/
export class CliError extends Error {
constructor(message: string) {
super(message);
this.name = 'CliError';
}
}
/** Flags that take a value. Map entry โ the ParsedFlags key it sets. */
const STRING_FLAGS: Record<string, keyof ParsedFlags> = {
'--key': 'key',
'--host': 'host',
'--basepath': 'basepath',
'--keyfile': 'keyfile',
'--certfile': 'certfile',
'--persist-to': 'persistTo',
};
/** Flags that take a numeric value. */
const NUMBER_FLAGS: Record<string, keyof ParsedFlags> = {
'--port': 'port',
'--expire': 'expire',
};
/** Boolean/presence flags. */
const BOOL_FLAGS: Record<string, keyof ParsedFlags> = {
'--cors': 'cors',
'--help': 'help',
'-h': 'help',
};
/**
* Parse argv (minus `node` + script name) into a `ParsedFlags`.
*
* Accepted forms, matching legacy optimist behavior:
* `--port 8080`
* `--port=8080`
* `--cors` (boolean flags stand alone)
* `-h` (only supported short flag โ matches old --help shim)
*
* Raises `CliError` on:
* - unknown flag (`--foo`)
* - string flag with no following value (`--port` at end of argv)
* - numeric flag with non-numeric value (`--port abc`)
* - positional arguments (we don't accept any)
*/
export function parseFlags(argv: readonly string[]): ParsedFlags {
const out: ParsedFlags = {};
let i = 0;
while (i < argv.length) {
// Loop condition keeps `raw` defined; the `as string` assertion is safe
// and preferable to a dead defensive branch that would never be covered.
const raw = argv[i] as string;
// `--foo=bar` splits into two halves; `--foo bar` uses the next token.
const eqIdx = raw.indexOf('=');
const flag = eqIdx >= 0 ? raw.slice(0, eqIdx) : raw;
const inlineValue = eqIdx >= 0 ? raw.slice(eqIdx + 1) : undefined;
if (Object.prototype.hasOwnProperty.call(BOOL_FLAGS, flag)) {
if (inlineValue !== undefined) {
throw new CliError(`${flag} does not take a value`);
}
const key = BOOL_FLAGS[flag] as keyof ParsedFlags;
(out as Record<string, unknown>)[key] = true;
i += 1;
continue;
}
if (Object.prototype.hasOwnProperty.call(STRING_FLAGS, flag)) {
const value = inlineValue !== undefined ? inlineValue : argv[i + 1];
if (value === undefined) {
throw new CliError(`${flag} requires a value`);
}
const key = STRING_FLAGS[flag] as keyof ParsedFlags;
(out as Record<string, unknown>)[key] = value;
i += inlineValue !== undefined ? 1 : 2;
continue;
}
if (Object.prototype.hasOwnProperty.call(NUMBER_FLAGS, flag)) {
const value = inlineValue !== undefined ? inlineValue : argv[i + 1];
if (value === undefined) {
throw new CliError(`${flag} requires a value`);
}
const n = Number(value);
if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0) {
throw new CliError(`${flag} expects a non-negative integer, got "${value}"`);
}
const key = NUMBER_FLAGS[flag] as keyof ParsedFlags;
(out as Record<string, unknown>)[key] = n;
i += inlineValue !== undefined ? 1 : 2;
continue;
}
// Unknown flag OR positional argument. We don't accept either.
throw new CliError(`Unknown flag: ${flag}`);
}
return out;
}
|