Archived
1
0
Fork 0

object-type properties conversion in req func

Change Full#advance and implement Full#advanced
This commit is contained in:
sup39 2020-08-17 13:12:34 +08:00
parent 771c34b8c8
commit 85c026ba01
13 changed files with 209 additions and 86 deletions

148
README.md
View file

@ -57,14 +57,20 @@ module.exports = {
```
### 3. Run this tool
```
yarn run api-codegen <your-openapi-document> [-o <output-dir>] [-s <ctx.state-interface-path>]
yarn run api-codegen <your-openapi-document> [-o <output-dir>] [-s <ctx.state-interface-path>] [-c]
```
The default output directory is `api/generated`.
For example, if you put your api document at `api.yml`, and want the generated code put in `generated/` directory, you can execute
```
# example
yarn run api-codegen api.yml -o generated
```
#### Flags(Optional)
- `-o` `--output-dir <output-dir>`: output directory(default: api/generated)
- `-c` `--client-only`: client code only(default: client & server)
### 4. Implement server api
```
import {IServerAPI} from '#api/IServerAPI';
@ -154,7 +160,7 @@ where the `path`, `query`, `header`, `cookie` is a object whose key is the `name
```
import api from '#api/ClientAPI';
// import {FullDate} from '@sup39/api-ts-gen/utils';
// import {FullDate} from '@sup39/api-ts-gen/dist/utils';
// import {SchemaA} from '#api/schemas';
// ...
@ -178,9 +184,9 @@ api.$baseURL = '/same/as/the/prefix/in/server';
If the format is `string` `date`, you should use `FullDate` instead of `Date`.
`FullDate` is a wrapper of `Date`, which implements `.toString()`, `.toJSON()` and `.valueOf()` to make it more convenience to convert it to String or JSON.
Import `FullDate` class from `@sup39/api-ts-gen/utils`.
Import `FullDate` class from `@sup39/api-ts-gen/dist/utils`.
```
import {FullDate} from '@sup39/api-ts-gen/utils';
import {FullDate} from '@sup39/api-ts-gen/dist/utils';
// initialization
new FullDate(new Date()); // from a Date instance
@ -204,13 +210,23 @@ d.month = 3; // date.setUTCMonth(3-1)
d.day = 5; // date.setUTCDate(5)
// method
/*
.advance(period: number): FullDate
return a new FullDate that advanced by $peroid days
/* CAUTION: this method has been updated since version 2.0.6
.advance(period: number): this
return this advanced by $peroid days
*/
const d0 = new FullDate('2015-05-04');
d0.advance(217) // 2015-12-07
d0.advance(-1129) // 2012-03-31
d0 === d0.advance(-1129) // true
/*
.advanced(period: number): FullDate
return a new FullDate advanced by $peroid days
*/
const d0 = new FullDate('2015-05-04');
d0.advance(217) // 2015-12-07
d0.advance(-1129) // 2012-03-31
d0 === d0.advance(-1129) // false
/*
.distanceFrom(d0: FullDate): number
@ -511,44 +527,120 @@ Its type is `Array<keyof Schema>`.
NamedCircle.fields // ['name', 'radius', 'color']: Array<keyof NamedCircle>
```
### Nested Object
Any object type property which contains `id` property
will be treat specially.
When sending request, properties other than `id` will be removed,
for the convenience to work well with [Vapor](https://vapor.codes).
For example,
```
Group:
type: "object"
properties:
id:
type: "integer"
format: "int32"
name:
type: "string"
note:
type: "string"
Person:
type: "object"
properties:
id:
type: "integer"
format: "int32"
group:
$ref: "#/components/schemas/Group"
fullName:
type: "object"
properties:
firstName:
type: "string"
lastName:
type: "string"
age:
type: "integer"
format: "int32"
```
will become
```
interface Group {
id: number;
name: string;
note: string;
}
interface Person {
id: number;
group: Group;
name: {
firstName: string;
lastName: string;
};
value: number;
}
```
However, in http-request function in ClientAPI,
the type of the parameter will become
```
interface Group {
id: number;
name: string;
note: string;
} // no change
interface Task {
id: number;
group: {
id: number;
}; // properties other than `id` is removed
name: {
firstName: string;
lastName: string;
}; // no change because there is no `id` property
value: number;
}
```
## Limitations
### application/json only
This tool only supports `application/json` type for request and response body. Any other type like `multipart/form` or `image/*` are **not supported** and will be ignored.
### schema $ref only
Other $ref like requestBody, responseBody are not supported currently.
## Versions
#### 2.0.6
- Change Full#advance and implement Full#advanced
- Nest [object-type properties with id property] conversion in request function
#### 2.0.5
- implement \$ref support for responses, parameters, requestBody
- Implement \$ref support for responses, parameters, requestBody
#### 2.0.4
- fix FullDate stringify in Axios params
- use local timezone instead of UTC in FullDate
- Fix FullDate stringify in Axios params
- Use local timezone instead of UTC in FullDate
#### 2.0.3
- implement `required` property of schema
- Implement `required` property of schema
- client-only codegen
#### 2.0.2
- make number convertible to boolean
- Make number convertible to boolean
#### 2.0.1
- use IState as a generic type and remove it from api-codegen.
- Use IState as a generic type and remove it from api-codegen.
#### 2.0.0
- simplify generated code
- merge all APIPromise class
- remove IServerAPI and IClientAPI
- remove res Object, return [status, body] in ServerAPI instead
- remove schema classes, use interface instead
- Simplify generated code
- Merge all APIPromise class
- Remove IServerAPI and IClientAPI
- Remove res Object, return [status, body] in ServerAPI instead
- Remove schema classes, use interface instead
- `-s` flag for `ctx.state` interface path
#### 1.1.3
- expose fields of schemas to XXX.fields(static variable)
- Expose fields of schemas to XXX.fields(static variable)
#### 1.1.2
- publish to npmjs and change the package name in generated code
- specify constructor argument type of FullDate
- Publish to npmjs and change the package name in generated code
- Specify constructor argument type of FullDate
#### 1.1.1
- implement FullDate#distanceFrom(d0)
- fix FullDate timezone bug, use UTC instead
- Implement FullDate#distanceFrom(d0)
- Fix FullDate timezone bug, use UTC instead
#### 1.1.0
- fix Partial constructor, enhance error msg
- add int32 STP
- Fix Partial constructor, enhance error msg
- Add int32 STP
#### 1.0.1
- implement FullDate getter, setter, function(advance)
#### 1.0.0

View file

@ -8,7 +8,7 @@ const badArgv = (x, code=1) => {
console.error([
'Usage: api-codegen <apiDocPath> [flags]',
'Flags:',
' -o --outputDir <output-dir>: output directory(default: api/generated)',
' -o --output-dir <output-dir>: output directory(default: api/generated)',
' -c --client-only: client code only(default: client & server)',
].join('\n'));
process.exit(code);
@ -22,7 +22,7 @@ const errExit = (x, err, code=1) => {
const argAttrs = ['apiDocPath'];
const flag2attr = {
'o': 'outputDir',
'outputDir': 'outputDir',
'output-dir': 'outputDir',
};
const flag2attr0 = { // nullary
'c': 'clientOnly',

9
dist/OpenAPI.d.ts vendored
View file

@ -107,16 +107,17 @@ declare type TResTypes = {
export declare function resolveRef<T>(obj: T | Reference, dict: Dict<T | Reference> | undefined, prefix: string): T | undefined;
export declare class SchemaType {
private _required;
private _sameFile;
private _typeName?;
get typeName(): string;
get required(): boolean;
get maxSize(): string | number | undefined;
forProp(prop: string): string;
stp(prop: string, label: string, partial?: boolean): string;
stp(prop: string, label: string, partial?: boolean, sameFile?: boolean): string;
private schema;
constructor(schema: Schema | Reference | string, _required: boolean);
static typeNameOf(schema: Schema | Reference): string;
static gcStp(para: string, schema: Schema | Reference, label: string, partial: boolean): string;
constructor(schema: Schema | Reference | string, _required: boolean, _sameFile: boolean);
static typeNameOf(schema: Schema | Reference, sameFile: boolean): string;
static gcStp(para: string, schema: Schema | Reference, label: string, partial: boolean, sameFile: boolean): string;
}
export declare type APIFunctions = {
[_: string]: APIFunction;

32
dist/OpenAPI.js vendored
View file

@ -56,21 +56,22 @@ function mediaTypes2type(content, required) {
if (Object.keys(content !== null && content !== void 0 ? content : {}).length > 0) {
warn('only support application/json now');
}
return new SchemaType('any', false);
return new SchemaType('any', false, false);
}
// schema
var schema = media.schema;
return new SchemaType(schema !== null && schema !== void 0 ? schema : 'any', required !== null && required !== void 0 ? required : false);
return new SchemaType(schema !== null && schema !== void 0 ? schema : 'any', required !== null && required !== void 0 ? required : false, false);
}
var SchemaType = /** @class */ (function () {
function SchemaType(schema, _required) {
function SchemaType(schema, _required, _sameFile) {
this._required = _required;
this._sameFile = _sameFile;
this.schema = typeof schema === 'string' ? { type: schema } : schema;
}
Object.defineProperty(SchemaType.prototype, "typeName", {
get: function () {
var _a;
return (_a = this._typeName) !== null && _a !== void 0 ? _a : (this._typeName = SchemaType.typeNameOf(this.schema));
return (_a = this._typeName) !== null && _a !== void 0 ? _a : (this._typeName = SchemaType.typeNameOf(this.schema, this._sameFile));
},
enumerable: true,
configurable: true
@ -92,12 +93,13 @@ var SchemaType = /** @class */ (function () {
SchemaType.prototype.forProp = function (prop) {
return "" + prop + (this.required ? '' : '?') + ": " + this.typeName;
};
SchemaType.prototype.stp = function (prop, label, partial) {
SchemaType.prototype.stp = function (prop, label, partial, sameFile) {
if (partial === void 0) { partial = false; }
var stp = SchemaType.gcStp(prop, this.schema, label, partial);
if (sameFile === void 0) { sameFile = false; }
var stp = SchemaType.gcStp(prop, this.schema, label, partial, sameFile);
return (this.required ? '' : prop + "===void 0 ? void 0 : ") + stp;
};
SchemaType.typeNameOf = function (schema) {
SchemaType.typeNameOf = function (schema, sameFile) {
var _a;
if (isReference(schema)) {
var $ref = schema.$ref;
@ -106,18 +108,18 @@ var SchemaType = /** @class */ (function () {
warn("Invalid $ref, use any instead: " + $ref);
return 'any';
}
return "Schemas." + typeName;
return sameFile ? typeName : "Schemas." + typeName;
}
var type = schema.type, format = schema.format, nullable = schema.nullable, readOnly = schema.readOnly;
var sType = type;
if (isArraySchema(schema)) {
sType = "Array<" + SchemaType.typeNameOf(schema.items) + ">";
sType = "Array<" + SchemaType.typeNameOf(schema.items, sameFile) + ">";
}
else if (isObjectSchema(schema)) {
sType = '{';
for (var _i = 0, _b = Object.entries(schema.properties); _i < _b.length; _i++) {
var _c = _b[_i], name_2 = _c[0], sub = _c[1];
sType += name_2 + ": " + SchemaType.typeNameOf(sub) + ", ";
sType += name_2 + ": " + SchemaType.typeNameOf(sub, sameFile) + ", ";
}
sType += '}';
}
@ -141,11 +143,11 @@ var SchemaType = /** @class */ (function () {
sType = "Readonly<" + sType + ">";
return sType;
};
SchemaType.gcStp = function (para, schema, label, partial) {
SchemaType.gcStp = function (para, schema, label, partial, sameFile) {
// partial: Object only, 1 layer only
// object
if (isReference(schema)) {
var typeName = new SchemaType(schema, true).typeName;
var typeName = new SchemaType(schema, true, sameFile).typeName;
return typeName + "." + (partial ? 'Partial' : 'from') + "(" + para + ")";
}
// any
@ -154,13 +156,13 @@ var SchemaType = /** @class */ (function () {
if (type === 'any')
return para;
if (isArraySchema(schema)) {
sStp = "(v, l)=>STP._Array(v, l, elm=>" + SchemaType.gcStp('elm', schema.items, label + "[]", false) + ")";
sStp = "(v, l)=>STP._Array(v, l, elm=>" + SchemaType.gcStp('elm', schema.items, label + "[]", false, sameFile) + ")";
}
else if (isObjectSchema(schema)) {
sStp = '()=>({';
for (var _i = 0, _a = Object.entries(schema.properties); _i < _a.length; _i++) {
var _b = _a[_i], name_3 = _b[0], sub = _b[1];
sStp += name_3 + ": " + SchemaType.gcStp(para + '.' + name_3, sub, label + '.' + name_3, false) + ", ";
sStp += name_3 + ": " + SchemaType.gcStp(para + '.' + name_3, sub, label + '.' + name_3, false, sameFile) + ", ";
}
sStp += '})';
}
@ -241,7 +243,7 @@ function apiFunctionsOf(openAPI) {
// add
if (reqTypes[_in] == null)
reqTypes[_in] = {};
reqTypes[_in][name_5] = new SchemaType(schema !== null && schema !== void 0 ? schema : 'any', required !== null && required !== void 0 ? required : false);
reqTypes[_in][name_5] = new SchemaType(schema !== null && schema !== void 0 ? schema : 'any', required !== null && required !== void 0 ? required : false, false);
}
}
// requestBody

14
dist/codegen.js vendored
View file

@ -166,6 +166,9 @@ function codegenClientAPI(funcs, config, cp) {
// type
cp.writeln("type TSTP<T> = {[K in keyof T]: (data: any) =>" +
"T[K] extends void ? any : T[K]};");
cp.writeln("export type ExID<T> = {[K in keyof T]: " +
"'id' extends keyof T[K] ? {id: T[K]['id']} : T[K]};");
cp.writeln();
// axios
cp.writeln('const $http = axios.create({', 1);
cp.writeln('validateStatus: () => true,');
@ -212,7 +215,7 @@ function codegenClientAPI(funcs, config, cp) {
}
// body
if (body != null) {
cp.writeln("body" + (body.required ? '' : '?') + ": " + gcReq('body') + ",");
cp.writeln("body" + (body.required ? '' : '?') + ": ExID<" + gcReq('body') + ">,");
}
// return value
cp.tab(-1);
@ -267,7 +270,7 @@ function codegenSchemas(schemas, config, cp) {
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));
var propType = new OpenAPI_1.SchemaType(prop, requireds.has(propName), true);
propTypes.push([propName, propType]);
cp.writeln(propType.forProp(propName) + ';');
}
@ -278,7 +281,7 @@ function codegenSchemas(schemas, config, cp) {
cp.writeln("from: (o: {[_: string]: any}): " + typeName + " => ({", 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(n + ": " + t.stp("o." + n, typeName + '.' + n, false, true) + ",");
}
cp.writeln('}),', -1);
// Partial
@ -287,7 +290,7 @@ function codegenSchemas(schemas, config, cp) {
var locPartial = "Partial<" + typeName + ">";
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("if (o." + n + " !== void 0) r." + n + " = " + t.stp("o." + n, locPartial + '.' + n, false, true) + ";");
}
cp.writeln('return r;');
cp.writeln('},', -1);
@ -299,7 +302,8 @@ function codegenSchemas(schemas, config, cp) {
cp.writeln('}', -1);
}
else {
cp.writeln("export type " + typeName + " = " + OpenAPI_1.SchemaType.typeNameOf(schema));
cp.writeln("export type " + typeName + " = " +
OpenAPI_1.SchemaType.typeNameOf(schema, true));
}
}
// return

View file

@ -17,6 +17,7 @@ export declare class FullDate {
set year(val: number);
set month(val: number);
set day(val: number);
advance(period: number): FullDate;
advance(period: number): this;
advanced(period: number): FullDate;
distanceFrom(d0: FullDate): number;
}

View file

@ -88,6 +88,10 @@ var FullDate = /** @class */ (function () {
});
// func
FullDate.prototype.advance = function (period) {
this._date = new Date(this._date.valueOf() + period * 86400e3);
return this;
};
FullDate.prototype.advanced = function (period) {
return new FullDate(this._date.valueOf() + period * 86400e3);
};
FullDate.prototype.distanceFrom = function (d0) {

View file

@ -5,8 +5,12 @@ var options0 = {
filter: function (prefix, value) {
var _a;
var con = value === null || value === void 0 ? void 0 : value.constructor;
// use Class.toString() if defined explicitly (exception: Object, Date)
return (con && con !== Object && con !== Date && ((_a = con.prototype) === null || _a === void 0 ? void 0 : _a.hasOwnProperty('toString'))) ? value.toString() : value;
if (con === null || con === Array || con === Object)
return value;
if (con === Date)
return value.toJSON();
// use Class.toString() if defined explicitly
return ((_a = con.prototype) === null || _a === void 0 ? void 0 : _a.hasOwnProperty('toString')) ? value.toString() : value;
},
};
function qStringify(obj, options) {

View file

@ -148,17 +148,17 @@ function mediaTypes2type(
if (Object.keys(content ?? {}).length > 0) {
warn('only support application/json now');
}
return new SchemaType('any', false);
return new SchemaType('any', false, false);
}
// schema
const {schema} = media;
return new SchemaType(schema ?? 'any', required ?? false);
return new SchemaType(schema ?? 'any', required ?? false, false);
}
export class SchemaType {
private _typeName?: string;
get typeName(): string {
return this._typeName ??
(this._typeName = SchemaType.typeNameOf(this.schema));
(this._typeName = SchemaType.typeNameOf(this.schema, this._sameFile));
}
get required(): boolean {
return this._required;
@ -169,18 +169,24 @@ export class SchemaType {
forProp(prop: string): string {
return `${prop}${this.required ? '' : '?'}: ${this.typeName}`;
}
stp(prop: string, label: string, partial: boolean=false): string {
const stp = SchemaType.gcStp(prop, this.schema, label, partial);
stp(
prop: string, label: string,
partial: boolean=false, sameFile: boolean=false,
): string {
const stp = SchemaType.gcStp(prop, this.schema, label, partial, sameFile);
return (this.required ? '' : `${prop}===void 0 ? void 0 : `)+stp;
}
private schema: Schema | Reference;
constructor(schema: Schema | Reference | string,
private _required: boolean) {
constructor(
schema: Schema | Reference | string,
private _required: boolean,
private _sameFile: boolean,
) {
this.schema = typeof schema === 'string' ? {type: schema} : schema;
}
static typeNameOf(schema: Schema | Reference): string {
static typeNameOf(schema: Schema | Reference, sameFile: boolean): string {
if (isReference(schema)) {
const {$ref} = schema;
const typeName = /^#\/components\/schemas\/(\w+)$/g.exec($ref)?.[1];
@ -188,18 +194,18 @@ export class SchemaType {
warn(`Invalid $ref, use any instead: ${$ref}`);
return 'any';
}
return `Schemas.${typeName}`;
return sameFile ? typeName : `Schemas.${typeName}`;
}
const {
type, format, nullable, readOnly,
} = schema;
let sType = type;
if (isArraySchema(schema)) {
sType = `Array<${SchemaType.typeNameOf(schema.items)}>`;
sType = `Array<${SchemaType.typeNameOf(schema.items, sameFile)}>`;
} else if (isObjectSchema(schema)) {
sType = '{';
for (const [name, sub] of Object.entries(schema.properties)) {
sType += `${name}: ${SchemaType.typeNameOf(sub)}, `;
sType += `${name}: ${SchemaType.typeNameOf(sub, sameFile)}, `;
}
sType += '}';
} else if (type === 'string') {
@ -214,11 +220,11 @@ export class SchemaType {
return sType;
}
static gcStp(para: string, schema: Schema | Reference,
label: string, partial: boolean): string {
label: string, partial: boolean, sameFile: boolean): string {
// partial: Object only, 1 layer only
// object
if (isReference(schema)) {
const typeName = new SchemaType(schema, true).typeName;
const typeName = new SchemaType(schema, true, sameFile).typeName;
return `${typeName}.${partial ? 'Partial': 'from'}(${para})`;
}
// any
@ -226,13 +232,13 @@ export class SchemaType {
let sStp;
if (type === 'any') return para;
if (isArraySchema(schema)) {
sStp = `(v, l)=>STP._Array(v, l, elm=>${
SchemaType.gcStp('elm', schema.items, `${label}[]`, false)})`;
sStp = `(v, l)=>STP._Array(v, l, elm=>${SchemaType.gcStp(
'elm', schema.items, `${label}[]`, false, sameFile)})`;
} else if (isObjectSchema(schema)) {
sStp = '()=>({';
for (const [name, sub] of Object.entries(schema.properties)) {
sStp += `${name}: ${
SchemaType.gcStp(para+'.'+name, sub, label+'.'+name, false)}, `;
sStp += `${name}: ${SchemaType.gcStp(
para+'.'+name, sub, label+'.'+name, false, sameFile)}, `;
}
sStp += '})';
} else {
@ -304,7 +310,7 @@ export function apiFunctionsOf(openAPI: OpenAPI): APIFunctions {
// add
if (reqTypes[_in] == null) reqTypes[_in] = {};
reqTypes[_in]![name] = new SchemaType(
schema ?? 'any', required ?? false);
schema ?? 'any', required ?? false, false);
}
}
// requestBody

View file

@ -166,6 +166,9 @@ function codegenClientAPI(funcs: APIFuncs, config: Config, cp: CodePrinter) {
// type
cp.writeln(`type TSTP<T> = {[K in keyof T]: (data: any) =>`+
`T[K] extends void ? any : T[K]};`);
cp.writeln(`export type ExID<T> = {[K in keyof T]: ` +
`'id' extends keyof T[K] ? {id: T[K]['id']} : T[K]};`);
cp.writeln();
// axios
cp.writeln('const $http = axios.create({', 1);
cp.writeln('validateStatus: () => true,');
@ -190,7 +193,7 @@ function codegenClientAPI(funcs: APIFuncs, config: Config, cp: CodePrinter) {
cp.writeln('},', -1);
// functions
for (const [funcName, func] of Object.entries(funcs)) {
const gcReq = (_in: string) => `TAPI['${funcName}']['req']['${_in}']`;
const gcReq = (_in: string) =>`TAPI['${funcName}']['req']['${_in}']`;
const {method, url, reqTypes, resTypes} = func;
const {
query, header, path, body,
@ -211,7 +214,7 @@ function codegenClientAPI(funcs: APIFuncs, config: Config, cp: CodePrinter) {
}
// body
if (body != null) {
cp.writeln(`body${body.required ? '' : '?'}: ${gcReq('body')},`);
cp.writeln(`body${body.required ? '' : '?'}: ExID<${gcReq('body')}>,`);
}
// return value
cp.tab(-1);
@ -258,7 +261,7 @@ function codegenSchemas(
const propTypes: [string, SchemaType][] = [];
const requireds = new Set(schema.required ?? []);
for (const [propName, prop] of Object.entries(schema.properties)) {
const propType = new SchemaType(prop, requireds.has(propName));
const propType = new SchemaType(prop, requireds.has(propName), true);
propTypes.push([propName, propType]);
cp.writeln(propType.forProp(propName)+';');
}
@ -268,7 +271,7 @@ function codegenSchemas(
// .from
cp.writeln(`from: (o: {[_: string]: any}): ${typeName} => ({`, 1);
for (const [n, t] of propTypes) {
cp.writeln(`${n}: ${t.stp(`o.${n}`, typeName+'.'+n)},`);
cp.writeln(`${n}: ${t.stp(`o.${n}`, typeName+'.'+n, false, true)},`);
}
cp.writeln('}),', -1);
// Partial
@ -278,7 +281,7 @@ function codegenSchemas(
const locPartial = `Partial<${typeName}>`;
for (const [n, t] of propTypes) {
cp.writeln(`if (o.${n} !== void 0) r.${n} = ${
t.stp(`o.${n}`, locPartial+'.'+n)};`);
t.stp(`o.${n}`, locPartial+'.'+n, false, true)};`);
}
cp.writeln('return r;');
cp.writeln('},', -1);
@ -289,7 +292,8 @@ function codegenSchemas(
// end of const
cp.writeln('}', -1);
} else {
cp.writeln(`export type ${typeName} = ${SchemaType.typeNameOf(schema)}`);
cp.writeln(`export type ${typeName} = ` +
SchemaType.typeNameOf(schema, true));
}
}
// return

View file

@ -65,7 +65,11 @@ export class FullDate {
this._date.setDate(val);
}
// func
advance(period: number): FullDate {
advance(period: number): this {
this._date = new Date(this._date.valueOf()+period*86400e3);
return this;
}
advanced(period: number): FullDate {
return new FullDate(this._date.valueOf()+period*86400e3);
}
distanceFrom(d0: FullDate): number {

View file

@ -3,9 +3,10 @@ import * as Qs0 from 'qs';
const options0 = {
filter(prefix: string, value: any) {
const con = value?.constructor;
// use Class.toString() if defined explicitly (exception: Object, Date)
return (con && con !== Object && con !== Date &&
con.prototype?.hasOwnProperty('toString')) ? value.toString() : value;
if (con === null || con === Array || con === Object) return value;
if (con === Date) return value.toJSON();
// use Class.toString() if defined explicitly
return con.prototype?.hasOwnProperty('toString') ? value.toString() : value;
},
};

View file

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