@devbie/apits 0.0.0-stage → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -2
- package/bin/apits +4 -0
- package/dist/cjs/core/cli.d.ts +29 -0
- package/dist/cjs/core/cli.js +396 -0
- package/dist/cjs/core/generator.js +301 -0
- package/dist/cjs/core/writeRequestClient.js +93 -0
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/types.js +90 -0
- package/dist/cjs/utils/console.js +79 -0
- package/dist/cjs/utils/getOutputPath.js +43 -0
- package/dist/cjs/utils/helpers.js +166 -0
- package/dist/cjs/utils/openApiToInterfaces.js +229 -0
- package/dist/cjs/utils/spinner.js +69 -0
- package/dist/cjs/utils/utils.d.ts +56 -0
- package/dist/cjs/utils/utils.js +355 -0
- package/dist/cjs/utils/vtilsLite.js +123 -0
- package/dist/esm/core/cli.d.mts +29 -0
- package/dist/esm/core/cli.mjs +713 -0
- package/dist/esm/core/generator.mjs +463 -0
- package/dist/esm/core/writeRequestClient.mjs +54 -0
- package/dist/esm/index.mjs +2 -0
- package/dist/esm/types.mjs +94 -0
- package/dist/esm/utils/console.mjs +65 -0
- package/dist/esm/utils/getOutputPath.mjs +12 -0
- package/dist/esm/utils/helpers.mjs +226 -0
- package/dist/esm/utils/openApiToInterfaces.mjs +326 -0
- package/dist/esm/utils/spinner.mjs +58 -0
- package/dist/esm/utils/utils.d.mts +56 -0
- package/dist/esm/utils/utils.mjs +545 -0
- package/dist/esm/utils/vtilsLite.mjs +142 -0
- package/package.json +68 -4
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
2
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
3
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
4
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
5
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
6
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
7
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
8
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
9
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
10
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
11
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
12
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
13
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
14
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
15
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
16
|
+
import { castArray, forOwn, isArray, isEmpty, isObject } from "./vtilsLite.mjs";
|
|
17
|
+
import { compile } from "json-schema-to-typescript";
|
|
18
|
+
import { format as prettierFormat, resolveConfig } from "prettier";
|
|
19
|
+
import { RequestBodyType, RequestFormItemType, Required, ResponseBodyType } from "../types.mjs";
|
|
20
|
+
/**
|
|
21
|
+
* Uppercase the first character of a string, leaving the rest untouched.
|
|
22
|
+
* Local replacement for lodash's `upperFirst`: lodash is not declared in
|
|
23
|
+
* package.json dependencies (it was only available via dependency
|
|
24
|
+
* hoisting), and the hoisted @types/lodash is incomplete, which broke
|
|
25
|
+
* declaration generation on the TypeScript 5 toolchain.
|
|
26
|
+
*
|
|
27
|
+
* @param value input string
|
|
28
|
+
* @returns string with its first character uppercased
|
|
29
|
+
*/
|
|
30
|
+
function upperFirst(value) {
|
|
31
|
+
return value ? value.charAt(0).toUpperCase() + value.slice(1) : value;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Process a JSON Schema in place.
|
|
36
|
+
*
|
|
37
|
+
* @param jsonSchema JSON Schema to process
|
|
38
|
+
* @returns the processed JSON Schema
|
|
39
|
+
*/
|
|
40
|
+
export function processJsonSchema(jsonSchema) {
|
|
41
|
+
if (!isObject(jsonSchema)) return jsonSchema;
|
|
42
|
+
|
|
43
|
+
// Remove `title` and `id` so json-schema-to-typescript does not extract them as interface names.
|
|
44
|
+
delete jsonSchema.title;
|
|
45
|
+
delete jsonSchema.id;
|
|
46
|
+
|
|
47
|
+
// Ignore array length limits.
|
|
48
|
+
delete jsonSchema.minItems;
|
|
49
|
+
delete jsonSchema.maxItems;
|
|
50
|
+
|
|
51
|
+
// Strip `default` so json-schema-to-typescript cannot infer a type from it.
|
|
52
|
+
delete jsonSchema.default;
|
|
53
|
+
|
|
54
|
+
// Normalize OpenAPI 3.x `nullable: true` into JSON Schema `type: [..., 'null']`.
|
|
55
|
+
// json-schema-to-typescript only understands the JSON Schema union-null form
|
|
56
|
+
// (a `type` array containing 'null'); OpenAPI's `nullable` keyword is silently
|
|
57
|
+
// ignored, which drops `| null` from generated types. This walker bridges
|
|
58
|
+
// that gap so nullable fields render as `T | null`.
|
|
59
|
+
if (jsonSchema.nullable === true) {
|
|
60
|
+
if (jsonSchema.type) {
|
|
61
|
+
// Merge 'null' into the existing type(s) without duplicates.
|
|
62
|
+
var types = castArray(jsonSchema.type).filter(function (t) {
|
|
63
|
+
return t !== "null";
|
|
64
|
+
});
|
|
65
|
+
if (!types.includes("null")) types.push("null");
|
|
66
|
+
jsonSchema.type = types.length === 1 ? types[0] : types;
|
|
67
|
+
} else if (jsonSchema.enum && Array.isArray(jsonSchema.enum)) {
|
|
68
|
+
// For enum schemas without a type, append a null literal so the
|
|
69
|
+
// generated union includes `null`.
|
|
70
|
+
if (!jsonSchema.enum.includes(null)) {
|
|
71
|
+
jsonSchema.enum = [].concat(_toConsumableArray(jsonSchema.enum), [null]);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Note: `$ref`/`allOf`/`oneOf`/`anyOf` + nullable combinations are not
|
|
75
|
+
// normalized here because they would require restructuring the schema
|
|
76
|
+
// (e.g. wrapping in anyOf). Nullable scalars cover the common case.
|
|
77
|
+
delete jsonSchema.nullable;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Normalize type names to standard JSON Schema type names.
|
|
81
|
+
if (jsonSchema.type) {
|
|
82
|
+
var isMultiple = Array.isArray(jsonSchema.type);
|
|
83
|
+
var _types = castArray(jsonSchema.type).map(function (type) {
|
|
84
|
+
// Lowercase all types, e.g. String -> string.
|
|
85
|
+
type = type.toLowerCase();
|
|
86
|
+
// Map to standard JSON Schema types.
|
|
87
|
+
type = {
|
|
88
|
+
int: "integer"
|
|
89
|
+
}[type] || type;
|
|
90
|
+
return type;
|
|
91
|
+
});
|
|
92
|
+
jsonSchema.type = isMultiple ? _types : _types[0];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Mock.toJSONSchema produces `properties` as an array, but JSONSchema4 expects an object.
|
|
96
|
+
if (isArray(jsonSchema.properties)) {
|
|
97
|
+
// @ts-ignore
|
|
98
|
+
jsonSchema.properties = jsonSchema.properties.reduce(function (props, js) {
|
|
99
|
+
props[js.name] = js;
|
|
100
|
+
return props;
|
|
101
|
+
}, {});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Trim whitespace from field names.
|
|
105
|
+
if (jsonSchema.properties) {
|
|
106
|
+
forOwn(jsonSchema.properties, function (_, prop) {
|
|
107
|
+
var propDef = jsonSchema.properties[prop];
|
|
108
|
+
delete jsonSchema.properties[prop];
|
|
109
|
+
jsonSchema.properties[prop.trim()] = propDef;
|
|
110
|
+
});
|
|
111
|
+
jsonSchema.required = jsonSchema.required && jsonSchema.required.map(function (prop) {
|
|
112
|
+
return prop.trim();
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Recurse into child properties.
|
|
117
|
+
if (jsonSchema.properties) {
|
|
118
|
+
forOwn(jsonSchema.properties, processJsonSchema);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Recurse into array items.
|
|
122
|
+
if (jsonSchema.items) {
|
|
123
|
+
castArray(jsonSchema.items).forEach(processJsonSchema);
|
|
124
|
+
}
|
|
125
|
+
if (jsonSchema.oneOf) {
|
|
126
|
+
jsonSchema.oneOf.forEach(processJsonSchema);
|
|
127
|
+
}
|
|
128
|
+
if (jsonSchema.anyOf) {
|
|
129
|
+
jsonSchema.anyOf.forEach(processJsonSchema);
|
|
130
|
+
}
|
|
131
|
+
if (jsonSchema.allOf) {
|
|
132
|
+
jsonSchema.allOf.forEach(processJsonSchema);
|
|
133
|
+
}
|
|
134
|
+
return jsonSchema;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Parse a JSON Schema string into a JSON Schema object.
|
|
139
|
+
*
|
|
140
|
+
* @param str JSON Schema string
|
|
141
|
+
* @returns parsed JSON Schema object
|
|
142
|
+
*/
|
|
143
|
+
function jsonSchemaStringToJsonSchema(str) {
|
|
144
|
+
return processJsonSchema(JSON.parse(str));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Derive a JSON Schema object from a list of property definitions.
|
|
149
|
+
*
|
|
150
|
+
* @param propDefinitions list of property definitions
|
|
151
|
+
* @returns JSON Schema object
|
|
152
|
+
*/
|
|
153
|
+
function propDefinitionsToJsonSchema(propDefinitions) {
|
|
154
|
+
return processJsonSchema({
|
|
155
|
+
type: "object",
|
|
156
|
+
required: propDefinitions.reduce(function (res, prop) {
|
|
157
|
+
if (prop.required) {
|
|
158
|
+
res.push(prop.name);
|
|
159
|
+
}
|
|
160
|
+
return res;
|
|
161
|
+
}, []),
|
|
162
|
+
properties: propDefinitions.reduce(function (res, prop) {
|
|
163
|
+
res[prop.name] = _objectSpread({
|
|
164
|
+
type: prop.type,
|
|
165
|
+
description: prop.comment
|
|
166
|
+
}, prop.type === "file" ? {
|
|
167
|
+
tsType: prop.isArray ? "File[]" : "File"
|
|
168
|
+
} : Array.isArray(prop.enum) && prop.enum.length ? {
|
|
169
|
+
enum: prop.enum
|
|
170
|
+
} : {});
|
|
171
|
+
return res;
|
|
172
|
+
}, {})
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Pre-process a schema before compiling it to TypeScript.
|
|
178
|
+
*
|
|
179
|
+
* Handles edge cases such as empty enums and normalizes OpenAPI 3.x
|
|
180
|
+
* `nullable: true` into the JSON Schema union-null form
|
|
181
|
+
* (`type: [T, 'null']`) so json-schema-to-typescript emits `T | null`.
|
|
182
|
+
* Component schemas reach the compiler through this preprocessor instead of
|
|
183
|
+
* `processJsonSchema`, and jstt silently ignores the OpenAPI `nullable`
|
|
184
|
+
* keyword. Every node here is a fresh copy, so the source document is never
|
|
185
|
+
* mutated.
|
|
186
|
+
*
|
|
187
|
+
* @param schema input JSON Schema
|
|
188
|
+
* @returns normalized JSON Schema (fresh copy, source is not mutated)
|
|
189
|
+
*/
|
|
190
|
+
export function preprocessSchema(schema) {
|
|
191
|
+
if (!isObject(schema)) {
|
|
192
|
+
return schema;
|
|
193
|
+
}
|
|
194
|
+
if (Array.isArray(schema)) {
|
|
195
|
+
return schema.map(preprocessSchema);
|
|
196
|
+
}
|
|
197
|
+
var processed = _objectSpread({}, schema);
|
|
198
|
+
|
|
199
|
+
// Drop empty enum arrays (a type with no values produces invalid output).
|
|
200
|
+
if (processed.enum && Array.isArray(processed.enum) && processed.enum.length === 0) {
|
|
201
|
+
delete processed.enum;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Normalize OpenAPI 3.x `nullable: true` into the JSON Schema union-null
|
|
205
|
+
// form (`type: [T, 'null']`) so json-schema-to-typescript emits `T | null`.
|
|
206
|
+
if (processed.nullable === true) {
|
|
207
|
+
if (processed.type) {
|
|
208
|
+
// Merge 'null' into the existing type(s) without duplicates.
|
|
209
|
+
var typeList = castArray(processed.type).filter(function (typeName) {
|
|
210
|
+
return typeName !== "null";
|
|
211
|
+
});
|
|
212
|
+
typeList.push("null");
|
|
213
|
+
processed.type = typeList.length === 1 ? typeList[0] : typeList;
|
|
214
|
+
} else if (Array.isArray(processed.enum)) {
|
|
215
|
+
// For enum schemas without a type, append a null literal.
|
|
216
|
+
if (!processed.enum.includes(null)) processed.enum = [].concat(_toConsumableArray(processed.enum), [null]);
|
|
217
|
+
}
|
|
218
|
+
delete processed.nullable;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Recurse into every child value.
|
|
222
|
+
for (var key in processed) {
|
|
223
|
+
if (processed.hasOwnProperty(key)) {
|
|
224
|
+
processed[key] = preprocessSchema(processed[key]);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return processed;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Map a JSON Schema property descriptor to a TypeScript type expression.
|
|
232
|
+
* Used when constructing inline object types for merged path/query params
|
|
233
|
+
* (see `rewriteRefs`), where `JSON.stringify` would incorrectly serialize
|
|
234
|
+
* type names as string literals.
|
|
235
|
+
*/
|
|
236
|
+
function jsonSchemaTypeToTs(propSchema) {
|
|
237
|
+
if (!propSchema || _typeof(propSchema) !== "object") {
|
|
238
|
+
return "unknown";
|
|
239
|
+
}
|
|
240
|
+
// Prefer an explicit tsType marker (set for $ref resolutions) over the
|
|
241
|
+
// raw JSON Schema type name.
|
|
242
|
+
if (propSchema.tsType) {
|
|
243
|
+
return propSchema.tsType;
|
|
244
|
+
}
|
|
245
|
+
// Enum schemas render as a union of string-literal types.
|
|
246
|
+
if (propSchema.enum && Array.isArray(propSchema.enum) && propSchema.enum.length) {
|
|
247
|
+
return propSchema.enum.map(function (v) {
|
|
248
|
+
return v === null ? "null" : "'".concat(String(v).replace(/'/g, "\\'"), "'");
|
|
249
|
+
}).join(" | ");
|
|
250
|
+
}
|
|
251
|
+
switch (propSchema.type) {
|
|
252
|
+
case "integer":
|
|
253
|
+
case "number":
|
|
254
|
+
return "number";
|
|
255
|
+
case "boolean":
|
|
256
|
+
return "boolean";
|
|
257
|
+
case "string":
|
|
258
|
+
return "string";
|
|
259
|
+
case "null":
|
|
260
|
+
return "null";
|
|
261
|
+
case "array":
|
|
262
|
+
{
|
|
263
|
+
// Best-effort: derive the element type from items, fall back to any.
|
|
264
|
+
var itemSchema = Array.isArray(propSchema.items) ? propSchema.items[0] : propSchema.items;
|
|
265
|
+
var itemTs = itemSchema && (itemSchema.tsType || jsonSchemaTypeToTs(itemSchema));
|
|
266
|
+
return itemTs ? "".concat(itemTs, "[]") : "any[]";
|
|
267
|
+
}
|
|
268
|
+
case "object":
|
|
269
|
+
case undefined:
|
|
270
|
+
default:
|
|
271
|
+
return "unknown";
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Generate a TypeScript type definition from a JSON Schema object.
|
|
277
|
+
*
|
|
278
|
+
* @param jsonSchema JSON Schema object
|
|
279
|
+
* @param typeName type name
|
|
280
|
+
* @returns TypeScript type definition
|
|
281
|
+
*/
|
|
282
|
+
export function jsonSchemaToTsCode(_x, _x2) {
|
|
283
|
+
return _jsonSchemaToTsCode.apply(this, arguments);
|
|
284
|
+
}
|
|
285
|
+
function _jsonSchemaToTsCode() {
|
|
286
|
+
_jsonSchemaToTsCode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(jsonSchema, typeName) {
|
|
287
|
+
var rewriteRefs, fakeTypeName, code;
|
|
288
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
289
|
+
while (1) switch (_context.prev = _context.next) {
|
|
290
|
+
case 0:
|
|
291
|
+
rewriteRefs = function _rewriteRefs(obj) {
|
|
292
|
+
var _loop = function _loop() {
|
|
293
|
+
if (obj.hasOwnProperty(key)) {
|
|
294
|
+
if (key === "$ref" && typeof obj[key] === "string") {
|
|
295
|
+
var refValue = obj[key];
|
|
296
|
+
// '#/components' is the standard path, but some non-standard sources use '#components'.
|
|
297
|
+
if (refValue.startsWith("#components")) {
|
|
298
|
+
refValue = refValue.replace("#components", "#/components");
|
|
299
|
+
}
|
|
300
|
+
// Resolve references pointing to components.schemas.
|
|
301
|
+
if (refValue.startsWith("#/components/schemas/")) {
|
|
302
|
+
var interfaceName = refValue.replace("#/components/schemas/", "");
|
|
303
|
+
// Files under /components/schemas are generated as ts interfaces named
|
|
304
|
+
// after the file. The `tsType` marker tells the compiler to emit a
|
|
305
|
+
// reference to that interface. The compiler uppercases the first
|
|
306
|
+
// letter of tsType, so we uppercase the name here to keep references
|
|
307
|
+
// aligned with the generated interface names.
|
|
308
|
+
obj["tsType"] = upperFirst(interfaceName);
|
|
309
|
+
// When the object has extra properties alongside `$ref`, build an
|
|
310
|
+
// inline object type from those properties. The common case is a
|
|
311
|
+
// path param merged onto a body DTO.
|
|
312
|
+
if (obj.properties) {
|
|
313
|
+
// Build the inline object type string manually instead of
|
|
314
|
+
// JSON.stringify, which would serialize type names as string
|
|
315
|
+
// literals (e.g. `{userId: "string"}` instead of `{userId: string}`).
|
|
316
|
+
// Guard `obj.required` because it may be undefined for schemas
|
|
317
|
+
// without a required array.
|
|
318
|
+
var requiredArr = Array.isArray(obj.required) ? obj.required : [];
|
|
319
|
+
var propParts = [];
|
|
320
|
+
Object.keys(obj.properties).forEach(function (key) {
|
|
321
|
+
var propSchema = obj.properties[key];
|
|
322
|
+
var tsType = propSchema.tsType || jsonSchemaTypeToTs(propSchema);
|
|
323
|
+
var optional = requiredArr.includes(key) ? "" : "?";
|
|
324
|
+
propParts.push("".concat(key).concat(optional, ": ").concat(tsType));
|
|
325
|
+
});
|
|
326
|
+
obj["tsType"] += " & { ".concat(propParts.join("; "), " }");
|
|
327
|
+
}
|
|
328
|
+
delete obj["$ref"];
|
|
329
|
+
}
|
|
330
|
+
} else if (_typeof(obj[key]) === "object" && obj[key] !== null) {
|
|
331
|
+
// Recurse into child objects.
|
|
332
|
+
rewriteRefs(obj[key]);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
for (var key in obj) {
|
|
337
|
+
_loop();
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
jsonSchema = preprocessSchema(jsonSchema);
|
|
341
|
+
// Capitalize the type name to avoid naming inconsistencies from the compiler.
|
|
342
|
+
typeName = upperFirst(typeName);
|
|
343
|
+
if (!isEmpty(jsonSchema)) {
|
|
344
|
+
_context.next = 5;
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
return _context.abrupt("return", "export interface ".concat(typeName, " {}"));
|
|
348
|
+
case 5:
|
|
349
|
+
if (!jsonSchema.__is_any__) {
|
|
350
|
+
_context.next = 8;
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
delete jsonSchema.__is_any__;
|
|
354
|
+
return _context.abrupt("return", "export type ".concat(typeName, " = any"));
|
|
355
|
+
case 8:
|
|
356
|
+
rewriteRefs(jsonSchema);
|
|
357
|
+
|
|
358
|
+
// Pass an all-caps fake type name to json-schema-to-typescript and replace
|
|
359
|
+
// it back afterwards. This avoids the compiler's generateName logic appending
|
|
360
|
+
// a numeric suffix when the same name appears in nested references.
|
|
361
|
+
fakeTypeName = "THISISAFAKETYPENAME";
|
|
362
|
+
_context.next = 12;
|
|
363
|
+
return compile(jsonSchema, fakeTypeName, {
|
|
364
|
+
bannerComment: "",
|
|
365
|
+
additionalProperties: false,
|
|
366
|
+
declareExternallyReferenced: false
|
|
367
|
+
});
|
|
368
|
+
case 12:
|
|
369
|
+
code = _context.sent;
|
|
370
|
+
delete jsonSchema.id;
|
|
371
|
+
return _context.abrupt("return", code.replace(fakeTypeName, typeName).trim());
|
|
372
|
+
case 15:
|
|
373
|
+
case "end":
|
|
374
|
+
return _context.stop();
|
|
375
|
+
}
|
|
376
|
+
}, _callee);
|
|
377
|
+
}));
|
|
378
|
+
return _jsonSchemaToTsCode.apply(this, arguments);
|
|
379
|
+
}
|
|
380
|
+
export function getRequestDataJsonSchema(interfaceInfo) {
|
|
381
|
+
var jsonSchema;
|
|
382
|
+
switch (interfaceInfo.req_body_type) {
|
|
383
|
+
case RequestBodyType.form:
|
|
384
|
+
jsonSchema = propDefinitionsToJsonSchema(interfaceInfo.req_body_form.map(function (item) {
|
|
385
|
+
return _objectSpread(_objectSpread({
|
|
386
|
+
name: item.name,
|
|
387
|
+
required: item.required === Required.true,
|
|
388
|
+
type: item.type === RequestFormItemType.file ? "file" : "string",
|
|
389
|
+
comment: item.desc
|
|
390
|
+
}, item.isArray ? {
|
|
391
|
+
isArray: true
|
|
392
|
+
} : {}), Array.isArray(item.enum) && item.enum.length ? {
|
|
393
|
+
enum: item.enum
|
|
394
|
+
} : {});
|
|
395
|
+
}));
|
|
396
|
+
break;
|
|
397
|
+
case RequestBodyType.json:
|
|
398
|
+
if (interfaceInfo.req_body_other) {
|
|
399
|
+
jsonSchema = jsonSchemaStringToJsonSchema(interfaceInfo.req_body_other);
|
|
400
|
+
}
|
|
401
|
+
break;
|
|
402
|
+
default:
|
|
403
|
+
/* istanbul ignore next */
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Normalize a degenerate body schema (G-3): when Nest fails to reflect a
|
|
408
|
+
// proper DTO schema (inline type / Prisma type / missing @ApiBody type),
|
|
409
|
+
// the request body may resolve to a bare primitive such as `{type:'string'}`
|
|
410
|
+
// or a non-object schema. Merging path/query params onto such a root
|
|
411
|
+
// produces `{id: number} & string`. Coerce it to an object-less schema so
|
|
412
|
+
// params attach cleanly; the upstream cause is surfaced as a warning (G-5).
|
|
413
|
+
if (jsonSchema && jsonSchema.type && jsonSchema.type !== "object" && !jsonSchema.properties && !jsonSchema.$ref && !jsonSchema.oneOf && !jsonSchema.anyOf && !jsonSchema.allOf) {
|
|
414
|
+
delete jsonSchema.type;
|
|
415
|
+
delete jsonSchema.tsType;
|
|
416
|
+
}
|
|
417
|
+
if (isArray(interfaceInfo.req_query) && interfaceInfo.req_query.length) {
|
|
418
|
+
var queryJsonSchema = propDefinitionsToJsonSchema(interfaceInfo.req_query.map(function (item) {
|
|
419
|
+
return {
|
|
420
|
+
name: item.name,
|
|
421
|
+
required: item.required === Required.true,
|
|
422
|
+
type: item.type || "any",
|
|
423
|
+
// `object` resolves to `{}`, which causes declaration issues, so strip it for now
|
|
424
|
+
comment: item.desc
|
|
425
|
+
};
|
|
426
|
+
}));
|
|
427
|
+
/* istanbul ignore else */
|
|
428
|
+
if (jsonSchema) {
|
|
429
|
+
jsonSchema.properties = _objectSpread(_objectSpread({}, jsonSchema.properties), queryJsonSchema.properties);
|
|
430
|
+
jsonSchema.required = [].concat(_toConsumableArray(jsonSchema.required || []), _toConsumableArray(queryJsonSchema.required || []));
|
|
431
|
+
} else {
|
|
432
|
+
jsonSchema = queryJsonSchema;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if (isArray(interfaceInfo.req_params) && interfaceInfo.req_params.length) {
|
|
436
|
+
var paramsJsonSchema = propDefinitionsToJsonSchema(interfaceInfo.req_params.map(function (item) {
|
|
437
|
+
return {
|
|
438
|
+
name: item.name,
|
|
439
|
+
required: true,
|
|
440
|
+
type: item.type || "string",
|
|
441
|
+
comment: item.desc
|
|
442
|
+
};
|
|
443
|
+
}));
|
|
444
|
+
/* istanbul ignore else */
|
|
445
|
+
if (jsonSchema) {
|
|
446
|
+
jsonSchema.properties = _objectSpread(_objectSpread({}, jsonSchema.properties), paramsJsonSchema.properties);
|
|
447
|
+
jsonSchema.required = [].concat(_toConsumableArray(jsonSchema.required || []), _toConsumableArray(paramsJsonSchema.required || []));
|
|
448
|
+
} else {
|
|
449
|
+
jsonSchema = paramsJsonSchema;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return jsonSchema;
|
|
453
|
+
}
|
|
454
|
+
export function getResponseDataJsonSchema(interfaceInfo) {
|
|
455
|
+
var jsonSchema = {};
|
|
456
|
+
switch (interfaceInfo.res_body_type) {
|
|
457
|
+
case ResponseBodyType.json:
|
|
458
|
+
if (interfaceInfo.res_body) {
|
|
459
|
+
jsonSchema = jsonSchemaStringToJsonSchema(interfaceInfo.res_body);
|
|
460
|
+
}
|
|
461
|
+
break;
|
|
462
|
+
default:
|
|
463
|
+
jsonSchema = {
|
|
464
|
+
__is_any__: true
|
|
465
|
+
};
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
return jsonSchema;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Format generated code with prettier.
|
|
473
|
+
*
|
|
474
|
+
* When the output file path is known, the consumer project's own prettier
|
|
475
|
+
* config is resolved from it (resolveConfig walks up from the file location),
|
|
476
|
+
* so generated code lands clean under the consumer's `prettier --check`. When
|
|
477
|
+
* the consumer has no config, pure prettier defaults are used, mirroring what
|
|
478
|
+
* the consumer's own prettier would produce. `filepath` is always set so
|
|
479
|
+
* prettier infers the parser from the extension and applies any matching
|
|
480
|
+
* `overrides` from the consumer config.
|
|
481
|
+
*
|
|
482
|
+
* @param content code to format
|
|
483
|
+
* @param filePath output file path used to resolve the consumer config
|
|
484
|
+
* @returns formatted code
|
|
485
|
+
* @see https://prettier.io/docs/en/options.html
|
|
486
|
+
*/
|
|
487
|
+
export function formatContent(_x3, _x4) {
|
|
488
|
+
return _formatContent.apply(this, arguments);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Generate the banner comment placed at the top of every generated file.
|
|
493
|
+
* @returns banner comment
|
|
494
|
+
*/
|
|
495
|
+
function _formatContent() {
|
|
496
|
+
_formatContent = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(content, filePath) {
|
|
497
|
+
var _yield$resolveConfig;
|
|
498
|
+
var consumerConfig;
|
|
499
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
500
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
501
|
+
case 0:
|
|
502
|
+
if (filePath) {
|
|
503
|
+
_context2.next = 2;
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
return _context2.abrupt("return", prettierFormat(content, {
|
|
507
|
+
parser: "babel-ts"
|
|
508
|
+
}));
|
|
509
|
+
case 2:
|
|
510
|
+
_context2.next = 4;
|
|
511
|
+
return resolveConfig(filePath);
|
|
512
|
+
case 4:
|
|
513
|
+
_context2.t1 = _yield$resolveConfig = _context2.sent;
|
|
514
|
+
_context2.t0 = _context2.t1 !== null;
|
|
515
|
+
if (!_context2.t0) {
|
|
516
|
+
_context2.next = 8;
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
_context2.t0 = _yield$resolveConfig !== void 0;
|
|
520
|
+
case 8:
|
|
521
|
+
if (!_context2.t0) {
|
|
522
|
+
_context2.next = 12;
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
_context2.t2 = _yield$resolveConfig;
|
|
526
|
+
_context2.next = 13;
|
|
527
|
+
break;
|
|
528
|
+
case 12:
|
|
529
|
+
_context2.t2 = {};
|
|
530
|
+
case 13:
|
|
531
|
+
consumerConfig = _context2.t2;
|
|
532
|
+
return _context2.abrupt("return", prettierFormat(content, _objectSpread(_objectSpread({}, consumerConfig), {}, {
|
|
533
|
+
filepath: filePath
|
|
534
|
+
})));
|
|
535
|
+
case 15:
|
|
536
|
+
case "end":
|
|
537
|
+
return _context2.stop();
|
|
538
|
+
}
|
|
539
|
+
}, _callee2);
|
|
540
|
+
}));
|
|
541
|
+
return _formatContent.apply(this, arguments);
|
|
542
|
+
}
|
|
543
|
+
export function topNotesContent() {
|
|
544
|
+
return "\n /**\n * Created By @devbie/apits\n */\n\n ";
|
|
545
|
+
}
|