diff --git a/README.md b/README.md index 90ea916..bea1032 100644 --- a/README.md +++ b/README.md @@ -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.4 +- fix FullDate stringify in Axios params +- use local timezone instead of UTC in FullDate #### 2.0.3 - implement `required` property of schema - client-only codegen diff --git a/dist/codegen.js b/dist/codegen.js index 0aa18f9..c070cc2 100644 --- a/dist/codegen.js +++ b/dist/codegen.js @@ -159,15 +159,17 @@ function codegenClientAPI(funcs, config, cp) { // import cp.writeln("import {TAPI} from './" + IHandlerName + "'"); cp.writeln("import * as Schemas from './" + schemasName + "'"); - cp.writeln("import {APIPromise, StrictTypeParser as STP} from '" + utilsTSPath + "'"); + cp.writeln("import {APIPromise, StrictTypeParser as STP, " + + ("qStringify} from '" + utilsTSPath + "'")); cp.writeln("import axios from 'axios'"); cp.writeln(''); // type - cp.writeln("type TSTP = {[K in keyof T]: (data: any) =>", 1); - cp.writeln("T[K] extends void ? any : T[K]};", -1, false); + cp.writeln("type TSTP = {[K in keyof T]: (data: any) =>" + + "T[K] extends void ? any : T[K]};"); // axios cp.writeln('const $http = axios.create({', 1); - cp.writeln('validateStatus: ()=>true,'); + cp.writeln('validateStatus: () => true,'); + cp.writeln('paramsSerializer: params => qStringify(params),'); cp.writeln('});', -1); // function cp.writeln('\nfunction urlReplacer(url: string, ' + diff --git a/dist/utils/FullDate.js b/dist/utils/FullDate.js index e184655..795089b 100644 --- a/dist/utils/FullDate.js +++ b/dist/utils/FullDate.js @@ -1,8 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function removeTime(date) { - var dt = date.getTimezoneOffset() * 60e3; - return new Date(new Date(date.valueOf() - dt).setUTCHours(0, 0, 0, 0)); + return new Date(date.setHours(0, 0, 0, 0)); } var FullDate = /** @class */ (function () { function FullDate() { @@ -33,7 +32,7 @@ var FullDate = /** @class */ (function () { FullDate.prototype.toString = function () { var d = this._date; var f = function (s) { return ('0' + s).slice(-2); }; - return d.getUTCFullYear() + "-" + f(d.getUTCMonth() + 1) + "-" + f(d.getUTCDate()); + return d.getFullYear() + "-" + f(d.getMonth() + 1) + "-" + f(d.getDate()); }; FullDate.prototype.toJSON = function () { return this.toString(); @@ -51,38 +50,38 @@ var FullDate = /** @class */ (function () { }); Object.defineProperty(FullDate.prototype, "year", { get: function () { - return this._date.getUTCFullYear(); + return this._date.getFullYear(); }, // setter set: function (val) { - this._date.setUTCFullYear(val); + this._date.setFullYear(val); }, enumerable: true, configurable: true }); Object.defineProperty(FullDate.prototype, "month", { get: function () { - return this._date.getUTCMonth() + 1; + return this._date.getMonth() + 1; }, set: function (val) { - this._date.setUTCMonth(val - 1); + this._date.setMonth(val - 1); }, enumerable: true, configurable: true }); Object.defineProperty(FullDate.prototype, "day", { get: function () { - return this._date.getUTCDate(); + return this._date.getDate(); }, set: function (val) { - this._date.setUTCDate(val); + this._date.setDate(val); }, enumerable: true, configurable: true }); Object.defineProperty(FullDate.prototype, "dayOfWeek", { get: function () { - return this._date.getUTCDay(); + return this._date.getDay(); }, enumerable: true, configurable: true diff --git a/dist/utils/index.d.ts b/dist/utils/index.d.ts index 5bb8a8c..cffdb78 100644 --- a/dist/utils/index.d.ts +++ b/dist/utils/index.d.ts @@ -1,3 +1,4 @@ export * from './APIPromise'; export * from './FullDate'; export * from './StrictTypeParser'; +export * from './qStringify'; diff --git a/dist/utils/index.js b/dist/utils/index.js index ea199c2..1b3826d 100644 --- a/dist/utils/index.js +++ b/dist/utils/index.js @@ -6,3 +6,4 @@ Object.defineProperty(exports, "__esModule", { value: true }); __export(require("./APIPromise")); __export(require("./FullDate")); __export(require("./StrictTypeParser")); +__export(require("./qStringify")); diff --git a/dist/utils/qStringify.d.ts b/dist/utils/qStringify.d.ts new file mode 100644 index 0000000..c4cfd4d --- /dev/null +++ b/dist/utils/qStringify.d.ts @@ -0,0 +1,2 @@ +import * as Qs0 from 'qs'; +export declare function qStringify(obj: any, options?: Qs0.IStringifyOptions): string; diff --git a/dist/utils/qStringify.js b/dist/utils/qStringify.js new file mode 100644 index 0000000..bd4a4f8 --- /dev/null +++ b/dist/utils/qStringify.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Qs0 = require("qs"); +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; + }, +}; +function qStringify(obj, options) { + return Qs0.stringify(obj, Object.assign({}, options0, options)); +} +exports.qStringify = qStringify; diff --git a/lib/codegen.ts b/lib/codegen.ts index f0cb960..e71c4a1 100644 --- a/lib/codegen.ts +++ b/lib/codegen.ts @@ -158,16 +158,17 @@ function codegenClientAPI(funcs: APIFuncs, config: Config, cp: CodePrinter) { // import cp.writeln(`import {TAPI} from './${IHandlerName}'`); cp.writeln(`import * as Schemas from './${schemasName}'`); - cp.writeln( - `import {APIPromise, StrictTypeParser as STP} from '${utilsTSPath}'`); + cp.writeln(`import {APIPromise, StrictTypeParser as STP, ` + + `qStringify} from '${utilsTSPath}'`); cp.writeln(`import axios from 'axios'`); cp.writeln(''); // type - cp.writeln(`type TSTP = {[K in keyof T]: (data: any) =>`, 1); - cp.writeln(`T[K] extends void ? any : T[K]};`, -1, false); + cp.writeln(`type TSTP = {[K in keyof T]: (data: any) =>`+ + `T[K] extends void ? any : T[K]};`); // axios cp.writeln('const $http = axios.create({', 1); - cp.writeln('validateStatus: ()=>true,'); + cp.writeln('validateStatus: () => true,'); + cp.writeln('paramsSerializer: params => qStringify(params),'); cp.writeln('});', -1); // function cp.writeln('\nfunction urlReplacer(url: string, ' + diff --git a/lib/utils/FullDate.ts b/lib/utils/FullDate.ts index d6ffe31..9f75a63 100644 --- a/lib/utils/FullDate.ts +++ b/lib/utils/FullDate.ts @@ -1,6 +1,5 @@ function removeTime(date: Date): Date { - const dt = date.getTimezoneOffset()*60e3; - return new Date(new Date(date.valueOf()-dt).setUTCHours(0, 0, 0, 0)); + return new Date(date.setHours(0, 0, 0, 0)); } export class FullDate { private _date: Date; @@ -30,8 +29,8 @@ export class FullDate { toString(): string { const d = this._date; const f = (s: any) => ('0'+s).slice(-2); - return `${d.getUTCFullYear()}-${ - f(d.getUTCMonth()+1)}-${f(d.getUTCDate())}`; + return `${d.getFullYear()}-${ + f(d.getMonth()+1)}-${f(d.getDate())}`; } toJSON(): string { return this.toString(); @@ -44,26 +43,26 @@ export class FullDate { return new Date(this._date); } get year(): number { - return this._date.getUTCFullYear(); + return this._date.getFullYear(); } get month(): number { - return this._date.getUTCMonth()+1; + return this._date.getMonth()+1; } get day(): number { - return this._date.getUTCDate(); + return this._date.getDate(); } get dayOfWeek(): number { - return this._date.getUTCDay(); + return this._date.getDay(); } // setter set year(val: number) { - this._date.setUTCFullYear(val); + this._date.setFullYear(val); } set month(val: number) { - this._date.setUTCMonth(val-1); + this._date.setMonth(val-1); } set day(val: number) { - this._date.setUTCDate(val); + this._date.setDate(val); } // func advance(period: number): FullDate { diff --git a/lib/utils/index.ts b/lib/utils/index.ts index 5bb8a8c..cffdb78 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -1,3 +1,4 @@ export * from './APIPromise'; export * from './FullDate'; export * from './StrictTypeParser'; +export * from './qStringify'; diff --git a/lib/utils/qStringify.ts b/lib/utils/qStringify.ts new file mode 100644 index 0000000..aa5fb31 --- /dev/null +++ b/lib/utils/qStringify.ts @@ -0,0 +1,14 @@ +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; + }, +}; + +export function qStringify(obj: any, options?: Qs0.IStringifyOptions) { + return Qs0.stringify(obj, Object.assign({}, options0, options)); +} diff --git a/package.json b/package.json index 933b407..752a0df 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,13 @@ "devDependencies": { "@types/js-yaml": "^3.12.3", "@types/node": "^13.11.0", + "@types/qs": "^6.9.3", "@typescript-eslint/eslint-plugin": "^2.26.0", "@typescript-eslint/parser": "^2.26.0", "axios": "^0.19.2", "eslint": "^6.8.0", "eslint-config-google": "^0.14.0", + "qs": "^6.9.4", "typescript": "^3.8.3" }, "dependencies": { diff --git a/yarn.lock b/yarn.lock index e58158e..90ad6b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -48,6 +48,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b" integrity sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ== +"@types/qs@^6.9.3": + version "6.9.3" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.3.tgz#b755a0934564a200d3efdf88546ec93c369abd03" + integrity sha512-7s9EQWupR1fTc2pSMtXRQ9w9gLOcrJn+h7HOXw4evxyvVqMi4f+q7d2tnFe3ng3SNHjtK+0EzGMGFUQX4/AQRA== + "@typescript-eslint/eslint-plugin@^2.26.0": version "2.26.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.26.0.tgz#04c96560c8981421e5a9caad8394192363cc423f" @@ -755,6 +760,11 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +qs@^6.9.4: + version "6.9.4" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" + integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ== + regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"