Skip to content

Commit e0080af

Browse files
feat: validate prefix value
1 parent 2b16e19 commit e0080af

File tree

2 files changed

+65
-31
lines changed

2 files changed

+65
-31
lines changed

bin/fastify-schema-to-typescript.js

+16-2
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,28 @@
33
const { program } = require("commander");
44
const { convert } = require("../dist/index");
55

6+
function parsePrefix(value) {
7+
if (!value.match(/^\w/i)) {
8+
console.error("Prefix needs to start with a letter");
9+
process.exit(-1);
10+
}
11+
12+
return value;
13+
}
14+
615
program
716
.option(
817
"-g, --glob <value>",
918
"glob matching JSON schema to convert",
1019
"src/**/schema.json"
1120
)
12-
.option("-p, --prefix <value>", "prefix to use before interfaces' name", "");
21+
.option(
22+
"-p, --prefix <value>",
23+
"prefix to use before interfaces' name",
24+
parsePrefix,
25+
""
26+
);
1327

1428
program.parse(process.argv);
1529

16-
convert(program.glob, program.prefix);
30+
convert({ glob: program.glob, prefix: program.prefix });

src/index.ts

+49-29
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@ import glob from "glob";
22
import path from "path";
33
import fs from "fs";
44
import { compile } from "json-schema-to-typescript";
5+
import { promisify } from "util";
56

6-
const opts = { bannerComment: "" };
7+
const compileOptions = { bannerComment: "" };
78
const defaultSchema = { type: "object", additionalProperties: false };
89

10+
export interface Options {
11+
glob: string;
12+
prefix: string;
13+
}
14+
915
export async function generateReplyInterfaces(
1016
prefix: string,
1117
replies: Record<any, any> = {}
@@ -18,7 +24,7 @@ export async function generateReplyInterfaces(
1824
await compile(
1925
replySchema || defaultSchema,
2026
prefix + "Reply" + replyCode.toUpperCase(),
21-
opts
27+
compileOptions
2228
)
2329
);
2430
}
@@ -29,12 +35,13 @@ type ${prefix}Reply = ${generatedReplyNames.join(" | ") || "{}"}
2935
`.trim();
3036
}
3137

32-
async function writeFile(
38+
async function generateInterfaces(
3339
parsedPath: path.ParsedPath,
34-
prefix: string,
35-
schema: any
40+
schema: any,
41+
options: Options
3642
) {
37-
const template = `/* tslint:disable */
43+
return `\
44+
/* tslint:disable */
3845
/* eslint-disable */
3946
/**
4047
* This file was automatically generated. DO NOT MODIFY IT BY HAND.
@@ -45,38 +52,51 @@ import { RouteHandler } from "fastify"
4552
4653
import schema from './${parsedPath.base}'
4754
48-
${await compile(schema.params || defaultSchema, prefix + "Params", opts)}
55+
${await compile(
56+
schema.params || defaultSchema,
57+
options.prefix + "Params",
58+
compileOptions
59+
)}
4960
${await compile(
5061
schema.querystring || schema.query || defaultSchema,
51-
prefix + "Query",
52-
opts
62+
options.prefix + "Query",
63+
compileOptions
5364
)}
54-
${await compile(schema.body || defaultSchema, prefix + "Body", opts)}
55-
${await compile(schema.headers || defaultSchema, prefix + "Headers", opts)}
56-
${await generateReplyInterfaces(prefix, schema.response)}
65+
${await compile(
66+
schema.body || defaultSchema,
67+
options.prefix + "Body",
68+
compileOptions
69+
)}
70+
${await compile(
71+
schema.headers || defaultSchema,
72+
options.prefix + "Headers",
73+
compileOptions
74+
)}
75+
${await generateReplyInterfaces(options.prefix, schema.response)}
5776
58-
type ${prefix}Handler = RouteHandler<{
59-
Query: ${prefix}Query;
60-
Body: ${prefix}Body;
61-
Params: ${prefix}Params;
62-
Headers: ${prefix}Headers;
63-
Reply: ${prefix}Reply;
77+
type ${options.prefix}Handler = RouteHandler<{
78+
Query: ${options.prefix}Query;
79+
Body: ${options.prefix}Body;
80+
Params: ${options.prefix}Params;
81+
Headers: ${options.prefix}Headers;
82+
Reply: ${options.prefix}Reply;
6483
}>;
6584
66-
export { ${prefix}Handler, schema }
67-
`;
85+
export { ${options.prefix}Handler, schema }\
86+
`;
87+
}
6888

69-
fs.writeFileSync(
70-
path.join(parsedPath.dir, parsedPath.name + ".ts"),
71-
template
72-
);
89+
async function writeFile(parsedPath: path.ParsedPath, template: string) {
90+
const write = promisify(fs.writeFile);
91+
return write(path.join(parsedPath.dir, parsedPath.name + ".ts"), template);
7392
}
7493

75-
export function convert(globString: string, prefix: string) {
76-
const filePaths = glob.sync(globString);
77-
filePaths.forEach((filePath) => {
94+
export async function convert(options: Options) {
95+
const filePaths = glob.sync(options.glob);
96+
for (const filePath of filePaths) {
7897
const parsedPath = path.parse(filePath);
7998
const schema = JSON.parse(fs.readFileSync(filePath, "utf-8"));
80-
writeFile(parsedPath, prefix, schema);
81-
});
99+
const template = await generateInterfaces(parsedPath, schema, options);
100+
await writeFile(parsedPath, template);
101+
}
82102
}

0 commit comments

Comments
 (0)