@orval/core 8.2.0 → 8.4.0
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/dist/{chunk-C6wwvPpM.mjs → chunk-1-as6MWF.mjs} +2 -0
- package/dist/index.d.mts +139 -54
- package/dist/index.mjs +1089 -704
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -7
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { t as __export } from "./chunk-
|
|
2
|
-
import {
|
|
1
|
+
import { t as __export } from "./chunk-1-as6MWF.mjs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { entries, groupBy, isArray, isBoolean, isBoolean as isBoolean$1, isEmptyish, isFunction, isNullish, isNullish as isNullish$1, isNumber, isString, isString as isString$1, prop, unique, uniqueBy, uniqueWith } from "remeda";
|
|
3
4
|
import { keyword } from "esutils";
|
|
4
5
|
import path from "node:path";
|
|
5
|
-
import fs from "node:fs";
|
|
6
|
-
import { globby } from "globby";
|
|
7
6
|
import { compare } from "compare-versions";
|
|
8
7
|
import debug from "debug";
|
|
9
8
|
import { pathToFileURL } from "node:url";
|
|
9
|
+
import fs, { existsSync, readFileSync } from "node:fs";
|
|
10
|
+
import { globby } from "globby";
|
|
10
11
|
import readline from "node:readline";
|
|
11
12
|
import chalk from "chalk";
|
|
12
13
|
import { isDereferenced } from "@scalar/openapi-types/helpers";
|
|
@@ -108,124 +109,20 @@ const generalJSTypes = [
|
|
|
108
109
|
"object",
|
|
109
110
|
"blob"
|
|
110
111
|
];
|
|
111
|
-
const generalJSTypesWithArray = generalJSTypes.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
112
|
+
const generalJSTypesWithArray = generalJSTypes.flatMap((type) => [
|
|
113
|
+
type,
|
|
114
|
+
`Array<${type}>`,
|
|
115
|
+
`${type}[]`
|
|
116
|
+
]);
|
|
115
117
|
const VERBS_WITH_BODY = [
|
|
116
118
|
Verbs.POST,
|
|
117
119
|
Verbs.PUT,
|
|
118
120
|
Verbs.PATCH,
|
|
119
121
|
Verbs.DELETE
|
|
120
122
|
];
|
|
121
|
-
const URL_REGEX = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w
|
|
123
|
+
const URL_REGEX = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w.-]+)+[\w\-._~:/?#[\]@!$&'()*+,;=.]+$/;
|
|
122
124
|
const TEMPLATE_TAG_REGEX = /\${(.+?)}/g;
|
|
123
125
|
|
|
124
|
-
//#endregion
|
|
125
|
-
//#region src/utils/extension.ts
|
|
126
|
-
function getExtension(path$2) {
|
|
127
|
-
return path$2.toLowerCase().includes(".yaml") || path$2.toLowerCase().includes(".yml") ? "yaml" : "json";
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
//#endregion
|
|
131
|
-
//#region src/utils/file.ts
|
|
132
|
-
function getFileInfo(target = "", { backupFilename = "filename", extension = ".ts" } = {}) {
|
|
133
|
-
const isDir = isDirectory(target);
|
|
134
|
-
const filePath = isDir ? path.join(target, backupFilename + extension) : target;
|
|
135
|
-
return {
|
|
136
|
-
path: filePath,
|
|
137
|
-
pathWithoutExtension: filePath.replace(/\.[^/.]+$/, ""),
|
|
138
|
-
extension,
|
|
139
|
-
isDirectory: isDir,
|
|
140
|
-
dirname: path.dirname(filePath),
|
|
141
|
-
filename: path.basename(filePath, extension.startsWith(".") ? extension : `.${extension}`)
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
async function removeFilesAndEmptyFolders(patterns, dir) {
|
|
145
|
-
const files = await globby(patterns, {
|
|
146
|
-
cwd: dir,
|
|
147
|
-
absolute: true
|
|
148
|
-
});
|
|
149
|
-
await Promise.all(files.map((file) => fs.promises.unlink(file)));
|
|
150
|
-
const sortedDirectories = (await globby(["**/*"], {
|
|
151
|
-
cwd: dir,
|
|
152
|
-
absolute: true,
|
|
153
|
-
onlyDirectories: true
|
|
154
|
-
})).toSorted((a, b) => {
|
|
155
|
-
const depthA = a.split("/").length;
|
|
156
|
-
return b.split("/").length - depthA;
|
|
157
|
-
});
|
|
158
|
-
for (const directory of sortedDirectories) try {
|
|
159
|
-
if ((await fs.promises.readdir(directory)).length === 0) await fs.promises.rmdir(directory);
|
|
160
|
-
} catch {}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
//#endregion
|
|
164
|
-
//#region src/utils/path.ts
|
|
165
|
-
var path_exports = /* @__PURE__ */ __export({
|
|
166
|
-
basename: () => basename,
|
|
167
|
-
dirname: () => dirname,
|
|
168
|
-
extname: () => extname,
|
|
169
|
-
getSchemaFileName: () => getSchemaFileName,
|
|
170
|
-
isAbsolute: () => isAbsolute,
|
|
171
|
-
join: () => join,
|
|
172
|
-
joinSafe: () => joinSafe,
|
|
173
|
-
normalizeSafe: () => normalizeSafe,
|
|
174
|
-
relativeSafe: () => relativeSafe,
|
|
175
|
-
resolve: () => resolve,
|
|
176
|
-
separator: () => separator
|
|
177
|
-
});
|
|
178
|
-
const path$1 = {};
|
|
179
|
-
const isFunction$1 = (val) => typeof val == "function";
|
|
180
|
-
const isString$1 = (val) => {
|
|
181
|
-
if (typeof val === "string") return true;
|
|
182
|
-
if (typeof val === "object" && val !== null) return Object.toString.call(val) == "[object String]";
|
|
183
|
-
return false;
|
|
184
|
-
};
|
|
185
|
-
for (const [propName, propValue] of Object.entries(path)) if (isFunction$1(propValue)) path$1[propName] = ((propName$1) => {
|
|
186
|
-
return (...args) => {
|
|
187
|
-
args = args.map((p) => {
|
|
188
|
-
return isString$1(p) ? toUnix(p) : p;
|
|
189
|
-
});
|
|
190
|
-
const result = path[propName$1](...args);
|
|
191
|
-
return isString$1(result) ? toUnix(result) : result;
|
|
192
|
-
};
|
|
193
|
-
})(propName);
|
|
194
|
-
else path$1[propName] = propValue;
|
|
195
|
-
const { join, resolve, extname, dirname, basename, isAbsolute } = path$1;
|
|
196
|
-
/**
|
|
197
|
-
* Behaves exactly like `path.relative(from, to)`, but keeps the first meaningful "./"
|
|
198
|
-
*/
|
|
199
|
-
function relativeSafe(from, to) {
|
|
200
|
-
return normalizeSafe(`.${separator}${path$1.relative(from, to)}`);
|
|
201
|
-
}
|
|
202
|
-
function getSchemaFileName(path$2) {
|
|
203
|
-
return path$2.replace(`.${getExtension(path$2)}`, "").slice(path$2.lastIndexOf("/") + 1);
|
|
204
|
-
}
|
|
205
|
-
const separator = "/";
|
|
206
|
-
const toUnix = function(value) {
|
|
207
|
-
value = value.replaceAll("\\", "/");
|
|
208
|
-
value = value.replaceAll(/(?<!^)\/+/g, "/");
|
|
209
|
-
return value;
|
|
210
|
-
};
|
|
211
|
-
function normalizeSafe(value) {
|
|
212
|
-
let result;
|
|
213
|
-
value = toUnix(value);
|
|
214
|
-
result = path$1.normalize(value);
|
|
215
|
-
if (value.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
|
|
216
|
-
else if (value.startsWith("//") && !result.startsWith("//")) result = value.startsWith("//./") ? "//." + result : "/" + result;
|
|
217
|
-
return result;
|
|
218
|
-
}
|
|
219
|
-
function joinSafe(...values) {
|
|
220
|
-
let result = path$1.join(...values);
|
|
221
|
-
if (values.length > 0) {
|
|
222
|
-
const firstValue = toUnix(values[0]);
|
|
223
|
-
if (firstValue.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
|
|
224
|
-
else if (firstValue.startsWith("//") && !result.startsWith("//")) result = firstValue.startsWith("//./") ? "//." + result : "/" + result;
|
|
225
|
-
}
|
|
226
|
-
return result;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
126
|
//#endregion
|
|
230
127
|
//#region src/utils/assertion.ts
|
|
231
128
|
/**
|
|
@@ -234,42 +131,29 @@ function joinSafe(...values) {
|
|
|
234
131
|
* @param property
|
|
235
132
|
*/
|
|
236
133
|
function isReference(obj) {
|
|
237
|
-
return !
|
|
134
|
+
return !isNullish$1(obj) && Object.hasOwn(obj, "$ref");
|
|
238
135
|
}
|
|
239
|
-
function isDirectory(
|
|
240
|
-
return !extname(
|
|
136
|
+
function isDirectory(pathValue) {
|
|
137
|
+
return !path.extname(pathValue);
|
|
241
138
|
}
|
|
242
139
|
function isObject(x) {
|
|
243
140
|
return Object.prototype.toString.call(x) === "[object Object]";
|
|
244
141
|
}
|
|
142
|
+
function isStringLike(val) {
|
|
143
|
+
if (isString$1(val)) return true;
|
|
144
|
+
return Object.prototype.toString.call(val) === "[object String]";
|
|
145
|
+
}
|
|
245
146
|
function isModule(x) {
|
|
246
147
|
return Object.prototype.toString.call(x) === "[object Module]";
|
|
247
148
|
}
|
|
248
|
-
function isString(x) {
|
|
249
|
-
return typeof x === "string";
|
|
250
|
-
}
|
|
251
|
-
function isNumber(x) {
|
|
252
|
-
return typeof x === "number";
|
|
253
|
-
}
|
|
254
149
|
function isNumeric(x) {
|
|
255
|
-
return
|
|
256
|
-
|
|
257
|
-
function isBoolean(x) {
|
|
258
|
-
return typeof x === "boolean";
|
|
259
|
-
}
|
|
260
|
-
function isFunction(x) {
|
|
261
|
-
return typeof x === "function";
|
|
262
|
-
}
|
|
263
|
-
function isUndefined(x) {
|
|
264
|
-
return x === void 0;
|
|
265
|
-
}
|
|
266
|
-
function isNull(x) {
|
|
267
|
-
return x === null;
|
|
150
|
+
if (typeof x === "number") return Number.isInteger(x);
|
|
151
|
+
return isString$1(x) && /^-?\d+$/.test(x);
|
|
268
152
|
}
|
|
269
153
|
function isSchema(x) {
|
|
270
154
|
if (!isObject(x)) return false;
|
|
271
|
-
if (isString(x.type) && Object.values(SchemaType).includes(x.type)) return true;
|
|
272
|
-
const combine = x.allOf
|
|
155
|
+
if (isString$1(x.type) && Object.values(SchemaType).includes(x.type)) return true;
|
|
156
|
+
const combine = x.allOf ?? x.anyOf ?? x.oneOf;
|
|
273
157
|
if (Array.isArray(combine)) return true;
|
|
274
158
|
if (isObject(x.properties)) return true;
|
|
275
159
|
return false;
|
|
@@ -278,27 +162,26 @@ function isVerb(verb) {
|
|
|
278
162
|
return Object.values(Verbs).includes(verb);
|
|
279
163
|
}
|
|
280
164
|
function isUrl(str) {
|
|
281
|
-
|
|
165
|
+
if (!str.trim()) return false;
|
|
282
166
|
try {
|
|
283
|
-
|
|
167
|
+
const url = new URL(str);
|
|
168
|
+
return ["http:", "https:"].includes(url.protocol);
|
|
284
169
|
} catch {
|
|
285
170
|
return false;
|
|
286
171
|
}
|
|
287
|
-
return givenURL.protocol === "http:" || givenURL.protocol === "https:";
|
|
288
172
|
}
|
|
289
173
|
|
|
290
174
|
//#endregion
|
|
291
175
|
//#region src/utils/async-reduce.ts
|
|
292
176
|
async function asyncReduce(array, reducer, initValue) {
|
|
293
|
-
let accumulate =
|
|
177
|
+
let accumulate = initValue === null || initValue === Object(initValue) && !isFunction(initValue) ? Object.create(initValue) : initValue;
|
|
294
178
|
for (const item of array) accumulate = await reducer(accumulate, item);
|
|
295
179
|
return accumulate;
|
|
296
180
|
}
|
|
297
181
|
|
|
298
182
|
//#endregion
|
|
299
183
|
//#region src/utils/case.ts
|
|
300
|
-
const unicodes = function(s, prefix) {
|
|
301
|
-
prefix = prefix || "";
|
|
184
|
+
const unicodes = function(s, prefix = "") {
|
|
302
185
|
return s.replaceAll(/(^|-)/g, String.raw`$1\u` + prefix).replaceAll(",", String.raw`\u` + prefix);
|
|
303
186
|
};
|
|
304
187
|
const symbols = unicodes("20-26,28-2F,3A-40,5B-60,7B-7E,A0-BF,D7,F7", "00");
|
|
@@ -320,8 +203,8 @@ const regexps = {
|
|
|
320
203
|
const deapostrophe = (s) => {
|
|
321
204
|
return s.replace(regexps.apostrophe, "");
|
|
322
205
|
};
|
|
323
|
-
const up =
|
|
324
|
-
const low =
|
|
206
|
+
const up = (s) => s.toUpperCase();
|
|
207
|
+
const low = (s) => s.toLowerCase();
|
|
325
208
|
const fill = (s, fillWith, isDeapostrophe = false) => {
|
|
326
209
|
s = s.replace(regexps.fill, function(m, next) {
|
|
327
210
|
return next ? fillWith + next : "";
|
|
@@ -330,14 +213,13 @@ const fill = (s, fillWith, isDeapostrophe = false) => {
|
|
|
330
213
|
return s;
|
|
331
214
|
};
|
|
332
215
|
const decap = (s, char = 0) => {
|
|
333
|
-
return low
|
|
216
|
+
return low(s.charAt(char)) + s.slice(char + 1);
|
|
334
217
|
};
|
|
335
218
|
const relax = (m, before, acronym, caps) => {
|
|
336
219
|
return before + " " + (acronym ? acronym + " " : "") + caps;
|
|
337
220
|
};
|
|
338
221
|
const prep = (s, isFill = false, isPascal = false, isUpper = false) => {
|
|
339
|
-
|
|
340
|
-
if (!isUpper && regexps.upper.test(s)) s = low.call(s);
|
|
222
|
+
if (!isUpper && regexps.upper.test(s)) s = low(s);
|
|
341
223
|
if (!isFill && !regexps.hole.test(s)) {
|
|
342
224
|
var holey = fill(s, " ");
|
|
343
225
|
if (regexps.hole.test(holey)) s = holey;
|
|
@@ -346,20 +228,20 @@ const prep = (s, isFill = false, isPascal = false, isUpper = false) => {
|
|
|
346
228
|
return s;
|
|
347
229
|
};
|
|
348
230
|
const lower = (s, fillWith, isDeapostrophe) => {
|
|
349
|
-
return fill(low
|
|
231
|
+
return fill(low(prep(s, !!fillWith)), fillWith, isDeapostrophe);
|
|
350
232
|
};
|
|
351
233
|
const pascalMemory = {};
|
|
352
|
-
function pascal(s) {
|
|
234
|
+
function pascal(s = "") {
|
|
353
235
|
if (pascalMemory[s]) return pascalMemory[s];
|
|
354
|
-
const isStartWithUnderscore = s
|
|
355
|
-
if (regexps.upper.test(s)) s = low
|
|
356
|
-
const pascalString = (s
|
|
236
|
+
const isStartWithUnderscore = s.startsWith("_");
|
|
237
|
+
if (regexps.upper.test(s)) s = low(s);
|
|
238
|
+
const pascalString = (s.match(/[a-zA-Z0-9\u00C0-\u017F]+/g) ?? []).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
357
239
|
const pascalWithUnderscore = isStartWithUnderscore ? `_${pascalString}` : pascalString;
|
|
358
240
|
pascalMemory[s] = pascalWithUnderscore;
|
|
359
241
|
return pascalWithUnderscore;
|
|
360
242
|
}
|
|
361
|
-
function camel(s) {
|
|
362
|
-
const isStartWithUnderscore = s
|
|
243
|
+
function camel(s = "") {
|
|
244
|
+
const isStartWithUnderscore = s.startsWith("_");
|
|
363
245
|
const camelString = decap(pascal(s), isStartWithUnderscore ? 1 : 0);
|
|
364
246
|
return isStartWithUnderscore ? `_${camelString}` : camelString;
|
|
365
247
|
}
|
|
@@ -370,7 +252,7 @@ function kebab(s) {
|
|
|
370
252
|
return lower(s, "-", true);
|
|
371
253
|
}
|
|
372
254
|
function upper(s, fillWith, isDeapostrophe) {
|
|
373
|
-
return fill(up
|
|
255
|
+
return fill(up(prep(s, !!fillWith, false, true)), fillWith, isDeapostrophe);
|
|
374
256
|
}
|
|
375
257
|
function conventionName(name, convention) {
|
|
376
258
|
let nameConventionTransform = camel;
|
|
@@ -388,6 +270,14 @@ function conventionName(name, convention) {
|
|
|
388
270
|
return nameConventionTransform(name);
|
|
389
271
|
}
|
|
390
272
|
|
|
273
|
+
//#endregion
|
|
274
|
+
//#region src/utils/compare-version.ts
|
|
275
|
+
function compareVersions(firstVersion, secondVersions, operator = ">=") {
|
|
276
|
+
if (firstVersion === "latest" || firstVersion === "*") return true;
|
|
277
|
+
if (firstVersion.startsWith("catalog:")) return true;
|
|
278
|
+
return compare(firstVersion.replace(/(\s(.*))/, ""), secondVersions, operator);
|
|
279
|
+
}
|
|
280
|
+
|
|
391
281
|
//#endregion
|
|
392
282
|
//#region src/utils/content-type.ts
|
|
393
283
|
/**
|
|
@@ -435,16 +325,38 @@ function isBinaryContentType(contentType) {
|
|
|
435
325
|
function getFormDataFieldFileType(resolvedSchema, partContentType) {
|
|
436
326
|
if (resolvedSchema.type !== "string") return;
|
|
437
327
|
if (resolvedSchema.contentEncoding) return;
|
|
438
|
-
const
|
|
328
|
+
const contentMediaType = resolvedSchema.contentMediaType;
|
|
329
|
+
const effectiveContentType = partContentType ?? contentMediaType;
|
|
439
330
|
if (effectiveContentType) return isBinaryContentType(effectiveContentType) ? "binary" : "text";
|
|
440
331
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
332
|
+
/**
|
|
333
|
+
* Filters items by content type based on include/exclude rules
|
|
334
|
+
*
|
|
335
|
+
* @param items - Array of items with contentType property
|
|
336
|
+
* @param filter - Optional filter configuration
|
|
337
|
+
* @returns Filtered array
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```ts
|
|
341
|
+
* const types = [
|
|
342
|
+
* { contentType: 'application/json', value: '...' },
|
|
343
|
+
* { contentType: 'text/xml', value: '...' }
|
|
344
|
+
* ];
|
|
345
|
+
*
|
|
346
|
+
* // Include only JSON
|
|
347
|
+
* filterByContentType(types, { include: ['application/json'] });
|
|
348
|
+
*
|
|
349
|
+
* // Exclude XML
|
|
350
|
+
* filterByContentType(types, { exclude: ['text/xml'] });
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
function filterByContentType(items, filter$1) {
|
|
354
|
+
if (!filter$1) return items;
|
|
355
|
+
return items.filter((item) => {
|
|
356
|
+
const shouldInclude = !filter$1.include || filter$1.include.includes(item.contentType);
|
|
357
|
+
const shouldExclude = filter$1.exclude?.includes(item.contentType) ?? false;
|
|
358
|
+
return shouldInclude && !shouldExclude;
|
|
359
|
+
});
|
|
448
360
|
}
|
|
449
361
|
|
|
450
362
|
//#endregion
|
|
@@ -454,7 +366,7 @@ const DEBUG = process.env.DEBUG;
|
|
|
454
366
|
function createDebugger(ns, options = {}) {
|
|
455
367
|
const log$1 = debug(ns);
|
|
456
368
|
const { onlyWhenFocused } = options;
|
|
457
|
-
const focus =
|
|
369
|
+
const focus = isString(onlyWhenFocused) ? onlyWhenFocused : ns;
|
|
458
370
|
return (msg, ...args) => {
|
|
459
371
|
if (filter && !msg.includes(filter)) return;
|
|
460
372
|
if (onlyWhenFocused && !DEBUG?.includes(focus)) return;
|
|
@@ -468,13 +380,13 @@ const search = String.raw`\*/`;
|
|
|
468
380
|
const replacement = String.raw`*\/`;
|
|
469
381
|
const regex$1 = new RegExp(search, "g");
|
|
470
382
|
function jsDoc(schema, tryOneLine = false, context) {
|
|
471
|
-
if (context?.output
|
|
383
|
+
if (context?.output.override.jsDoc) {
|
|
472
384
|
const { filter: filter$1 } = context.output.override.jsDoc;
|
|
473
385
|
if (filter$1) return keyValuePairsToJsDoc(filter$1(schema));
|
|
474
386
|
}
|
|
475
387
|
const { description, deprecated, summary, minLength, maxLength, minimum, maximum, exclusiveMinimum, exclusiveMaximum, minItems, maxItems, pattern } = schema;
|
|
476
388
|
const isNullable = schema.type === "null" || Array.isArray(schema.type) && schema.type.includes("null");
|
|
477
|
-
const lines = (Array.isArray(description) ? description.filter((d) => !d.includes("eslint-disable")) : [description
|
|
389
|
+
const lines = (Array.isArray(description) ? description.filter((d) => !d.includes("eslint-disable")) : [description ?? ""]).map((line) => line.replaceAll(regex$1, replacement));
|
|
478
390
|
const count$1 = [
|
|
479
391
|
description,
|
|
480
392
|
deprecated,
|
|
@@ -489,7 +401,7 @@ function jsDoc(schema, tryOneLine = false, context) {
|
|
|
489
401
|
maxItems?.toString(),
|
|
490
402
|
isNullable ? "null" : "",
|
|
491
403
|
pattern
|
|
492
|
-
].
|
|
404
|
+
].filter(Boolean).length;
|
|
493
405
|
if (!count$1) return "";
|
|
494
406
|
const oneLine = count$1 === 1 && tryOneLine;
|
|
495
407
|
const eslintDisable = Array.isArray(description) ? description.find((d) => d.includes("eslint-disable"))?.replaceAll(regex$1, replacement) : void 0;
|
|
@@ -556,10 +468,49 @@ async function dynamicImport(toImport, from = process.cwd(), takeDefault = true)
|
|
|
556
468
|
}
|
|
557
469
|
return toImport;
|
|
558
470
|
} catch (error) {
|
|
559
|
-
throw new Error(`Oups... 🍻. Path: ${toImport} => ${error}`);
|
|
471
|
+
throw new Error(`Oups... 🍻. Path: ${String(toImport)} => ${String(error)}`);
|
|
560
472
|
}
|
|
561
473
|
}
|
|
562
474
|
|
|
475
|
+
//#endregion
|
|
476
|
+
//#region src/utils/extension.ts
|
|
477
|
+
function getExtension(path$2) {
|
|
478
|
+
return path$2.toLowerCase().includes(".yaml") || path$2.toLowerCase().includes(".yml") ? "yaml" : "json";
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
//#endregion
|
|
482
|
+
//#region src/utils/file.ts
|
|
483
|
+
function getFileInfo(target = "", { backupFilename = "filename", extension = ".ts" } = {}) {
|
|
484
|
+
const isDir = isDirectory(target);
|
|
485
|
+
const filePath = isDir ? path.join(target, backupFilename + extension) : target;
|
|
486
|
+
return {
|
|
487
|
+
path: filePath,
|
|
488
|
+
pathWithoutExtension: filePath.replace(/\.[^/.]+$/, ""),
|
|
489
|
+
extension,
|
|
490
|
+
isDirectory: isDir,
|
|
491
|
+
dirname: path.dirname(filePath),
|
|
492
|
+
filename: path.basename(filePath, extension.startsWith(".") ? extension : `.${extension}`)
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
async function removeFilesAndEmptyFolders(patterns, dir) {
|
|
496
|
+
const files = await globby(patterns, {
|
|
497
|
+
cwd: dir,
|
|
498
|
+
absolute: true
|
|
499
|
+
});
|
|
500
|
+
await Promise.all(files.map((file) => fs.promises.unlink(file)));
|
|
501
|
+
const sortedDirectories = (await globby(["**/*"], {
|
|
502
|
+
cwd: dir,
|
|
503
|
+
absolute: true,
|
|
504
|
+
onlyDirectories: true
|
|
505
|
+
})).toSorted((a, b) => {
|
|
506
|
+
const depthA = a.split("/").length;
|
|
507
|
+
return b.split("/").length - depthA;
|
|
508
|
+
});
|
|
509
|
+
for (const directory of sortedDirectories) try {
|
|
510
|
+
if ((await fs.promises.readdir(directory)).length === 0) await fs.promises.rmdir(directory);
|
|
511
|
+
} catch {}
|
|
512
|
+
}
|
|
513
|
+
|
|
563
514
|
//#endregion
|
|
564
515
|
//#region src/utils/file-extensions.ts
|
|
565
516
|
function getMockFileExtensionByTypeName(mock) {
|
|
@@ -608,7 +559,7 @@ function logError(err, tag) {
|
|
|
608
559
|
if (err instanceof Error) {
|
|
609
560
|
message = (err.message || err.stack) ?? "Unknown error";
|
|
610
561
|
if (err.cause) {
|
|
611
|
-
const causeMsg = err.cause instanceof Error ? err.cause.message :
|
|
562
|
+
const causeMsg = err.cause instanceof Error ? err.cause.message : isString(err.cause) ? err.cause : JSON.stringify(err.cause, void 0, 2);
|
|
612
563
|
message += `\n Cause: ${causeMsg}`;
|
|
613
564
|
}
|
|
614
565
|
} else message = String(err);
|
|
@@ -695,16 +646,16 @@ function createLogger(level = "info", options = {}) {
|
|
|
695
646
|
|
|
696
647
|
//#endregion
|
|
697
648
|
//#region src/utils/merge-deep.ts
|
|
698
|
-
const isObject$1 = (obj) => obj && typeof obj === "object";
|
|
699
649
|
function mergeDeep(source, target) {
|
|
700
|
-
if (!isObject
|
|
701
|
-
|
|
650
|
+
if (!isObject(target) || !isObject(source)) return source;
|
|
651
|
+
const acc = Object.assign({}, source);
|
|
652
|
+
for (const [key, value] of Object.entries(target)) {
|
|
702
653
|
const sourceValue = acc[key];
|
|
703
654
|
if (Array.isArray(sourceValue) && Array.isArray(value)) acc[key] = [...sourceValue, ...value];
|
|
704
|
-
else if (isObject
|
|
655
|
+
else if (isObject(sourceValue) && isObject(value)) acc[key] = mergeDeep(sourceValue, value);
|
|
705
656
|
else acc[key] = value;
|
|
706
|
-
|
|
707
|
-
|
|
657
|
+
}
|
|
658
|
+
return acc;
|
|
708
659
|
}
|
|
709
660
|
|
|
710
661
|
//#endregion
|
|
@@ -714,9 +665,106 @@ function count(str = "", key) {
|
|
|
714
665
|
return (str.match(new RegExp(key, "g")) ?? []).length;
|
|
715
666
|
}
|
|
716
667
|
|
|
668
|
+
//#endregion
|
|
669
|
+
//#region src/utils/path.ts
|
|
670
|
+
var path_exports = /* @__PURE__ */ __export({
|
|
671
|
+
basename: () => basename,
|
|
672
|
+
dirname: () => dirname,
|
|
673
|
+
extname: () => extname,
|
|
674
|
+
getSchemaFileName: () => getSchemaFileName,
|
|
675
|
+
isAbsolute: () => isAbsolute,
|
|
676
|
+
join: () => join,
|
|
677
|
+
joinSafe: () => joinSafe,
|
|
678
|
+
normalizeSafe: () => normalizeSafe,
|
|
679
|
+
relativeSafe: () => relativeSafe,
|
|
680
|
+
resolve: () => resolve,
|
|
681
|
+
separator: () => separator
|
|
682
|
+
});
|
|
683
|
+
function wrapPathFn(fn) {
|
|
684
|
+
return (...args) => {
|
|
685
|
+
const result = fn(...args.map((p) => isStringLike(p) ? toUnix(p) : p));
|
|
686
|
+
return isStringLike(result) ? toUnix(result) : result;
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
const path$1 = Object.fromEntries(Object.entries(path).map(([key, value]) => [key, isFunction(value) ? wrapPathFn(value) : value]));
|
|
690
|
+
const { join, resolve, extname, dirname, basename, isAbsolute } = path$1;
|
|
691
|
+
/**
|
|
692
|
+
* Behaves exactly like `path.relative(from, to)`, but keeps the first meaningful "./"
|
|
693
|
+
*/
|
|
694
|
+
function relativeSafe(from, to) {
|
|
695
|
+
return normalizeSafe(`.${separator}${path$1.relative(from, to)}`);
|
|
696
|
+
}
|
|
697
|
+
function getSchemaFileName(path$2) {
|
|
698
|
+
return path$2.replace(`.${getExtension(path$2)}`, "").slice(path$2.lastIndexOf("/") + 1);
|
|
699
|
+
}
|
|
700
|
+
const separator = "/";
|
|
701
|
+
const toUnix = function(value) {
|
|
702
|
+
value = value.replaceAll("\\", "/");
|
|
703
|
+
value = value.replaceAll(/(?<!^)\/+/g, "/");
|
|
704
|
+
return value;
|
|
705
|
+
};
|
|
706
|
+
function normalizeSafe(value) {
|
|
707
|
+
let result;
|
|
708
|
+
value = toUnix(value);
|
|
709
|
+
result = path$1.normalize(value);
|
|
710
|
+
if (value.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
|
|
711
|
+
else if (value.startsWith("//") && !result.startsWith("//")) result = value.startsWith("//./") ? "//." + result : "/" + result;
|
|
712
|
+
return result;
|
|
713
|
+
}
|
|
714
|
+
function joinSafe(...values) {
|
|
715
|
+
let result = path$1.join(...values);
|
|
716
|
+
if (values.length > 0) {
|
|
717
|
+
const firstValue = toUnix(values[0]);
|
|
718
|
+
if (firstValue.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
|
|
719
|
+
else if (firstValue.startsWith("//") && !result.startsWith("//")) result = firstValue.startsWith("//./") ? "//." + result : "/" + result;
|
|
720
|
+
}
|
|
721
|
+
return result;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
//#endregion
|
|
725
|
+
//#region src/utils/resolve-version.ts
|
|
726
|
+
function resolveInstalledVersion(packageName, fromDir) {
|
|
727
|
+
try {
|
|
728
|
+
const require = createRequire(path.join(fromDir, "noop.js"));
|
|
729
|
+
try {
|
|
730
|
+
return require(`${packageName}/package.json`).version;
|
|
731
|
+
} catch (directError) {
|
|
732
|
+
if (directError instanceof Error && "code" in directError && directError.code === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
|
|
733
|
+
const entryPath = require.resolve(packageName);
|
|
734
|
+
let dir = path.dirname(entryPath);
|
|
735
|
+
while (dir !== path.parse(dir).root) {
|
|
736
|
+
const pkgPath = path.join(dir, "package.json");
|
|
737
|
+
if (existsSync(pkgPath)) {
|
|
738
|
+
const pkgData = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
739
|
+
if (pkgData.name === packageName) return pkgData.version;
|
|
740
|
+
}
|
|
741
|
+
dir = path.dirname(dir);
|
|
742
|
+
}
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
throw directError;
|
|
746
|
+
}
|
|
747
|
+
} catch {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
function resolveInstalledVersions(packageJson, fromDir) {
|
|
752
|
+
const resolved = {};
|
|
753
|
+
const allDeps = new Set([
|
|
754
|
+
...Object.keys(packageJson.dependencies ?? {}),
|
|
755
|
+
...Object.keys(packageJson.devDependencies ?? {}),
|
|
756
|
+
...Object.keys(packageJson.peerDependencies ?? {})
|
|
757
|
+
]);
|
|
758
|
+
for (const pkgName of allDeps) {
|
|
759
|
+
const version = resolveInstalledVersion(pkgName, fromDir);
|
|
760
|
+
if (version) resolved[pkgName] = version;
|
|
761
|
+
}
|
|
762
|
+
return resolved;
|
|
763
|
+
}
|
|
764
|
+
|
|
717
765
|
//#endregion
|
|
718
766
|
//#region src/utils/sort.ts
|
|
719
|
-
const sortByPriority = (arr) => arr.
|
|
767
|
+
const sortByPriority = (arr) => arr.toSorted((a, b) => {
|
|
720
768
|
if (a.default) return 1;
|
|
721
769
|
if (b.default) return -1;
|
|
722
770
|
if (a.required && b.required) return 0;
|
|
@@ -740,17 +788,20 @@ const sortByPriority = (arr) => arr.sort((a, b) => {
|
|
|
740
788
|
* stringify({ a: 1, b: 'test' }) // returns "{ a: 1, b: 'test', }"
|
|
741
789
|
*/
|
|
742
790
|
function stringify(data) {
|
|
743
|
-
if (
|
|
791
|
+
if (isNullish$1(data)) return;
|
|
744
792
|
if (isString(data)) return `'${data.replaceAll("'", String.raw`\'`)}'`;
|
|
745
|
-
if (isNumber(data) || isBoolean(data) || isFunction(data)) return
|
|
746
|
-
if (Array.isArray(data)) return `[${data.map(stringify).join(", ")}]`;
|
|
747
|
-
|
|
793
|
+
if (isNumber(data) || isBoolean(data) || isFunction(data)) return String(data);
|
|
794
|
+
if (Array.isArray(data)) return `[${data.map((item) => stringify(item)).join(", ")}]`;
|
|
795
|
+
const entries$1 = Object.entries(data);
|
|
796
|
+
let result = "";
|
|
797
|
+
for (const [index, [key, value]] of entries$1.entries()) {
|
|
748
798
|
const strValue = stringify(value);
|
|
749
|
-
if (
|
|
750
|
-
if (!index)
|
|
751
|
-
if (
|
|
752
|
-
|
|
753
|
-
}
|
|
799
|
+
if (entries$1.length === 1) result = `{ ${key}: ${strValue}, }`;
|
|
800
|
+
else if (!index) result = `{ ${key}: ${strValue}, `;
|
|
801
|
+
else if (entries$1.length - 1 === index) result += `${key}: ${strValue}, }`;
|
|
802
|
+
else result += `${key}: ${strValue}, `;
|
|
803
|
+
}
|
|
804
|
+
return result;
|
|
754
805
|
}
|
|
755
806
|
/**
|
|
756
807
|
* Sanitizes a string value by removing or replacing special characters and ensuring
|
|
@@ -774,7 +825,7 @@ function stringify(data) {
|
|
|
774
825
|
function sanitize(value, options) {
|
|
775
826
|
const { whitespace = "", underscore = "", dot = "", dash = "", es5keyword = false, es5IdentifierName = false, special = false } = options ?? {};
|
|
776
827
|
let newValue = value;
|
|
777
|
-
if (!special) newValue = newValue.replaceAll(/[!"`'#%&,:;<>=@{}
|
|
828
|
+
if (!special) newValue = newValue.replaceAll(/[!"`'#%&,:;<>=@{}~$()*+/\\?[\]^|]/g, "");
|
|
778
829
|
if (whitespace !== true) newValue = newValue.replaceAll(/[\s]/g, whitespace);
|
|
779
830
|
if (underscore !== true) newValue = newValue.replaceAll(/['_']/g, underscore);
|
|
780
831
|
if (dot !== true) newValue = newValue.replaceAll(/[.]/g, dot);
|
|
@@ -799,7 +850,11 @@ function sanitize(value, options) {
|
|
|
799
850
|
*/
|
|
800
851
|
function toObjectString(props, path$2) {
|
|
801
852
|
if (props.length === 0) return "";
|
|
802
|
-
return (
|
|
853
|
+
return (isString(path$2) ? props.map((prop$1) => {
|
|
854
|
+
let obj = prop$1;
|
|
855
|
+
for (const key of path$2.split(".")) obj = obj && (isObject(obj) || Array.isArray(obj)) ? obj[key] : void 0;
|
|
856
|
+
return obj;
|
|
857
|
+
}) : props).join(",\n ") + ",";
|
|
803
858
|
}
|
|
804
859
|
const NUMBERS = {
|
|
805
860
|
"0": "zero",
|
|
@@ -823,7 +878,7 @@ const NUMBERS = {
|
|
|
823
878
|
* getNumberWord(42) // returns "fourtwo"
|
|
824
879
|
*/
|
|
825
880
|
function getNumberWord(num) {
|
|
826
|
-
return num.toString().
|
|
881
|
+
return [...num.toString()].reduce((acc, n) => acc + NUMBERS[n], "");
|
|
827
882
|
}
|
|
828
883
|
/**
|
|
829
884
|
* Escapes a specific character in a string by prefixing it with a backslash.
|
|
@@ -917,8 +972,7 @@ function getEnumDescriptions(schemaObject) {
|
|
|
917
972
|
function getEnum(value, enumName, names, enumGenerationType, descriptions, enumNamingConvention) {
|
|
918
973
|
if (enumGenerationType === EnumGeneration.CONST) return getTypeConstEnum(value, enumName, names, descriptions, enumNamingConvention);
|
|
919
974
|
if (enumGenerationType === EnumGeneration.ENUM) return getNativeEnum(value, enumName, names, enumNamingConvention);
|
|
920
|
-
|
|
921
|
-
throw new Error(`Invalid enumGenerationType: ${enumGenerationType}`);
|
|
975
|
+
return getUnion(value, enumName);
|
|
922
976
|
}
|
|
923
977
|
const getTypeConstEnum = (value, enumName, names, descriptions, enumNamingConvention) => {
|
|
924
978
|
let enumValue = `export type ${enumName} = typeof ${enumName}[keyof typeof ${enumName}]`;
|
|
@@ -934,11 +988,16 @@ const getTypeConstEnum = (value, enumName, names, descriptions, enumNamingConven
|
|
|
934
988
|
};
|
|
935
989
|
function getEnumImplementation(value, names, descriptions, enumNamingConvention) {
|
|
936
990
|
if (value === "") return "";
|
|
937
|
-
|
|
991
|
+
const uniqueValues = [...new Set(value.split(" | "))];
|
|
992
|
+
let result = "";
|
|
993
|
+
for (const [index, val] of uniqueValues.entries()) {
|
|
938
994
|
const name = names?.[index];
|
|
939
995
|
const description = descriptions?.[index];
|
|
940
996
|
const comment = description ? ` /** ${description} */\n` : "";
|
|
941
|
-
if (name)
|
|
997
|
+
if (name) {
|
|
998
|
+
result += comment + ` ${keyword.isIdentifierNameES5(name) ? name : `'${name}'`}: ${val},\n`;
|
|
999
|
+
continue;
|
|
1000
|
+
}
|
|
942
1001
|
let key = val.startsWith("'") ? val.slice(1, -1) : val;
|
|
943
1002
|
if (isNumeric(key)) key = toNumberKey(key);
|
|
944
1003
|
if (key.length > 1) key = sanitize(key, {
|
|
@@ -948,17 +1007,23 @@ function getEnumImplementation(value, names, descriptions, enumNamingConvention)
|
|
|
948
1007
|
special: true
|
|
949
1008
|
});
|
|
950
1009
|
if (enumNamingConvention) key = conventionName(key, enumNamingConvention);
|
|
951
|
-
|
|
952
|
-
}
|
|
1010
|
+
result += comment + ` ${keyword.isIdentifierNameES5(key) ? key : `'${key}'`}: ${val},\n`;
|
|
1011
|
+
}
|
|
1012
|
+
return result;
|
|
953
1013
|
}
|
|
954
1014
|
const getNativeEnum = (value, enumName, names, enumNamingConvention) => {
|
|
955
1015
|
return `export enum ${enumName} {\n${getNativeEnumItems(value, names, enumNamingConvention)}\n}`;
|
|
956
1016
|
};
|
|
957
1017
|
const getNativeEnumItems = (value, names, enumNamingConvention) => {
|
|
958
1018
|
if (value === "") return "";
|
|
959
|
-
|
|
1019
|
+
const uniqueValues = [...new Set(value.split(" | "))];
|
|
1020
|
+
let result = "";
|
|
1021
|
+
for (const [index, val] of uniqueValues.entries()) {
|
|
960
1022
|
const name = names?.[index];
|
|
961
|
-
if (name)
|
|
1023
|
+
if (name) {
|
|
1024
|
+
result += ` ${keyword.isIdentifierNameES5(name) ? name : `'${name}'`}= ${val},\n`;
|
|
1025
|
+
continue;
|
|
1026
|
+
}
|
|
962
1027
|
let key = val.startsWith("'") ? val.slice(1, -1) : val;
|
|
963
1028
|
if (isNumeric(key)) key = toNumberKey(key);
|
|
964
1029
|
if (key.length > 1) key = sanitize(key, {
|
|
@@ -968,8 +1033,9 @@ const getNativeEnumItems = (value, names, enumNamingConvention) => {
|
|
|
968
1033
|
special: true
|
|
969
1034
|
});
|
|
970
1035
|
if (enumNamingConvention) key = conventionName(key, enumNamingConvention);
|
|
971
|
-
|
|
972
|
-
}
|
|
1036
|
+
result += ` ${keyword.isIdentifierNameES5(key) ? key : `'${key}'`}= ${val},\n`;
|
|
1037
|
+
}
|
|
1038
|
+
return result;
|
|
973
1039
|
};
|
|
974
1040
|
const toNumberKey = (value) => {
|
|
975
1041
|
if (value.startsWith("-")) return `NUMBER_MINUS_${value.slice(1)}`;
|
|
@@ -981,9 +1047,9 @@ const getUnion = (value, enumName) => {
|
|
|
981
1047
|
};
|
|
982
1048
|
function getEnumUnionFromSchema(schema) {
|
|
983
1049
|
if (!schema?.enum) return "";
|
|
984
|
-
return schema.enum.filter((val) => val !== null).map((val) => isString(val) ? `'${escape(val)}'` :
|
|
1050
|
+
return schema.enum.filter((val) => val !== null).map((val) => isString(val) ? `'${escape(val)}'` : String(val)).join(" | ");
|
|
985
1051
|
}
|
|
986
|
-
const stripNullUnion = (value) => value.
|
|
1052
|
+
const stripNullUnion = (value) => value.replaceAll(/\s*\|\s*null/g, "").trim();
|
|
987
1053
|
const isSpreadableEnumRef = (schema, refName) => {
|
|
988
1054
|
if (!schema?.enum || !refName) return false;
|
|
989
1055
|
if (!getEnumUnionFromSchema(schema)) return false;
|
|
@@ -1129,17 +1195,23 @@ function getSchema$1(schema, context) {
|
|
|
1129
1195
|
const refInfo = getRefInfo(schema.$ref, context);
|
|
1130
1196
|
const { refPaths } = refInfo;
|
|
1131
1197
|
let schemaByRefPaths = Array.isArray(refPaths) ? prop(context.spec, ...refPaths) : void 0;
|
|
1132
|
-
|
|
1198
|
+
schemaByRefPaths ??= context.spec;
|
|
1133
1199
|
if (isReference(schemaByRefPaths)) return getSchema$1(schemaByRefPaths, context);
|
|
1134
|
-
let currentSchema = schemaByRefPaths
|
|
1135
|
-
if ("nullable" in schema)
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1200
|
+
let currentSchema = schemaByRefPaths || context.spec;
|
|
1201
|
+
if ("nullable" in schema) {
|
|
1202
|
+
const nullable = schema.nullable;
|
|
1203
|
+
currentSchema = {
|
|
1204
|
+
...currentSchema,
|
|
1205
|
+
nullable
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1208
|
+
if ("type" in schema && Array.isArray(schema.type)) {
|
|
1209
|
+
const type = schema.type;
|
|
1210
|
+
currentSchema = {
|
|
1211
|
+
...currentSchema,
|
|
1212
|
+
type
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1143
1215
|
return {
|
|
1144
1216
|
currentSchema,
|
|
1145
1217
|
refInfo
|
|
@@ -1153,14 +1225,11 @@ function resolveExampleRefs(examples, context) {
|
|
|
1153
1225
|
return schema.value;
|
|
1154
1226
|
}
|
|
1155
1227
|
return example;
|
|
1156
|
-
}) :
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
return
|
|
1160
|
-
|
|
1161
|
-
[key]: schema
|
|
1162
|
-
};
|
|
1163
|
-
}, {});
|
|
1228
|
+
}) : (() => {
|
|
1229
|
+
const result = {};
|
|
1230
|
+
for (const [key, example] of Object.entries(examples)) result[key] = isReference(example) ? resolveRef(example, context).schema.value : example;
|
|
1231
|
+
return result;
|
|
1232
|
+
})();
|
|
1164
1233
|
}
|
|
1165
1234
|
|
|
1166
1235
|
//#endregion
|
|
@@ -1179,7 +1248,8 @@ function resolveValue({ schema, name, context, formDataContext }) {
|
|
|
1179
1248
|
parents: [...context.parents ?? [], refName]
|
|
1180
1249
|
}
|
|
1181
1250
|
}).hasReadonlyProps;
|
|
1182
|
-
const
|
|
1251
|
+
const isAnyOfNullable = schemaObject.anyOf?.some((anyOfItem) => !isReference(anyOfItem) && (anyOfItem.type === "null" || Array.isArray(anyOfItem.type) && anyOfItem.type.includes("null")));
|
|
1252
|
+
const nullable = Array.isArray(schemaObject.type) && schemaObject.type.includes("null") || schemaObject.nullable === true || isAnyOfNullable ? " | null" : "";
|
|
1183
1253
|
return {
|
|
1184
1254
|
value: resolvedImport.name + nullable,
|
|
1185
1255
|
imports: [{
|
|
@@ -1216,7 +1286,7 @@ function resolveValue({ schema, name, context, formDataContext }) {
|
|
|
1216
1286
|
function createTypeAliasIfNeeded({ resolvedValue, propName, context }) {
|
|
1217
1287
|
if (!propName) return;
|
|
1218
1288
|
if (resolvedValue.isEnum || resolvedValue.type !== "object") return;
|
|
1219
|
-
const aliasPattern = context.output.override.aliasCombinedTypes ?
|
|
1289
|
+
const aliasPattern = context.output.override.aliasCombinedTypes ? String.raw`{|&|\|` : "{";
|
|
1220
1290
|
if (!new RegExp(aliasPattern).test(resolvedValue.value)) return;
|
|
1221
1291
|
const { originalSchema } = resolvedValue;
|
|
1222
1292
|
const doc = jsDoc(originalSchema);
|
|
@@ -1259,8 +1329,8 @@ function resolveObjectOriginal({ schema, propName, combined = false, context, fo
|
|
|
1259
1329
|
originalSchema: resolvedValue.originalSchema
|
|
1260
1330
|
};
|
|
1261
1331
|
if (propName && resolvedValue.isEnum && !combined && !resolvedValue.isRef) {
|
|
1262
|
-
const doc = jsDoc(resolvedValue.originalSchema
|
|
1263
|
-
const enumValue = getEnum(resolvedValue.value, propName, getEnumNames(resolvedValue.originalSchema), context.output.override.enumGenerationType, getEnumDescriptions(resolvedValue.originalSchema), context.output.override.namingConvention
|
|
1332
|
+
const doc = jsDoc(resolvedValue.originalSchema);
|
|
1333
|
+
const enumValue = getEnum(resolvedValue.value, propName, getEnumNames(resolvedValue.originalSchema), context.output.override.enumGenerationType, getEnumDescriptions(resolvedValue.originalSchema), context.output.override.namingConvention.enum);
|
|
1264
1334
|
return {
|
|
1265
1335
|
value: propName,
|
|
1266
1336
|
imports: [{ name: propName }],
|
|
@@ -1309,17 +1379,20 @@ function resolveObject({ schema, propName, combined = false, context, formDataCo
|
|
|
1309
1379
|
* @param item item with type === "array"
|
|
1310
1380
|
*/
|
|
1311
1381
|
function getArray({ schema, name, context, formDataContext }) {
|
|
1312
|
-
const
|
|
1382
|
+
const schemaPrefixItems = schema.prefixItems;
|
|
1383
|
+
const schemaItems = schema.items;
|
|
1384
|
+
const schemaExample = schema.example;
|
|
1385
|
+
const schemaExamples = schema.examples;
|
|
1313
1386
|
const itemSuffix = context.output.override.components.schemas.itemSuffix;
|
|
1314
|
-
if (
|
|
1315
|
-
const resolvedObjects =
|
|
1387
|
+
if (schemaPrefixItems) {
|
|
1388
|
+
const resolvedObjects = schemaPrefixItems.map((item, index) => resolveObject({
|
|
1316
1389
|
schema: item,
|
|
1317
|
-
propName: name ? name + itemSuffix + index : void 0,
|
|
1390
|
+
propName: name ? name + itemSuffix + String(index) : void 0,
|
|
1318
1391
|
context
|
|
1319
1392
|
}));
|
|
1320
|
-
if (
|
|
1393
|
+
if (schemaItems) {
|
|
1321
1394
|
const additional = resolveObject({
|
|
1322
|
-
schema:
|
|
1395
|
+
schema: schemaItems,
|
|
1323
1396
|
propName: name ? name + itemSuffix + "Additional" : void 0,
|
|
1324
1397
|
context
|
|
1325
1398
|
});
|
|
@@ -1337,13 +1410,13 @@ function getArray({ schema, name, context, formDataContext }) {
|
|
|
1337
1410
|
schemas: resolvedObjects.flatMap((o) => o.schemas),
|
|
1338
1411
|
dependencies: resolvedObjects.flatMap((o) => o.dependencies),
|
|
1339
1412
|
hasReadonlyProps: resolvedObjects.some((o) => o.hasReadonlyProps),
|
|
1340
|
-
example:
|
|
1341
|
-
examples: resolveExampleRefs(
|
|
1413
|
+
example: schemaExample,
|
|
1414
|
+
examples: resolveExampleRefs(schemaExamples, context)
|
|
1342
1415
|
};
|
|
1343
1416
|
}
|
|
1344
|
-
if (
|
|
1417
|
+
if (schemaItems) {
|
|
1345
1418
|
const resolvedObject = resolveObject({
|
|
1346
|
-
schema:
|
|
1419
|
+
schema: schemaItems,
|
|
1347
1420
|
propName: name ? name + itemSuffix : void 0,
|
|
1348
1421
|
context,
|
|
1349
1422
|
formDataContext
|
|
@@ -1357,8 +1430,8 @@ function getArray({ schema, name, context, formDataContext }) {
|
|
|
1357
1430
|
type: "array",
|
|
1358
1431
|
isRef: false,
|
|
1359
1432
|
hasReadonlyProps: resolvedObject.hasReadonlyProps,
|
|
1360
|
-
example:
|
|
1361
|
-
examples: resolveExampleRefs(
|
|
1433
|
+
example: schemaExample,
|
|
1434
|
+
examples: resolveExampleRefs(schemaExamples, context)
|
|
1362
1435
|
};
|
|
1363
1436
|
} else if (compareVersions(context.spec.openapi, "3.1", ">=")) return {
|
|
1364
1437
|
value: "unknown[]",
|
|
@@ -1375,6 +1448,13 @@ function getArray({ schema, name, context, formDataContext }) {
|
|
|
1375
1448
|
|
|
1376
1449
|
//#endregion
|
|
1377
1450
|
//#region src/getters/res-req-types.ts
|
|
1451
|
+
const getSchemaType = (s) => s.type;
|
|
1452
|
+
const getSchemaCombined = (s) => s.oneOf ?? s.anyOf ?? s.allOf;
|
|
1453
|
+
const getSchemaOneOf = (s) => s.oneOf;
|
|
1454
|
+
const getSchemaAnyOf = (s) => s.anyOf;
|
|
1455
|
+
const getSchemaItems = (s) => s.items;
|
|
1456
|
+
const getSchemaRequired = (s) => s.required;
|
|
1457
|
+
const getSchemaProperties = (s) => s.properties;
|
|
1378
1458
|
const formDataContentTypes = new Set(["multipart/form-data"]);
|
|
1379
1459
|
const formUrlEncodedContentTypes = new Set(["application/x-www-form-urlencoded"]);
|
|
1380
1460
|
function getResReqContentTypes({ mediaType, propName, context, isFormData, contentType }) {
|
|
@@ -1396,10 +1476,28 @@ function getResReqContentTypes({ mediaType, propName, context, isFormData, conte
|
|
|
1396
1476
|
return resolvedObject;
|
|
1397
1477
|
}
|
|
1398
1478
|
function getResReqTypes(responsesOrRequests, name, context, defaultType = "unknown", uniqueKey = (item) => item.value) {
|
|
1399
|
-
return uniqueBy(responsesOrRequests.filter(([
|
|
1479
|
+
return uniqueBy(responsesOrRequests.filter(([, res]) => Boolean(res)).map(([key, res]) => {
|
|
1400
1480
|
if (isReference(res)) {
|
|
1401
1481
|
const { schema: bodySchema, imports: [{ name: name$1, schemaName }] } = resolveRef(res, context);
|
|
1402
|
-
const
|
|
1482
|
+
const firstEntry = Object.entries(bodySchema.content ?? {}).at(0);
|
|
1483
|
+
if (!firstEntry) return [{
|
|
1484
|
+
value: name$1,
|
|
1485
|
+
imports: [{
|
|
1486
|
+
name: name$1,
|
|
1487
|
+
schemaName
|
|
1488
|
+
}],
|
|
1489
|
+
schemas: [],
|
|
1490
|
+
type: "unknown",
|
|
1491
|
+
isEnum: false,
|
|
1492
|
+
isRef: true,
|
|
1493
|
+
hasReadonlyProps: false,
|
|
1494
|
+
originalSchema: void 0,
|
|
1495
|
+
example: void 0,
|
|
1496
|
+
examples: void 0,
|
|
1497
|
+
key,
|
|
1498
|
+
contentType: void 0
|
|
1499
|
+
}];
|
|
1500
|
+
const [contentType, mediaType] = firstEntry;
|
|
1403
1501
|
const isFormData = formDataContentTypes.has(contentType);
|
|
1404
1502
|
const isFormUrlEncoded = formUrlEncodedContentTypes.has(contentType);
|
|
1405
1503
|
if (!isFormData && !isFormUrlEncoded || !mediaType.schema) return [{
|
|
@@ -1413,9 +1511,9 @@ function getResReqTypes(responsesOrRequests, name, context, defaultType = "unkno
|
|
|
1413
1511
|
isEnum: false,
|
|
1414
1512
|
isRef: true,
|
|
1415
1513
|
hasReadonlyProps: false,
|
|
1416
|
-
originalSchema: mediaType
|
|
1417
|
-
example: mediaType
|
|
1418
|
-
examples: resolveExampleRefs(mediaType
|
|
1514
|
+
originalSchema: mediaType.schema,
|
|
1515
|
+
example: mediaType.example,
|
|
1516
|
+
examples: resolveExampleRefs(mediaType.examples, context),
|
|
1419
1517
|
key,
|
|
1420
1518
|
contentType
|
|
1421
1519
|
}];
|
|
@@ -1491,7 +1589,7 @@ function getResReqTypes(responsesOrRequests, name, context, defaultType = "unkno
|
|
|
1491
1589
|
return;
|
|
1492
1590
|
}
|
|
1493
1591
|
const isFormUrlEncoded = formUrlEncodedContentTypes.has(contentType);
|
|
1494
|
-
if (!isFormData && !isFormUrlEncoded || !effectivePropName) return {
|
|
1592
|
+
if (!isFormData && !isFormUrlEncoded || !effectivePropName || !mediaType.schema) return {
|
|
1495
1593
|
...resolvedValue,
|
|
1496
1594
|
imports: resolvedValue.imports,
|
|
1497
1595
|
contentType,
|
|
@@ -1556,6 +1654,17 @@ function getResReqTypes(responsesOrRequests, name, context, defaultType = "unkno
|
|
|
1556
1654
|
}).flat(), uniqueKey);
|
|
1557
1655
|
}
|
|
1558
1656
|
/**
|
|
1657
|
+
* Determine the responseType option based on success content types only.
|
|
1658
|
+
* This avoids error-response content types influencing the responseType.
|
|
1659
|
+
*/
|
|
1660
|
+
function getSuccessResponseType(response) {
|
|
1661
|
+
const successContentTypes = response.types.success.map((t) => t.contentType).filter(Boolean);
|
|
1662
|
+
if (response.isBlob) return "blob";
|
|
1663
|
+
const hasJsonResponse = successContentTypes.some((contentType) => contentType.includes("json") || contentType.includes("+json"));
|
|
1664
|
+
const hasTextResponse = successContentTypes.some((contentType) => contentType.startsWith("text/") || contentType.includes("xml"));
|
|
1665
|
+
if (!hasJsonResponse && hasTextResponse) return "text";
|
|
1666
|
+
}
|
|
1667
|
+
/**
|
|
1559
1668
|
* Determine the response type category for a given content type.
|
|
1560
1669
|
* Used to set the correct responseType option in HTTP clients.
|
|
1561
1670
|
*
|
|
@@ -1584,9 +1693,9 @@ function getDefaultContentType(contentTypes) {
|
|
|
1584
1693
|
function getFormDataAdditionalImports({ schemaObject, context }) {
|
|
1585
1694
|
const { schema } = resolveRef(schemaObject, context);
|
|
1586
1695
|
if (schema.type !== "object") return [];
|
|
1587
|
-
const combinedSchemas = schema
|
|
1696
|
+
const combinedSchemas = getSchemaOneOf(schema) ?? getSchemaAnyOf(schema);
|
|
1588
1697
|
if (!combinedSchemas) return [];
|
|
1589
|
-
return combinedSchemas.map((
|
|
1698
|
+
return combinedSchemas.map((subSchema) => resolveRef(subSchema, context).imports[0]).filter(Boolean);
|
|
1590
1699
|
}
|
|
1591
1700
|
function getSchemaFormDataAndUrlEncoded({ name, schemaObject, context, isRequestBodyOptional, isUrlEncoded, isRef, encoding }) {
|
|
1592
1701
|
const { schema, imports } = resolveRef(schemaObject, context);
|
|
@@ -1594,12 +1703,12 @@ function getSchemaFormDataAndUrlEncoded({ name, schemaObject, context, isRequest
|
|
|
1594
1703
|
const additionalImports = [];
|
|
1595
1704
|
const variableName = isUrlEncoded ? "formUrlEncoded" : "formData";
|
|
1596
1705
|
let form = isUrlEncoded ? `const ${variableName} = new URLSearchParams();\n` : `const ${variableName} = new FormData();\n`;
|
|
1597
|
-
const combinedSchemas = schema
|
|
1706
|
+
const combinedSchemas = getSchemaCombined(schema);
|
|
1598
1707
|
if (schema.type === "object" || schema.type === void 0 && combinedSchemas) {
|
|
1599
1708
|
if (combinedSchemas) {
|
|
1600
|
-
const shouldCast = !!schema
|
|
1601
|
-
const combinedSchemasFormData = combinedSchemas.map((
|
|
1602
|
-
const { schema: combinedSchema, imports: imports$1 } = resolveRef(
|
|
1709
|
+
const shouldCast = !!getSchemaOneOf(schema) || !!getSchemaAnyOf(schema);
|
|
1710
|
+
const combinedSchemasFormData = combinedSchemas.map((subSchema) => {
|
|
1711
|
+
const { schema: combinedSchema, imports: imports$1 } = resolveRef(subSchema, context);
|
|
1603
1712
|
let newPropName = propName;
|
|
1604
1713
|
let newPropDefinition = "";
|
|
1605
1714
|
if (shouldCast && imports$1[0]) {
|
|
@@ -1633,8 +1742,9 @@ function getSchemaFormDataAndUrlEncoded({ name, schemaObject, context, isRequest
|
|
|
1633
1742
|
}
|
|
1634
1743
|
if (schema.type === "array") {
|
|
1635
1744
|
let valueStr = "value";
|
|
1636
|
-
|
|
1637
|
-
|
|
1745
|
+
const schemaItems = getSchemaItems(schema);
|
|
1746
|
+
if (schemaItems) {
|
|
1747
|
+
const { schema: itemSchema } = resolveRef(schemaItems, context);
|
|
1638
1748
|
if (itemSchema.type === "object" || itemSchema.type === "array") valueStr = "JSON.stringify(value)";
|
|
1639
1749
|
else if (itemSchema.type === "number" || itemSchema.type === "integer" || itemSchema.type === "boolean") valueStr = "value.toString()";
|
|
1640
1750
|
}
|
|
@@ -1644,9 +1754,11 @@ function getSchemaFormDataAndUrlEncoded({ name, schemaObject, context, isRequest
|
|
|
1644
1754
|
return `${form}${variableName}.append('data', ${propName})\n`;
|
|
1645
1755
|
}
|
|
1646
1756
|
function resolveSchemaPropertiesToFormData({ schema, variableName, propName, context, isRequestBodyOptional, keyPrefix = "", depth = 0, encoding }) {
|
|
1647
|
-
|
|
1757
|
+
let formDataValues = "";
|
|
1758
|
+
const schemaProps = getSchemaProperties(schema) ?? {};
|
|
1759
|
+
for (const [key, value] of Object.entries(schemaProps)) {
|
|
1648
1760
|
const { schema: property } = resolveRef(value, context);
|
|
1649
|
-
if (property.readOnly)
|
|
1761
|
+
if (property.readOnly) continue;
|
|
1650
1762
|
let formDataValue = "";
|
|
1651
1763
|
const partContentType = (depth === 0 ? encoding?.[key] : void 0)?.contentType;
|
|
1652
1764
|
const formattedKeyPrefix = isRequestBodyOptional ? keyword.isIdentifierNameES5(key) ? "?" : "?." : "";
|
|
@@ -1670,8 +1782,9 @@ function resolveSchemaPropertiesToFormData({ schema, variableName, propName, con
|
|
|
1670
1782
|
else if (property.type === "array") {
|
|
1671
1783
|
let valueStr = "value";
|
|
1672
1784
|
let hasNonPrimitiveChild = false;
|
|
1673
|
-
|
|
1674
|
-
|
|
1785
|
+
const propertyItems = getSchemaItems(property);
|
|
1786
|
+
if (propertyItems) {
|
|
1787
|
+
const { schema: itemSchema } = resolveRef(propertyItems, context);
|
|
1675
1788
|
if (itemSchema.type === "object" || itemSchema.type === "array") if (context.output.override.formData.arrayHandling === FormDataArrayHandling.EXPLODE) {
|
|
1676
1789
|
hasNonPrimitiveChild = true;
|
|
1677
1790
|
const resolvedValue = resolveSchemaPropertiesToFormData({
|
|
@@ -1686,52 +1799,69 @@ function resolveSchemaPropertiesToFormData({ schema, variableName, propName, con
|
|
|
1686
1799
|
formDataValue = `${valueKey}.forEach((value, index${depth > 0 ? depth : ""}) => {
|
|
1687
1800
|
${resolvedValue}});\n`;
|
|
1688
1801
|
} else valueStr = "JSON.stringify(value)";
|
|
1689
|
-
else
|
|
1802
|
+
else {
|
|
1803
|
+
const itemType = getSchemaType(itemSchema);
|
|
1804
|
+
if (itemType === "number" || Array.isArray(itemType) && itemType.includes("number") || itemType === "integer" || Array.isArray(itemType) && itemType.includes("integer") || itemType === "boolean" || Array.isArray(itemType) && itemType.includes("boolean")) valueStr = "value.toString()";
|
|
1805
|
+
}
|
|
1690
1806
|
}
|
|
1691
1807
|
if (context.output.override.formData.arrayHandling === FormDataArrayHandling.EXPLODE) {
|
|
1692
1808
|
if (!hasNonPrimitiveChild) formDataValue = `${valueKey}.forEach((value, index${depth > 0 ? depth : ""}) => ${variableName}.append(\`${keyPrefix}${key}[\${index${depth > 0 ? depth : ""}}]\`, ${valueStr}));\n`;
|
|
1693
1809
|
} else formDataValue = `${valueKey}.forEach(value => ${variableName}.append(\`${keyPrefix}${key}${context.output.override.formData.arrayHandling === FormDataArrayHandling.SERIALIZE_WITH_BRACKETS ? "[]" : ""}\`, ${valueStr}));\n`;
|
|
1694
|
-
} else if (
|
|
1810
|
+
} else if ((() => {
|
|
1811
|
+
const propType$1 = getSchemaType(property);
|
|
1812
|
+
return propType$1 === "number" || Array.isArray(propType$1) && propType$1.includes("number") || propType$1 === "integer" || Array.isArray(propType$1) && propType$1.includes("integer") || propType$1 === "boolean" || Array.isArray(propType$1) && propType$1.includes("boolean");
|
|
1813
|
+
})()) formDataValue = `${variableName}.append(\`${keyPrefix}${key}\`, ${nonOptionalValueKey}.toString())\n`;
|
|
1695
1814
|
else formDataValue = `${variableName}.append(\`${keyPrefix}${key}\`, ${nonOptionalValueKey});\n`;
|
|
1696
1815
|
let existSubSchemaNullable = false;
|
|
1697
|
-
|
|
1698
|
-
|
|
1816
|
+
const combine = getSchemaCombined(property);
|
|
1817
|
+
if (combine) {
|
|
1818
|
+
const subSchemas = combine.map((c) => resolveObject({
|
|
1699
1819
|
schema: c,
|
|
1700
1820
|
combined: true,
|
|
1701
1821
|
context
|
|
1702
1822
|
}));
|
|
1703
|
-
if (subSchemas
|
|
1823
|
+
if (subSchemas.some((subSchema) => {
|
|
1704
1824
|
return [
|
|
1705
1825
|
"number",
|
|
1706
1826
|
"integer",
|
|
1707
1827
|
"boolean"
|
|
1708
1828
|
].includes(subSchema.type);
|
|
1709
1829
|
})) formDataValue = `${variableName}.append(\`${key}\`, ${nonOptionalValueKey}.toString())\n`;
|
|
1710
|
-
if (subSchemas
|
|
1830
|
+
if (subSchemas.some((subSchema) => {
|
|
1711
1831
|
return subSchema.type === "null";
|
|
1712
1832
|
})) existSubSchemaNullable = true;
|
|
1713
1833
|
}
|
|
1714
|
-
const isRequired = schema
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1834
|
+
const isRequired = getSchemaRequired(schema)?.includes(key) && !isRequestBodyOptional;
|
|
1835
|
+
const propType = getSchemaType(property);
|
|
1836
|
+
if (property.nullable || Array.isArray(propType) && propType.includes("null") || existSubSchemaNullable) {
|
|
1837
|
+
if (isRequired) {
|
|
1838
|
+
formDataValues += `if(${valueKey} !== null) {\n ${formDataValue} }\n`;
|
|
1839
|
+
continue;
|
|
1840
|
+
}
|
|
1841
|
+
formDataValues += `if(${valueKey} !== undefined && ${nonOptionalValueKey} !== null) {\n ${formDataValue} }\n`;
|
|
1842
|
+
continue;
|
|
1843
|
+
}
|
|
1844
|
+
if (isRequired) {
|
|
1845
|
+
formDataValues += formDataValue;
|
|
1846
|
+
continue;
|
|
1718
1847
|
}
|
|
1719
|
-
if
|
|
1720
|
-
|
|
1721
|
-
|
|
1848
|
+
formDataValues += `if(${valueKey} !== undefined) {\n ${formDataValue} }\n`;
|
|
1849
|
+
}
|
|
1850
|
+
return formDataValues;
|
|
1722
1851
|
}
|
|
1723
1852
|
|
|
1724
1853
|
//#endregion
|
|
1725
1854
|
//#region src/getters/body.ts
|
|
1855
|
+
/**
|
|
1856
|
+
* Extract all content types from a requestBody (#2812)
|
|
1857
|
+
*/
|
|
1858
|
+
function getRequestBodyContentTypes(requestBody, context) {
|
|
1859
|
+
if (!requestBody) return [];
|
|
1860
|
+
const content = (isReference(requestBody) ? resolveRef(requestBody, context).schema : requestBody).content;
|
|
1861
|
+
return content ? Object.keys(content) : [];
|
|
1862
|
+
}
|
|
1726
1863
|
function getBody({ requestBody, operationName, context, contentType }) {
|
|
1727
|
-
const
|
|
1728
|
-
const filteredBodyTypes = contentType ? allBodyTypes.filter((type) => {
|
|
1729
|
-
let include = true;
|
|
1730
|
-
let exclude = false;
|
|
1731
|
-
if (contentType.include) include = contentType.include.includes(type.contentType);
|
|
1732
|
-
if (contentType.exclude) exclude = contentType.exclude.includes(type.contentType);
|
|
1733
|
-
return include && !exclude;
|
|
1734
|
-
}) : allBodyTypes;
|
|
1864
|
+
const filteredBodyTypes = filterByContentType(getResReqTypes([[context.output.override.components.requestBodies.suffix, requestBody]], operationName, context), contentType);
|
|
1735
1865
|
const imports = filteredBodyTypes.flatMap(({ imports: imports$1 }) => imports$1);
|
|
1736
1866
|
const schemas = filteredBodyTypes.flatMap(({ schemas: schemas$1 }) => schemas$1);
|
|
1737
1867
|
const definition = filteredBodyTypes.map(({ value }) => value).join(" | ");
|
|
@@ -1805,7 +1935,10 @@ function getKey(key) {
|
|
|
1805
1935
|
* Returns undefined if propertyNames doesn't have an enum
|
|
1806
1936
|
*/
|
|
1807
1937
|
function getPropertyNamesEnum(item) {
|
|
1808
|
-
if ("propertyNames" in item && item.propertyNames && "enum" in item.propertyNames
|
|
1938
|
+
if ("propertyNames" in item && item.propertyNames && "enum" in item.propertyNames) {
|
|
1939
|
+
const propertyNames = item.propertyNames;
|
|
1940
|
+
if (Array.isArray(propertyNames.enum)) return propertyNames.enum.filter((val) => isString(val));
|
|
1941
|
+
}
|
|
1809
1942
|
}
|
|
1810
1943
|
/**
|
|
1811
1944
|
* Generate index signature key type based on propertyNames enum
|
|
@@ -1850,23 +1983,43 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
1850
1983
|
nullable,
|
|
1851
1984
|
formDataContext
|
|
1852
1985
|
});
|
|
1853
|
-
if (Array.isArray(item.type))
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1986
|
+
if (Array.isArray(item.type)) {
|
|
1987
|
+
const typeArray = item.type;
|
|
1988
|
+
const baseItem = item;
|
|
1989
|
+
return combineSchemas({
|
|
1990
|
+
schema: { anyOf: typeArray.map((type) => ({
|
|
1991
|
+
...baseItem,
|
|
1992
|
+
type
|
|
1993
|
+
})) },
|
|
1994
|
+
name,
|
|
1995
|
+
separator: "anyOf",
|
|
1996
|
+
context,
|
|
1997
|
+
nullable
|
|
1998
|
+
});
|
|
1999
|
+
}
|
|
2000
|
+
const itemProperties = item.properties;
|
|
2001
|
+
if (itemProperties && Object.entries(itemProperties).length > 0) {
|
|
2002
|
+
const entries$1 = Object.entries(itemProperties);
|
|
1865
2003
|
if (context.output.propertySortOrder === PropertySortOrder.ALPHABETICAL) entries$1.sort((a, b) => {
|
|
1866
2004
|
return a[0].localeCompare(b[0]);
|
|
1867
2005
|
});
|
|
1868
|
-
|
|
1869
|
-
|
|
2006
|
+
const acc = {
|
|
2007
|
+
imports: [],
|
|
2008
|
+
schemas: [],
|
|
2009
|
+
value: "",
|
|
2010
|
+
isEnum: false,
|
|
2011
|
+
type: "object",
|
|
2012
|
+
isRef: false,
|
|
2013
|
+
schema: {},
|
|
2014
|
+
hasReadonlyProps: false,
|
|
2015
|
+
useTypeAlias: false,
|
|
2016
|
+
dependencies: [],
|
|
2017
|
+
example: item.example,
|
|
2018
|
+
examples: resolveExampleRefs(item.examples, context)
|
|
2019
|
+
};
|
|
2020
|
+
const itemRequired = item.required;
|
|
2021
|
+
for (const [index, [key, schema]] of entries$1.entries()) {
|
|
2022
|
+
const isRequired = (Array.isArray(itemRequired) ? itemRequired : []).includes(key);
|
|
1870
2023
|
let propName = "";
|
|
1871
2024
|
if (name) {
|
|
1872
2025
|
const isKeyStartWithUnderscore = key.startsWith("_");
|
|
@@ -1884,16 +2037,16 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
1884
2037
|
context,
|
|
1885
2038
|
formDataContext: propertyFormDataContext
|
|
1886
2039
|
});
|
|
1887
|
-
const isReadOnly = item.readOnly
|
|
2040
|
+
const isReadOnly = item.readOnly ?? schema.readOnly;
|
|
1888
2041
|
if (!index) acc.value += "{";
|
|
1889
2042
|
const doc = jsDoc(schema, true, context);
|
|
1890
|
-
acc.hasReadonlyProps
|
|
1891
|
-
const constValue = "const" in schema ? schema.const : void 0;
|
|
1892
|
-
const hasConst = constValue !== void 0;
|
|
2043
|
+
if (isReadOnly ?? false) acc.hasReadonlyProps = true;
|
|
2044
|
+
const constValue$1 = "const" in schema ? schema.const : void 0;
|
|
2045
|
+
const hasConst = constValue$1 !== void 0;
|
|
1893
2046
|
let constLiteral;
|
|
1894
2047
|
if (!hasConst) constLiteral = void 0;
|
|
1895
|
-
else if (
|
|
1896
|
-
else constLiteral = JSON.stringify(constValue);
|
|
2048
|
+
else if (isString(constValue$1)) constLiteral = `'${escape(constValue$1)}'`;
|
|
2049
|
+
else constLiteral = JSON.stringify(constValue$1);
|
|
1897
2050
|
const needsValueImport = hasConst && (resolvedValue.isEnum || resolvedValue.type === "enum");
|
|
1898
2051
|
const aliasedImports = needsValueImport ? resolvedValue.imports.map((imp) => ({
|
|
1899
2052
|
...imp,
|
|
@@ -1914,8 +2067,9 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
1914
2067
|
acc.value += `\n ${doc ? `${doc} ` : ""}${isReadOnly && !context.output.override.suppressReadonlyModifier ? "readonly " : ""}${getKey(key)}${isRequired ? "" : "?"}: ${finalPropValue};`;
|
|
1915
2068
|
acc.schemas.push(...resolvedValue.schemas);
|
|
1916
2069
|
acc.dependencies.push(...resolvedValue.dependencies);
|
|
1917
|
-
if (
|
|
1918
|
-
|
|
2070
|
+
if (entries$1.length - 1 === index) {
|
|
2071
|
+
const additionalProps = item.additionalProperties;
|
|
2072
|
+
if (additionalProps) if (isBoolean(additionalProps)) {
|
|
1919
2073
|
const recordType$1 = getPropertyNamesRecordType(item, "unknown");
|
|
1920
2074
|
if (recordType$1) {
|
|
1921
2075
|
acc.value += "\n}";
|
|
@@ -1927,7 +2081,7 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
1927
2081
|
}
|
|
1928
2082
|
} else {
|
|
1929
2083
|
const resolvedValue$1 = resolveValue({
|
|
1930
|
-
schema:
|
|
2084
|
+
schema: additionalProps,
|
|
1931
2085
|
name,
|
|
1932
2086
|
context
|
|
1933
2087
|
});
|
|
@@ -1945,24 +2099,13 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
1945
2099
|
else acc.value += "\n}";
|
|
1946
2100
|
acc.value += nullable;
|
|
1947
2101
|
}
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
imports: [],
|
|
1951
|
-
schemas: [],
|
|
1952
|
-
value: "",
|
|
1953
|
-
isEnum: false,
|
|
1954
|
-
type: "object",
|
|
1955
|
-
isRef: false,
|
|
1956
|
-
schema: {},
|
|
1957
|
-
hasReadonlyProps: false,
|
|
1958
|
-
useTypeAlias: false,
|
|
1959
|
-
dependencies: [],
|
|
1960
|
-
example: item.example,
|
|
1961
|
-
examples: resolveExampleRefs(item.examples, context)
|
|
1962
|
-
});
|
|
2102
|
+
}
|
|
2103
|
+
return acc;
|
|
1963
2104
|
}
|
|
1964
|
-
|
|
1965
|
-
|
|
2105
|
+
const outerAdditionalProps = item.additionalProperties;
|
|
2106
|
+
const readOnlyFlag = item.readOnly;
|
|
2107
|
+
if (outerAdditionalProps) {
|
|
2108
|
+
if (isBoolean(outerAdditionalProps)) {
|
|
1966
2109
|
const recordType$2 = getPropertyNamesRecordType(item, "unknown");
|
|
1967
2110
|
if (recordType$2) return {
|
|
1968
2111
|
value: recordType$2 + nullable,
|
|
@@ -1971,7 +2114,7 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
1971
2114
|
isEnum: false,
|
|
1972
2115
|
type: "object",
|
|
1973
2116
|
isRef: false,
|
|
1974
|
-
hasReadonlyProps:
|
|
2117
|
+
hasReadonlyProps: readOnlyFlag ?? false,
|
|
1975
2118
|
useTypeAlias: true,
|
|
1976
2119
|
dependencies: []
|
|
1977
2120
|
};
|
|
@@ -1982,21 +2125,21 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
1982
2125
|
isEnum: false,
|
|
1983
2126
|
type: "object",
|
|
1984
2127
|
isRef: false,
|
|
1985
|
-
hasReadonlyProps:
|
|
2128
|
+
hasReadonlyProps: readOnlyFlag ?? false,
|
|
1986
2129
|
useTypeAlias: false,
|
|
1987
2130
|
dependencies: []
|
|
1988
2131
|
};
|
|
1989
2132
|
}
|
|
1990
2133
|
const resolvedValue = resolveValue({
|
|
1991
|
-
schema:
|
|
2134
|
+
schema: outerAdditionalProps,
|
|
1992
2135
|
name,
|
|
1993
2136
|
context
|
|
1994
2137
|
});
|
|
1995
2138
|
const recordType$1 = getPropertyNamesRecordType(item, resolvedValue.value);
|
|
1996
2139
|
if (recordType$1) return {
|
|
1997
2140
|
value: recordType$1 + nullable,
|
|
1998
|
-
imports: resolvedValue.imports
|
|
1999
|
-
schemas: resolvedValue.schemas
|
|
2141
|
+
imports: resolvedValue.imports,
|
|
2142
|
+
schemas: resolvedValue.schemas,
|
|
2000
2143
|
isEnum: false,
|
|
2001
2144
|
type: "object",
|
|
2002
2145
|
isRef: false,
|
|
@@ -2006,8 +2149,8 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2006
2149
|
};
|
|
2007
2150
|
return {
|
|
2008
2151
|
value: `{[key: ${getIndexSignatureKey(item)}]: ${resolvedValue.value}}` + nullable,
|
|
2009
|
-
imports: resolvedValue.imports
|
|
2010
|
-
schemas: resolvedValue.schemas
|
|
2152
|
+
imports: resolvedValue.imports,
|
|
2153
|
+
schemas: resolvedValue.schemas,
|
|
2011
2154
|
isEnum: false,
|
|
2012
2155
|
type: "object",
|
|
2013
2156
|
isRef: false,
|
|
@@ -2016,15 +2159,15 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2016
2159
|
dependencies: resolvedValue.dependencies
|
|
2017
2160
|
};
|
|
2018
2161
|
}
|
|
2019
|
-
const
|
|
2020
|
-
if (
|
|
2021
|
-
value: `'${
|
|
2162
|
+
const constValue = item.const;
|
|
2163
|
+
if (constValue) return {
|
|
2164
|
+
value: `'${constValue}'`,
|
|
2022
2165
|
imports: [],
|
|
2023
2166
|
schemas: [],
|
|
2024
2167
|
isEnum: false,
|
|
2025
2168
|
type: "string",
|
|
2026
2169
|
isRef: false,
|
|
2027
|
-
hasReadonlyProps:
|
|
2170
|
+
hasReadonlyProps: readOnlyFlag ?? false,
|
|
2028
2171
|
dependencies: []
|
|
2029
2172
|
};
|
|
2030
2173
|
const keyType = item.type === "object" ? getIndexSignatureKey(item) : "string";
|
|
@@ -2036,7 +2179,7 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2036
2179
|
isEnum: false,
|
|
2037
2180
|
type: "object",
|
|
2038
2181
|
isRef: false,
|
|
2039
|
-
hasReadonlyProps:
|
|
2182
|
+
hasReadonlyProps: readOnlyFlag ?? false,
|
|
2040
2183
|
useTypeAlias: true,
|
|
2041
2184
|
dependencies: []
|
|
2042
2185
|
};
|
|
@@ -2047,7 +2190,7 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2047
2190
|
isEnum: false,
|
|
2048
2191
|
type: "object",
|
|
2049
2192
|
isRef: false,
|
|
2050
|
-
hasReadonlyProps:
|
|
2193
|
+
hasReadonlyProps: readOnlyFlag ?? false,
|
|
2051
2194
|
useTypeAlias: false,
|
|
2052
2195
|
dependencies: []
|
|
2053
2196
|
};
|
|
@@ -2062,29 +2205,36 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2062
2205
|
* @ref https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.1.md#data-types
|
|
2063
2206
|
*/
|
|
2064
2207
|
function getScalar({ item, name, context, formDataContext }) {
|
|
2065
|
-
const
|
|
2066
|
-
const
|
|
2067
|
-
|
|
2208
|
+
const schemaEnum = item.enum;
|
|
2209
|
+
const schemaType = item.type;
|
|
2210
|
+
const schemaReadOnly = item.readOnly;
|
|
2211
|
+
const schemaExample = item.example;
|
|
2212
|
+
const schemaExamples = item.examples;
|
|
2213
|
+
const schemaConst = item.const;
|
|
2214
|
+
const schemaFormat = item.format;
|
|
2215
|
+
const schemaNullable = item.nullable;
|
|
2216
|
+
const nullable = isArray(schemaType) && schemaType.includes("null") || schemaNullable === true ? " | null" : "";
|
|
2217
|
+
const enumItems = schemaEnum?.filter((enumItem) => enumItem !== null);
|
|
2218
|
+
let itemType = schemaType;
|
|
2068
2219
|
if (!itemType && item.items) {
|
|
2069
2220
|
item.type = "array";
|
|
2070
2221
|
itemType = "array";
|
|
2071
2222
|
}
|
|
2072
|
-
if (isArray(
|
|
2073
|
-
const typesWithoutNull =
|
|
2223
|
+
if (isArray(schemaType) && schemaType.includes("null")) {
|
|
2224
|
+
const typesWithoutNull = schemaType.filter((x) => x !== "null");
|
|
2074
2225
|
itemType = typesWithoutNull.length === 1 ? typesWithoutNull[0] : typesWithoutNull;
|
|
2075
2226
|
}
|
|
2076
2227
|
switch (itemType) {
|
|
2077
2228
|
case "number":
|
|
2078
2229
|
case "integer": {
|
|
2079
|
-
let value = context.output.override.useBigInt && (
|
|
2230
|
+
let value = context.output.override.useBigInt && (schemaFormat === "int64" || schemaFormat === "uint64") ? "bigint" : "number";
|
|
2080
2231
|
let isEnum = false;
|
|
2081
2232
|
if (enumItems) {
|
|
2082
2233
|
value = enumItems.map((enumItem) => `${enumItem}`).join(" | ");
|
|
2083
2234
|
isEnum = true;
|
|
2084
2235
|
}
|
|
2085
2236
|
value += nullable;
|
|
2086
|
-
|
|
2087
|
-
if (itemWithConst.const !== void 0) value = itemWithConst.const;
|
|
2237
|
+
if (schemaConst !== void 0) value = schemaConst;
|
|
2088
2238
|
return {
|
|
2089
2239
|
value,
|
|
2090
2240
|
isEnum,
|
|
@@ -2092,16 +2242,15 @@ function getScalar({ item, name, context, formDataContext }) {
|
|
|
2092
2242
|
schemas: [],
|
|
2093
2243
|
imports: [],
|
|
2094
2244
|
isRef: false,
|
|
2095
|
-
hasReadonlyProps:
|
|
2245
|
+
hasReadonlyProps: schemaReadOnly ?? false,
|
|
2096
2246
|
dependencies: [],
|
|
2097
|
-
example:
|
|
2098
|
-
examples: resolveExampleRefs(
|
|
2247
|
+
example: schemaExample,
|
|
2248
|
+
examples: resolveExampleRefs(schemaExamples, context)
|
|
2099
2249
|
};
|
|
2100
2250
|
}
|
|
2101
2251
|
case "boolean": {
|
|
2102
2252
|
let value = "boolean" + nullable;
|
|
2103
|
-
|
|
2104
|
-
if (itemWithConst.const !== void 0) value = itemWithConst.const;
|
|
2253
|
+
if (schemaConst !== void 0) value = schemaConst;
|
|
2105
2254
|
return {
|
|
2106
2255
|
value,
|
|
2107
2256
|
type: "boolean",
|
|
@@ -2109,10 +2258,10 @@ function getScalar({ item, name, context, formDataContext }) {
|
|
|
2109
2258
|
schemas: [],
|
|
2110
2259
|
imports: [],
|
|
2111
2260
|
isRef: false,
|
|
2112
|
-
hasReadonlyProps:
|
|
2261
|
+
hasReadonlyProps: schemaReadOnly ?? false,
|
|
2113
2262
|
dependencies: [],
|
|
2114
|
-
example:
|
|
2115
|
-
examples: resolveExampleRefs(
|
|
2263
|
+
example: schemaExample,
|
|
2264
|
+
examples: resolveExampleRefs(schemaExamples, context)
|
|
2116
2265
|
};
|
|
2117
2266
|
}
|
|
2118
2267
|
case "array": {
|
|
@@ -2125,7 +2274,7 @@ function getScalar({ item, name, context, formDataContext }) {
|
|
|
2125
2274
|
return {
|
|
2126
2275
|
value: value + nullable,
|
|
2127
2276
|
...rest,
|
|
2128
|
-
dependencies: rest.dependencies
|
|
2277
|
+
dependencies: rest.dependencies
|
|
2129
2278
|
};
|
|
2130
2279
|
}
|
|
2131
2280
|
case "string": {
|
|
@@ -2135,15 +2284,14 @@ function getScalar({ item, name, context, formDataContext }) {
|
|
|
2135
2284
|
value = enumItems.map((enumItem) => isString(enumItem) ? `'${escape(enumItem)}'` : `${enumItem}`).filter(Boolean).join(` | `);
|
|
2136
2285
|
isEnum = true;
|
|
2137
2286
|
}
|
|
2138
|
-
if (
|
|
2287
|
+
if (schemaFormat === "binary") value = "Blob";
|
|
2139
2288
|
else if (formDataContext?.atPart) {
|
|
2140
2289
|
const fileType = getFormDataFieldFileType(item, formDataContext.partContentType);
|
|
2141
2290
|
if (fileType) value = fileType === "binary" ? "Blob" : "Blob | string";
|
|
2142
2291
|
}
|
|
2143
|
-
if (context.output.override.useDates && (
|
|
2292
|
+
if (context.output.override.useDates && (schemaFormat === "date" || schemaFormat === "date-time")) value = "Date";
|
|
2144
2293
|
value += nullable;
|
|
2145
|
-
|
|
2146
|
-
if (itemWithConst.const) value = `'${itemWithConst.const}'`;
|
|
2294
|
+
if (schemaConst) value = `'${schemaConst}'`;
|
|
2147
2295
|
return {
|
|
2148
2296
|
value,
|
|
2149
2297
|
isEnum,
|
|
@@ -2151,10 +2299,10 @@ function getScalar({ item, name, context, formDataContext }) {
|
|
|
2151
2299
|
imports: [],
|
|
2152
2300
|
schemas: [],
|
|
2153
2301
|
isRef: false,
|
|
2154
|
-
hasReadonlyProps:
|
|
2302
|
+
hasReadonlyProps: schemaReadOnly ?? false,
|
|
2155
2303
|
dependencies: [],
|
|
2156
|
-
example:
|
|
2157
|
-
examples: resolveExampleRefs(
|
|
2304
|
+
example: schemaExample,
|
|
2305
|
+
examples: resolveExampleRefs(schemaExamples, context)
|
|
2158
2306
|
};
|
|
2159
2307
|
}
|
|
2160
2308
|
case "null": return {
|
|
@@ -2164,34 +2312,30 @@ function getScalar({ item, name, context, formDataContext }) {
|
|
|
2164
2312
|
imports: [],
|
|
2165
2313
|
schemas: [],
|
|
2166
2314
|
isRef: false,
|
|
2167
|
-
hasReadonlyProps:
|
|
2315
|
+
hasReadonlyProps: schemaReadOnly ?? false,
|
|
2168
2316
|
dependencies: []
|
|
2169
2317
|
};
|
|
2170
|
-
case "object":
|
|
2171
2318
|
default: {
|
|
2172
2319
|
if (isArray(itemType)) return combineSchemas({
|
|
2173
|
-
schema: { anyOf: itemType.map((type) => ({
|
|
2174
|
-
...item,
|
|
2175
|
-
type
|
|
2176
|
-
})) },
|
|
2320
|
+
schema: { anyOf: itemType.map((type) => Object.assign({}, item, { type })) },
|
|
2177
2321
|
name,
|
|
2178
2322
|
separator: "anyOf",
|
|
2179
2323
|
context,
|
|
2180
2324
|
nullable
|
|
2181
2325
|
});
|
|
2182
2326
|
if (enumItems) return {
|
|
2183
|
-
value: enumItems.map((enumItem) => isString(enumItem) ? `'${escape(enumItem)}'` :
|
|
2327
|
+
value: enumItems.map((enumItem) => isString(enumItem) ? `'${escape(enumItem)}'` : String(enumItem)).filter(Boolean).join(` | `) + nullable,
|
|
2184
2328
|
isEnum: true,
|
|
2185
2329
|
type: "string",
|
|
2186
2330
|
imports: [],
|
|
2187
2331
|
schemas: [],
|
|
2188
2332
|
isRef: false,
|
|
2189
|
-
hasReadonlyProps:
|
|
2333
|
+
hasReadonlyProps: schemaReadOnly ?? false,
|
|
2190
2334
|
dependencies: [],
|
|
2191
|
-
example:
|
|
2192
|
-
examples: resolveExampleRefs(
|
|
2335
|
+
example: schemaExample,
|
|
2336
|
+
examples: resolveExampleRefs(schemaExamples, context)
|
|
2193
2337
|
};
|
|
2194
|
-
const hasCombiners = item.allOf
|
|
2338
|
+
const hasCombiners = item.allOf ?? item.anyOf ?? item.oneOf;
|
|
2195
2339
|
const { value, ...rest } = getObject({
|
|
2196
2340
|
item,
|
|
2197
2341
|
name,
|
|
@@ -2209,17 +2353,66 @@ function getScalar({ item, name, context, formDataContext }) {
|
|
|
2209
2353
|
|
|
2210
2354
|
//#endregion
|
|
2211
2355
|
//#region src/getters/combine.ts
|
|
2212
|
-
|
|
2356
|
+
const mergeableAllOfKeys = new Set([
|
|
2357
|
+
"type",
|
|
2358
|
+
"properties",
|
|
2359
|
+
"required"
|
|
2360
|
+
]);
|
|
2361
|
+
function isMergeableAllOfObject(schema) {
|
|
2362
|
+
if (isNullish$1(schema.properties)) return false;
|
|
2363
|
+
if (schema.allOf || schema.anyOf || schema.oneOf) return false;
|
|
2364
|
+
if (!isNullish$1(schema.type) && schema.type !== "object") return false;
|
|
2365
|
+
return Object.keys(schema).every((key) => mergeableAllOfKeys.has(key));
|
|
2366
|
+
}
|
|
2367
|
+
function normalizeAllOfSchema(schema) {
|
|
2368
|
+
const schemaAllOf = schema.allOf;
|
|
2369
|
+
if (!schemaAllOf) return schema;
|
|
2370
|
+
let didMerge = false;
|
|
2371
|
+
const schemaProperties = schema.properties;
|
|
2372
|
+
const schemaRequired = schema.required;
|
|
2373
|
+
const mergedProperties = { ...schemaProperties };
|
|
2374
|
+
const mergedRequired = new Set(schemaRequired);
|
|
2375
|
+
const remainingAllOf = [];
|
|
2376
|
+
for (const subSchema of schemaAllOf) {
|
|
2377
|
+
if (isSchema(subSchema) && isMergeableAllOfObject(subSchema)) {
|
|
2378
|
+
didMerge = true;
|
|
2379
|
+
if (subSchema.properties) Object.assign(mergedProperties, subSchema.properties);
|
|
2380
|
+
const subRequired = subSchema.required;
|
|
2381
|
+
if (subRequired) for (const prop$1 of subRequired) mergedRequired.add(prop$1);
|
|
2382
|
+
continue;
|
|
2383
|
+
}
|
|
2384
|
+
remainingAllOf.push(subSchema);
|
|
2385
|
+
}
|
|
2386
|
+
if (!didMerge || remainingAllOf.length === 0) return schema;
|
|
2387
|
+
return {
|
|
2388
|
+
...schema,
|
|
2389
|
+
...Object.keys(mergedProperties).length > 0 && { properties: mergedProperties },
|
|
2390
|
+
...mergedRequired.size > 0 && { required: [...mergedRequired] },
|
|
2391
|
+
...remainingAllOf.length > 0 && { allOf: remainingAllOf }
|
|
2392
|
+
};
|
|
2393
|
+
}
|
|
2394
|
+
function combineValues({ resolvedData, resolvedValue, separator: separator$1, context, parentSchema }) {
|
|
2213
2395
|
if (resolvedData.isEnum.every(Boolean)) return `${resolvedData.values.join(` | `)}${resolvedValue ? ` | ${resolvedValue.value}` : ""}`;
|
|
2214
2396
|
if (separator$1 === "allOf") {
|
|
2215
2397
|
let resolvedDataValue = resolvedData.values.map((v) => v.includes(" | ") ? `(${v})` : v).join(` & `);
|
|
2216
2398
|
if (resolvedData.originalSchema.length > 0 && resolvedValue) {
|
|
2217
|
-
const discriminatedPropertySchemas = resolvedData.originalSchema.filter((s) =>
|
|
2399
|
+
const discriminatedPropertySchemas = resolvedData.originalSchema.filter((s) => {
|
|
2400
|
+
const disc = s?.discriminator;
|
|
2401
|
+
return disc && resolvedValue.value.includes(` ${disc.propertyName}:`);
|
|
2402
|
+
});
|
|
2218
2403
|
if (discriminatedPropertySchemas.length > 0) resolvedDataValue = `Omit<${resolvedDataValue}, '${discriminatedPropertySchemas.map((s) => s.discriminator?.propertyName).join("' | '")}'>`;
|
|
2219
2404
|
}
|
|
2220
2405
|
const resolvedValueStr = resolvedValue?.value.includes(" | ") ? `(${resolvedValue.value})` : resolvedValue?.value;
|
|
2221
2406
|
const joined = `${resolvedDataValue}${resolvedValue ? ` & ${resolvedValueStr}` : ""}`;
|
|
2222
|
-
const overrideRequiredProperties = resolvedData.requiredProperties.filter((prop$1) => !resolvedData.originalSchema.some((schema) =>
|
|
2407
|
+
const overrideRequiredProperties = resolvedData.requiredProperties.filter((prop$1) => !resolvedData.originalSchema.some((schema) => {
|
|
2408
|
+
const props = schema?.properties;
|
|
2409
|
+
const req = schema?.required;
|
|
2410
|
+
return props?.[prop$1] && req?.includes(prop$1);
|
|
2411
|
+
}) && !(() => {
|
|
2412
|
+
const parentProps = parentSchema?.properties;
|
|
2413
|
+
const parentReq = parentSchema?.required;
|
|
2414
|
+
return !!(parentProps?.[prop$1] && parentReq?.includes(prop$1));
|
|
2415
|
+
})());
|
|
2223
2416
|
if (overrideRequiredProperties.length > 0) return `${joined} & Required<Pick<${joined}, '${overrideRequiredProperties.join("' | '")}'>>`;
|
|
2224
2417
|
return joined;
|
|
2225
2418
|
}
|
|
@@ -2228,11 +2421,12 @@ function combineValues({ resolvedData, resolvedValue, separator: separator$1, co
|
|
|
2228
2421
|
values = [];
|
|
2229
2422
|
for (let i = 0; i < resolvedData.values.length; i += 1) {
|
|
2230
2423
|
const subSchema = resolvedData.originalSchema[i];
|
|
2231
|
-
if (subSchema?.type !== "object") {
|
|
2424
|
+
if (subSchema?.type !== "object" || !subSchema.properties) {
|
|
2232
2425
|
values.push(resolvedData.values[i]);
|
|
2233
2426
|
continue;
|
|
2234
2427
|
}
|
|
2235
|
-
const
|
|
2428
|
+
const subSchemaProps = subSchema.properties;
|
|
2429
|
+
const missingProperties = unique(resolvedData.allProperties.filter((p) => !Object.keys(subSchemaProps).includes(p)));
|
|
2236
2430
|
values.push(`${resolvedData.values[i]}${missingProperties.length > 0 ? ` & {${missingProperties.map((p) => `${p}?: never`).join("; ")}}` : ""}`);
|
|
2237
2431
|
}
|
|
2238
2432
|
}
|
|
@@ -2240,14 +2434,30 @@ function combineValues({ resolvedData, resolvedValue, separator: separator$1, co
|
|
|
2240
2434
|
return values.join(" | ");
|
|
2241
2435
|
}
|
|
2242
2436
|
function combineSchemas({ name, schema, separator: separator$1, context, nullable, formDataContext }) {
|
|
2243
|
-
const
|
|
2244
|
-
const
|
|
2437
|
+
const normalizedSchema = separator$1 === "allOf" && !context.output.override.aliasCombinedTypes && !schema.oneOf && !schema.anyOf ? normalizeAllOfSchema(schema) : schema;
|
|
2438
|
+
const items = normalizedSchema[separator$1] ?? [];
|
|
2439
|
+
const resolvedData = {
|
|
2440
|
+
values: [],
|
|
2441
|
+
imports: [],
|
|
2442
|
+
schemas: [],
|
|
2443
|
+
isEnum: [],
|
|
2444
|
+
isRef: [],
|
|
2445
|
+
types: [],
|
|
2446
|
+
dependencies: [],
|
|
2447
|
+
originalSchema: [],
|
|
2448
|
+
allProperties: [],
|
|
2449
|
+
hasReadonlyProps: false,
|
|
2450
|
+
example: schema.example,
|
|
2451
|
+
examples: resolveExampleRefs(schema.examples, context),
|
|
2452
|
+
requiredProperties: separator$1 === "allOf" ? schema.required ?? [] : []
|
|
2453
|
+
};
|
|
2454
|
+
for (const subSchema of items) {
|
|
2245
2455
|
let propName;
|
|
2246
2456
|
if (context.output.override.aliasCombinedTypes) {
|
|
2247
2457
|
propName = name ? name + pascal(separator$1) : void 0;
|
|
2248
|
-
if (propName &&
|
|
2458
|
+
if (propName && resolvedData.schemas.length > 0) propName = propName + pascal(getNumberWord(resolvedData.schemas.length + 1));
|
|
2249
2459
|
}
|
|
2250
|
-
if (separator$1 === "allOf" && isSchema(subSchema) && subSchema.required)
|
|
2460
|
+
if (separator$1 === "allOf" && isSchema(subSchema) && subSchema.required) resolvedData.requiredProperties.push(...subSchema.required);
|
|
2251
2461
|
const resolvedValue$1 = resolveObject({
|
|
2252
2462
|
schema: subSchema,
|
|
2253
2463
|
propName,
|
|
@@ -2265,32 +2475,18 @@ function combineSchemas({ name, schema, separator: separator$1, context, nullabl
|
|
|
2265
2475
|
resolvedValue: resolvedValue$1,
|
|
2266
2476
|
imports: aliasedImports
|
|
2267
2477
|
});
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
}
|
|
2280
|
-
values: [],
|
|
2281
|
-
imports: [],
|
|
2282
|
-
schemas: [],
|
|
2283
|
-
isEnum: [],
|
|
2284
|
-
isRef: [],
|
|
2285
|
-
types: [],
|
|
2286
|
-
dependencies: [],
|
|
2287
|
-
originalSchema: [],
|
|
2288
|
-
allProperties: [],
|
|
2289
|
-
hasReadonlyProps: false,
|
|
2290
|
-
example: schema.example,
|
|
2291
|
-
examples: resolveExampleRefs(schema.examples, context),
|
|
2292
|
-
requiredProperties: separator$1 === "allOf" ? schema.required ?? [] : []
|
|
2293
|
-
});
|
|
2478
|
+
resolvedData.values.push(value);
|
|
2479
|
+
resolvedData.imports.push(...aliasedImports);
|
|
2480
|
+
resolvedData.schemas.push(...resolvedValue$1.schemas);
|
|
2481
|
+
resolvedData.dependencies.push(...resolvedValue$1.dependencies);
|
|
2482
|
+
resolvedData.isEnum.push(resolvedValue$1.isEnum);
|
|
2483
|
+
resolvedData.types.push(resolvedValue$1.type);
|
|
2484
|
+
resolvedData.isRef.push(resolvedValue$1.isRef);
|
|
2485
|
+
resolvedData.originalSchema.push(resolvedValue$1.originalSchema);
|
|
2486
|
+
if (resolvedValue$1.hasReadonlyProps) resolvedData.hasReadonlyProps = true;
|
|
2487
|
+
const originalProps = resolvedValue$1.originalSchema.properties;
|
|
2488
|
+
if (resolvedValue$1.type === "object" && originalProps) resolvedData.allProperties.push(...Object.keys(originalProps));
|
|
2489
|
+
}
|
|
2294
2490
|
if (resolvedData.isEnum.every(Boolean) && name && items.length > 1 && context.output.override.enumGenerationType !== EnumGeneration.UNION) {
|
|
2295
2491
|
const { value: combinedEnumValue, valueImports, hasNull } = getCombinedEnumValue(resolvedData.values.map((value, index) => ({
|
|
2296
2492
|
value,
|
|
@@ -2321,15 +2517,17 @@ function combineSchemas({ name, schema, separator: separator$1, context, nullabl
|
|
|
2321
2517
|
};
|
|
2322
2518
|
}
|
|
2323
2519
|
let resolvedValue;
|
|
2324
|
-
if (
|
|
2325
|
-
item: Object.fromEntries(Object.entries(
|
|
2520
|
+
if (normalizedSchema.properties) resolvedValue = getScalar({
|
|
2521
|
+
item: Object.fromEntries(Object.entries(normalizedSchema).filter(([key]) => key !== separator$1)),
|
|
2326
2522
|
name,
|
|
2327
|
-
context
|
|
2523
|
+
context,
|
|
2524
|
+
formDataContext
|
|
2328
2525
|
});
|
|
2329
2526
|
else if (separator$1 === "allOf" && (schema.oneOf || schema.anyOf)) {
|
|
2330
2527
|
const siblingCombiner = schema.oneOf ? "oneOf" : "anyOf";
|
|
2528
|
+
const siblingSchemas = schema[siblingCombiner];
|
|
2331
2529
|
resolvedValue = combineSchemas({
|
|
2332
|
-
schema: { [siblingCombiner]:
|
|
2530
|
+
schema: { [siblingCombiner]: siblingSchemas },
|
|
2333
2531
|
name,
|
|
2334
2532
|
separator: siblingCombiner,
|
|
2335
2533
|
context,
|
|
@@ -2341,7 +2539,8 @@ function combineSchemas({ name, schema, separator: separator$1, context, nullabl
|
|
|
2341
2539
|
resolvedData,
|
|
2342
2540
|
separator: separator$1,
|
|
2343
2541
|
resolvedValue,
|
|
2344
|
-
context
|
|
2542
|
+
context,
|
|
2543
|
+
parentSchema: normalizedSchema
|
|
2345
2544
|
}) + nullable),
|
|
2346
2545
|
imports: resolvedValue ? [...resolvedData.imports, ...resolvedValue.imports] : resolvedData.imports,
|
|
2347
2546
|
schemas: resolvedValue ? [...resolvedData.schemas, ...resolvedValue.schemas] : resolvedData.schemas,
|
|
@@ -2349,7 +2548,7 @@ function combineSchemas({ name, schema, separator: separator$1, context, nullabl
|
|
|
2349
2548
|
isEnum: false,
|
|
2350
2549
|
type: "object",
|
|
2351
2550
|
isRef: false,
|
|
2352
|
-
hasReadonlyProps: resolvedData
|
|
2551
|
+
hasReadonlyProps: resolvedData.hasReadonlyProps || (resolvedValue?.hasReadonlyProps ?? false),
|
|
2353
2552
|
example: schema.example,
|
|
2354
2553
|
examples: resolveExampleRefs(schema.examples, context)
|
|
2355
2554
|
};
|
|
@@ -2360,7 +2559,9 @@ function combineSchemas({ name, schema, separator: separator$1, context, nullabl
|
|
|
2360
2559
|
function resolveDiscriminators(schemas, context) {
|
|
2361
2560
|
const transformedSchemas = schemas;
|
|
2362
2561
|
for (const schema of Object.values(transformedSchemas)) {
|
|
2363
|
-
if (
|
|
2562
|
+
if (isBoolean$1(schema)) continue;
|
|
2563
|
+
const discriminator = schema.discriminator;
|
|
2564
|
+
if (!schema.oneOf && isArray(discriminator?.oneOf)) schema.oneOf = discriminator.oneOf;
|
|
2364
2565
|
if (schema.discriminator?.mapping) {
|
|
2365
2566
|
const { mapping, propertyName } = schema.discriminator;
|
|
2366
2567
|
for (const [mappingKey, mappingValue] of Object.entries(mapping)) {
|
|
@@ -2371,17 +2572,25 @@ function resolveDiscriminators(schemas, context) {
|
|
|
2371
2572
|
} catch {
|
|
2372
2573
|
subTypeSchema = transformedSchemas[mappingValue];
|
|
2373
2574
|
}
|
|
2374
|
-
if (
|
|
2575
|
+
if (isBoolean$1(subTypeSchema) || propertyName === void 0) continue;
|
|
2375
2576
|
const property = subTypeSchema.properties?.[propertyName];
|
|
2376
|
-
if (
|
|
2577
|
+
if (isBoolean$1(property)) continue;
|
|
2578
|
+
const schemaProperty = property && !isReference(property) ? property : void 0;
|
|
2579
|
+
const enumProperty = schemaProperty ? getPropertySafe(schemaProperty, "enum") : {
|
|
2580
|
+
hasProperty: false,
|
|
2581
|
+
value: void 0
|
|
2582
|
+
};
|
|
2583
|
+
const mergedEnumValues = [...((enumProperty.hasProperty && Array.isArray(enumProperty.value) ? enumProperty.value : void 0) ?? []).filter((value) => value !== mappingKey), mappingKey];
|
|
2584
|
+
const mergedProperty = {
|
|
2585
|
+
...schemaProperty,
|
|
2586
|
+
type: "string",
|
|
2587
|
+
enum: mergedEnumValues
|
|
2588
|
+
};
|
|
2377
2589
|
subTypeSchema.properties = {
|
|
2378
2590
|
...subTypeSchema.properties,
|
|
2379
|
-
[propertyName]:
|
|
2380
|
-
type: "string",
|
|
2381
|
-
enum: [...property?.enum?.filter((value) => value !== mappingKey) ?? [], mappingKey]
|
|
2382
|
-
}
|
|
2591
|
+
[propertyName]: mergedProperty
|
|
2383
2592
|
};
|
|
2384
|
-
subTypeSchema.required = [...subTypeSchema.required ?? [], propertyName];
|
|
2593
|
+
subTypeSchema.required = [...new Set([...subTypeSchema.required ?? [], propertyName])];
|
|
2385
2594
|
}
|
|
2386
2595
|
}
|
|
2387
2596
|
}
|
|
@@ -2403,23 +2612,22 @@ function getOperationId(operation, route, verb) {
|
|
|
2403
2612
|
//#endregion
|
|
2404
2613
|
//#region src/getters/parameters.ts
|
|
2405
2614
|
function getParameters({ parameters, context }) {
|
|
2406
|
-
|
|
2407
|
-
if (isReference(p)) {
|
|
2408
|
-
const { schema: parameter, imports } = resolveRef(p, context);
|
|
2409
|
-
if (parameter.in === "path" || parameter.in === "query" || parameter.in === "header") acc[parameter.in].push({
|
|
2410
|
-
parameter,
|
|
2411
|
-
imports
|
|
2412
|
-
});
|
|
2413
|
-
} else if (p.in === "query" || p.in === "path" || p.in === "header") acc[p.in].push({
|
|
2414
|
-
parameter: p,
|
|
2415
|
-
imports: []
|
|
2416
|
-
});
|
|
2417
|
-
return acc;
|
|
2418
|
-
}, {
|
|
2615
|
+
const result = {
|
|
2419
2616
|
path: [],
|
|
2420
2617
|
query: [],
|
|
2421
2618
|
header: []
|
|
2619
|
+
};
|
|
2620
|
+
for (const p of parameters) if (isReference(p)) {
|
|
2621
|
+
const { schema: parameter, imports } = resolveRef(p, context);
|
|
2622
|
+
if (parameter.in === "path" || parameter.in === "query" || parameter.in === "header") result[parameter.in].push({
|
|
2623
|
+
parameter,
|
|
2624
|
+
imports
|
|
2625
|
+
});
|
|
2626
|
+
} else if (p.in === "query" || p.in === "path" || p.in === "header") result[p.in].push({
|
|
2627
|
+
parameter: p,
|
|
2628
|
+
imports: []
|
|
2422
2629
|
});
|
|
2630
|
+
return result;
|
|
2423
2631
|
}
|
|
2424
2632
|
|
|
2425
2633
|
//#endregion
|
|
@@ -2463,16 +2671,18 @@ function getParams({ route, pathParams = [], operationId, context, output }) {
|
|
|
2463
2671
|
schema,
|
|
2464
2672
|
context
|
|
2465
2673
|
});
|
|
2674
|
+
const originalSchema = resolvedValue.originalSchema;
|
|
2675
|
+
const schemaDefault = originalSchema.default;
|
|
2466
2676
|
let paramType = resolvedValue.value;
|
|
2467
2677
|
if (output.allParamsOptional) paramType = `${paramType} | undefined | null`;
|
|
2468
2678
|
return {
|
|
2469
2679
|
name,
|
|
2470
|
-
definition: `${name}${!required ||
|
|
2471
|
-
implementation: `${name}${!required && !
|
|
2472
|
-
default:
|
|
2680
|
+
definition: `${name}${!required || schemaDefault ? "?" : ""}: ${paramType}`,
|
|
2681
|
+
implementation: `${name}${!required && !schemaDefault ? "?" : ""}${schemaDefault ? `: ${paramType} = ${stringify(schemaDefault)}` : `: ${paramType}`}`,
|
|
2682
|
+
default: schemaDefault,
|
|
2473
2683
|
required,
|
|
2474
2684
|
imports: resolvedValue.imports,
|
|
2475
|
-
originalSchema
|
|
2685
|
+
originalSchema
|
|
2476
2686
|
};
|
|
2477
2687
|
});
|
|
2478
2688
|
}
|
|
@@ -2493,7 +2703,7 @@ function getProps({ body, queryParams, params, operationName, headers, context }
|
|
|
2493
2703
|
definition: getQueryParamDefinition(queryParams, context),
|
|
2494
2704
|
implementation: getQueryParamDefinition(queryParams, context),
|
|
2495
2705
|
default: false,
|
|
2496
|
-
required:
|
|
2706
|
+
required: isNullish(queryParams?.isOptional) ? !context.output.allParamsOptional || context.output.optionsParamRequired : !queryParams.isOptional && !context.output.allParamsOptional || context.output.optionsParamRequired,
|
|
2497
2707
|
type: GetterPropType.QUERY_PARAM
|
|
2498
2708
|
};
|
|
2499
2709
|
const headersProp = {
|
|
@@ -2501,7 +2711,7 @@ function getProps({ body, queryParams, params, operationName, headers, context }
|
|
|
2501
2711
|
definition: `headers${headers?.isOptional && !context.output.optionsParamRequired ? "?" : ""}: ${headers?.schema.name}`,
|
|
2502
2712
|
implementation: `headers${headers?.isOptional && !context.output.optionsParamRequired ? "?" : ""}: ${headers?.schema.name}`,
|
|
2503
2713
|
default: false,
|
|
2504
|
-
required:
|
|
2714
|
+
required: isNullish(headers?.isOptional) ? false : !headers.isOptional || context.output.optionsParamRequired,
|
|
2505
2715
|
type: GetterPropType.HEADER
|
|
2506
2716
|
};
|
|
2507
2717
|
let paramGetterProps;
|
|
@@ -2538,13 +2748,27 @@ function getProps({ body, queryParams, params, operationName, headers, context }
|
|
|
2538
2748
|
]);
|
|
2539
2749
|
}
|
|
2540
2750
|
function getQueryParamDefinition(queryParams, context) {
|
|
2541
|
-
|
|
2542
|
-
if (OutputClient.ANGULAR === context.output.client) paramType = `DeepNonNullable<${paramType}>`;
|
|
2751
|
+
const paramType = queryParams?.schema.name;
|
|
2543
2752
|
return `params${(queryParams?.isOptional || context.output.allParamsOptional) && !context.output.optionsParamRequired ? "?" : ""}: ${paramType}`;
|
|
2544
2753
|
}
|
|
2545
2754
|
|
|
2546
2755
|
//#endregion
|
|
2547
2756
|
//#region src/getters/query-params.ts
|
|
2757
|
+
const isOpenApiSchemaObject = (value) => {
|
|
2758
|
+
if (!value || typeof value !== "object") return false;
|
|
2759
|
+
return !("$ref" in value);
|
|
2760
|
+
};
|
|
2761
|
+
const isSchemaNullable = (schema) => {
|
|
2762
|
+
if (schema.nullable === true) return true;
|
|
2763
|
+
if (schema.type === "null") return true;
|
|
2764
|
+
if (Array.isArray(schema.type) && schema.type.includes("null")) return true;
|
|
2765
|
+
const oneOfVariants = Array.isArray(schema.oneOf) ? schema.oneOf : [];
|
|
2766
|
+
const anyOfVariants = Array.isArray(schema.anyOf) ? schema.anyOf : [];
|
|
2767
|
+
return [...oneOfVariants, ...anyOfVariants].some((variant) => {
|
|
2768
|
+
if (!isOpenApiSchemaObject(variant)) return false;
|
|
2769
|
+
return isSchemaNullable(variant);
|
|
2770
|
+
});
|
|
2771
|
+
};
|
|
2548
2772
|
function getQueryParamsTypes(queryParams, operationName, context) {
|
|
2549
2773
|
return queryParams.map(({ parameter, imports: parameterImports }) => {
|
|
2550
2774
|
const { name, required, schema: schemaParam, content } = parameter;
|
|
@@ -2555,18 +2779,22 @@ function getQueryParamsTypes(queryParams, operationName, context) {
|
|
|
2555
2779
|
es5keyword: true,
|
|
2556
2780
|
es5IdentifierName: true
|
|
2557
2781
|
});
|
|
2558
|
-
const schema = schemaParam
|
|
2782
|
+
const schema = schemaParam ?? content?.["application/json"]?.schema;
|
|
2783
|
+
if (!schema) throw new Error(`Query parameter "${name}" has no schema or content definition`);
|
|
2559
2784
|
const resolvedValue = resolveValue({
|
|
2560
2785
|
schema,
|
|
2561
2786
|
context,
|
|
2562
2787
|
name: queryName
|
|
2563
2788
|
});
|
|
2564
2789
|
const key = getKey(name);
|
|
2790
|
+
const schemaForDoc = schema;
|
|
2565
2791
|
const doc = jsDoc({
|
|
2566
2792
|
description: parameter.description,
|
|
2567
|
-
...
|
|
2793
|
+
...schemaForDoc
|
|
2568
2794
|
}, void 0, context);
|
|
2569
2795
|
if (parameterImports.length > 0) return {
|
|
2796
|
+
name,
|
|
2797
|
+
required,
|
|
2570
2798
|
definition: `${doc}${key}${!required || schema.default ? "?" : ""}: ${parameterImports[0].name};`,
|
|
2571
2799
|
imports: parameterImports,
|
|
2572
2800
|
schemas: [],
|
|
@@ -2574,8 +2802,10 @@ function getQueryParamsTypes(queryParams, operationName, context) {
|
|
|
2574
2802
|
};
|
|
2575
2803
|
if (resolvedValue.isEnum && !resolvedValue.isRef) {
|
|
2576
2804
|
const enumName = queryName;
|
|
2577
|
-
const enumValue = getEnum(resolvedValue.value, enumName, getEnumNames(resolvedValue.originalSchema), context.output.override.enumGenerationType, getEnumDescriptions(resolvedValue.originalSchema), context.output.override.namingConvention
|
|
2805
|
+
const enumValue = getEnum(resolvedValue.value, enumName, getEnumNames(resolvedValue.originalSchema), context.output.override.enumGenerationType, getEnumDescriptions(resolvedValue.originalSchema), context.output.override.namingConvention.enum);
|
|
2578
2806
|
return {
|
|
2807
|
+
name,
|
|
2808
|
+
required,
|
|
2579
2809
|
definition: `${doc}${key}${!required || schema.default ? "?" : ""}: ${enumName};`,
|
|
2580
2810
|
imports: [{ name: enumName }],
|
|
2581
2811
|
schemas: [...resolvedValue.schemas, {
|
|
@@ -2587,6 +2817,8 @@ function getQueryParamsTypes(queryParams, operationName, context) {
|
|
|
2587
2817
|
};
|
|
2588
2818
|
}
|
|
2589
2819
|
return {
|
|
2820
|
+
name,
|
|
2821
|
+
required,
|
|
2590
2822
|
definition: `${doc}${key}${!required || schema.default ? "?" : ""}: ${resolvedValue.value};`,
|
|
2591
2823
|
imports: resolvedValue.imports,
|
|
2592
2824
|
schemas: resolvedValue.schemas,
|
|
@@ -2602,6 +2834,7 @@ function getQueryParams({ queryParams, operationName, context, suffix = "params"
|
|
|
2602
2834
|
const name = `${pascal(operationName)}${pascal(suffix)}`;
|
|
2603
2835
|
const type = types.map(({ definition }) => definition).join("\n");
|
|
2604
2836
|
const allOptional = queryParams.every(({ parameter }) => !parameter.required);
|
|
2837
|
+
const requiredNullableKeys = types.filter(({ required, originalSchema }) => required && isSchemaNullable(originalSchema)).map(({ name: name$1 }) => name$1);
|
|
2605
2838
|
return {
|
|
2606
2839
|
schema: {
|
|
2607
2840
|
name,
|
|
@@ -2609,46 +2842,24 @@ function getQueryParams({ queryParams, operationName, context, suffix = "params"
|
|
|
2609
2842
|
imports
|
|
2610
2843
|
},
|
|
2611
2844
|
deps: schemas,
|
|
2612
|
-
isOptional: allOptional
|
|
2845
|
+
isOptional: allOptional,
|
|
2846
|
+
requiredNullableKeys
|
|
2613
2847
|
};
|
|
2614
2848
|
}
|
|
2615
2849
|
|
|
2616
2850
|
//#endregion
|
|
2617
2851
|
//#region src/getters/response.ts
|
|
2618
2852
|
function getResponse({ responses, operationName, context, contentType }) {
|
|
2619
|
-
|
|
2620
|
-
imports: [],
|
|
2621
|
-
definition: {
|
|
2622
|
-
success: "",
|
|
2623
|
-
errors: ""
|
|
2624
|
-
},
|
|
2625
|
-
isBlob: false,
|
|
2626
|
-
types: {
|
|
2627
|
-
success: [],
|
|
2628
|
-
errors: []
|
|
2629
|
-
},
|
|
2630
|
-
schemas: [],
|
|
2631
|
-
contentTypes: []
|
|
2632
|
-
};
|
|
2633
|
-
const types = getResReqTypes(Object.entries(responses), operationName, context, "void", (type) => `${type.key}-${type.value}`);
|
|
2634
|
-
const filteredTypes = contentType ? types.filter((type) => {
|
|
2635
|
-
let include = true;
|
|
2636
|
-
let exclude = false;
|
|
2637
|
-
if (contentType.include) include = contentType.include.includes(type.contentType);
|
|
2638
|
-
if (contentType.exclude) exclude = contentType.exclude.includes(type.contentType);
|
|
2639
|
-
return include && !exclude;
|
|
2640
|
-
}) : types;
|
|
2853
|
+
const filteredTypes = filterByContentType(getResReqTypes(Object.entries(responses), operationName, context, "void", (type) => `${type.key}-${type.value}-${type.contentType}`), contentType);
|
|
2641
2854
|
const imports = filteredTypes.flatMap(({ imports: imports$1 }) => imports$1);
|
|
2642
2855
|
const schemas = filteredTypes.flatMap(({ schemas: schemas$1 }) => schemas$1);
|
|
2643
2856
|
const contentTypes = [...new Set(filteredTypes.map(({ contentType: contentType$1 }) => contentType$1))];
|
|
2644
|
-
const groupedByStatus =
|
|
2645
|
-
if (type.key.startsWith("2")) acc.success.push(type);
|
|
2646
|
-
else acc.errors.push(type);
|
|
2647
|
-
return acc;
|
|
2648
|
-
}, {
|
|
2857
|
+
const groupedByStatus = {
|
|
2649
2858
|
success: [],
|
|
2650
2859
|
errors: []
|
|
2651
|
-
}
|
|
2860
|
+
};
|
|
2861
|
+
for (const type of filteredTypes) if (type.key.startsWith("2")) groupedByStatus.success.push(type);
|
|
2862
|
+
else groupedByStatus.errors.push(type);
|
|
2652
2863
|
const success = dedupeUnionType(groupedByStatus.success.map(({ value, formData }) => formData ? "Blob" : value).join(" | "));
|
|
2653
2864
|
const errors = dedupeUnionType(groupedByStatus.errors.map(({ value }) => value).join(" | "));
|
|
2654
2865
|
const defaultType = filteredTypes.find(({ key }) => key === "default")?.value;
|
|
@@ -2684,16 +2895,18 @@ const getRoutePath = (path$2) => {
|
|
|
2684
2895
|
return hasParam(path$2) ? `${prev}\${${param}}${next}` : `${prev}${param}${next}`;
|
|
2685
2896
|
};
|
|
2686
2897
|
function getRoute(route) {
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2898
|
+
const splittedRoute = route.split("/");
|
|
2899
|
+
let result = "";
|
|
2900
|
+
for (const [i, path$2] of splittedRoute.entries()) {
|
|
2901
|
+
if (!path$2 && !i) continue;
|
|
2902
|
+
result += path$2.includes("{") ? `/${getRoutePath(path$2)}` : `/${path$2}`;
|
|
2903
|
+
}
|
|
2904
|
+
return result;
|
|
2692
2905
|
}
|
|
2693
2906
|
function getFullRoute(route, servers, baseUrl) {
|
|
2694
2907
|
const getBaseUrl = () => {
|
|
2695
2908
|
if (!baseUrl) return "";
|
|
2696
|
-
if (
|
|
2909
|
+
if (isString(baseUrl)) return baseUrl;
|
|
2697
2910
|
if (baseUrl.getBaseUrlFromSpecification) {
|
|
2698
2911
|
if (!servers) throw new Error("Orval is configured to use baseUrl from the specifications 'servers' field, but there exist no servers in the specification.");
|
|
2699
2912
|
const server = servers.at(Math.min(baseUrl.index ?? 0, servers.length - 1));
|
|
@@ -2756,7 +2969,7 @@ function generateComponentDefinition(responses = {}, context, suffix) {
|
|
|
2756
2969
|
//#region src/generators/imports.ts
|
|
2757
2970
|
function generateImports({ imports, namingConvention = NamingConvention.CAMEL_CASE }) {
|
|
2758
2971
|
if (imports.length === 0) return "";
|
|
2759
|
-
const grouped = groupBy(uniqueWith(imports, (a, b) => a.name === b.name && a.default === b.default).map((imp) => ({
|
|
2972
|
+
const grouped = groupBy(uniqueWith(imports, (a, b) => a.name === b.name && a.default === b.default && a.alias === b.alias && a.values === b.values && a.isConstant === b.isConstant && a.namespaceImport === b.namespaceImport && a.syntheticDefaultImport === b.syntheticDefaultImport && a.importPath === b.importPath).map((imp) => ({
|
|
2760
2973
|
...imp,
|
|
2761
2974
|
importPath: imp.importPath ?? `./${conventionName(imp.name, namingConvention)}`
|
|
2762
2975
|
})), (imp) => !imp.default && !imp.namespaceImport && !imp.syntheticDefaultImport && !imp.values && !imp.isConstant ? `aggregate|${imp.importPath}` : `single|${imp.importPath}|${imp.name}|${imp.alias ?? ""}|${String(imp.default)}|${String(imp.namespaceImport)}|${String(imp.syntheticDefaultImport)}|${String(imp.values)}|${String(imp.isConstant)}`);
|
|
@@ -2768,25 +2981,26 @@ function generateImports({ imports, namingConvention = NamingConvention.CAMEL_CA
|
|
|
2768
2981
|
}).join("\n");
|
|
2769
2982
|
}
|
|
2770
2983
|
function generateMutatorImports({ mutators, implementation, oneMore }) {
|
|
2771
|
-
|
|
2984
|
+
let imports = "";
|
|
2985
|
+
for (const mutator of uniqueWith(mutators, (a, b) => a.name === b.name && a.default === b.default)) {
|
|
2772
2986
|
const path$2 = `${oneMore ? "../" : ""}${mutator.path}`;
|
|
2773
2987
|
const importDefault = mutator.default ? mutator.name : `{ ${mutator.name} }`;
|
|
2774
|
-
|
|
2775
|
-
|
|
2988
|
+
imports += `import ${importDefault} from '${path$2}';`;
|
|
2989
|
+
imports += "\n";
|
|
2776
2990
|
if (implementation && (mutator.hasErrorType || mutator.bodyTypeName)) {
|
|
2777
2991
|
let errorImportName = "";
|
|
2778
2992
|
const targetErrorImportName = mutator.default ? `ErrorType as ${mutator.errorTypeName}` : mutator.errorTypeName;
|
|
2779
|
-
if (mutator.hasErrorType && implementation.includes(mutator.errorTypeName) && !
|
|
2993
|
+
if (mutator.hasErrorType && implementation.includes(mutator.errorTypeName) && !imports.includes(`{ ${targetErrorImportName} `)) errorImportName = targetErrorImportName;
|
|
2780
2994
|
let bodyImportName = "";
|
|
2781
2995
|
const targetBodyImportName = mutator.default ? `BodyType as ${mutator.bodyTypeName}` : mutator.bodyTypeName;
|
|
2782
|
-
if (mutator.bodyTypeName && implementation.includes(mutator.bodyTypeName) && !
|
|
2996
|
+
if (mutator.bodyTypeName && implementation.includes(mutator.bodyTypeName) && !imports.includes(` ${targetBodyImportName} }`)) bodyImportName = targetBodyImportName ?? "";
|
|
2783
2997
|
if (bodyImportName || errorImportName) {
|
|
2784
|
-
|
|
2785
|
-
|
|
2998
|
+
imports += `import type { ${errorImportName}${errorImportName && bodyImportName ? " , " : ""}${bodyImportName} } from '${path$2}';`;
|
|
2999
|
+
imports += "\n";
|
|
2786
3000
|
}
|
|
2787
3001
|
}
|
|
2788
|
-
|
|
2789
|
-
|
|
3002
|
+
}
|
|
3003
|
+
return imports;
|
|
2790
3004
|
}
|
|
2791
3005
|
function generateDependency({ deps, isAllowSyntheticDefaultImports, dependency, projectName, key, onlyTypes }) {
|
|
2792
3006
|
const defaultDep = deps.find((e) => e.default && (isAllowSyntheticDefaultImports || !e.syntheticDefaultImport));
|
|
@@ -2801,31 +3015,25 @@ function generateDependency({ deps, isAllowSyntheticDefaultImports, dependency,
|
|
|
2801
3015
|
importString += `import ${onlyTypes ? "type " : ""}${defaultDep ? `${defaultDep.name}${depsString ? "," : ""}` : ""}${depsString ? `{\n ${depsString}\n}` : ""} from '${dependency}${key !== "default" && projectName ? `/${projectName}` : ""}';`;
|
|
2802
3016
|
return importString;
|
|
2803
3017
|
}
|
|
2804
|
-
function addDependency({ implementation, exports, dependency, projectName,
|
|
3018
|
+
function addDependency({ implementation, exports, dependency, projectName, isAllowSyntheticDefaultImports }) {
|
|
2805
3019
|
const toAdds = exports.filter((e) => {
|
|
2806
3020
|
const searchWords = [e.alias, e.name].filter((p) => p?.length).join("|");
|
|
2807
3021
|
const pattern = new RegExp(String.raw`\b(${searchWords})\b`, "g");
|
|
2808
3022
|
return implementation.match(pattern);
|
|
2809
3023
|
});
|
|
2810
3024
|
if (toAdds.length === 0) return;
|
|
2811
|
-
const groupedBySpecKey =
|
|
3025
|
+
const groupedBySpecKey = { default: {
|
|
3026
|
+
types: [],
|
|
3027
|
+
values: []
|
|
3028
|
+
} };
|
|
3029
|
+
for (const dep of toAdds) {
|
|
2812
3030
|
const key = "default";
|
|
2813
|
-
if (dep.values && (isAllowSyntheticDefaultImports || !dep.syntheticDefaultImport))
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
values: [...acc[key]?.values ?? [], dep]
|
|
2817
|
-
};
|
|
2818
|
-
return acc;
|
|
2819
|
-
}
|
|
2820
|
-
acc[key] = {
|
|
2821
|
-
...acc[key],
|
|
2822
|
-
types: [...acc[key]?.types ?? [], dep]
|
|
2823
|
-
};
|
|
2824
|
-
return acc;
|
|
2825
|
-
}, {});
|
|
3031
|
+
if (dep.values && (isAllowSyntheticDefaultImports || !dep.syntheticDefaultImport)) groupedBySpecKey[key].values.push(dep);
|
|
3032
|
+
else groupedBySpecKey[key].types.push(dep);
|
|
3033
|
+
}
|
|
2826
3034
|
return Object.entries(groupedBySpecKey).map(([key, { values, types }]) => {
|
|
2827
3035
|
let dep = "";
|
|
2828
|
-
if (values) dep += generateDependency({
|
|
3036
|
+
if (values.length > 0) dep += generateDependency({
|
|
2829
3037
|
deps: values,
|
|
2830
3038
|
isAllowSyntheticDefaultImports,
|
|
2831
3039
|
dependency,
|
|
@@ -2833,10 +3041,10 @@ function addDependency({ implementation, exports, dependency, projectName, hasSc
|
|
|
2833
3041
|
key,
|
|
2834
3042
|
onlyTypes: false
|
|
2835
3043
|
});
|
|
2836
|
-
if (types) {
|
|
3044
|
+
if (types.length > 0) {
|
|
2837
3045
|
let uniqueTypes = types;
|
|
2838
|
-
if (values) {
|
|
2839
|
-
uniqueTypes = types.filter((t) => !values.some((v) => v.name === t.name));
|
|
3046
|
+
if (values.length > 0) {
|
|
3047
|
+
uniqueTypes = types.filter((t) => !values.some((v) => v.name === t.name && (v.alias ?? "") === (t.alias ?? "")));
|
|
2840
3048
|
dep += "\n";
|
|
2841
3049
|
}
|
|
2842
3050
|
dep += generateDependency({
|
|
@@ -2862,7 +3070,7 @@ function generateDependencyImports(implementation, imports, projectName, hasSche
|
|
|
2862
3070
|
projectName,
|
|
2863
3071
|
hasSchemaDir,
|
|
2864
3072
|
isAllowSyntheticDefaultImports
|
|
2865
|
-
})).filter(Boolean).
|
|
3073
|
+
})).filter((x) => Boolean(x)).toSorted((a, b) => {
|
|
2866
3074
|
const aLib = getLibName(a);
|
|
2867
3075
|
const bLib = getLibName(b);
|
|
2868
3076
|
if (aLib === bLib) return 0;
|
|
@@ -2879,7 +3087,17 @@ function generateVerbImports({ response, body, queryParams, props, headers, para
|
|
|
2879
3087
|
...queryParams ? [{ name: queryParams.schema.name }] : [],
|
|
2880
3088
|
...headers ? [{ name: headers.schema.name }] : [],
|
|
2881
3089
|
...params.flatMap(({ imports }) => imports)
|
|
2882
|
-
]
|
|
3090
|
+
].flatMap((imp) => {
|
|
3091
|
+
if (imp.name !== "Error" || !imp.values || imp.alias) return [imp];
|
|
3092
|
+
return [{
|
|
3093
|
+
...imp,
|
|
3094
|
+
values: void 0
|
|
3095
|
+
}, {
|
|
3096
|
+
...imp,
|
|
3097
|
+
alias: "ErrorSchema",
|
|
3098
|
+
values: true
|
|
3099
|
+
}];
|
|
3100
|
+
});
|
|
2883
3101
|
}
|
|
2884
3102
|
|
|
2885
3103
|
//#endregion
|
|
@@ -2888,7 +3106,10 @@ function generateModelInline(acc, model) {
|
|
|
2888
3106
|
return acc + `${model}\n`;
|
|
2889
3107
|
}
|
|
2890
3108
|
function generateModelsInline(obj) {
|
|
2891
|
-
|
|
3109
|
+
const schemas = Object.values(obj).flat();
|
|
3110
|
+
let result = "";
|
|
3111
|
+
for (const { model } of schemas) result = generateModelInline(result, model);
|
|
3112
|
+
return result;
|
|
2892
3113
|
}
|
|
2893
3114
|
|
|
2894
3115
|
//#endregion
|
|
@@ -2914,7 +3135,7 @@ async function bundleFile(root, fileName, alias, external, compilerOptions) {
|
|
|
2914
3135
|
treeShaking: false,
|
|
2915
3136
|
keepNames: false,
|
|
2916
3137
|
alias,
|
|
2917
|
-
external: external
|
|
3138
|
+
external: external ?? ["*"]
|
|
2918
3139
|
})).outputFiles[0];
|
|
2919
3140
|
return text;
|
|
2920
3141
|
}
|
|
@@ -3038,46 +3259,143 @@ function removeComments(file) {
|
|
|
3038
3259
|
|
|
3039
3260
|
//#endregion
|
|
3040
3261
|
//#region src/generators/options.ts
|
|
3262
|
+
/**
|
|
3263
|
+
* Filters query params for Angular's HttpClient.
|
|
3264
|
+
*
|
|
3265
|
+
* Why: Angular's HttpParams / HttpClient `params` type does not accept `null` or
|
|
3266
|
+
* `undefined` values, and arrays must only contain string/number/boolean.
|
|
3267
|
+
* Orval models often include nullable query params, so we remove nullish values
|
|
3268
|
+
* (including nulls inside arrays) before passing params to HttpClient or a
|
|
3269
|
+
* paramsSerializer to avoid runtime and type issues.
|
|
3270
|
+
*
|
|
3271
|
+
* Returns an inline IIFE expression. For paths that benefit from a shared helper
|
|
3272
|
+
* (e.g. observe-mode branches), prefer getAngularFilteredParamsCallExpression +
|
|
3273
|
+
* getAngularFilteredParamsHelperBody instead.
|
|
3274
|
+
*/
|
|
3275
|
+
const getAngularFilteredParamsExpression = (paramsExpression, requiredNullableParamKeys = []) => `(() => {
|
|
3276
|
+
const requiredNullableParamKeys = new Set<string>(${JSON.stringify(requiredNullableParamKeys)});
|
|
3277
|
+
const filteredParams = {} as Record<string, string | number | boolean | null | Array<string | number | boolean>>;
|
|
3278
|
+
for (const [key, value] of Object.entries(${paramsExpression})) {
|
|
3279
|
+
if (Array.isArray(value)) {
|
|
3280
|
+
const filtered = value.filter(
|
|
3281
|
+
(item) =>
|
|
3282
|
+
item != null &&
|
|
3283
|
+
(typeof item === 'string' ||
|
|
3284
|
+
typeof item === 'number' ||
|
|
3285
|
+
typeof item === 'boolean'),
|
|
3286
|
+
) as Array<string | number | boolean>;
|
|
3287
|
+
if (filtered.length) {
|
|
3288
|
+
filteredParams[key] = filtered;
|
|
3289
|
+
}
|
|
3290
|
+
} else if (value === null && requiredNullableParamKeys.has(key)) {
|
|
3291
|
+
filteredParams[key] = value;
|
|
3292
|
+
} else if (
|
|
3293
|
+
value != null &&
|
|
3294
|
+
(typeof value === 'string' ||
|
|
3295
|
+
typeof value === 'number' ||
|
|
3296
|
+
typeof value === 'boolean')
|
|
3297
|
+
) {
|
|
3298
|
+
filteredParams[key] = value as string | number | boolean;
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
return filteredParams as unknown as Record<string, string | number | boolean | Array<string | number | boolean>>;
|
|
3302
|
+
})()`;
|
|
3303
|
+
/**
|
|
3304
|
+
* Returns the body of a standalone `filterParams` helper function
|
|
3305
|
+
* to be emitted once in the generated file header, replacing the
|
|
3306
|
+
* inline IIFE that was previously duplicated in every method.
|
|
3307
|
+
*/
|
|
3308
|
+
const getAngularFilteredParamsHelperBody = () => `function filterParams(
|
|
3309
|
+
params: Record<string, unknown>,
|
|
3310
|
+
requiredNullableKeys: Set<string> = new Set(),
|
|
3311
|
+
): Record<string, string | number | boolean | Array<string | number | boolean>> {
|
|
3312
|
+
const filteredParams: Record<string, string | number | boolean | null | Array<string | number | boolean>> = {};
|
|
3313
|
+
for (const [key, value] of Object.entries(params)) {
|
|
3314
|
+
if (Array.isArray(value)) {
|
|
3315
|
+
const filtered = value.filter(
|
|
3316
|
+
(item) =>
|
|
3317
|
+
item != null &&
|
|
3318
|
+
(typeof item === 'string' ||
|
|
3319
|
+
typeof item === 'number' ||
|
|
3320
|
+
typeof item === 'boolean'),
|
|
3321
|
+
) as Array<string | number | boolean>;
|
|
3322
|
+
if (filtered.length) {
|
|
3323
|
+
filteredParams[key] = filtered;
|
|
3324
|
+
}
|
|
3325
|
+
} else if (value === null && requiredNullableKeys.has(key)) {
|
|
3326
|
+
filteredParams[key] = value;
|
|
3327
|
+
} else if (
|
|
3328
|
+
value != null &&
|
|
3329
|
+
(typeof value === 'string' ||
|
|
3330
|
+
typeof value === 'number' ||
|
|
3331
|
+
typeof value === 'boolean')
|
|
3332
|
+
) {
|
|
3333
|
+
filteredParams[key] = value as string | number | boolean;
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
return filteredParams as Record<string, string | number | boolean | Array<string | number | boolean>>;
|
|
3337
|
+
}`;
|
|
3338
|
+
/**
|
|
3339
|
+
* Returns a call expression to the `filterParams` helper function.
|
|
3340
|
+
*/
|
|
3341
|
+
const getAngularFilteredParamsCallExpression = (paramsExpression, requiredNullableParamKeys = []) => `filterParams(${paramsExpression}, new Set<string>(${JSON.stringify(requiredNullableParamKeys)}))`;
|
|
3041
3342
|
function generateBodyOptions(body, isFormData, isFormUrlEncoded) {
|
|
3042
3343
|
if (isFormData && body.formData) return "\n formData,";
|
|
3043
3344
|
if (isFormUrlEncoded && body.formUrlEncoded) return "\n formUrlEncoded,";
|
|
3044
3345
|
if (body.implementation) return `\n ${body.implementation},`;
|
|
3045
3346
|
return "";
|
|
3046
3347
|
}
|
|
3047
|
-
function generateAxiosOptions({ response, isExactOptionalPropertyTypes, queryParams, headers, requestOptions, hasSignal, hasSignalParam = false, isVue, isAngular, paramsSerializer, paramsSerializerOptions }) {
|
|
3348
|
+
function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularObserve, angularParamsRef, requiredNullableQueryParamKeys, queryParams, headers, requestOptions, hasSignal, hasSignalParam = false, isVue, isAngular, paramsSerializer, paramsSerializerOptions }) {
|
|
3048
3349
|
const isRequestOptions = requestOptions !== false;
|
|
3049
3350
|
const signalVar = hasSignalParam ? "querySignal" : "signal";
|
|
3050
3351
|
const signalProp = hasSignalParam ? `signal: ${signalVar}` : "signal";
|
|
3051
3352
|
if (!queryParams && !headers && !response.isBlob && response.definition.success !== "string") {
|
|
3052
|
-
if (isRequestOptions) return
|
|
3353
|
+
if (isRequestOptions) return isAngular ? angularObserve ? `{
|
|
3354
|
+
...(options as Omit<NonNullable<typeof options>, 'observe'>),
|
|
3355
|
+
observe: '${angularObserve}',
|
|
3356
|
+
}` : "(options as Omit<NonNullable<typeof options>, 'observe'>)" : "options";
|
|
3053
3357
|
if (hasSignal) return isExactOptionalPropertyTypes ? `...(${signalVar} ? { ${signalProp} } : {})` : signalProp;
|
|
3054
3358
|
return "";
|
|
3055
3359
|
}
|
|
3056
3360
|
let value = "";
|
|
3057
3361
|
if (!isRequestOptions) {
|
|
3058
|
-
if (queryParams)
|
|
3362
|
+
if (queryParams) if (isAngular) {
|
|
3363
|
+
const iifeExpr = getAngularFilteredParamsExpression("params ?? {}", requiredNullableQueryParamKeys);
|
|
3364
|
+
value += paramsSerializer ? `\n params: ${paramsSerializer.name}(${iifeExpr}),` : `\n params: ${iifeExpr},`;
|
|
3365
|
+
} else value += "\n params,";
|
|
3059
3366
|
if (headers) value += "\n headers,";
|
|
3060
3367
|
if (hasSignal) value += isExactOptionalPropertyTypes ? `\n ...(${signalVar} ? { ${signalProp} } : {}),` : `\n ${signalProp},`;
|
|
3061
3368
|
}
|
|
3062
|
-
if (!isObject(requestOptions) || !
|
|
3063
|
-
|
|
3064
|
-
|
|
3369
|
+
if (!isObject(requestOptions) || !Object.hasOwn(requestOptions, "responseType")) {
|
|
3370
|
+
const successResponseType = getSuccessResponseType(response);
|
|
3371
|
+
if (successResponseType) value += `\n responseType: '${successResponseType}',`;
|
|
3065
3372
|
}
|
|
3066
3373
|
if (isObject(requestOptions)) value += `\n ${stringify(requestOptions)?.slice(1, -1)}`;
|
|
3067
3374
|
if (isRequestOptions) {
|
|
3068
|
-
value += "\n ...options,";
|
|
3375
|
+
value += isAngular ? "\n ...(options as Omit<NonNullable<typeof options>, 'observe'>)," : "\n ...options,";
|
|
3376
|
+
if (isAngular && angularObserve) value += `\n observe: '${angularObserve}',`;
|
|
3069
3377
|
if (queryParams) if (isVue) value += "\n params: {...unref(params), ...options?.params},";
|
|
3070
|
-
else if (isAngular &&
|
|
3378
|
+
else if (isAngular && angularParamsRef) value += `\n params: ${angularParamsRef},`;
|
|
3379
|
+
else if (isAngular && paramsSerializer) {
|
|
3380
|
+
const callExpr = getAngularFilteredParamsCallExpression("{...params, ...options?.params}", requiredNullableQueryParamKeys);
|
|
3381
|
+
value += `\n params: ${paramsSerializer.name}(${callExpr}),`;
|
|
3382
|
+
} else if (isAngular) value += `\n params: ${getAngularFilteredParamsCallExpression("{...params, ...options?.params}", requiredNullableQueryParamKeys)},`;
|
|
3071
3383
|
else value += "\n params: {...params, ...options?.params},";
|
|
3072
3384
|
if (headers) value += "\n headers: {...headers, ...options?.headers},";
|
|
3073
3385
|
}
|
|
3074
|
-
if (!isAngular && queryParams && (paramsSerializer || paramsSerializerOptions?.qs))
|
|
3386
|
+
if (!isAngular && queryParams && (paramsSerializer || paramsSerializerOptions?.qs)) {
|
|
3387
|
+
const qsOptions = paramsSerializerOptions?.qs;
|
|
3388
|
+
value += paramsSerializer ? `\n paramsSerializer: ${paramsSerializer.name},` : `\n paramsSerializer: (params) => qs.stringify(params, ${JSON.stringify(qsOptions)}),`;
|
|
3389
|
+
}
|
|
3075
3390
|
return value;
|
|
3076
3391
|
}
|
|
3077
|
-
function generateOptions({ route, body, headers, queryParams, response, verb, requestOptions, isFormData, isFormUrlEncoded, isAngular, isExactOptionalPropertyTypes, hasSignal, hasSignalParam, isVue, paramsSerializer, paramsSerializerOptions }) {
|
|
3392
|
+
function generateOptions({ route, body, angularObserve, angularParamsRef, headers, queryParams, response, verb, requestOptions, isFormData, isFormUrlEncoded, isAngular, isExactOptionalPropertyTypes, hasSignal, hasSignalParam, isVue, paramsSerializer, paramsSerializerOptions }) {
|
|
3078
3393
|
const bodyOptions = getIsBodyVerb(verb) ? generateBodyOptions(body, isFormData, isFormUrlEncoded) : "";
|
|
3079
3394
|
const axiosOptions = generateAxiosOptions({
|
|
3080
3395
|
response,
|
|
3396
|
+
angularObserve,
|
|
3397
|
+
angularParamsRef,
|
|
3398
|
+
requiredNullableQueryParamKeys: queryParams?.requiredNullableKeys,
|
|
3081
3399
|
queryParams: queryParams?.schema,
|
|
3082
3400
|
headers: headers?.schema,
|
|
3083
3401
|
requestOptions,
|
|
@@ -3089,12 +3407,15 @@ function generateOptions({ route, body, headers, queryParams, response, verb, re
|
|
|
3089
3407
|
paramsSerializer,
|
|
3090
3408
|
paramsSerializerOptions
|
|
3091
3409
|
});
|
|
3092
|
-
const
|
|
3410
|
+
const isRawOptionsArgument = axiosOptions === "options" || axiosOptions.startsWith("(") && axiosOptions.endsWith(")");
|
|
3411
|
+
const optionsArgument = axiosOptions ? isRawOptionsArgument ? axiosOptions : `{${axiosOptions}}` : "";
|
|
3093
3412
|
if (verb === Verbs.DELETE) {
|
|
3094
|
-
if (!bodyOptions) return `\n \`${route}
|
|
3095
|
-
|
|
3413
|
+
if (!bodyOptions) return `\n \`${route}\`${optionsArgument ? `,${optionsArgument}` : ""}\n `;
|
|
3414
|
+
const deleteBodyOptions = isRawOptionsArgument ? `...${optionsArgument}` : axiosOptions;
|
|
3415
|
+
return `\n \`${route}\`,{${isAngular ? "body" : "data"}:${bodyOptions} ${axiosOptions ? deleteBodyOptions : ""}}\n `;
|
|
3096
3416
|
}
|
|
3097
|
-
|
|
3417
|
+
const bodyOrOptions = getIsBodyVerb(verb) ? bodyOptions || "undefined," : "";
|
|
3418
|
+
return `\n \`${route}\`${bodyOrOptions || optionsArgument ? "," : ""}${bodyOrOptions}${optionsArgument}\n `;
|
|
3098
3419
|
}
|
|
3099
3420
|
function generateBodyMutatorConfig(body, isFormData, isFormUrlEncoded) {
|
|
3100
3421
|
if (isFormData && body.formData) return ",\n data: formData";
|
|
@@ -3102,17 +3423,19 @@ function generateBodyMutatorConfig(body, isFormData, isFormUrlEncoded) {
|
|
|
3102
3423
|
if (body.implementation) return `,\n data: ${body.implementation}`;
|
|
3103
3424
|
return "";
|
|
3104
3425
|
}
|
|
3105
|
-
function generateQueryParamsAxiosConfig(response, isVue, queryParams) {
|
|
3426
|
+
function generateQueryParamsAxiosConfig(response, isVue, isAngular, requiredNullableQueryParamKeys, queryParams) {
|
|
3106
3427
|
if (!queryParams && !response.isBlob) return "";
|
|
3107
3428
|
let value = "";
|
|
3108
|
-
if (queryParams) value +=
|
|
3429
|
+
if (queryParams) if (isVue) value += ",\n params: unref(params)";
|
|
3430
|
+
else if (isAngular) value += `,\n params: ${getAngularFilteredParamsExpression("params ?? {}", requiredNullableQueryParamKeys)}`;
|
|
3431
|
+
else value += ",\n params";
|
|
3109
3432
|
if (response.isBlob) value += `,\n responseType: 'blob'`;
|
|
3110
3433
|
return value;
|
|
3111
3434
|
}
|
|
3112
|
-
function generateMutatorConfig({ route, body, headers, queryParams, response, verb, isFormData, isFormUrlEncoded, hasSignal, hasSignalParam = false, isExactOptionalPropertyTypes, isVue }) {
|
|
3435
|
+
function generateMutatorConfig({ route, body, headers, queryParams, response, verb, isFormData, isFormUrlEncoded, hasSignal, hasSignalParam = false, isExactOptionalPropertyTypes, isVue, isAngular }) {
|
|
3113
3436
|
const bodyOptions = getIsBodyVerb(verb) ? generateBodyMutatorConfig(body, isFormData, isFormUrlEncoded) : "";
|
|
3114
|
-
const queryParamsOptions = generateQueryParamsAxiosConfig(response, isVue ?? false, queryParams);
|
|
3115
|
-
const headerOptions = body.contentType ? `,\n headers: {'Content-Type': '${body.contentType}', ${headers ? "...headers" : ""}}` : headers ? ",\n headers" : "";
|
|
3437
|
+
const queryParamsOptions = generateQueryParamsAxiosConfig(response, isVue ?? false, isAngular ?? false, queryParams?.requiredNullableKeys, queryParams);
|
|
3438
|
+
const headerOptions = body.contentType && !["multipart/form-data"].includes(body.contentType) ? `,\n headers: {'Content-Type': '${body.contentType}', ${headers ? "...headers" : ""}}` : headers ? ",\n headers" : "";
|
|
3116
3439
|
const signalVar = hasSignalParam ? "querySignal" : "signal";
|
|
3117
3440
|
const signalProp = hasSignalParam ? `signal: ${signalVar}` : "signal";
|
|
3118
3441
|
return `{url: \`${route}\`, method: '${verb.toUpperCase()}'${headerOptions}${bodyOptions}${queryParamsOptions}${hasSignal ? `, ${isExactOptionalPropertyTypes ? `...(${signalVar} ? { ${signalProp} }: {})` : signalProp}` : ""}\n }`;
|
|
@@ -3194,18 +3517,20 @@ function generateInterface({ name, schema, context }) {
|
|
|
3194
3517
|
context
|
|
3195
3518
|
});
|
|
3196
3519
|
const isEmptyObject = scalar.value === "{}";
|
|
3197
|
-
const shouldUseTypeAlias = context
|
|
3520
|
+
const shouldUseTypeAlias = context.output.override.useTypeOverInterfaces ?? scalar.useTypeAlias;
|
|
3198
3521
|
let model = "";
|
|
3199
3522
|
model += jsDoc(schema);
|
|
3200
3523
|
if (isEmptyObject) model += "// eslint-disable-next-line @typescript-eslint/no-empty-interface\n";
|
|
3201
|
-
if (scalar.type === "object" && !shouldUseTypeAlias)
|
|
3202
|
-
const
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3524
|
+
if (scalar.type === "object" && !shouldUseTypeAlias) {
|
|
3525
|
+
const properties = schema.properties;
|
|
3526
|
+
if (properties && Object.values(properties).length > 0 && Object.values(properties).every((item) => "const" in item)) {
|
|
3527
|
+
const mappedScalarValue = scalar.value.replaceAll(";", ",").replaceAll("?:", ":");
|
|
3528
|
+
model += `export const ${name}Value = ${mappedScalarValue} as const;\nexport type ${name} = typeof ${name}Value;\n`;
|
|
3529
|
+
} else {
|
|
3530
|
+
const blankInterfaceValue = scalar.value === "unknown" ? "{}" : scalar.value;
|
|
3531
|
+
model += `export interface ${name} ${blankInterfaceValue}\n`;
|
|
3532
|
+
}
|
|
3533
|
+
} else model += `export type ${name} = ${scalar.value};\n`;
|
|
3209
3534
|
const externalModulesImportsOnly = scalar.imports.filter((importName) => importName.alias ? importName.alias !== name : importName.name !== name);
|
|
3210
3535
|
return [...scalar.schemas, {
|
|
3211
3536
|
name,
|
|
@@ -3255,7 +3580,7 @@ function sortSchemasByDependencies(schemas) {
|
|
|
3255
3580
|
for (const dependencyName of schema.dependencies) if (dependencyName && schemaNames.has(dependencyName)) dependencies.add(dependencyName);
|
|
3256
3581
|
}
|
|
3257
3582
|
for (const imp of schema.imports) {
|
|
3258
|
-
const dependencyName = imp.alias
|
|
3583
|
+
const dependencyName = imp.alias ?? imp.name;
|
|
3259
3584
|
if (dependencyName && schemaNames.has(dependencyName)) dependencies.add(dependencyName);
|
|
3260
3585
|
}
|
|
3261
3586
|
dependencyMap.set(schema.name, dependencies);
|
|
@@ -3292,7 +3617,7 @@ function generateSchemaDefinitions(schemaName, schema, context, suffix) {
|
|
|
3292
3617
|
es5keyword: true,
|
|
3293
3618
|
es5IdentifierName: true
|
|
3294
3619
|
});
|
|
3295
|
-
if (
|
|
3620
|
+
if (isBoolean(schema)) return [{
|
|
3296
3621
|
name: sanitizedSchemaName,
|
|
3297
3622
|
model: `export type ${sanitizedSchemaName} = ${schema ? "any" : "never"};\n`,
|
|
3298
3623
|
imports: [],
|
|
@@ -3311,7 +3636,7 @@ function generateSchemaDefinitions(schemaName, schema, context, suffix) {
|
|
|
3311
3636
|
let output = "";
|
|
3312
3637
|
let imports = resolvedValue.imports;
|
|
3313
3638
|
output += jsDoc(schema);
|
|
3314
|
-
if (resolvedValue.isEnum && !resolvedValue.isRef) output += getEnum(resolvedValue.value, sanitizedSchemaName, getEnumNames(resolvedValue.originalSchema), context.output.override.enumGenerationType, getEnumDescriptions(resolvedValue.originalSchema), context.output.override.namingConvention
|
|
3639
|
+
if (resolvedValue.isEnum && !resolvedValue.isRef) output += getEnum(resolvedValue.value, sanitizedSchemaName, getEnumNames(resolvedValue.originalSchema), context.output.override.enumGenerationType, getEnumDescriptions(resolvedValue.originalSchema), context.output.override.namingConvention.enum);
|
|
3315
3640
|
else if (sanitizedSchemaName === resolvedValue.value && resolvedValue.isRef) {
|
|
3316
3641
|
const { schema: referredSchema } = resolveRef(schema, context);
|
|
3317
3642
|
if (!shouldCreateInterface(referredSchema)) {
|
|
@@ -3330,7 +3655,7 @@ function generateSchemaDefinitions(schemaName, schema, context, suffix) {
|
|
|
3330
3655
|
resolvedValue.schemas = resolvedValue.schemas.filter((schema$1) => {
|
|
3331
3656
|
if (schema$1.name !== sanitizedSchemaName) return true;
|
|
3332
3657
|
output += `${schema$1.model}\n`;
|
|
3333
|
-
imports = imports
|
|
3658
|
+
imports = [...imports, ...schema$1.imports];
|
|
3334
3659
|
resolvedValue.dependencies.push(...schema$1.dependencies ?? []);
|
|
3335
3660
|
return false;
|
|
3336
3661
|
});
|
|
@@ -3347,26 +3672,56 @@ function generateSchemaDefinitions(schemaName, schema, context, suffix) {
|
|
|
3347
3672
|
|
|
3348
3673
|
//#endregion
|
|
3349
3674
|
//#region src/generators/verbs-options.ts
|
|
3350
|
-
|
|
3351
|
-
|
|
3675
|
+
/**
|
|
3676
|
+
* Get a content-type specific suffix for operation names (#2812)
|
|
3677
|
+
*/
|
|
3678
|
+
function getContentTypeSuffix(contentType) {
|
|
3679
|
+
return {
|
|
3680
|
+
"application/json": "Json",
|
|
3681
|
+
"multipart/form-data": "FormData",
|
|
3682
|
+
"application/x-www-form-urlencoded": "UrlEncoded",
|
|
3683
|
+
"application/xml": "Xml",
|
|
3684
|
+
"text/plain": "Text"
|
|
3685
|
+
}[contentType] || pascal(contentType.replaceAll(/[^a-zA-Z0-9]/g, "_"));
|
|
3686
|
+
}
|
|
3687
|
+
async function generateVerbOptions({ verb, output, operation, route, pathRoute, verbParameters = [], context, contentType }) {
|
|
3688
|
+
const { responses, requestBody, parameters: operationParameters, tags: rawTags, deprecated: rawDeprecated, description: rawDescription, summary: rawSummary } = operation;
|
|
3689
|
+
const tags = rawTags ?? [];
|
|
3690
|
+
const deprecated = rawDeprecated;
|
|
3691
|
+
const description = rawDescription;
|
|
3692
|
+
const summary = rawSummary;
|
|
3352
3693
|
const operationId = getOperationId(operation, route, verb);
|
|
3353
3694
|
const overrideOperation = output.override.operations[operationId];
|
|
3354
|
-
|
|
3355
|
-
const
|
|
3695
|
+
let overrideTag = {};
|
|
3696
|
+
for (const [tag, options] of Object.entries(output.override.tags)) if (tags.includes(tag) && options) overrideTag = mergeDeep(overrideTag, options);
|
|
3697
|
+
const override = mergeDeep(mergeDeep(output.override, overrideTag), overrideOperation ?? {});
|
|
3698
|
+
const originalContentTypeFilter = override.contentType;
|
|
3699
|
+
const requestBodyContentTypeFilter = contentType ? { include: [contentType] } : override.contentType;
|
|
3356
3700
|
const overrideOperationName = overrideOperation?.operationName ?? output.override.operationName;
|
|
3357
|
-
|
|
3701
|
+
let operationName = overrideOperationName ? overrideOperationName(operation, route, verb) : sanitize(camel(operationId), { es5keyword: true });
|
|
3702
|
+
if (contentType) operationName = operationName + "With" + getContentTypeSuffix(contentType);
|
|
3358
3703
|
const response = getResponse({
|
|
3359
|
-
responses,
|
|
3704
|
+
responses: responses ?? {},
|
|
3360
3705
|
operationName,
|
|
3361
3706
|
context,
|
|
3362
|
-
contentType:
|
|
3707
|
+
contentType: originalContentTypeFilter
|
|
3363
3708
|
});
|
|
3364
|
-
const body = getBody({
|
|
3709
|
+
const body = requestBody ? getBody({
|
|
3365
3710
|
requestBody,
|
|
3366
3711
|
operationName,
|
|
3367
3712
|
context,
|
|
3368
|
-
contentType:
|
|
3369
|
-
})
|
|
3713
|
+
contentType: requestBodyContentTypeFilter
|
|
3714
|
+
}) : {
|
|
3715
|
+
originalSchema: {},
|
|
3716
|
+
definition: "",
|
|
3717
|
+
implementation: "",
|
|
3718
|
+
imports: [],
|
|
3719
|
+
schemas: [],
|
|
3720
|
+
formData: "",
|
|
3721
|
+
formUrlEncoded: "",
|
|
3722
|
+
contentType: "",
|
|
3723
|
+
isOptional: false
|
|
3724
|
+
};
|
|
3370
3725
|
const parameters = getParameters({
|
|
3371
3726
|
parameters: [...verbParameters, ...operationParameters ?? []],
|
|
3372
3727
|
context
|
|
@@ -3442,7 +3797,7 @@ async function generateVerbOptions({ verb, output, operation, route, pathRoute,
|
|
|
3442
3797
|
tags,
|
|
3443
3798
|
route,
|
|
3444
3799
|
pathRoute,
|
|
3445
|
-
summary
|
|
3800
|
+
summary,
|
|
3446
3801
|
operationId,
|
|
3447
3802
|
operationName,
|
|
3448
3803
|
response,
|
|
@@ -3467,23 +3822,39 @@ async function generateVerbOptions({ verb, output, operation, route, pathRoute,
|
|
|
3467
3822
|
function generateVerbsOptions({ verbs, input, output, route, pathRoute, context }) {
|
|
3468
3823
|
return asyncReduce(_filteredVerbs(verbs, input.filters), async (acc, [verb, operation]) => {
|
|
3469
3824
|
if (isVerb(verb)) {
|
|
3470
|
-
const
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3825
|
+
const contentTypes = getRequestBodyContentTypes(operation.requestBody, context);
|
|
3826
|
+
if (contentTypes.length > 1) for (const contentType of contentTypes) {
|
|
3827
|
+
const verbOptions = await generateVerbOptions({
|
|
3828
|
+
verb,
|
|
3829
|
+
output,
|
|
3830
|
+
verbParameters: verbs.parameters,
|
|
3831
|
+
route,
|
|
3832
|
+
pathRoute,
|
|
3833
|
+
operation,
|
|
3834
|
+
context,
|
|
3835
|
+
contentType
|
|
3836
|
+
});
|
|
3837
|
+
acc.push(verbOptions);
|
|
3838
|
+
}
|
|
3839
|
+
else {
|
|
3840
|
+
const verbOptions = await generateVerbOptions({
|
|
3841
|
+
verb,
|
|
3842
|
+
output,
|
|
3843
|
+
verbParameters: verbs.parameters,
|
|
3844
|
+
route,
|
|
3845
|
+
pathRoute,
|
|
3846
|
+
operation,
|
|
3847
|
+
context
|
|
3848
|
+
});
|
|
3849
|
+
acc.push(verbOptions);
|
|
3850
|
+
}
|
|
3480
3851
|
}
|
|
3481
3852
|
return acc;
|
|
3482
3853
|
}, []);
|
|
3483
3854
|
}
|
|
3484
3855
|
function _filteredVerbs(verbs, filters) {
|
|
3485
3856
|
if (filters?.tags === void 0) return Object.entries(verbs);
|
|
3486
|
-
const filterTags = filters.tags
|
|
3857
|
+
const filterTags = filters.tags;
|
|
3487
3858
|
const filterMode = filters.mode ?? "include";
|
|
3488
3859
|
return Object.entries(verbs).filter(([, operation]) => {
|
|
3489
3860
|
const isMatch = (operation.tags ?? []).some((tag) => filterTags.some((filterTag) => filterTag instanceof RegExp ? filterTag.test(tag) : filterTag === tag));
|
|
@@ -3529,17 +3900,25 @@ function splitSchemasByType(schemas) {
|
|
|
3529
3900
|
};
|
|
3530
3901
|
}
|
|
3531
3902
|
/**
|
|
3903
|
+
* Get the import extension from a file extension.
|
|
3904
|
+
* Removes `.ts` suffix since TypeScript doesn't need it in imports.
|
|
3905
|
+
*/
|
|
3906
|
+
function getImportExtension(fileExtension) {
|
|
3907
|
+
return fileExtension.replace(/\.ts$/, "") || "";
|
|
3908
|
+
}
|
|
3909
|
+
/**
|
|
3532
3910
|
* Fix cross-directory imports when schemas reference other schemas in a different directory.
|
|
3533
3911
|
* Updates import paths to use correct relative paths between directories.
|
|
3534
3912
|
*/
|
|
3535
|
-
function fixSchemaImports(schemas, targetSchemaNames, fromPath, toPath, namingConvention) {
|
|
3913
|
+
function fixSchemaImports(schemas, targetSchemaNames, fromPath, toPath, namingConvention, fileExtension) {
|
|
3536
3914
|
const relativePath = relativeSafe(fromPath, toPath);
|
|
3915
|
+
const importExtension = getImportExtension(fileExtension);
|
|
3537
3916
|
for (const schema of schemas) schema.imports = schema.imports.map((imp) => {
|
|
3538
3917
|
if (targetSchemaNames.has(imp.name)) {
|
|
3539
3918
|
const fileName = conventionName(imp.name, namingConvention);
|
|
3540
3919
|
return {
|
|
3541
3920
|
...imp,
|
|
3542
|
-
importPath: joinSafe(relativePath, fileName)
|
|
3921
|
+
importPath: joinSafe(relativePath, fileName) + importExtension
|
|
3543
3922
|
};
|
|
3544
3923
|
}
|
|
3545
3924
|
return imp;
|
|
@@ -3548,14 +3927,14 @@ function fixSchemaImports(schemas, targetSchemaNames, fromPath, toPath, namingCo
|
|
|
3548
3927
|
/**
|
|
3549
3928
|
* Fix imports in operation schemas that reference regular schemas.
|
|
3550
3929
|
*/
|
|
3551
|
-
function fixCrossDirectoryImports(operationSchemas, regularSchemaNames, schemaPath, operationSchemaPath, namingConvention) {
|
|
3552
|
-
fixSchemaImports(operationSchemas, regularSchemaNames, operationSchemaPath, schemaPath, namingConvention);
|
|
3930
|
+
function fixCrossDirectoryImports(operationSchemas, regularSchemaNames, schemaPath, operationSchemaPath, namingConvention, fileExtension) {
|
|
3931
|
+
fixSchemaImports(operationSchemas, regularSchemaNames, operationSchemaPath, schemaPath, namingConvention, fileExtension);
|
|
3553
3932
|
}
|
|
3554
3933
|
/**
|
|
3555
3934
|
* Fix imports in regular schemas that reference operation schemas.
|
|
3556
3935
|
*/
|
|
3557
|
-
function fixRegularSchemaImports(regularSchemas, operationSchemaNames, schemaPath, operationSchemaPath, namingConvention) {
|
|
3558
|
-
fixSchemaImports(regularSchemas, operationSchemaNames, schemaPath, operationSchemaPath, namingConvention);
|
|
3936
|
+
function fixRegularSchemaImports(regularSchemas, operationSchemaNames, schemaPath, operationSchemaPath, namingConvention, fileExtension) {
|
|
3937
|
+
fixSchemaImports(regularSchemas, operationSchemaNames, schemaPath, operationSchemaPath, namingConvention, fileExtension);
|
|
3559
3938
|
}
|
|
3560
3939
|
function getSchemaKey(schemaPath, schemaName, namingConvention, fileExtension) {
|
|
3561
3940
|
return getPath(schemaPath, conventionName(schemaName, namingConvention), fileExtension).toLowerCase().replaceAll("\\", "/");
|
|
@@ -3608,7 +3987,7 @@ function removeFileExtension(path$2, fileExtension) {
|
|
|
3608
3987
|
function getSchema({ schema: { imports, model }, target, header, namingConvention = NamingConvention.CAMEL_CASE }) {
|
|
3609
3988
|
let file = header;
|
|
3610
3989
|
file += generateImports({
|
|
3611
|
-
imports: imports.filter((imp) => !model.includes(`type ${imp.alias
|
|
3990
|
+
imports: imports.filter((imp) => !model.includes(`type ${imp.alias ?? imp.name} =`) && !model.includes(`interface ${imp.alias ?? imp.name} {`)),
|
|
3612
3991
|
target,
|
|
3613
3992
|
namingConvention
|
|
3614
3993
|
});
|
|
@@ -3637,7 +4016,7 @@ async function writeSchema({ path: path$2, schema, target, namingConvention, fil
|
|
|
3637
4016
|
namingConvention
|
|
3638
4017
|
}));
|
|
3639
4018
|
} catch (error) {
|
|
3640
|
-
throw new Error(`Oups... 🍻. An Error occurred while writing schema ${name} => ${error}`);
|
|
4019
|
+
throw new Error(`Oups... 🍻. An Error occurred while writing schema ${name} => ${String(error)}`);
|
|
3641
4020
|
}
|
|
3642
4021
|
}
|
|
3643
4022
|
async function writeSchemas({ schemaPath, schemas, target, namingConvention, fileExtension, header, indexFiles }) {
|
|
@@ -3672,14 +4051,14 @@ async function writeSchemas({ schemaPath, schemas, target, namingConvention, fil
|
|
|
3672
4051
|
try {
|
|
3673
4052
|
const currentExports = [...conventionNamesSet].map((schemaName) => `export * from './${schemaName}${ext}';`).toSorted((a, b) => a.localeCompare(b));
|
|
3674
4053
|
const existingExports = (await fs$1.readFile(schemaFilePath, "utf8")).match(/export\s+\*\s+from\s+['"][^'"]+['"]/g)?.map((statement) => {
|
|
3675
|
-
const match =
|
|
3676
|
-
if (!match) return
|
|
4054
|
+
const match = /export\s+\*\s+from\s+['"]([^'"]+)['"]/.exec(statement);
|
|
4055
|
+
if (!match) return;
|
|
3677
4056
|
return `export * from '${match[1]}';`;
|
|
3678
|
-
}).filter(
|
|
4057
|
+
}).filter(Boolean) ?? [];
|
|
3679
4058
|
const fileContent = `${header}\n${[...new Set([...existingExports, ...currentExports])].toSorted((a, b) => a.localeCompare(b)).join("\n")}`;
|
|
3680
4059
|
await fs$1.writeFile(schemaFilePath, fileContent, { encoding: "utf8" });
|
|
3681
4060
|
} catch (error) {
|
|
3682
|
-
throw new Error(`Oups... 🍻. An Error occurred while writing schema index file ${schemaFilePath} => ${error}`);
|
|
4061
|
+
throw new Error(`Oups... 🍻. An Error occurred while writing schema index file ${schemaFilePath} => ${String(error)}`);
|
|
3683
4062
|
}
|
|
3684
4063
|
}
|
|
3685
4064
|
}
|
|
@@ -3688,58 +4067,76 @@ async function writeSchemas({ schemaPath, schemas, target, namingConvention, fil
|
|
|
3688
4067
|
//#region src/writers/generate-imports-for-builder.ts
|
|
3689
4068
|
function generateImportsForBuilder(output, imports, relativeSchemasPath) {
|
|
3690
4069
|
const isZodSchemaOutput = isObject(output.schemas) && output.schemas.type === "zod";
|
|
3691
|
-
|
|
3692
|
-
|
|
4070
|
+
let schemaImports = [];
|
|
4071
|
+
if (output.indexFiles) schemaImports = isZodSchemaOutput ? [{
|
|
4072
|
+
exports: imports.filter((i) => !i.importPath),
|
|
4073
|
+
dependency: joinSafe(relativeSchemasPath, "index.zod")
|
|
4074
|
+
}] : [{
|
|
4075
|
+
exports: imports.filter((i) => !i.importPath),
|
|
4076
|
+
dependency: relativeSchemasPath
|
|
4077
|
+
}];
|
|
4078
|
+
else schemaImports = uniqueBy(imports.filter((i) => !i.importPath), (x) => x.name).map((i) => {
|
|
4079
|
+
const name = conventionName(i.schemaName ?? i.name, output.namingConvention);
|
|
3693
4080
|
const suffix = isZodSchemaOutput ? ".zod" : "";
|
|
3694
|
-
const importExtension = output.fileExtension
|
|
4081
|
+
const importExtension = output.fileExtension.replace(/\.ts$/, "") || "";
|
|
3695
4082
|
return {
|
|
3696
|
-
exports:
|
|
3697
|
-
...i,
|
|
3698
|
-
values: true
|
|
3699
|
-
}] : [i],
|
|
4083
|
+
exports: [i],
|
|
3700
4084
|
dependency: joinSafe(relativeSchemasPath, `${name}${suffix}${importExtension}`)
|
|
3701
4085
|
};
|
|
3702
4086
|
});
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
}
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
else return [{
|
|
3711
|
-
exports: imports,
|
|
3712
|
-
dependency: relativeSchemasPath
|
|
3713
|
-
}];
|
|
4087
|
+
const otherImports = uniqueBy(imports.filter((i) => !!i.importPath), (x) => x.name + (x.importPath ?? "")).map((i) => {
|
|
4088
|
+
return {
|
|
4089
|
+
exports: [i],
|
|
4090
|
+
dependency: i.importPath
|
|
4091
|
+
};
|
|
4092
|
+
});
|
|
4093
|
+
return [...schemaImports, ...otherImports];
|
|
3714
4094
|
}
|
|
3715
4095
|
|
|
3716
4096
|
//#endregion
|
|
3717
4097
|
//#region src/writers/target.ts
|
|
3718
4098
|
function generateTarget(builder, options) {
|
|
3719
4099
|
const operationNames = Object.values(builder.operations).map(({ operationName }) => operationName);
|
|
3720
|
-
const isAngularClient = options
|
|
4100
|
+
const isAngularClient = options.client === OutputClient.ANGULAR;
|
|
3721
4101
|
const titles = builder.title({
|
|
3722
4102
|
outputClient: options.client,
|
|
3723
4103
|
title: pascal(builder.info.title),
|
|
3724
4104
|
customTitleFunc: options.override.title,
|
|
3725
4105
|
output: options
|
|
3726
4106
|
});
|
|
3727
|
-
const target =
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
4107
|
+
const target = {
|
|
4108
|
+
imports: [],
|
|
4109
|
+
implementation: "",
|
|
4110
|
+
implementationMock: {
|
|
4111
|
+
function: "",
|
|
4112
|
+
handler: "",
|
|
4113
|
+
handlerName: ""
|
|
4114
|
+
},
|
|
4115
|
+
importsMock: [],
|
|
4116
|
+
mutators: [],
|
|
4117
|
+
clientMutators: [],
|
|
4118
|
+
formData: [],
|
|
4119
|
+
formUrlEncoded: [],
|
|
4120
|
+
paramsSerializer: [],
|
|
4121
|
+
fetchReviver: []
|
|
4122
|
+
};
|
|
4123
|
+
const operations = Object.values(builder.operations);
|
|
4124
|
+
for (const [index, operation] of operations.entries()) {
|
|
4125
|
+
target.imports.push(...operation.imports);
|
|
4126
|
+
target.importsMock.push(...operation.importsMock);
|
|
4127
|
+
target.implementation += operation.implementation + "\n";
|
|
4128
|
+
target.implementationMock.function += operation.implementationMock.function;
|
|
4129
|
+
target.implementationMock.handler += operation.implementationMock.handler;
|
|
4130
|
+
const handlerNameSeparator = target.implementationMock.handlerName.length > 0 ? ",\n " : " ";
|
|
4131
|
+
target.implementationMock.handlerName += handlerNameSeparator + operation.implementationMock.handlerName + "()";
|
|
4132
|
+
if (operation.mutator) target.mutators.push(operation.mutator);
|
|
4133
|
+
if (operation.formData) target.formData.push(operation.formData);
|
|
4134
|
+
if (operation.formUrlEncoded) target.formUrlEncoded.push(operation.formUrlEncoded);
|
|
4135
|
+
if (operation.paramsSerializer) target.paramsSerializer.push(operation.paramsSerializer);
|
|
4136
|
+
if (operation.clientMutators) target.clientMutators.push(...operation.clientMutators);
|
|
4137
|
+
if (operation.fetchReviver) target.fetchReviver.push(operation.fetchReviver);
|
|
4138
|
+
if (index === operations.length - 1) {
|
|
4139
|
+
const isMutator = target.mutators.some((mutator) => isAngularClient ? mutator.hasThirdArg : mutator.hasSecondArg);
|
|
3743
4140
|
const hasAwaitedType = compareVersions(options.packageJson?.dependencies?.typescript ?? options.packageJson?.devDependencies?.typescript ?? "4.4.0", "4.5.0");
|
|
3744
4141
|
const header = builder.header({
|
|
3745
4142
|
outputClient: options.client,
|
|
@@ -3751,38 +4148,22 @@ function generateTarget(builder, options) {
|
|
|
3751
4148
|
titles,
|
|
3752
4149
|
output: options,
|
|
3753
4150
|
verbOptions: builder.verbOptions,
|
|
3754
|
-
clientImplementation:
|
|
4151
|
+
clientImplementation: target.implementation
|
|
3755
4152
|
});
|
|
3756
|
-
|
|
3757
|
-
|
|
4153
|
+
target.implementation = header.implementation + target.implementation;
|
|
4154
|
+
target.implementationMock.handler = target.implementationMock.handler + header.implementationMock + target.implementationMock.handlerName;
|
|
3758
4155
|
const footer = builder.footer({
|
|
3759
|
-
outputClient: options
|
|
4156
|
+
outputClient: options.client,
|
|
3760
4157
|
operationNames,
|
|
3761
|
-
hasMutator:
|
|
4158
|
+
hasMutator: target.mutators.length > 0,
|
|
3762
4159
|
hasAwaitedType,
|
|
3763
4160
|
titles,
|
|
3764
4161
|
output: options
|
|
3765
4162
|
});
|
|
3766
|
-
|
|
3767
|
-
|
|
4163
|
+
target.implementation += footer.implementation;
|
|
4164
|
+
target.implementationMock.handler += footer.implementationMock;
|
|
3768
4165
|
}
|
|
3769
|
-
|
|
3770
|
-
}, {
|
|
3771
|
-
imports: [],
|
|
3772
|
-
implementation: "",
|
|
3773
|
-
implementationMock: {
|
|
3774
|
-
function: "",
|
|
3775
|
-
handler: "",
|
|
3776
|
-
handlerName: ""
|
|
3777
|
-
},
|
|
3778
|
-
importsMock: [],
|
|
3779
|
-
mutators: [],
|
|
3780
|
-
clientMutators: [],
|
|
3781
|
-
formData: [],
|
|
3782
|
-
formUrlEncoded: [],
|
|
3783
|
-
paramsSerializer: [],
|
|
3784
|
-
fetchReviver: []
|
|
3785
|
-
});
|
|
4166
|
+
}
|
|
3786
4167
|
return {
|
|
3787
4168
|
...target,
|
|
3788
4169
|
implementationMock: target.implementationMock.function + target.implementationMock.handler
|
|
@@ -3838,7 +4219,7 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
|
|
|
3838
4219
|
});
|
|
3839
4220
|
const { imports, importsMock, implementation, implementationMock, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, fetchReviver } = generateTarget(builder, output);
|
|
3840
4221
|
let data = header;
|
|
3841
|
-
const schemasPath = output.schemas ? relativeSafe(dirname$1, getFileInfo(
|
|
4222
|
+
const schemasPath = output.schemas ? relativeSafe(dirname$1, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : void 0;
|
|
3842
4223
|
const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
|
|
3843
4224
|
const importsForBuilder = schemasPath ? generateImportsForBuilder(output, imports.filter((imp) => !importsMock.some((impMock) => imp.name === impMock.name)), schemasPath) : [];
|
|
3844
4225
|
data += builder.imports({
|
|
@@ -3907,7 +4288,7 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
|
|
|
3907
4288
|
const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, fetchReviver } = generateTarget(builder, output);
|
|
3908
4289
|
let implementationData = header;
|
|
3909
4290
|
let mockData = header;
|
|
3910
|
-
const relativeSchemasPath = output.schemas ? relativeSafe(dirname$1, getFileInfo(
|
|
4291
|
+
const relativeSchemasPath = output.schemas ? relativeSafe(dirname$1, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas";
|
|
3911
4292
|
const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
|
|
3912
4293
|
const importsForBuilder = generateImportsForBuilder(output, imports, relativeSchemasPath);
|
|
3913
4294
|
implementationData += builder.imports({
|
|
@@ -3967,7 +4348,7 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
|
|
|
3967
4348
|
...mockPath ? [mockPath] : []
|
|
3968
4349
|
];
|
|
3969
4350
|
} catch (error) {
|
|
3970
|
-
throw new Error(`Oups... 🍻. An Error occurred while splitting => ${error}`);
|
|
4351
|
+
throw new Error(`Oups... 🍻. An Error occurred while splitting => ${String(error)}`);
|
|
3971
4352
|
}
|
|
3972
4353
|
}
|
|
3973
4354
|
|
|
@@ -3981,8 +4362,7 @@ function addDefaultTagIfEmpty(operation) {
|
|
|
3981
4362
|
}
|
|
3982
4363
|
function generateTargetTags(currentAcc, operation) {
|
|
3983
4364
|
const tag = kebab(operation.tags[0]);
|
|
3984
|
-
|
|
3985
|
-
if (!currentOperation) {
|
|
4365
|
+
if (!(tag in currentAcc)) {
|
|
3986
4366
|
currentAcc[tag] = {
|
|
3987
4367
|
imports: operation.imports,
|
|
3988
4368
|
importsMock: operation.importsMock,
|
|
@@ -4001,6 +4381,7 @@ function generateTargetTags(currentAcc, operation) {
|
|
|
4001
4381
|
};
|
|
4002
4382
|
return currentAcc;
|
|
4003
4383
|
}
|
|
4384
|
+
const currentOperation = currentAcc[tag];
|
|
4004
4385
|
currentAcc[tag] = {
|
|
4005
4386
|
implementation: currentOperation.implementation + operation.implementation,
|
|
4006
4387
|
imports: [...currentOperation.imports, ...operation.imports],
|
|
@@ -4021,66 +4402,69 @@ function generateTargetTags(currentAcc, operation) {
|
|
|
4021
4402
|
}
|
|
4022
4403
|
function generateTargetForTags(builder, options) {
|
|
4023
4404
|
const isAngularClient = options.client === OutputClient.ANGULAR;
|
|
4024
|
-
const
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
const
|
|
4030
|
-
const
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4405
|
+
const operations = Object.values(builder.operations).map((operation) => addDefaultTagIfEmpty(operation));
|
|
4406
|
+
let allTargetTags = {};
|
|
4407
|
+
for (const [index, operation] of operations.entries()) {
|
|
4408
|
+
allTargetTags = generateTargetTags(allTargetTags, operation);
|
|
4409
|
+
if (index === operations.length - 1) {
|
|
4410
|
+
const transformed = {};
|
|
4411
|
+
for (const [tag, target] of Object.entries(allTargetTags)) {
|
|
4412
|
+
const isMutator = !!target.mutators?.some((mutator) => isAngularClient ? mutator.hasThirdArg : mutator.hasSecondArg);
|
|
4413
|
+
const operationNames = Object.values(builder.operations).filter(({ tags }) => tags.map((tag$1) => kebab(tag$1)).indexOf(kebab(tag)) === 0).map(({ operationName }) => operationName);
|
|
4414
|
+
const hasAwaitedType = compareVersions(options.packageJson?.dependencies?.typescript ?? options.packageJson?.devDependencies?.typescript ?? "4.4.0", "4.5.0");
|
|
4415
|
+
const titles = builder.title({
|
|
4416
|
+
outputClient: options.client,
|
|
4417
|
+
title: pascal(tag),
|
|
4418
|
+
customTitleFunc: options.override.title,
|
|
4419
|
+
output: options
|
|
4420
|
+
});
|
|
4421
|
+
const footer = builder.footer({
|
|
4422
|
+
outputClient: options.client,
|
|
4423
|
+
operationNames,
|
|
4424
|
+
hasMutator: !!target.mutators?.length,
|
|
4425
|
+
hasAwaitedType,
|
|
4426
|
+
titles,
|
|
4427
|
+
output: options
|
|
4428
|
+
});
|
|
4429
|
+
const header = builder.header({
|
|
4430
|
+
outputClient: options.client,
|
|
4431
|
+
isRequestOptions: options.override.requestOptions !== false,
|
|
4432
|
+
isMutator,
|
|
4433
|
+
isGlobalMutator: !!options.override.mutator,
|
|
4434
|
+
provideIn: options.override.angular.provideIn,
|
|
4435
|
+
hasAwaitedType,
|
|
4436
|
+
titles,
|
|
4437
|
+
output: options,
|
|
4438
|
+
verbOptions: builder.verbOptions,
|
|
4439
|
+
tag,
|
|
4440
|
+
clientImplementation: target.implementation
|
|
4441
|
+
});
|
|
4442
|
+
transformed[tag] = {
|
|
4443
|
+
implementation: header.implementation + target.implementation + footer.implementation,
|
|
4444
|
+
implementationMock: {
|
|
4445
|
+
function: target.implementationMock.function,
|
|
4446
|
+
handler: target.implementationMock.handler + header.implementationMock + target.implementationMock.handlerName + footer.implementationMock,
|
|
4447
|
+
handlerName: target.implementationMock.handlerName
|
|
4448
|
+
},
|
|
4449
|
+
imports: target.imports,
|
|
4450
|
+
importsMock: target.importsMock,
|
|
4451
|
+
mutators: target.mutators,
|
|
4452
|
+
clientMutators: target.clientMutators,
|
|
4453
|
+
formData: target.formData,
|
|
4454
|
+
formUrlEncoded: target.formUrlEncoded,
|
|
4455
|
+
paramsSerializer: target.paramsSerializer,
|
|
4456
|
+
fetchReviver: target.fetchReviver
|
|
4457
|
+
};
|
|
4458
|
+
}
|
|
4459
|
+
allTargetTags = transformed;
|
|
4460
|
+
}
|
|
4461
|
+
}
|
|
4462
|
+
const result = {};
|
|
4463
|
+
for (const [tag, target] of Object.entries(allTargetTags)) result[tag] = {
|
|
4464
|
+
...target,
|
|
4465
|
+
implementationMock: target.implementationMock.function + target.implementationMock.handler
|
|
4466
|
+
};
|
|
4467
|
+
return result;
|
|
4084
4468
|
}
|
|
4085
4469
|
|
|
4086
4470
|
//#endregion
|
|
@@ -4092,14 +4476,15 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4092
4476
|
});
|
|
4093
4477
|
const target = generateTargetForTags(builder, output);
|
|
4094
4478
|
const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
|
|
4095
|
-
const
|
|
4479
|
+
const mockOption = output.mock && !isFunction(output.mock) ? output.mock : void 0;
|
|
4480
|
+
const indexFilePath = mockOption?.indexMockFiles ? join(dirname$1, "index." + getMockFileExtensionByTypeName(mockOption) + extension) : void 0;
|
|
4096
4481
|
if (indexFilePath) await fs$1.outputFile(indexFilePath, "");
|
|
4097
4482
|
return (await Promise.all(Object.entries(target).map(async ([tag, target$1]) => {
|
|
4098
4483
|
try {
|
|
4099
4484
|
const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, fetchReviver, formUrlEncoded, paramsSerializer } = target$1;
|
|
4100
4485
|
let implementationData = header;
|
|
4101
4486
|
let mockData = header;
|
|
4102
|
-
const relativeSchemasPath = output.schemas ? "../" + relativeSafe(dirname$1, getFileInfo(
|
|
4487
|
+
const relativeSchemasPath = output.schemas ? "../" + relativeSafe(dirname$1, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "../" + filename + ".schemas";
|
|
4103
4488
|
const importsForBuilder = generateImportsForBuilder(output, imports, relativeSchemasPath);
|
|
4104
4489
|
implementationData += builder.imports({
|
|
4105
4490
|
client: output.client,
|
|
@@ -4169,9 +4554,9 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4169
4554
|
const mockPath = output.mock ? join(dirname$1, tag, tag + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
|
|
4170
4555
|
if (mockPath) {
|
|
4171
4556
|
await fs$1.outputFile(mockPath, mockData);
|
|
4172
|
-
if (indexFilePath) {
|
|
4173
|
-
const localMockPath = joinSafe("./", tag, tag + "." + getMockFileExtensionByTypeName(
|
|
4174
|
-
fs$1.appendFile(indexFilePath, `export { get${pascal(tag)}Mock } from '${localMockPath}'\n`);
|
|
4557
|
+
if (indexFilePath && mockOption) {
|
|
4558
|
+
const localMockPath = joinSafe("./", tag, tag + "." + getMockFileExtensionByTypeName(mockOption));
|
|
4559
|
+
await fs$1.appendFile(indexFilePath, `export { get${pascal(tag)}Mock } from '${localMockPath}'\n`);
|
|
4175
4560
|
}
|
|
4176
4561
|
}
|
|
4177
4562
|
return [
|
|
@@ -4180,7 +4565,7 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4180
4565
|
...mockPath ? [mockPath] : []
|
|
4181
4566
|
];
|
|
4182
4567
|
} catch (error) {
|
|
4183
|
-
throw new Error(`Oups... 🍻. An Error occurred while splitting tag ${tag} => ${error}`);
|
|
4568
|
+
throw new Error(`Oups... 🍻. An Error occurred while splitting tag ${tag} => ${String(error)}`);
|
|
4184
4569
|
}
|
|
4185
4570
|
}))).flat();
|
|
4186
4571
|
}
|
|
@@ -4198,7 +4583,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema
|
|
|
4198
4583
|
try {
|
|
4199
4584
|
const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, formUrlEncoded, fetchReviver, paramsSerializer } = target$1;
|
|
4200
4585
|
let data = header;
|
|
4201
|
-
const schemasPathRelative = output.schemas ? relativeSafe(dirname$1, getFileInfo(
|
|
4586
|
+
const schemasPathRelative = output.schemas ? relativeSafe(dirname$1, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas";
|
|
4202
4587
|
const importsForBuilder = generateImportsForBuilder(output, imports.filter((imp) => !importsMock.some((impMock) => imp.name === impMock.name)), schemasPathRelative);
|
|
4203
4588
|
data += builder.imports({
|
|
4204
4589
|
client: output.client,
|
|
@@ -4256,11 +4641,11 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema
|
|
|
4256
4641
|
await fs$1.outputFile(implementationPath, data);
|
|
4257
4642
|
return [implementationPath, ...schemasPath ? [schemasPath] : []];
|
|
4258
4643
|
} catch (error) {
|
|
4259
|
-
throw new Error(`Oups... 🍻. An Error occurred while writing tag ${tag} => ${error}`);
|
|
4644
|
+
throw new Error(`Oups... 🍻. An Error occurred while writing tag ${tag} => ${String(error)}`);
|
|
4260
4645
|
}
|
|
4261
4646
|
}))).flat();
|
|
4262
4647
|
}
|
|
4263
4648
|
|
|
4264
4649
|
//#endregion
|
|
4265
|
-
export { BODY_TYPE_NAME, EnumGeneration, ErrorWithTag, FormDataArrayHandling, GetterPropType, LogLevels, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SchemaType, TEMPLATE_TAG_REGEX, URL_REGEX, VERBS_WITH_BODY, Verbs, _filteredVerbs, addDependency, asyncReduce, camel, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dedupeUnionType, dynamicImport, escape, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFormDataAndUrlEncodedFunction, generateImports, generateModelInline, generateModelsInline, generateMutator, generateMutatorConfig, generateMutatorImports, generateMutatorRequestOptions, generateOptions, generateParameterDefinition, generateQueryParamsAxiosConfig, generateSchemasDefinition, generateTarget, generateTargetForTags, generateVerbImports, generateVerbOptions, generateVerbsOptions, getArray, getBody, getCombinedEnumValue, getDefaultContentType, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getEnumUnionFromSchema, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getTypedResponse, isBinaryContentType, isBoolean, isDirectory, isFunction, isModule,
|
|
4650
|
+
export { BODY_TYPE_NAME, EnumGeneration, ErrorWithTag, FormDataArrayHandling, GetterPropType, LogLevels, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SchemaType, TEMPLATE_TAG_REGEX, URL_REGEX, VERBS_WITH_BODY, Verbs, _filteredVerbs, addDependency, asyncReduce, camel, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dedupeUnionType, dynamicImport, escape, filterByContentType, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFormDataAndUrlEncodedFunction, generateImports, generateModelInline, generateModelsInline, generateMutator, generateMutatorConfig, generateMutatorImports, generateMutatorRequestOptions, generateOptions, generateParameterDefinition, generateQueryParamsAxiosConfig, generateSchemasDefinition, generateTarget, generateTargetForTags, generateVerbImports, generateVerbOptions, generateVerbsOptions, getAngularFilteredParamsCallExpression, getAngularFilteredParamsExpression, getAngularFilteredParamsHelperBody, getArray, getBody, getCombinedEnumValue, getDefaultContentType, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getEnumUnionFromSchema, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getRequestBodyContentTypes, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getSuccessResponseType, getTypedResponse, isBinaryContentType, isBoolean, isDirectory, isFunction, isModule, isNullish, isNumber, isNumeric, isObject, isReference, isSchema, isString, isStringLike, isSyntheticDefaultImportsAllow, isUrl, isVerb, jsDoc, jsStringEscape, kebab, keyValuePairsToJsDoc, log, logError, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resolveDiscriminators, resolveExampleRefs, resolveInstalledVersion, resolveInstalledVersions, resolveObject, resolveRef, resolveValue, sanitize, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_exports as upath, upper, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
|
|
4266
4651
|
//# sourceMappingURL=index.mjs.map
|