-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJSONSchema.decorator.ts
85 lines (72 loc) · 1.83 KB
/
JSONSchema.decorator.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import fs from "fs";
import { klass, property, propertyVoid } from "../index";
type SchemaType = "number" | "string" | "boolean" | "ID";
const typeMap = {
ID: "number",
number: "number",
string: "string",
boolean: "boolean",
};
type SchemaMap = {
[key: string]: {
type: SchemaType;
description?: string;
};
};
const schemaFileMap: { [key: string]: SchemaMap } = {};
type PropType = [SchemaType, string];
type OptionalPropType = Partial<PropType>;
export const field = property<OptionalPropType>(
({
key,
type,
args: [schemaType, description] = [],
metadata: { filePath },
}) => {
if (!schemaFileMap[filePath]) {
schemaFileMap[filePath] = {};
}
const schema = schemaFileMap[filePath];
schema[key] = {
type: typeMap[schemaType || type] as SchemaType,
};
if (description?.trim().length) {
schema[key].description = description?.trim();
}
}
);
export const auto = propertyVoid(({ key, type, metadata: { filePath } }) => {
if (!schemaFileMap[filePath]) {
schemaFileMap[filePath] = {};
}
const schema = schemaFileMap[filePath];
if (type !== "number" && type !== "string" && type !== "boolean") {
throw `Invalid or missing type definition at ${type}`;
}
schema[key] = {
type: type as SchemaType,
};
});
export const type = klass<[string] | undefined>(
async ({ args: [object], metadata: { filePath } }) => {
if (!schemaFileMap[filePath]) {
return;
}
const schemaFile = filePath.replace(".ts", ".json");
await fs.promises.writeFile(
schemaFile,
JSON.stringify(
{
[object]: schemaFileMap[filePath],
},
null,
2
),
{
encoding: "utf-8",
}
);
console.log("Saved JSON schema to", schemaFile);
}
);
export const decorators = { auto, field, type };