orval 8.0.0-rc.2 → 8.0.0-rc.3
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.
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { FormDataArrayHandling, GetterPropType, NamingConvention, OutputClient, OutputHttpClient, OutputMode, PropertySortOrder, RefComponentSuffix, asyncReduce, createLogger, createSuccessMessage, dynamicImport, generateComponentDefinition, generateDependencyImports, generateParameterDefinition, generateSchemasDefinition, generateVerbsOptions, getFileInfo, getFullRoute, getMockFileExtensionByTypeName, getRoute,
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import yaml from "js-yaml";
|
|
2
|
+
import { FormDataArrayHandling, GetterPropType, NamingConvention, OutputClient, OutputHttpClient, OutputMode, PropertySortOrder, RefComponentSuffix, asyncReduce, createLogger, createSuccessMessage, dynamicImport, generateComponentDefinition, generateDependencyImports, generateParameterDefinition, generateSchemasDefinition, generateVerbsOptions, getFileInfo, getFullRoute, getMockFileExtensionByTypeName, getRoute, isBoolean, isFunction, isObject, isReference, isString, isUndefined, isUrl, jsDoc, log, logError, pascal, removeFilesAndEmptyFolders, resolveRef, upath, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode } from "@orval/core";
|
|
3
|
+
import { bundle } from "@scalar/json-magic/bundle";
|
|
4
|
+
import { fetchUrls, parseJson, parseYaml, readFiles } from "@scalar/json-magic/bundle/plugins/node";
|
|
5
|
+
import { upgrade, validate } from "@scalar/openapi-parser";
|
|
7
6
|
import * as mock from "@orval/mock";
|
|
8
7
|
import { DEFAULT_MOCK_OPTIONS, generateMockImports } from "@orval/mock";
|
|
9
8
|
import angular from "@orval/angular";
|
|
@@ -14,12 +13,13 @@ import mcp from "@orval/mcp";
|
|
|
14
13
|
import query from "@orval/query";
|
|
15
14
|
import swr from "@orval/swr";
|
|
16
15
|
import zod from "@orval/zod";
|
|
16
|
+
import chalk from "chalk";
|
|
17
17
|
import { ExecaError, execa } from "execa";
|
|
18
|
+
import fs from "fs-extra";
|
|
18
19
|
import { unique } from "remeda";
|
|
19
20
|
import { parseArgsStringToArgv } from "string-argv";
|
|
20
|
-
import https from "node:https";
|
|
21
|
-
import enquirer from "enquirer";
|
|
22
21
|
import { findUp } from "find-up";
|
|
22
|
+
import yaml from "js-yaml";
|
|
23
23
|
import { parse } from "tsconfck";
|
|
24
24
|
import fs$1 from "node:fs";
|
|
25
25
|
import { createJiti } from "jiti";
|
|
@@ -27,7 +27,7 @@ import { createJiti } from "jiti";
|
|
|
27
27
|
//#region package.json
|
|
28
28
|
var name = "orval";
|
|
29
29
|
var description = "A swagger client generator for typescript";
|
|
30
|
-
var version = "8.0.0-rc.
|
|
30
|
+
var version = "8.0.0-rc.3";
|
|
31
31
|
|
|
32
32
|
//#endregion
|
|
33
33
|
//#region src/client.ts
|
|
@@ -59,9 +59,9 @@ const getGeneratorClient = (outputClient, output) => {
|
|
|
59
59
|
if (!generator) throw new Error(`Oups... 🍻. Client not found: ${outputClient}`);
|
|
60
60
|
return generator;
|
|
61
61
|
};
|
|
62
|
-
const generateClientImports = ({ client = DEFAULT_CLIENT, implementation, imports,
|
|
62
|
+
const generateClientImports = ({ client = DEFAULT_CLIENT, implementation, imports, projectName, hasSchemaDir, isAllowSyntheticDefaultImports, hasGlobalMutator, hasTagsMutator, hasParamsSerializerOptions, packageJson, output }) => {
|
|
63
63
|
const { dependencies } = getGeneratorClient(client, output);
|
|
64
|
-
return generateDependencyImports(implementation, dependencies ? [...dependencies(hasGlobalMutator, hasParamsSerializerOptions, packageJson, output.httpClient, hasTagsMutator, output.override), ...imports] : imports,
|
|
64
|
+
return generateDependencyImports(implementation, dependencies ? [...dependencies(hasGlobalMutator, hasParamsSerializerOptions, packageJson, output.httpClient, hasTagsMutator, output.override), ...imports] : imports, projectName, hasSchemaDir, isAllowSyntheticDefaultImports);
|
|
65
65
|
};
|
|
66
66
|
const generateClientHeader = ({ outputClient = DEFAULT_CLIENT, isRequestOptions, isGlobalMutator, isMutator, provideIn, hasAwaitedType, titles, output, verbOptions, tag, clientImplementation }) => {
|
|
67
67
|
const { header } = getGeneratorClient(outputClient, output);
|
|
@@ -172,18 +172,13 @@ const generateExtraFiles = (outputClient = DEFAULT_CLIENT, verbsOptions, output,
|
|
|
172
172
|
|
|
173
173
|
//#endregion
|
|
174
174
|
//#region src/api.ts
|
|
175
|
-
|
|
176
|
-
const api = await asyncReduce(Object.entries(context.
|
|
175
|
+
async function getApiBuilder({ input, output, context }) {
|
|
176
|
+
const api = await asyncReduce(Object.entries(context.spec.paths ?? {}), async (acc, [pathRoute, verbs]) => {
|
|
177
177
|
const route = getRoute(pathRoute);
|
|
178
178
|
let resolvedVerbs = verbs;
|
|
179
|
-
let resolvedContext = context;
|
|
180
179
|
if (isReference(verbs)) {
|
|
181
180
|
const { schema, imports } = resolveRef(verbs, context);
|
|
182
181
|
resolvedVerbs = schema;
|
|
183
|
-
resolvedContext = {
|
|
184
|
-
...context,
|
|
185
|
-
...imports.length > 0 ? { specKey: imports[0].specKey } : {}
|
|
186
|
-
};
|
|
187
182
|
}
|
|
188
183
|
let verbsOptions = await generateVerbsOptions({
|
|
189
184
|
verbs: resolvedVerbs,
|
|
@@ -191,7 +186,7 @@ const getApiBuilder = async ({ input, output, context }) => {
|
|
|
191
186
|
output,
|
|
192
187
|
route,
|
|
193
188
|
pathRoute,
|
|
194
|
-
context
|
|
189
|
+
context
|
|
195
190
|
});
|
|
196
191
|
if (output.override.useDeprecatedOperations === false) verbsOptions = verbsOptions.filter((verb) => {
|
|
197
192
|
return !verb.deprecated;
|
|
@@ -203,13 +198,13 @@ const getApiBuilder = async ({ input, output, context }) => {
|
|
|
203
198
|
acc$1.push(...body.schemas, ...response.schemas);
|
|
204
199
|
return acc$1;
|
|
205
200
|
}, []);
|
|
206
|
-
const fullRoute = getFullRoute(route, verbs.servers ?? context.
|
|
201
|
+
const fullRoute = getFullRoute(route, verbs.servers ?? context.spec.servers, output.baseUrl);
|
|
207
202
|
if (!output.target) throw new Error("Output does not have a target");
|
|
208
203
|
const pathOperations = await generateOperations(output.client, verbsOptions, {
|
|
209
204
|
route: fullRoute,
|
|
210
205
|
pathRoute,
|
|
211
206
|
override: output.override,
|
|
212
|
-
context
|
|
207
|
+
context,
|
|
213
208
|
mock: output.mock,
|
|
214
209
|
output: output.target
|
|
215
210
|
}, output);
|
|
@@ -237,155 +232,145 @@ const getApiBuilder = async ({ input, output, context }) => {
|
|
|
237
232
|
importsMock: generateMockImports,
|
|
238
233
|
extraFiles
|
|
239
234
|
};
|
|
240
|
-
}
|
|
235
|
+
}
|
|
241
236
|
|
|
242
237
|
//#endregion
|
|
243
238
|
//#region src/import-open-api.ts
|
|
244
|
-
|
|
245
|
-
const
|
|
246
|
-
specs: data,
|
|
247
|
-
input,
|
|
248
|
-
workspace
|
|
249
|
-
});
|
|
239
|
+
async function importOpenApi({ spec, input, output, target, workspace, projectName }) {
|
|
240
|
+
const transformedOpenApi = await applyTransformer(spec, input.override.transformer, workspace);
|
|
250
241
|
const schemas = getApiSchemas({
|
|
251
242
|
input,
|
|
252
243
|
output,
|
|
253
244
|
target,
|
|
254
245
|
workspace,
|
|
255
|
-
|
|
246
|
+
spec: transformedOpenApi
|
|
256
247
|
});
|
|
257
248
|
const api = await getApiBuilder({
|
|
258
249
|
input,
|
|
259
250
|
output,
|
|
260
251
|
context: {
|
|
261
|
-
|
|
252
|
+
projectName,
|
|
262
253
|
target,
|
|
263
254
|
workspace,
|
|
264
|
-
|
|
255
|
+
spec: transformedOpenApi,
|
|
265
256
|
output
|
|
266
257
|
}
|
|
267
258
|
});
|
|
268
259
|
return {
|
|
269
260
|
...api,
|
|
270
|
-
schemas:
|
|
271
|
-
...schemas,
|
|
272
|
-
[target]: [...schemas[target] ?? [], ...api.schemas]
|
|
273
|
-
},
|
|
261
|
+
schemas: [...schemas, ...api.schemas],
|
|
274
262
|
target,
|
|
275
|
-
info:
|
|
263
|
+
info: transformedOpenApi.info
|
|
276
264
|
};
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const transformerFn =
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
target,
|
|
293
|
-
workspace,
|
|
294
|
-
specs,
|
|
295
|
-
output
|
|
296
|
-
};
|
|
297
|
-
const schemaDefinition = generateSchemasDefinition(spec.openapi ? spec.components?.schemas : getAllSchemas(spec, specKey), context, output.override.components.schemas.suffix, input.filters);
|
|
298
|
-
const responseDefinition = generateComponentDefinition(spec.components?.responses, context, output.override.components.responses.suffix);
|
|
299
|
-
const bodyDefinition = generateComponentDefinition(spec.components?.requestBodies, context, output.override.components.requestBodies.suffix);
|
|
300
|
-
const parameters = generateParameterDefinition(spec.components?.parameters, context, output.override.components.parameters.suffix);
|
|
301
|
-
const schemas = [
|
|
302
|
-
...schemaDefinition,
|
|
303
|
-
...responseDefinition,
|
|
304
|
-
...bodyDefinition,
|
|
305
|
-
...parameters
|
|
306
|
-
];
|
|
307
|
-
if (schemas.length === 0) return acc;
|
|
308
|
-
acc[specKey] = schemas;
|
|
309
|
-
return acc;
|
|
310
|
-
}, {});
|
|
311
|
-
};
|
|
312
|
-
const getAllSchemas = (spec, specKey) => {
|
|
313
|
-
const keysToOmit = new Set([
|
|
314
|
-
"openapi",
|
|
315
|
-
"info",
|
|
316
|
-
"servers",
|
|
317
|
-
"paths",
|
|
318
|
-
"components",
|
|
319
|
-
"security",
|
|
320
|
-
"tags",
|
|
321
|
-
"externalDocs"
|
|
322
|
-
]);
|
|
323
|
-
const cleanedSpec = Object.fromEntries(Object.entries(spec).filter(([key]) => !keysToOmit.has(key)));
|
|
324
|
-
if (specKey && isSchema(cleanedSpec)) {
|
|
325
|
-
const name$1 = upath.getSchemaFileName(specKey);
|
|
326
|
-
const additionalKeysToOmit = new Set([
|
|
327
|
-
"type",
|
|
328
|
-
"properties",
|
|
329
|
-
"allOf",
|
|
330
|
-
"oneOf",
|
|
331
|
-
"anyOf",
|
|
332
|
-
"items"
|
|
333
|
-
]);
|
|
334
|
-
return {
|
|
335
|
-
[name$1]: cleanedSpec,
|
|
336
|
-
...getAllSchemas(Object.fromEntries(Object.entries(cleanedSpec).filter(([key]) => !additionalKeysToOmit.has(key))))
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
return {
|
|
340
|
-
...Object.entries(cleanedSpec).reduce((acc, [key, value]) => {
|
|
341
|
-
if (!isObject(value)) return acc;
|
|
342
|
-
if (!isSchema(value) && !isReference(value)) return {
|
|
343
|
-
...acc,
|
|
344
|
-
...getAllSchemas(value)
|
|
345
|
-
};
|
|
346
|
-
acc[key] = value;
|
|
347
|
-
return acc;
|
|
348
|
-
}, {}),
|
|
349
|
-
...spec?.components?.schemas
|
|
265
|
+
}
|
|
266
|
+
async function applyTransformer(openApi, transformer, workspace) {
|
|
267
|
+
const transformerFn = transformer ? await dynamicImport(transformer, workspace) : void 0;
|
|
268
|
+
if (!transformerFn) return openApi;
|
|
269
|
+
const transformedOpenApi = transformerFn(openApi);
|
|
270
|
+
const { valid, errors } = await validate(transformedOpenApi);
|
|
271
|
+
if (!valid) throw new Error(`Validation failed`, { cause: errors });
|
|
272
|
+
return transformedOpenApi;
|
|
273
|
+
}
|
|
274
|
+
function getApiSchemas({ input, output, target, workspace, spec }) {
|
|
275
|
+
const context = {
|
|
276
|
+
target,
|
|
277
|
+
workspace,
|
|
278
|
+
spec,
|
|
279
|
+
output
|
|
350
280
|
};
|
|
351
|
-
|
|
281
|
+
const schemaDefinition = generateSchemasDefinition(spec.components?.schemas, context, output.override.components.schemas.suffix, input.filters);
|
|
282
|
+
const responseDefinition = generateComponentDefinition(spec.components?.responses, context, output.override.components.responses.suffix);
|
|
283
|
+
const bodyDefinition = generateComponentDefinition(spec.components?.requestBodies, context, output.override.components.requestBodies.suffix);
|
|
284
|
+
const parameters = generateParameterDefinition(spec.components?.parameters, context, output.override.components.parameters.suffix);
|
|
285
|
+
return [
|
|
286
|
+
...schemaDefinition,
|
|
287
|
+
...responseDefinition,
|
|
288
|
+
...bodyDefinition,
|
|
289
|
+
...parameters
|
|
290
|
+
];
|
|
291
|
+
}
|
|
352
292
|
|
|
353
293
|
//#endregion
|
|
354
294
|
//#region src/import-specs.ts
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
const importSpecs = async (workspace, options) => {
|
|
295
|
+
async function resolveSpec(input) {
|
|
296
|
+
const dereferencedData = dereferenceExternalRef(await bundle(input, {
|
|
297
|
+
plugins: [
|
|
298
|
+
readFiles(),
|
|
299
|
+
fetchUrls(),
|
|
300
|
+
parseJson(),
|
|
301
|
+
parseYaml()
|
|
302
|
+
],
|
|
303
|
+
treeShake: true
|
|
304
|
+
}));
|
|
305
|
+
const { valid, errors } = await validate(dereferencedData);
|
|
306
|
+
if (!valid) throw new Error("Validation failed", { cause: errors });
|
|
307
|
+
const { specification } = upgrade(dereferencedData);
|
|
308
|
+
return specification;
|
|
309
|
+
}
|
|
310
|
+
async function importSpecs(workspace, options, projectName) {
|
|
372
311
|
const { input, output } = options;
|
|
373
|
-
if (!isString(input.target)) return importOpenApi({
|
|
374
|
-
data: { [workspace]: input.target },
|
|
375
|
-
input,
|
|
376
|
-
output,
|
|
377
|
-
target: workspace,
|
|
378
|
-
workspace
|
|
379
|
-
});
|
|
380
|
-
const isPathUrl = isUrl(input.target);
|
|
381
312
|
return importOpenApi({
|
|
382
|
-
|
|
313
|
+
spec: await resolveSpec(input.target),
|
|
383
314
|
input,
|
|
384
315
|
output,
|
|
385
316
|
target: input.target,
|
|
386
|
-
workspace
|
|
317
|
+
workspace,
|
|
318
|
+
projectName
|
|
387
319
|
});
|
|
388
|
-
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* The plugins from `@scalar/json-magic` does not dereference $ref.
|
|
323
|
+
* Instead if fetches them and puts them under x-ext, and changes the $ref to point to #x-ext/<name>.
|
|
324
|
+
* This function dereferences those x-ext $ref's.
|
|
325
|
+
*/
|
|
326
|
+
function dereferenceExternalRef(data) {
|
|
327
|
+
const extensions = data["x-ext"] ?? {};
|
|
328
|
+
const UNWANTED_KEYS = new Set(["$schema", "$id"]);
|
|
329
|
+
function scrub(obj) {
|
|
330
|
+
if (obj === null || obj === void 0) return obj;
|
|
331
|
+
if (Array.isArray(obj)) return obj.map((x) => scrub(x));
|
|
332
|
+
if (typeof obj === "object") {
|
|
333
|
+
const rec = obj;
|
|
334
|
+
const out = {};
|
|
335
|
+
for (const [k, v] of Object.entries(rec)) {
|
|
336
|
+
if (UNWANTED_KEYS.has(k)) continue;
|
|
337
|
+
out[k] = scrub(v);
|
|
338
|
+
}
|
|
339
|
+
return out;
|
|
340
|
+
}
|
|
341
|
+
return obj;
|
|
342
|
+
}
|
|
343
|
+
function replaceRefs(obj) {
|
|
344
|
+
if (obj === null || obj === void 0) return obj;
|
|
345
|
+
if (typeof obj === "object") {
|
|
346
|
+
if (Array.isArray(obj)) return obj.map((element) => replaceRefs(element));
|
|
347
|
+
const record = obj;
|
|
348
|
+
if ("$ref" in record && typeof record.$ref === "string") {
|
|
349
|
+
const refValue = record.$ref;
|
|
350
|
+
if (refValue.startsWith("#/x-ext/")) {
|
|
351
|
+
const parts = refValue.replace("#/x-ext/", "").split("/");
|
|
352
|
+
const extKey = parts.shift();
|
|
353
|
+
if (extKey) {
|
|
354
|
+
let refObj = extensions[extKey];
|
|
355
|
+
for (const p of parts) if (refObj && typeof refObj === "object" && p in refObj) refObj = refObj[p];
|
|
356
|
+
else {
|
|
357
|
+
refObj = void 0;
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
if (refObj) return replaceRefs(scrub(refObj));
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const result$1 = {};
|
|
365
|
+
for (const [key, value] of Object.entries(record)) result$1[key] = replaceRefs(value);
|
|
366
|
+
return result$1;
|
|
367
|
+
}
|
|
368
|
+
return obj;
|
|
369
|
+
}
|
|
370
|
+
const result = {};
|
|
371
|
+
for (const [key, value] of Object.entries(data)) if (key !== "x-ext") result[key] = replaceRefs(value);
|
|
372
|
+
return result;
|
|
373
|
+
}
|
|
389
374
|
|
|
390
375
|
//#endregion
|
|
391
376
|
//#region src/utils/execute-hook.ts
|
|
@@ -409,123 +394,6 @@ async function executeObjectCommand(command, args) {
|
|
|
409
394
|
else if (isFunction(command.command)) await command.command();
|
|
410
395
|
}
|
|
411
396
|
|
|
412
|
-
//#endregion
|
|
413
|
-
//#region src/utils/request.ts
|
|
414
|
-
const request = (urlOptions, data) => {
|
|
415
|
-
return new Promise((resolve, reject) => {
|
|
416
|
-
const req = https.request(urlOptions, (res) => {
|
|
417
|
-
let body = "";
|
|
418
|
-
res.on("data", (chunk) => body += chunk.toString());
|
|
419
|
-
res.on("error", reject);
|
|
420
|
-
res.on("end", () => {
|
|
421
|
-
const response = {
|
|
422
|
-
status: res.statusCode,
|
|
423
|
-
headers: res.headers,
|
|
424
|
-
body: JSON.parse(body)
|
|
425
|
-
};
|
|
426
|
-
if (res.statusCode && res.statusCode >= 200 && res.statusCode <= 299) resolve(response);
|
|
427
|
-
else reject(response);
|
|
428
|
-
});
|
|
429
|
-
});
|
|
430
|
-
req.on("error", reject);
|
|
431
|
-
if (data) req.write(data, "binary");
|
|
432
|
-
req.end();
|
|
433
|
-
});
|
|
434
|
-
};
|
|
435
|
-
|
|
436
|
-
//#endregion
|
|
437
|
-
//#region src/utils/github.ts
|
|
438
|
-
const getGithubSpecReq = ({ accessToken, repo, owner, branch, path: path$1 }) => {
|
|
439
|
-
const payload = JSON.stringify({ query: `query {
|
|
440
|
-
repository(name: "${repo}", owner: "${owner}") {
|
|
441
|
-
object(expression: "${branch}:${path$1}") {
|
|
442
|
-
... on Blob {
|
|
443
|
-
text
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}` });
|
|
448
|
-
return [{
|
|
449
|
-
method: "POST",
|
|
450
|
-
hostname: "api.github.com",
|
|
451
|
-
path: "/graphql",
|
|
452
|
-
headers: {
|
|
453
|
-
"content-type": "application/json",
|
|
454
|
-
"user-agent": "orval-importer",
|
|
455
|
-
authorization: `bearer ${accessToken}`,
|
|
456
|
-
"Content-Length": payload.length
|
|
457
|
-
}
|
|
458
|
-
}, payload];
|
|
459
|
-
};
|
|
460
|
-
let githubToken = null;
|
|
461
|
-
const getGithubAcessToken = async (githubTokenPath) => {
|
|
462
|
-
if (githubToken) return githubToken;
|
|
463
|
-
if (await fs.pathExists(githubTokenPath)) return fs.readFile(githubTokenPath, "utf8");
|
|
464
|
-
else {
|
|
465
|
-
const answers = await enquirer.prompt([{
|
|
466
|
-
type: "input",
|
|
467
|
-
name: "githubToken",
|
|
468
|
-
message: "Please provide a GitHub token with `repo` rules checked (https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/)"
|
|
469
|
-
}, {
|
|
470
|
-
type: "confirm",
|
|
471
|
-
name: "saveToken",
|
|
472
|
-
message: "Would you like to store your token for the next time? (stored in your node_modules)"
|
|
473
|
-
}]);
|
|
474
|
-
githubToken = answers.githubToken;
|
|
475
|
-
if (answers.saveToken) await fs.outputFile(githubTokenPath, answers.githubToken);
|
|
476
|
-
return answers.githubToken;
|
|
477
|
-
}
|
|
478
|
-
};
|
|
479
|
-
const getGithubOpenApi = async (url) => {
|
|
480
|
-
const githubTokenPath = upath.join(import.meta.dirname, ".githubToken");
|
|
481
|
-
const accessToken = await getGithubAcessToken(githubTokenPath);
|
|
482
|
-
const [info] = url.split("github.com/").slice(-1);
|
|
483
|
-
const [owner, repo, , branch, ...paths] = info.split("/");
|
|
484
|
-
const path$1 = paths.join("/");
|
|
485
|
-
try {
|
|
486
|
-
const { body } = await request(...getGithubSpecReq({
|
|
487
|
-
accessToken,
|
|
488
|
-
repo,
|
|
489
|
-
owner,
|
|
490
|
-
branch,
|
|
491
|
-
path: path$1
|
|
492
|
-
}));
|
|
493
|
-
if (body.errors?.length) {
|
|
494
|
-
if (body.errors?.some((error) => error?.type === "NOT_FOUND")) {
|
|
495
|
-
if ((await enquirer.prompt([{
|
|
496
|
-
type: "confirm",
|
|
497
|
-
name: "removeToken",
|
|
498
|
-
message: "Your token doesn't have the correct permissions, should we remove it?"
|
|
499
|
-
}])).removeToken) await fs.unlink(githubTokenPath);
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
return body.data?.repository?.object.text;
|
|
503
|
-
} catch (error) {
|
|
504
|
-
if (!error.body) throw new Error(`Oups... 🍻. ${error}`);
|
|
505
|
-
if (error.body.message === "Bad credentials") {
|
|
506
|
-
if ((await enquirer.prompt([{
|
|
507
|
-
type: "confirm",
|
|
508
|
-
name: "removeToken",
|
|
509
|
-
message: "Your token doesn't have the correct permissions, should we remove it?"
|
|
510
|
-
}])).removeToken) await fs.unlink(githubTokenPath);
|
|
511
|
-
}
|
|
512
|
-
throw new Error(error.body.message || `Oups... 🍻. ${error}`);
|
|
513
|
-
}
|
|
514
|
-
};
|
|
515
|
-
const githubResolver = {
|
|
516
|
-
order: 199,
|
|
517
|
-
canRead(file) {
|
|
518
|
-
return file.url.includes("github.com");
|
|
519
|
-
},
|
|
520
|
-
read(file) {
|
|
521
|
-
return getGithubOpenApi(file.url);
|
|
522
|
-
}
|
|
523
|
-
};
|
|
524
|
-
|
|
525
|
-
//#endregion
|
|
526
|
-
//#region src/utils/http-resolver.ts
|
|
527
|
-
const httpResolver = { safeUrlResolver: false };
|
|
528
|
-
|
|
529
397
|
//#endregion
|
|
530
398
|
//#region src/utils/package-json.ts
|
|
531
399
|
const loadPackageJson = async (packageJson, workspace = process.cwd()) => {
|
|
@@ -621,7 +489,7 @@ const loadTsconfig = async (tsconfig, workspace = process.cwd()) => {
|
|
|
621
489
|
function defineConfig(options) {
|
|
622
490
|
return options;
|
|
623
491
|
}
|
|
624
|
-
|
|
492
|
+
function createFormData(workspace, formData) {
|
|
625
493
|
const defaultArrayHandling = FormDataArrayHandling.SERIALIZE;
|
|
626
494
|
if (formData === void 0) return {
|
|
627
495
|
disabled: false,
|
|
@@ -646,8 +514,8 @@ const createFormData = (workspace, formData) => {
|
|
|
646
514
|
mutator: normalizeMutator(workspace, formData),
|
|
647
515
|
arrayHandling: defaultArrayHandling
|
|
648
516
|
};
|
|
649
|
-
}
|
|
650
|
-
|
|
517
|
+
}
|
|
518
|
+
async function normalizeOptions(optionsExport, workspace = process.cwd(), globalOptions = {}) {
|
|
651
519
|
const options = await (isFunction(optionsExport) ? optionsExport() : optionsExport);
|
|
652
520
|
if (!options.input) throw new Error(chalk.red(`Config require an input`));
|
|
653
521
|
if (!options.output) throw new Error(chalk.red(`Config require an output`));
|
|
@@ -680,10 +548,7 @@ const normalizeOptions = async (optionsExport, workspace = process.cwd(), global
|
|
|
680
548
|
const normalizedOptions = {
|
|
681
549
|
input: {
|
|
682
550
|
target: globalOptions.input ? normalizePathOrUrl(globalOptions.input, process.cwd()) : normalizePathOrUrl(inputOptions.target, workspace),
|
|
683
|
-
validation: inputOptions.validation || false,
|
|
684
551
|
override: { transformer: normalizePath(inputOptions.override?.transformer, workspace) },
|
|
685
|
-
converterOptions: inputOptions.converterOptions ?? {},
|
|
686
|
-
parserOptions: mergeDeep(parserDefaultOptions, inputOptions.parserOptions ?? {}),
|
|
687
552
|
filters: inputOptions.filters
|
|
688
553
|
},
|
|
689
554
|
output: {
|
|
@@ -802,15 +667,8 @@ const normalizeOptions = async (optionsExport, workspace = process.cwd(), global
|
|
|
802
667
|
if (!normalizedOptions.input.target) throw new Error(chalk.red(`Config require an input target`));
|
|
803
668
|
if (!normalizedOptions.output.target && !normalizedOptions.output.schemas) throw new Error(chalk.red(`Config require an output target or schemas`));
|
|
804
669
|
return normalizedOptions;
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
validate: true,
|
|
808
|
-
resolve: {
|
|
809
|
-
github: githubResolver,
|
|
810
|
-
http: httpResolver
|
|
811
|
-
}
|
|
812
|
-
};
|
|
813
|
-
const normalizeMutator = (workspace, mutator) => {
|
|
670
|
+
}
|
|
671
|
+
function normalizeMutator(workspace, mutator) {
|
|
814
672
|
if (isObject(mutator)) {
|
|
815
673
|
if (!mutator.path) throw new Error(chalk.red(`Mutator need a path`));
|
|
816
674
|
return {
|
|
@@ -824,16 +682,16 @@ const normalizeMutator = (workspace, mutator) => {
|
|
|
824
682
|
default: true
|
|
825
683
|
};
|
|
826
684
|
return mutator;
|
|
827
|
-
}
|
|
828
|
-
|
|
685
|
+
}
|
|
686
|
+
function normalizePathOrUrl(path$1, workspace) {
|
|
829
687
|
if (isString(path$1) && !isUrl(path$1)) return normalizePath(path$1, workspace);
|
|
830
688
|
return path$1;
|
|
831
|
-
}
|
|
832
|
-
|
|
689
|
+
}
|
|
690
|
+
function normalizePath(path$1, workspace) {
|
|
833
691
|
if (!isString(path$1)) return path$1;
|
|
834
692
|
return upath.resolve(workspace, path$1);
|
|
835
|
-
}
|
|
836
|
-
|
|
693
|
+
}
|
|
694
|
+
function normalizeOperationsAndTags(operationsOrTags, workspace, global) {
|
|
837
695
|
return Object.fromEntries(Object.entries(operationsOrTags).map(([key, { transformer, mutator, formData, formUrlEncoded, paramsSerializer, query: query$1, zod: zod$1, ...rest }]) => {
|
|
838
696
|
return [key, {
|
|
839
697
|
...rest,
|
|
@@ -878,16 +736,16 @@ const normalizeOperationsAndTags = (operationsOrTags, workspace, global) => {
|
|
|
878
736
|
...paramsSerializer ? { paramsSerializer: normalizeMutator(workspace, paramsSerializer) } : {}
|
|
879
737
|
}];
|
|
880
738
|
}));
|
|
881
|
-
}
|
|
882
|
-
|
|
739
|
+
}
|
|
740
|
+
function normalizeOutputMode(mode) {
|
|
883
741
|
if (!mode) return OutputMode.SINGLE;
|
|
884
742
|
if (!Object.values(OutputMode).includes(mode)) {
|
|
885
743
|
createLogger().warn(chalk.yellow(`Unknown the provided mode => ${mode}`));
|
|
886
744
|
return OutputMode.SINGLE;
|
|
887
745
|
}
|
|
888
746
|
return mode;
|
|
889
|
-
}
|
|
890
|
-
|
|
747
|
+
}
|
|
748
|
+
function normalizeHooks(hooks) {
|
|
891
749
|
return Object.keys(hooks).reduce((acc, key) => {
|
|
892
750
|
if (isString(hooks[key])) return {
|
|
893
751
|
...acc,
|
|
@@ -907,19 +765,19 @@ const normalizeHooks = (hooks) => {
|
|
|
907
765
|
};
|
|
908
766
|
return acc;
|
|
909
767
|
}, {});
|
|
910
|
-
}
|
|
911
|
-
|
|
768
|
+
}
|
|
769
|
+
function normalizeHonoOptions(hono$1 = {}, workspace) {
|
|
912
770
|
return {
|
|
913
771
|
...hono$1.handlers ? { handlers: upath.resolve(workspace, hono$1.handlers) } : {},
|
|
914
772
|
compositeRoute: hono$1.compositeRoute ?? "",
|
|
915
773
|
validator: hono$1.validator ?? true,
|
|
916
774
|
validatorOutputPath: hono$1.validatorOutputPath ? upath.resolve(workspace, hono$1.validatorOutputPath) : ""
|
|
917
775
|
};
|
|
918
|
-
}
|
|
919
|
-
|
|
776
|
+
}
|
|
777
|
+
function normalizeJSDocOptions(jsdoc = {}) {
|
|
920
778
|
return { ...jsdoc };
|
|
921
|
-
}
|
|
922
|
-
|
|
779
|
+
}
|
|
780
|
+
function normalizeQueryOptions(queryOptions = {}, outputWorkspace, globalOptions = {}) {
|
|
923
781
|
if (queryOptions.options) console.warn("[WARN] Using query options is deprecated and will be removed in a future major release. Please use queryOptions or mutationOptions instead.");
|
|
924
782
|
return {
|
|
925
783
|
...isUndefined(queryOptions.usePrefetch) ? {} : { usePrefetch: queryOptions.usePrefetch },
|
|
@@ -953,14 +811,16 @@ const normalizeQueryOptions = (queryOptions = {}, outputWorkspace, globalOptions
|
|
|
953
811
|
...isUndefined(globalOptions.version) ? {} : { version: globalOptions.version },
|
|
954
812
|
...isUndefined(queryOptions.version) ? {} : { version: queryOptions.version }
|
|
955
813
|
};
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
]
|
|
814
|
+
}
|
|
815
|
+
function getDefaultFilesHeader({ title, description: description$1, version: version$1 } = {}) {
|
|
816
|
+
return [
|
|
817
|
+
`Generated by ${name} v${version} 🍺`,
|
|
818
|
+
`Do not edit manually.`,
|
|
819
|
+
...title ? [title] : [],
|
|
820
|
+
...description$1 ? [description$1] : [],
|
|
821
|
+
...version$1 ? [`OpenAPI spec version: ${version$1}`] : []
|
|
822
|
+
];
|
|
823
|
+
}
|
|
964
824
|
|
|
965
825
|
//#endregion
|
|
966
826
|
//#region src/utils/watcher.ts
|
|
@@ -999,22 +859,18 @@ async function startWatcher(watchOptions, watchFn, defaultTarget = ".") {
|
|
|
999
859
|
|
|
1000
860
|
//#endregion
|
|
1001
861
|
//#region src/write-specs.ts
|
|
1002
|
-
|
|
862
|
+
function getHeader(option, info) {
|
|
1003
863
|
if (!option) return "";
|
|
1004
864
|
const header = option(info);
|
|
1005
865
|
return Array.isArray(header) ? jsDoc({ description: header }) : header;
|
|
1006
|
-
}
|
|
1007
|
-
|
|
866
|
+
}
|
|
867
|
+
async function writeSpecs(builder, workspace, options, projectName) {
|
|
1008
868
|
const { info = {
|
|
1009
869
|
title: "",
|
|
1010
870
|
version: 0
|
|
1011
871
|
}, schemas, target } = builder;
|
|
1012
872
|
const { output } = options;
|
|
1013
873
|
const projectTitle = projectName ?? info.title;
|
|
1014
|
-
const specsName = Object.keys(schemas).reduce((acc, specKey) => {
|
|
1015
|
-
acc[specKey] = upath.getSpecName(specKey, target).slice(1).split("/").join("-");
|
|
1016
|
-
return acc;
|
|
1017
|
-
}, {});
|
|
1018
874
|
const header = getHeader(output.override.header, info);
|
|
1019
875
|
if (output.schemas) {
|
|
1020
876
|
const rootSchemaPath = output.schemas;
|
|
@@ -1022,28 +878,23 @@ const writeSpecs = async (builder, workspace, options, projectName) => {
|
|
|
1022
878
|
"tags",
|
|
1023
879
|
"tags-split",
|
|
1024
880
|
"split"
|
|
1025
|
-
].includes(output.mode) ? ".ts" : output.fileExtension
|
|
1026
|
-
await
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
isRootKey: isRootKey(specKey, target),
|
|
1036
|
-
header,
|
|
1037
|
-
indexFiles: output.indexFiles
|
|
1038
|
-
});
|
|
1039
|
-
}));
|
|
881
|
+
].includes(output.mode) ? ".ts" : output.fileExtension;
|
|
882
|
+
await writeSchemas({
|
|
883
|
+
schemaPath: rootSchemaPath,
|
|
884
|
+
schemas,
|
|
885
|
+
target,
|
|
886
|
+
namingConvention: output.namingConvention,
|
|
887
|
+
fileExtension,
|
|
888
|
+
header,
|
|
889
|
+
indexFiles: output.indexFiles
|
|
890
|
+
});
|
|
1040
891
|
}
|
|
1041
892
|
let implementationPaths = [];
|
|
1042
893
|
if (output.target) implementationPaths = await getWriteMode(output.mode)({
|
|
1043
894
|
builder,
|
|
1044
895
|
workspace,
|
|
1045
896
|
output,
|
|
1046
|
-
|
|
897
|
+
projectName,
|
|
1047
898
|
header,
|
|
1048
899
|
needSchema: !output.schemas && output.client !== "zod"
|
|
1049
900
|
});
|
|
@@ -1110,8 +961,8 @@ const writeSpecs = async (builder, workspace, options, projectName) => {
|
|
|
1110
961
|
log(chalk.yellow(message));
|
|
1111
962
|
}
|
|
1112
963
|
createSuccessMessage(projectTitle);
|
|
1113
|
-
}
|
|
1114
|
-
|
|
964
|
+
}
|
|
965
|
+
function getWriteMode(mode) {
|
|
1115
966
|
switch (mode) {
|
|
1116
967
|
case OutputMode.SPLIT: return writeSplitMode;
|
|
1117
968
|
case OutputMode.TAGS: return writeTagsMode;
|
|
@@ -1119,7 +970,7 @@ const getWriteMode = (mode) => {
|
|
|
1119
970
|
case OutputMode.SINGLE:
|
|
1120
971
|
default: return writeSingleMode;
|
|
1121
972
|
}
|
|
1122
|
-
}
|
|
973
|
+
}
|
|
1123
974
|
|
|
1124
975
|
//#endregion
|
|
1125
976
|
//#region src/generate-spec.ts
|
|
@@ -1149,7 +1000,7 @@ async function generateSpec(workspace, options, projectName) {
|
|
|
1149
1000
|
], getFileInfo(options.output.schemas).dirname);
|
|
1150
1001
|
log(`${projectName} Cleaning output folder`);
|
|
1151
1002
|
}
|
|
1152
|
-
await writeSpecs(await importSpecs(workspace, options), workspace, options, projectName);
|
|
1003
|
+
await writeSpecs(await importSpecs(workspace, options, projectName), workspace, options, projectName);
|
|
1153
1004
|
}
|
|
1154
1005
|
|
|
1155
1006
|
//#endregion
|
|
@@ -1205,4 +1056,4 @@ async function loadConfigFile(configFilePath) {
|
|
|
1205
1056
|
|
|
1206
1057
|
//#endregion
|
|
1207
1058
|
export { defineConfig as a, name as c, startWatcher as i, version as l, loadConfigFile as n, normalizeOptions as o, generateSpec as r, description as s, findConfigFile as t };
|
|
1208
|
-
//# sourceMappingURL=config-
|
|
1059
|
+
//# sourceMappingURL=config-CJTbXPiX.mjs.map
|