( inline: string | undefined, filePath: string | undefined, readFile: (path: string) => string = (p) => readFileSync(resolve(p), "utf8"), )
| 45 | // type-discriminated parser whose value is exactly testability. |
| 46 | // fallow-ignore-next-line unused-export complexity |
| 47 | export function parseVariablesArg( |
| 48 | inline: string | undefined, |
| 49 | filePath: string | undefined, |
| 50 | readFile: (path: string) => string = (p) => readFileSync(resolve(p), "utf8"), |
| 51 | ): VariablesParseResult { |
| 52 | if (inline != null && filePath != null) { |
| 53 | return { ok: false, error: { kind: "conflict" } }; |
| 54 | } |
| 55 | let raw: string | undefined; |
| 56 | let source: "inline" | "file" | undefined; |
| 57 | if (inline != null) { |
| 58 | raw = inline; |
| 59 | source = "inline"; |
| 60 | } else if (filePath != null) { |
| 61 | try { |
| 62 | raw = readFile(filePath); |
| 63 | source = "file"; |
| 64 | } catch (error: unknown) { |
| 65 | return { |
| 66 | ok: false, |
| 67 | error: { |
| 68 | kind: "read-error", |
| 69 | path: filePath, |
| 70 | cause: error instanceof Error ? error.message : String(error), |
| 71 | }, |
| 72 | }; |
| 73 | } |
| 74 | } |
| 75 | if (raw == null) return { ok: true, value: undefined }; |
| 76 | |
| 77 | let parsed: unknown; |
| 78 | try { |
| 79 | parsed = JSON.parse(raw); |
| 80 | } catch (error: unknown) { |
| 81 | return { |
| 82 | ok: false, |
| 83 | error: { |
| 84 | kind: "parse-error", |
| 85 | source: source ?? "inline", |
| 86 | cause: error instanceof Error ? error.message : String(error), |
| 87 | }, |
| 88 | }; |
| 89 | } |
| 90 | if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) { |
| 91 | return { ok: false, error: { kind: "shape-error" } }; |
| 92 | } |
| 93 | return { ok: true, value: parsed as Record<string, unknown> }; |
| 94 | } |
| 95 | |
| 96 | function variablesErrorMessage(error: VariablesParseError): { title: string; message: string } { |
| 97 | switch (error.kind) { |
no test coverage detected