Archived
1
0
Fork 0

fix Partial constructor, enhance error msg

add more info to BadValueError
  special message on undefined and null
  trace the location where the error is thrown
add int32 STP
fix STP null argument bug
This commit is contained in:
supmiku39 2020-04-08 20:17:57 +09:00
parent 8f97095fbc
commit 87615616d6
9 changed files with 266 additions and 130 deletions

4
dist/OpenAPI.d.ts vendored
View file

@ -114,11 +114,11 @@ export declare class SchemaType {
get required(): boolean;
get maxSize(): string | number | undefined;
forProp(prop: string): string;
stp(prop: string): string;
stp(prop: string, label: string, partial?: boolean): string;
private schema;
constructor(schema: Schema | Reference | string, _required: boolean);
static typeNameOf(schema: Schema | Reference): string;
static gcStp(para: string, schema: Schema | Reference): string;
static gcStp(para: string, schema: Schema | Reference, label: string, partial: boolean): string;
}
export declare type APIFunctions = {
[_: string]: APIFunction;

55
dist/OpenAPI.js vendored
View file

@ -70,8 +70,9 @@ var SchemaType = /** @class */ (function () {
SchemaType.prototype.forProp = function (prop) {
return "" + prop + (this.required ? '' : '?') + ": " + this.typeName;
};
SchemaType.prototype.stp = function (prop) {
var stp = SchemaType.gcStp(prop, this.schema);
SchemaType.prototype.stp = function (prop, label, partial) {
if (partial === void 0) { partial = false; }
var stp = SchemaType.gcStp(prop, this.schema, label, partial);
return (this.required ? '' : prop + "===undefined ? undefined : ") + stp;
};
SchemaType.typeNameOf = function (schema) {
@ -118,27 +119,30 @@ var SchemaType = /** @class */ (function () {
sType = "Readonly<" + sType + ">";
return sType;
};
SchemaType.gcStp = function (para, schema) {
var sPara = "'" + para.replace(/'/g, '\\\'') + "'";
SchemaType.gcStp = function (para, schema, label, partial) {
// partial: Object only, 1 layer only
// object
if (isReference(schema)) {
return "new " + new SchemaType(schema, true).typeName + "(" + para + ")";
var typeName = new SchemaType(schema, true).typeName;
return partial ?
typeName + ".Partial(" + para + ")" :
"new " + typeName + "(" + para + ")";
}
// any
var code;
var type = schema.type, nullable = schema.nullable, format = schema.format;
var sStp;
if (type === 'any')
return para;
if (isArraySchema(schema)) {
code = "STP._Array(" + para + ", " + sPara + ").map(o=>" + SchemaType.gcStp('o', schema.items) + ")";
sStp = "(v, l)=>STP._Array(v, l, elm=>" + SchemaType.gcStp('elm', schema.items, label + "[]", false) + ")";
}
else if (isObjectSchema(schema)) {
code = '{';
sStp = '()=>({';
for (var _i = 0, _a = Object.entries(schema.properties); _i < _a.length; _i++) {
var _b = _a[_i], name_2 = _b[0], sub = _b[1];
code += name_2 + ": " + SchemaType.gcStp(para + '.' + name_2, sub) + ", ";
sStp += name_2 + ": " + SchemaType.gcStp(para + '.' + name_2, sub, label + '.' + name_2, false) + ", ";
}
code += '}';
sStp += '})';
}
else {
var t = void 0;
@ -148,30 +152,37 @@ var SchemaType = /** @class */ (function () {
else if (format === 'date')
t = 'FullDate';
else if (format === 'byte')
t = 'string'; // TODO
t = 'byte';
else if (format === 'binary')
t = 'string'; // TODO
t = 'binary';
else {
if (format)
warn("Unknown format " + format + ", use string instead");
if (format) {
warn("Unknown string format " + format + ", use string instead");
}
t = 'string';
}
}
else if (type === 'integer')
t = 'number';
else if (type === 'integer') {
if (format === 'int32')
t = 'int32';
else {
warn("Unsupport integer format " + format + ", use number instead");
t = 'number'; // TODO int64
}
}
else
t = type;
if (!StrictTypeParser_1.StrictTypeParser.supportTypes.includes(t)) {
warn("Unknown type " + type + ", use any instead");
warn("Unsupport type " + type + " " + format + ", use any instead");
return para;
}
else
code = "STP._" + t + "(" + para + ", " + sPara + ")";
sStp = "STP._" + t;
}
// nullable
if (nullable)
code = para + "===null ? null : " + code;
return code;
var funcName = nullable ? 'nullableParse' : 'parse';
// result
var sLabel = "'" + label.replace(/'/g, '\\\'') + "'"; // escape
return "STP." + funcName + "(" + sStp + ", " + para + ", " + sLabel + ")";
};
return SchemaType;
}());

33
dist/codegen.js vendored
View file

@ -102,7 +102,7 @@ function codegenIHandler(funcs, config, cp) {
// TODO void -> string or any
var isValid = validateStatus(status_2);
cp.writeln("case " + status_2 + ": return this." + (isValid ? 'onSuccess' : 'onFail') + "(this.handlers[" + status_2 + "],", 1);
cp.writeln(schema.stp('data') + ");");
cp.writeln(schema.stp('data', 'res.body') + ");");
cp.tab(-1);
if (isValid)
validTypes.add(schema.typeName);
@ -164,6 +164,7 @@ function codegenRouter(funcs, config, cp) {
for (var _i = 0, _a = Object.entries(funcs); _i < _a.length; _i++) {
var _b = _a[_i], funcName = _b[0], func = _b[1];
var method = func.method, url = func.url, reqTypes = func.reqTypes, resTypes = func.resTypes;
var isPartial = method === 'patch';
var statuses = Object.keys(resTypes);
// TODO escape
var sURL = url.replace(/{(.*?)}/g, ':$1'); // {a} -> :a
@ -174,7 +175,7 @@ function codegenRouter(funcs, config, cp) {
mid = "bodyParser(" + config_1 + "), ";
}
cp.writeln("router." + method + "('" + sURL + "', " + mid + "async ctx => {", 1);
// TODO permission check, etc
// req
if (Object.keys(reqTypes).length === 0) {
cp.writeln('const req = {};');
}
@ -192,16 +193,15 @@ function codegenRouter(funcs, config, cp) {
for (var _d = 0, _e = Object.entries(paras); _d < _e.length; _d++) {
var _f = _e[_d], name_1 = _f[0], schema = _f[1];
var pn = "ctxGetParas." + _in + "(ctx, '" + name_1 + "')";
cp.writeln(name_1 + ": " + schema.stp(pn) + ",");
var label = "req." + _in;
cp.writeln(name_1 + ": " + schema.stp(pn, label) + ",");
}
cp.writeln('},', -1);
}
// body
var body = reqTypes.body;
if (body != null) {
var name_2 = 'body';
var pn = 'reqBody';
cp.writeln(name_2 + ": " + body.stp(pn));
cp.writeln("body: " + body.stp('reqBody', 'req.body', isPartial));
}
cp.writeln('}} catch(err) {', -1);
cp.tab(1);
@ -320,13 +320,13 @@ function codegenSchemas(schemas, config, cp) {
cp.writeln();
// schema
for (var _i = 0, _a = Object.entries(schemas); _i < _a.length; _i++) {
var _b = _a[_i], name_3 = _b[0], schema = _b[1];
var _b = _a[_i], typeName = _b[0], schema = _b[1];
if (OpenAPI_1.isObjectSchema(schema)) {
cp.writeln("export class " + name_3 + " {", 1);
cp.writeln("export class " + 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 propType = new OpenAPI_1.SchemaType(prop, true); // TODO required
propTypes.push([propName, propType]);
cp.writeln(propType.forProp(propName) + ';');
}
@ -334,13 +334,24 @@ function codegenSchemas(schemas, config, cp) {
cp.writeln('constructor(o: {[_: string]: any}){', 1);
for (var _f = 0, propTypes_1 = propTypes; _f < propTypes_1.length; _f++) {
var _g = propTypes_1[_f], n = _g[0], t = _g[1];
cp.writeln("this." + n + " = " + t.stp("o." + n) + ";");
cp.writeln("this." + n + " = " + t.stp("o." + n, typeName + '.' + n) + ";");
}
cp.writeln('}', -1);
// Partial
cp.writeln("static 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];
cp.writeln("if (o." + n + " !== undefined) r." + n + " = " + t.stp("o." + n, locPartial + '.' + n) + ";");
}
cp.writeln('return r;');
cp.writeln('}', -1);
// end of class
cp.writeln('}', -1);
}
else {
cp.writeln("export type " + name_3 + " = " + OpenAPI_1.SchemaType.typeNameOf(schema));
cp.writeln("export type " + typeName + " = " + OpenAPI_1.SchemaType.typeNameOf(schema));
}
}
// return

View file

@ -1,18 +1,25 @@
import { FullDate } from './FullDate';
export declare module StrictTypeParser {
class BadValueError extends Error {
attr: string;
label: string;
constructor(label: string, message: string);
}
class BadTypeError extends BadValueError {
label: string;
type: string;
value: any;
constructor(attr: string, type: string, value: any);
constructor(label: string, type: string, value: any);
}
function _number(x: any, attr: string): number;
function _string(x: any, attr: string): string;
function _boolean(x: any, attr: string): boolean;
function _Date(x: any, attr: string): Date;
function _FullDate(x: any, attr: string): FullDate;
function _byte(x: any, attr: string): string;
function _binary(x: any, attr: string): string;
function _Array(x: any, attr: string): Array<any>;
function _int32(x: any, label: string): number;
function _number(x: any, label: string): number;
function _string(x: any, label: string): string;
function _boolean(x: any, label: string): boolean;
function _Date(x: any, label: string): Date;
function _FullDate(x: any, label: string): FullDate;
function _byte(x: any, label: string): string;
function _binary(x: any, label: string): string;
function _Array<T>(x: any, label: string, mapper: (x: any) => T): Array<T>;
function parse<T>(stp: (val: any, label: string) => T, val: any, label: string): T;
function nullableParse<T>(stp: (val: any, label: string) => T, val: any, label: string): T | null;
const supportTypes: string[];
}

View file

@ -18,87 +18,129 @@ var StrictTypeParser;
(function (StrictTypeParser) {
var BadValueError = /** @class */ (function (_super) {
__extends(BadValueError, _super);
function BadValueError(attr, type, value) {
var _this = _super.call(this, attr + ": Can not convert `" + (['object', 'array'].includes(typeof value) ?
JSON.stringify(value) : "" + value) + "` to type " + type) || this;
_this.attr = attr;
_this.type = type;
_this.value = value;
function BadValueError(label, message) {
var _this = _super.call(this, message) || this;
_this.label = label;
console.error(_this.message);
Object.setPrototypeOf(_this, BadValueError.prototype);
Object.setPrototypeOf(_this, BadTypeError.prototype);
return _this;
}
return BadValueError;
}(Error));
StrictTypeParser.BadValueError = BadValueError;
function _number(x, attr) {
var BadTypeError = /** @class */ (function (_super) {
__extends(BadTypeError, _super);
function BadTypeError(label, type, value) {
var _this = _super.call(this, label, label + ": Can not convert `" + (['object', 'array'].includes(typeof value) ?
JSON.stringify(value) : "" + value) + "` to type " + type) || this;
_this.label = label;
_this.type = type;
_this.value = value;
return _this;
}
return BadTypeError;
}(BadValueError));
StrictTypeParser.BadTypeError = BadTypeError;
function _int32(x, label) {
if (typeof x === 'number' && x === (x | 0))
return x;
if (typeof x === 'string') { // convert from url
var r = +x | 0;
if (x === r.toString())
return r;
}
throw new BadTypeError(label, 'int32', x);
}
StrictTypeParser._int32 = _int32;
function _number(x, label) {
if (typeof x === 'number')
return x;
if (typeof x === 'string') {
if (typeof x === 'string') { // convert from url
var r = +x;
if (!isNaN(r))
return r;
}
throw new BadValueError(attr, 'number', x);
throw new BadTypeError(label, 'number', x);
}
StrictTypeParser._number = _number;
function _string(x, attr) {
function _string(x, label) {
if (typeof x === 'string')
return x;
if (typeof x === 'object')
return x.toString();
throw new BadValueError(attr, 'string', x);
throw new BadTypeError(label, 'string', x);
}
StrictTypeParser._string = _string;
function _boolean(x, attr) {
function _boolean(x, label) {
if (typeof x === 'boolean')
return x;
if (x === 'true')
return true;
if (x === 'false')
return false;
throw new BadValueError(attr, 'boolean', x);
throw new BadTypeError(label, 'boolean', x);
}
StrictTypeParser._boolean = _boolean;
function _Date(x, attr) {
function _Date(x, label) {
var r = new Date(x);
if (!isNaN(+r))
if (x != null && !isNaN(+r))
return r;
throw new BadValueError(attr, 'Date', x);
throw new BadTypeError(label, 'Date', x);
}
StrictTypeParser._Date = _Date;
function _FullDate(x, attr) {
function _FullDate(x, label) {
var r = new FullDate_1.FullDate(x);
if (!isNaN(+r))
if (x != null && !isNaN(+r))
return r;
throw new BadValueError(attr, 'FullDate', x);
throw new BadTypeError(label, 'FullDate', x);
}
StrictTypeParser._FullDate = _FullDate;
function _byte(x, attr) {
function _byte(x, label) {
if (typeof x === 'string')
return x;
if (x instanceof Buffer)
return x.toString('base64');
throw new BadValueError(attr, 'byte', x);
throw new BadTypeError(label, 'byte', x);
}
StrictTypeParser._byte = _byte;
function _binary(x, attr) {
function _binary(x, label) {
if (typeof x === 'string')
return x;
if (x instanceof Buffer)
return x.toString('hex');
if ((x === null || x === void 0 ? void 0 : x.buffer) instanceof Buffer)
return x.toString('hex');
throw new BadValueError(attr, 'binary', x);
throw new BadTypeError(label, 'binary', x);
}
StrictTypeParser._binary = _binary;
function _Array(x, attr) {
function _Array(x, label, mapper) {
if (x instanceof Array)
return x;
throw new BadValueError(attr, 'Array', x);
return x.map(mapper);
throw new BadTypeError(label, 'Array', x);
}
StrictTypeParser._Array = _Array;
function undefinedCheck(val, label) {
if (val === undefined) {
throw new BadValueError(label, label + " is required, but got undefined");
}
}
function parse(stp, val, label) {
// body
undefinedCheck(val, label);
if (val === null) {
throw new BadValueError(label, label + " is not nullable, but got null");
}
return stp(val, label);
}
StrictTypeParser.parse = parse;
function nullableParse(stp, val, label) {
// body
undefinedCheck(val, label);
return val === null ? null : stp(val, label);
}
StrictTypeParser.nullableParse = nullableParse;
StrictTypeParser.supportTypes = [
'number', 'string', 'boolean', 'Date', 'FullDate', 'byte', 'binary'
'int32', 'number', 'string', 'boolean',
'Date', 'FullDate', 'byte', 'binary'
];
})(StrictTypeParser = exports.StrictTypeParser || (exports.StrictTypeParser = {}));

View file

@ -145,8 +145,8 @@ export class SchemaType {
forProp(prop: string): string {
return `${prop}${this.required ? '' : '?'}: ${this.typeName}`;
}
stp(prop: string): string {
const stp = SchemaType.gcStp(prop, this.schema);
stp(prop: string, label: string, partial: boolean=false): string {
const stp = SchemaType.gcStp(prop, this.schema, label, partial);
return (this.required ? '' : `${prop}===undefined ? undefined : `)+stp;
}
@ -189,46 +189,61 @@ export class SchemaType {
if (readOnly) sType = `Readonly<${sType}>`;
return sType;
}
static gcStp(para: string, schema: Schema | Reference): string {
const sPara = `'${para.replace(/'/g, '\\\'')}'`;
static gcStp(para: string, schema: Schema | Reference,
label: string, partial: boolean): string {
// partial: Object only, 1 layer only
// object
if (isReference(schema)) {
return `new ${new SchemaType(schema, true).typeName}(${para})`;
const typeName = new SchemaType(schema, true).typeName;
return partial ?
`${typeName}.Partial(${para})` :
`new ${typeName}(${para})`;
}
// any
let code;
const {type, nullable, format} = schema;
let sStp;
if (type === 'any') return para;
if (isArraySchema(schema)) {
code = `STP._Array(${para}, ${sPara}).map(o=>${
SchemaType.gcStp('o', schema.items)})`;
sStp = `(v, l)=>STP._Array(v, l, elm=>${
SchemaType.gcStp('elm', schema.items, `${label}[]`, false)})`;
} else if (isObjectSchema(schema)) {
code = '{';
sStp = '()=>({';
for (const [name, sub] of Object.entries(schema.properties)) {
code += `${name}: ${SchemaType.gcStp(para+'.'+name, sub)}, `;
sStp += `${name}: ${
SchemaType.gcStp(para+'.'+name, sub, label+'.'+name, false)}, `;
}
code += '}';
sStp += '})';
} else {
let t;
if (type === 'string') {
if (format === 'date-time') t = 'Date';
else if (format === 'date') t = 'FullDate';
else if (format === 'byte') t = 'string'; // TODO
else if (format === 'binary') t = 'string'; // TODO
else if (format === 'byte') t = 'byte';
else if (format === 'binary') t = 'binary';
else {
if (format) warn(`Unknown format ${format}, use string instead`);
if (format) {
warn(`Unknown string format ${format}, use string instead`);
}
t = 'string';
}
} else if (type === 'integer') t = 'number';
else t = type;
} else if (type === 'integer') {
if (format === 'int32') t = 'int32';
else {
warn(`Unsupport integer format ${format}, use number instead`);
t = 'number'; // TODO int64
}
} else t = type;
if (!STP.supportTypes.includes(t)) {
warn(`Unknown type ${type}, use any instead`);
warn(`Unsupport type ${type} ${format}, use any instead`);
return para;
} else code = `STP._${t}(${para}, ${sPara})`;
}
sStp = `STP._${t}`;
}
// nullable
if (nullable) code = `${para}===null ? null : ${code}`;
return code;
const funcName = nullable ? 'nullableParse' : 'parse';
// result
const sLabel = `'${label.replace(/'/g, '\\\'')}'`; // escape
return `STP.${funcName}(${sStp}, ${para}, ${sLabel})`;
}
}

View file

@ -101,7 +101,7 @@ function codegenIHandler(funcs: APIFuncs, config: Config, cp: CodePrinter) {
cp.writeln(`case ${status}: return this.${
isValid ? 'onSuccess' : 'onFail'
}(this.handlers[${status}],`, 1);
cp.writeln(`${schema.stp('data')});`);
cp.writeln(`${schema.stp('data', 'res.body')});`);
cp.tab(-1);
if (isValid) validTypes.add(schema.typeName);
}
@ -167,6 +167,7 @@ function codegenRouter(funcs: APIFuncs, config: Config, cp: CodePrinter) {
const {
method, url, reqTypes, resTypes,
} = func;
const isPartial = method === 'patch';
const statuses = Object.keys(resTypes);
// TODO escape
const sURL = url.replace(/{(.*?)}/g, ':$1'); // {a} -> :a
@ -177,7 +178,7 @@ function codegenRouter(funcs: APIFuncs, config: Config, cp: CodePrinter) {
mid = `bodyParser(${config}), `;
}
cp.writeln(`router.${method}('${sURL}', ${mid}async ctx => {`, 1);
// TODO permission check, etc
// req
if (Object.keys(reqTypes).length === 0) {
cp.writeln('const req = {};');
} else {
@ -191,16 +192,15 @@ function codegenRouter(funcs: APIFuncs, config: Config, cp: CodePrinter) {
cp.writeln(`${_in}: {`, 1);
for (const [name, schema] of Object.entries(paras)) {
const pn = `ctxGetParas.${_in}(ctx, '${name}')`;
cp.writeln(`${name}: ${schema.stp(pn)},`);
const label = `req.${_in}`;
cp.writeln(`${name}: ${schema.stp(pn, label)},`);
}
cp.writeln('},', -1);
}
// body
const {body} = reqTypes;
if (body != null) {
const name = 'body';
const pn = 'reqBody';
cp.writeln(`${name}: ${body.stp(pn)}`);
cp.writeln(`body: ${body.stp('reqBody', 'req.body', isPartial)}`);
}
cp.writeln('}} catch(err) {', -1); cp.tab(1);
cp.writeln('if(err instanceof STP.BadValueError)', 1);
@ -316,24 +316,36 @@ function codegenSchemas(schemas: Schemas, config: Config, cp: CodePrinter) {
`import {FullDate, StrictTypeParser as STP} from '${utilsTSPath}'`);
cp.writeln();
// schema
for (const [name, schema] of Object.entries(schemas)) {
for (const [typeName, schema] of Object.entries(schemas)) {
if (isObjectSchema(schema)) {
cp.writeln(`export class ${name} {`, 1);
cp.writeln(`export class ${typeName} {`, 1);
const propTypes: [string, SchemaType][] = [];
for (const [propName, prop] of Object.entries(schema.properties)) {
const propType = new SchemaType(prop, true); // TODO required?
const propType = new SchemaType(prop, true); // TODO required
propTypes.push([propName, propType]);
cp.writeln(propType.forProp(propName)+';');
}
// method
cp.writeln('constructor(o: {[_: string]: any}){', 1);
for (const [n, t] of propTypes) {
cp.writeln(`this.${n} = ${t.stp(`o.${n}`)};`);
cp.writeln(`this.${n} = ${t.stp(`o.${n}`, typeName+'.'+n)};`);
}
cp.writeln('}', -1);
// Partial
cp.writeln(
`static Partial(o: {[_: string]: any}): Partial<${typeName}> {`, 1);
cp.writeln(`const r: Partial<${typeName}> = {};`);
const locPartial = `Partial<${typeName}>`;
for (const [n, t] of propTypes) {
cp.writeln(`if (o.${n} !== undefined) r.${n} = ${
t.stp(`o.${n}`, locPartial+'.'+n)};`);
}
cp.writeln('return r;');
cp.writeln('}', -1);
// end of class
cp.writeln('}', -1);
} else {
cp.writeln(`export type ${name} = ${SchemaType.typeNameOf(schema)}`);
cp.writeln(`export type ${typeName} = ${SchemaType.typeNameOf(schema)}`);
}
}
// return

View file

@ -2,60 +2,98 @@ import {FullDate} from './FullDate';
export module StrictTypeParser {
export class BadValueError extends Error {
constructor(public attr: string, public type: string, public value: any) {
super(`${attr}: Can not convert \`${
constructor(public label: string, message: string) {
super(message);
console.error(this.message);
Object.setPrototypeOf(this, BadTypeError.prototype);
}
}
export class BadTypeError extends BadValueError {
constructor(public label: string, public type: string, public value: any) {
super(label, `${label}: Can not convert \`${
['object', 'array'].includes(typeof value) ?
JSON.stringify(value) : `${value}`
}\` to type ${type}`);
console.error(this.message);
Object.setPrototypeOf(this, BadValueError.prototype);
}
}
export function _number(x: any, attr: string): number {
export function _int32(x: any, label: string): number {
if (typeof x === 'number' && x === (x|0)) return x;
if (typeof x === 'string') { // convert from url
const r = +x|0;
if (x === r.toString()) return r;
}
throw new BadTypeError(label, 'int32', x);
}
export function _number(x: any, label: string): number {
if (typeof x === 'number') return x;
if (typeof x === 'string') {
if (typeof x === 'string') { // convert from url
const r = +x;
if (!isNaN(r)) return r;
}
throw new BadValueError(attr, 'number', x);
throw new BadTypeError(label, 'number', x);
}
export function _string(x: any, attr: string): string {
export function _string(x: any, label: string): string {
if (typeof x === 'string') return x;
if (typeof x === 'object') return x.toString();
throw new BadValueError(attr, 'string', x);
throw new BadTypeError(label, 'string', x);
}
export function _boolean(x: any, attr: string): boolean {
export function _boolean(x: any, label: string): boolean {
if (typeof x === 'boolean') return x;
if (x==='true') return true;
if (x==='false') return false;
throw new BadValueError(attr, 'boolean', x);
throw new BadTypeError(label, 'boolean', x);
}
export function _Date(x: any, attr: string): Date {
export function _Date(x: any, label: string): Date {
const r = new Date(x);
if (!isNaN(+r)) return r;
throw new BadValueError(attr, 'Date', x);
if (x != null && !isNaN(+r)) return r;
throw new BadTypeError(label, 'Date', x);
}
export function _FullDate(x: any, attr: string): FullDate {
export function _FullDate(x: any, label: string): FullDate {
const r = new FullDate(x);
if (!isNaN(+r)) return r;
throw new BadValueError(attr, 'FullDate', x);
if (x != null && !isNaN(+r)) return r;
throw new BadTypeError(label, 'FullDate', x);
}
export function _byte(x: any, attr: string): string {
export function _byte(x: any, label: string): string {
if (typeof x === 'string') return x;
if (x instanceof Buffer) return x.toString('base64');
throw new BadValueError(attr, 'byte', x);
throw new BadTypeError(label, 'byte', x);
}
export function _binary(x: any, attr: string): string {
export function _binary(x: any, label: string): string {
if (typeof x === 'string') return x;
if (x instanceof Buffer) return x.toString('hex');
if (x?.buffer instanceof Buffer) return x.toString('hex');
throw new BadValueError(attr, 'binary', x);
throw new BadTypeError(label, 'binary', x);
}
export function _Array(x: any, attr: string): Array<any> {
if (x instanceof Array) return x;
throw new BadValueError(attr, 'Array', x);
export function _Array<T>(x: any, label: string,
mapper: (x: any)=>T): Array<T> {
if (x instanceof Array) return x.map(mapper);
throw new BadTypeError(label, 'Array', x);
}
function undefinedCheck(val: any, label: string) {
if (val === undefined) {
throw new BadValueError(label,
`${label} is required, but got undefined`);
}
}
export function parse<T>(
stp: (val: any, label: string)=>T, val: any, label: string): T {
// body
undefinedCheck(val, label);
if (val === null) {
throw new BadValueError(label,
`${label} is not nullable, but got null`);
}
return stp(val, label);
}
export function nullableParse<T>(
stp: (val: any, label: string)=>T, val: any, label: string): T | null {
// body
undefinedCheck(val, label);
return val === null ? null : stp(val, label);
}
export const supportTypes = [
'number', 'string', 'boolean', 'Date', 'FullDate', 'byte', 'binary'];
'int32', 'number', 'string', 'boolean',
'Date', 'FullDate', 'byte', 'binary'];
}

View file

@ -1,6 +1,6 @@
{
"name": "api-codegen-ts",
"version": "1.0.1",
"version": "1.1.0",
"description": "OpenAPI code generator for TypeScript",
"main": "dist/index.js",
"types": "dist/index.d.ts",