-
Notifications
You must be signed in to change notification settings - Fork 310
Expand file tree
/
Copy pathloadSpec.ts
More file actions
63 lines (57 loc) · 2.01 KB
/
loadSpec.ts
File metadata and controls
63 lines (57 loc) · 2.01 KB
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
import type { AbsoluteFilePath } from "@fern-api/fs-utils";
import { CliError } from "@fern-api/task-context";
import { readFile } from "fs/promises";
import yaml from "js-yaml";
import { isEnoentError } from "./isEnoentError.js";
// biome-ignore lint/suspicious/noExplicitAny: OpenAPI specs can have any shape
type Spec = Record<string, any>;
/**
* Reads and parses a JSON or YAML spec file.
* Tries JSON first, then YAML. Throws a CliError with a clear message on failure.
*/
export async function loadSpec(filepath: AbsoluteFilePath): Promise<Spec> {
let contents: string;
try {
contents = await readFile(filepath, "utf8");
} catch (error) {
if (isEnoentError(error)) {
throw new CliError({ message: `File does not exist: ${filepath}`, code: CliError.Code.ConfigError });
}
throw new CliError({ message: `Failed to read file: ${filepath}`, code: CliError.Code.ParseError });
}
return parseSpec(contents, filepath);
}
/**
* Parses a string as JSON or YAML.
* Tries JSON first, then YAML. Throws a CliError on failure.
*/
export function parseSpec(contents: string, filepath: string): Spec {
try {
return JSON.parse(contents);
} catch {
try {
return yaml.load(contents) as Spec;
} catch {
throw new CliError({
message: `Failed to parse file as JSON or YAML: ${filepath}`,
code: CliError.Code.ParseError
});
}
}
}
/**
* Returns true if the filepath has a JSON extension (.json).
*/
export function isJsonFile(filepath: string): boolean {
return filepath.endsWith(".json");
}
/**
* Serializes a spec to a string in the format matching the given filepath's extension.
* JSON files are written as pretty-printed JSON; all others as YAML.
*/
export function serializeSpec(data: Spec, filepath: string): string {
if (isJsonFile(filepath)) {
return JSON.stringify(data, null, 2) + "\n";
}
return yaml.dump(data, { lineWidth: -1, noRefs: true });
}