Archived
1
0
Fork 0

implement required property of schema

client-only codegen
This commit is contained in:
sup39 2020-05-20 05:17:08 +09:00
parent 456cb9d119
commit 3d2fea95cb
11 changed files with 54 additions and 21 deletions

View file

@ -519,6 +519,9 @@ This tool only supports `application/json` type for request and response body. A
Other $ref like requestBody, responseBody are not supported currently.
## Versions
#### 2.0.3
- implement `required` property of schema
- client-only codegen
#### 2.0.2
- make number convertible to boolean
#### 2.0.1

View file

@ -8,7 +8,8 @@ const badArgv = (x, code=1) => {
console.error([
'Usage: api-codegen <apiDocPath> [flags]',
'Flags:',
' -o --outputDir: outputDir',
' -o --outputDir <output-dir>: output directory(default: api/generated)',
' -c --client-only: client code only(default: client & server)',
].join('\n'));
process.exit(code);
};
@ -20,8 +21,12 @@ const errExit = (x, err, code=1) => {
const argAttrs = ['apiDocPath'];
const flag2attr = {
o: 'outputDir',
outputDir: 'outputDir',
'o': 'outputDir',
'outputDir': 'outputDir',
};
const flag2attr0 = { // nullary
'c': 'clientOnly',
'client-only': 'clientOnly',
};
const requiredAttrs = [
...argAttrs,
@ -35,9 +40,17 @@ function parseArgv(argv) {
const setFlag = flag => {
flag0 = flag;
const attr0 = flag2attr[flag];
if (attr0 == null) return badArgv(`Unknown flag: ${flag}`);
if (config[attr0] != null) return badArgv(`Duplicate flag: ${flag}`);
attr = attr0;
if (attr0 == null) {
const attr0 = flag2attr0[flag];
if (attr0 == null) return badArgv(`Unknown flag: ${flag}`);
// nullary attr
if (config[attr0] != null) return badArgv(`Duplicate flag: ${flag}`);
config[attr0] = true;
} else {
// attr
if (config[attr0] != null) return badArgv(`Duplicate flag: ${flag}`);
attr = attr0;
}
};
const setVal = val => {
if (attr == null) {

1
dist/Config.d.ts vendored
View file

@ -13,5 +13,6 @@ export interface ConfigOptional {
utilsTSPath: string;
outputDir: string;
validateStatus: (status: string) => boolean;
clientOnly: boolean;
}
export declare const configDefault: ConfigOptional;

1
dist/Config.js vendored
View file

@ -15,4 +15,5 @@ exports.configDefault = {
// other
outputDir: 'api/generated',
validateStatus: function (status) { return /^2..$/.test(status); },
clientOnly: false,
};

1
dist/OpenAPI.d.ts vendored
View file

@ -67,6 +67,7 @@ interface Schema {
nullable?: boolean;
readOnly?: boolean;
maxSize?: number;
required?: string[];
}
interface ArraySchema extends Schema {
items: Schema | Reference;

4
dist/OpenAPI.js vendored
View file

@ -164,7 +164,9 @@ var SchemaType = /** @class */ (function () {
if (format === 'int32')
t = 'int32';
else {
warn("Unsupport integer format " + format + ", use number instead");
if (format && format != 'int64') {
warn("Unsupport integer format " + format + ", use number instead");
}
t = 'number'; // TODO int64
}
}

24
dist/codegen.js vendored
View file

@ -242,20 +242,22 @@ function codegenClientAPI(funcs, config, cp) {
return cp.end();
}
function codegenSchemas(schemas, config, cp) {
var _a;
var utilsTSPath = config.utilsTSPath;
// import
cp.writeln("import {FullDate, StrictTypeParser as STP} from '" + utilsTSPath + "'");
// schema
for (var _i = 0, _a = Object.entries(schemas); _i < _a.length; _i++) {
var _b = _a[_i], typeName = _b[0], schema = _b[1];
for (var _i = 0, _b = Object.entries(schemas); _i < _b.length; _i++) {
var _c = _b[_i], typeName = _c[0], schema = _c[1];
cp.writeln();
if (OpenAPI_1.isObjectSchema(schema)) {
// interface
cp.writeln("export interface " + typeName + " {", 1);
var propTypes = [];
for (var _c = 0, _d = Object.entries(schema.properties); _c < _d.length; _c++) {
var _e = _d[_c], propName = _e[0], prop = _e[1];
var propType = new OpenAPI_1.SchemaType(prop, true); // TODO required
var requireds = new Set((_a = schema.required) !== null && _a !== void 0 ? _a : []);
for (var _d = 0, _e = Object.entries(schema.properties); _d < _e.length; _d++) {
var _f = _e[_d], propName = _f[0], prop = _f[1];
var propType = new OpenAPI_1.SchemaType(prop, requireds.has(propName));
propTypes.push([propName, propType]);
cp.writeln(propType.forProp(propName) + ';');
}
@ -264,8 +266,8 @@ function codegenSchemas(schemas, config, cp) {
cp.writeln("export const " + typeName + " = {", 1);
// .from
cp.writeln("from: (o: {[_: string]: any}): " + typeName + " => ({", 1);
for (var _f = 0, propTypes_1 = propTypes; _f < propTypes_1.length; _f++) {
var _g = propTypes_1[_f], n = _g[0], t = _g[1];
for (var _g = 0, propTypes_1 = propTypes; _g < propTypes_1.length; _g++) {
var _h = propTypes_1[_g], n = _h[0], t = _h[1];
cp.writeln(n + ": " + t.stp("o." + n, typeName + '.' + n) + ",");
}
cp.writeln('}),', -1);
@ -273,8 +275,8 @@ function codegenSchemas(schemas, config, cp) {
cp.writeln("Partial: (o: {[_: string]: any}): Partial<" + typeName + "> => {", 1);
cp.writeln("const r: Partial<" + typeName + "> = {};");
var locPartial = "Partial<" + typeName + ">";
for (var _h = 0, propTypes_2 = propTypes; _h < propTypes_2.length; _h++) {
var _j = propTypes_2[_h], n = _j[0], t = _j[1];
for (var _j = 0, propTypes_2 = propTypes; _j < propTypes_2.length; _j++) {
var _k = propTypes_2[_j], n = _k[0], t = _k[1];
cp.writeln("if (o." + n + " !== void 0) r." + n + " = " + t.stp("o." + n, locPartial + '.' + n) + ";");
}
cp.writeln('return r;');
@ -305,7 +307,9 @@ function codegen(openAPI, configUser) {
// handler
ps.push(codegenIHandler(apiFuncs, config, gCP(config.IHandlerName)));
// server
ps.push(codegenRouter(apiFuncs, config, gCP(config.routerName)));
if (!config.clientOnly) {
ps.push(codegenRouter(apiFuncs, config, gCP(config.routerName)));
}
// client
ps.push(codegenClientAPI(apiFuncs, config, gCP(config.ClientAPIName)));
// schema

View file

@ -17,6 +17,7 @@ export interface ConfigOptional {
// other
outputDir: string;
validateStatus: (status: string) => boolean;
clientOnly: boolean;
}
export const configDefault: ConfigOptional = {
// format
@ -33,4 +34,5 @@ export const configDefault: ConfigOptional = {
// other
outputDir: 'api/generated',
validateStatus: (status: string) => /^2..$/.test(status),
clientOnly: false,
};

View file

@ -77,6 +77,7 @@ interface Schema {
nullable?: boolean;
readOnly?: boolean;
maxSize?: number;
required?: string[];
}
interface ArraySchema extends Schema {
items: Schema | Reference;
@ -227,7 +228,9 @@ export class SchemaType {
} else if (type === 'integer') {
if (format === 'int32') t = 'int32';
else {
warn(`Unsupport integer format ${format}, use number instead`);
if (format && format != 'int64') {
warn(`Unsupport integer format ${format}, use number instead`);
}
t = 'number'; // TODO int64
}
} else t = type;

View file

@ -245,8 +245,9 @@ function codegenSchemas(schemas: Schemas, config: Config, cp: CodePrinter) {
// interface
cp.writeln(`export interface ${typeName} {`, 1);
const propTypes: [string, SchemaType][] = [];
const requireds = new Set(schema.required ?? []);
for (const [propName, prop] of Object.entries(schema.properties)) {
const propType = new SchemaType(prop, true); // TODO required
const propType = new SchemaType(prop, requireds.has(propName));
propTypes.push([propName, propType]);
cp.writeln(propType.forProp(propName)+';');
}
@ -298,7 +299,9 @@ export default function codegen(openAPI: OpenAPI, configUser: ConfigUser) {
// handler
ps.push(codegenIHandler(apiFuncs, config, gCP(config.IHandlerName)));
// server
ps.push(codegenRouter(apiFuncs, config, gCP(config.routerName)));
if (!config.clientOnly) {
ps.push(codegenRouter(apiFuncs, config, gCP(config.routerName)));
}
// client
ps.push(codegenClientAPI(apiFuncs, config, gCP(config.ClientAPIName)));
// schema

View file

@ -1,6 +1,6 @@
{
"name": "@sup39/api-ts-gen",
"version": "2.0.2-b",
"version": "2.0.3",
"description": "OpenAPI code generator for TypeScript",
"main": "dist/index.js",
"types": "dist/index.d.ts",