-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.ts
63 lines (54 loc) · 1.73 KB
/
index.ts
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 { Input, Output, ActionStep, Json } from "@shanzhai/interfaces";
/**
* An {@link ActionStep} which converts JSON to TypeScript type declarations.
*/
export class ConvertJsonToTypeScriptStep extends ActionStep {
/**
* @param name A description of the operation being performed.
* @param input An {@link Input} for the declarations to convert to
* TypeScript type declarations.
* @param output An {@link Output} for the generated TypeScript type
* declarations.
*/
constructor(
name: string,
public readonly input: Input<{ readonly [key: string]: Json }>,
public readonly output: Output<string>
) {
super(name, output.effects);
}
async execute(): Promise<void> {
const recurse = (json: Json): string => {
if (json === null) {
return `null`;
} else if (typeof json === `object`) {
if (Array.isArray(json)) {
return `readonly [${json.map(recurse).join(`, `)}]`;
} else {
const entries = Object.entries(json);
if (entries.length === 0) {
return `{}`;
} else {
return `{ ${entries
.sort(([a], [b]) => a.localeCompare(b))
.map(
([key, value]) =>
`readonly ${JSON.stringify(key)}: ${recurse(value)}`
)
.join(`, `)} }`;
}
}
} else {
return JSON.stringify(json);
}
};
const json = await this.input.get();
let combined = ``;
for (const key of Object.keys(json).sort()) {
const value = json[key];
const types = recurse(value);
combined += `declare const ${key}: ${types};\n\n`;
}
await this.output.set(combined);
}
}