-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathjson-schema-fs.mjs
98 lines (89 loc) · 3.21 KB
/
json-schema-fs.mjs
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
import { readdirSync, readFileSync } from 'fs';
import { basename, join } from 'node:path';
import { toSafeString } from 'json-schema-to-typescript/dist/src/utils.js';
import { generateSchema } from './json-schema.mjs';
/**
* From a directory, produce a list of valid json-schema files that can be used.
* @param {string} rootDir
* @param {string} [featureDirName] - optional feature dir name
*/
export function createFileList(rootDir, featureDirName = '') {
const files = readdirSync(join(rootDir, featureDirName), { withFileTypes: true });
return files.map((x) => {
const valid = isValidFileName(x);
if (valid.result) {
const abs = join(rootDir, featureDirName, x.name);
const content = readFileSync(abs, 'utf8');
return {
relative: join(featureDirName, x.name),
valid: true,
filename: x.name,
method: valid.method,
kind: valid.kind,
json: JSON.parse(content),
};
}
return {
valid: false,
errors: [`invalid filename ${x.name}, expected \`request\`, \`notify\` or \`subscribe\``],
};
});
}
/**
* @param {string} rootDir
* @return {{
* schema: import("json-schema-to-typescript").JSONSchema;
* featureName: string;
* dirname: string;
* topLevelType: string;
* }[]}
*/
export function createSchemasFromSubDirectories(rootDir) {
const dirList = readdirSync(rootDir, { withFileTypes: true });
const dirs = dirList.filter((x) => x.isDirectory());
const outputs = [];
for (const dir of dirs) {
outputs.push(processOneDirectory({ rootDir, subDir: dir.name, featureNameTitle: dir.name }));
}
return outputs.filter((x) => x !== null);
}
/**
* @param {object} params
* @param {string} params.rootDir - the full path to the directory in question
* @param {string} [params.subDir] - optional subdirectory
* @param {string} [params.featureNameTitle]
* @return {{
* schema: import('json-schema-to-typescript').JSONSchema,
* featureName: string,
* topLevelType: string
* dirname: string
* } | null}
*/
export function processOneDirectory({ rootDir, subDir = '', featureNameTitle = '' }) {
const fileList = createFileList(rootDir, subDir);
const valid = fileList.filter((x) => x.valid);
if (valid.length === 0) return null;
const featureName = toSafeString(featureNameTitle);
const schema = generateSchema(featureName, valid);
if (!schema.title) throw new Error('invariant: expected string');
const topLevelType = toSafeString(schema.title);
return {
featureName,
topLevelType,
dirname: subDir || basename(rootDir),
schema,
};
}
/**
* @param {import("node:fs").Dirent} file
*/
export function isValidFileName(file) {
if (!file.isFile()) return { result: false };
if (!file.name.endsWith('json')) return { result: false };
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [method, kind, ext] = file.name.split('.');
if (kind === 'request' || kind === 'response' || kind === 'notify' || kind === 'subscribe') {
return { result: true, method, kind };
}
return { result: false };
}