@omer-x/next-openapi-json-generator 2.0.3 → 2.1.0-rc.2
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/index.cjs +36 -147
- package/dist/index.js +36 -147
- package/package.json +9 -6
package/dist/index.cjs
CHANGED
|
@@ -36,6 +36,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
36
36
|
|
|
37
37
|
// src/core/generateOpenApiSpec.ts
|
|
38
38
|
var import_node_path4 = __toESM(require("path"), 1);
|
|
39
|
+
var import_openapi_optimizer = require("@omer-x/openapi-optimizer");
|
|
39
40
|
var import_package_metadata = __toESM(require("@omer-x/package-metadata"), 1);
|
|
40
41
|
|
|
41
42
|
// src/utils/object.ts
|
|
@@ -281,54 +282,57 @@ function getRoutePathName(filePath, rootPath) {
|
|
|
281
282
|
return "/" + import_node_path3.default.relative(rootPath, dirName).replaceAll("[", "{").replaceAll("]", "}").replaceAll("\\", "/");
|
|
282
283
|
}
|
|
283
284
|
|
|
284
|
-
// src/
|
|
285
|
-
function
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
285
|
+
// src/core/route.ts
|
|
286
|
+
function createRouteRecord(method, filePath, rootPath, apiData) {
|
|
287
|
+
return {
|
|
288
|
+
method: method.toLocaleLowerCase(),
|
|
289
|
+
path: getRoutePathName(filePath, rootPath),
|
|
290
|
+
apiData
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function bundlePaths(source) {
|
|
294
|
+
source.sort((a, b) => a.path.localeCompare(b.path));
|
|
295
|
+
return source.reduce((collection, route) => ({
|
|
296
|
+
...collection,
|
|
297
|
+
[route.path]: {
|
|
298
|
+
...collection[route.path],
|
|
299
|
+
[route.method]: route.apiData
|
|
297
300
|
}
|
|
298
|
-
|
|
299
|
-
case "symbol":
|
|
300
|
-
return false;
|
|
301
|
-
default:
|
|
302
|
-
return a === b;
|
|
303
|
-
}
|
|
301
|
+
}), {});
|
|
304
302
|
}
|
|
305
303
|
|
|
306
304
|
// src/core/zod-to-openapi.ts
|
|
307
305
|
var import_zod2 = require("zod");
|
|
306
|
+
function alterSchema(schema, newShape) {
|
|
307
|
+
if (schema.description) {
|
|
308
|
+
newShape = newShape.describe(schema.description);
|
|
309
|
+
}
|
|
310
|
+
return newShape;
|
|
311
|
+
}
|
|
308
312
|
function fixSchema(schema) {
|
|
309
313
|
if ("unwrap" in schema && typeof schema.unwrap === "function") {
|
|
310
314
|
switch (schema._zod.def.type) {
|
|
311
315
|
case "nullable":
|
|
312
|
-
return fixSchema(schema.unwrap()).nullable();
|
|
316
|
+
return alterSchema(schema, fixSchema(schema.unwrap()).nullable());
|
|
313
317
|
case "optional":
|
|
314
|
-
return fixSchema(schema.unwrap()).optional();
|
|
318
|
+
return alterSchema(schema, fixSchema(schema.unwrap()).optional());
|
|
315
319
|
case "readonly":
|
|
316
|
-
return fixSchema(schema.unwrap()).readonly();
|
|
320
|
+
return alterSchema(schema, fixSchema(schema.unwrap()).readonly());
|
|
317
321
|
case "array":
|
|
318
|
-
return fixSchema(schema.unwrap()).array();
|
|
322
|
+
return alterSchema(schema, fixSchema(schema.unwrap()).array());
|
|
319
323
|
default:
|
|
320
324
|
throw new Error(`${schema._zod.def.type} type is not covered in fixSchema (@omer-x/next-openapi-json-generator")`);
|
|
321
325
|
}
|
|
322
326
|
}
|
|
323
327
|
if (schema._zod.def.type === "date") {
|
|
324
|
-
return import_zod2.z.iso.datetime();
|
|
328
|
+
return alterSchema(schema, import_zod2.z.iso.datetime());
|
|
325
329
|
}
|
|
326
330
|
if (schema._zod.def.type === "object") {
|
|
327
331
|
const { shape } = schema;
|
|
328
332
|
const entries = Object.entries(shape);
|
|
329
333
|
const alteredEntries = entries.map(([propName, prop]) => [propName, fixSchema(prop)]);
|
|
330
334
|
const newShape = Object.fromEntries(alteredEntries);
|
|
331
|
-
return import_zod2.z.object(newShape);
|
|
335
|
+
return alterSchema(schema, import_zod2.z.object(newShape));
|
|
332
336
|
}
|
|
333
337
|
return schema;
|
|
334
338
|
}
|
|
@@ -336,128 +340,12 @@ function convertToOpenAPI(schema, isArray) {
|
|
|
336
340
|
return import_zod2.z.toJSONSchema(fixSchema(isArray ? schema.array() : schema));
|
|
337
341
|
}
|
|
338
342
|
|
|
339
|
-
// src/core/mask.ts
|
|
340
|
-
function maskWithReference(schema, storedSchemas, self) {
|
|
341
|
-
if (self) {
|
|
342
|
-
for (const [schemaName, zodSchema] of Object.entries(storedSchemas)) {
|
|
343
|
-
if (deepEqual(schema, convertToOpenAPI(zodSchema, false))) {
|
|
344
|
-
return {
|
|
345
|
-
$ref: `#/components/schemas/${schemaName}`
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
if ("$ref" in schema) return schema;
|
|
351
|
-
if (schema.oneOf) {
|
|
352
|
-
return {
|
|
353
|
-
...schema,
|
|
354
|
-
oneOf: schema.oneOf.map((i) => maskWithReference(i, storedSchemas, true))
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
if (schema.anyOf) {
|
|
358
|
-
return {
|
|
359
|
-
...schema,
|
|
360
|
-
anyOf: schema.anyOf.map((i) => maskWithReference(i, storedSchemas, true))
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
switch (schema.type) {
|
|
364
|
-
case "object":
|
|
365
|
-
return {
|
|
366
|
-
...schema,
|
|
367
|
-
properties: Object.entries(schema.properties ?? {}).reduce((props, [propName, prop]) => ({
|
|
368
|
-
...props,
|
|
369
|
-
[propName]: maskWithReference(prop, storedSchemas, true)
|
|
370
|
-
}), {})
|
|
371
|
-
};
|
|
372
|
-
case "array":
|
|
373
|
-
if (Array.isArray(schema.items)) {
|
|
374
|
-
return {
|
|
375
|
-
...schema,
|
|
376
|
-
items: schema.items.map((i) => maskWithReference(i, storedSchemas, true))
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
return {
|
|
380
|
-
...schema,
|
|
381
|
-
items: maskWithReference(schema.items, storedSchemas, true)
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
return schema;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// src/core/operation-mask.ts
|
|
388
|
-
function maskSchema(storedSchemas, schema) {
|
|
389
|
-
if (!schema) return schema;
|
|
390
|
-
return maskWithReference(schema, storedSchemas, true);
|
|
391
|
-
}
|
|
392
|
-
function maskParameterSchema(param, storedSchemas) {
|
|
393
|
-
if ("$ref" in param) return param;
|
|
394
|
-
return { ...param, schema: maskSchema(storedSchemas, param.schema) };
|
|
395
|
-
}
|
|
396
|
-
function maskContentSchema(storedSchemas, bodyContent) {
|
|
397
|
-
if (!bodyContent) return bodyContent;
|
|
398
|
-
return Object.entries(bodyContent).reduce((collection, [contentType, content]) => ({
|
|
399
|
-
...collection,
|
|
400
|
-
[contentType]: {
|
|
401
|
-
...content,
|
|
402
|
-
schema: maskSchema(storedSchemas, content.schema)
|
|
403
|
-
}
|
|
404
|
-
}), {});
|
|
405
|
-
}
|
|
406
|
-
function maskRequestBodySchema(storedSchemas, body) {
|
|
407
|
-
if (!body || "$ref" in body) return body;
|
|
408
|
-
return { ...body, content: maskContentSchema(storedSchemas, body.content) };
|
|
409
|
-
}
|
|
410
|
-
function maskResponseSchema(storedSchemas, response) {
|
|
411
|
-
if ("$ref" in response) return response;
|
|
412
|
-
return { ...response, content: maskContentSchema(storedSchemas, response.content) };
|
|
413
|
-
}
|
|
414
|
-
function maskSchemasInResponses(storedSchemas, responses) {
|
|
415
|
-
if (!responses) return responses;
|
|
416
|
-
return Object.entries(responses).reduce((collection, [key, response]) => ({
|
|
417
|
-
...collection,
|
|
418
|
-
[key]: maskResponseSchema(storedSchemas, response)
|
|
419
|
-
}), {});
|
|
420
|
-
}
|
|
421
|
-
function maskOperationSchemas(operation, storedSchemas) {
|
|
422
|
-
return {
|
|
423
|
-
...operation,
|
|
424
|
-
parameters: operation.parameters?.map((p) => maskParameterSchema(p, storedSchemas)),
|
|
425
|
-
requestBody: maskRequestBodySchema(storedSchemas, operation.requestBody),
|
|
426
|
-
responses: maskSchemasInResponses(storedSchemas, operation.responses)
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// src/core/route.ts
|
|
431
|
-
function createRouteRecord(method, filePath, rootPath, apiData) {
|
|
432
|
-
return {
|
|
433
|
-
method: method.toLocaleLowerCase(),
|
|
434
|
-
path: getRoutePathName(filePath, rootPath),
|
|
435
|
-
apiData
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
function bundlePaths(source, storedSchemas) {
|
|
439
|
-
source.sort((a, b) => a.path.localeCompare(b.path));
|
|
440
|
-
return source.reduce((collection, route) => ({
|
|
441
|
-
...collection,
|
|
442
|
-
[route.path]: {
|
|
443
|
-
...collection[route.path],
|
|
444
|
-
[route.method]: maskOperationSchemas(route.apiData, storedSchemas)
|
|
445
|
-
}
|
|
446
|
-
}), {});
|
|
447
|
-
}
|
|
448
|
-
|
|
449
343
|
// src/core/schema.ts
|
|
450
344
|
function bundleSchemas(schemas) {
|
|
451
|
-
const
|
|
452
|
-
return
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
};
|
|
456
|
-
}, {});
|
|
457
|
-
return Object.entries(bundledSchemas).reduce((bundle, [schemaName, schema]) => ({
|
|
458
|
-
...bundle,
|
|
459
|
-
[schemaName]: maskWithReference(schema, schemas, false)
|
|
460
|
-
}), {});
|
|
345
|
+
const entries = Object.entries(schemas).map(([schemaName, schema]) => {
|
|
346
|
+
return [schemaName, convertToOpenAPI(schema, false)];
|
|
347
|
+
});
|
|
348
|
+
return Object.fromEntries(entries);
|
|
461
349
|
}
|
|
462
350
|
|
|
463
351
|
// src/core/generateOpenApiSpec.ts
|
|
@@ -495,13 +383,13 @@ async function generateOpenApiSpec(schemas, {
|
|
|
495
383
|
}
|
|
496
384
|
const metadata = (0, import_package_metadata.default)();
|
|
497
385
|
const pathsAndComponents = {
|
|
498
|
-
paths: bundlePaths(validRoutes
|
|
386
|
+
paths: bundlePaths(validRoutes),
|
|
499
387
|
components: {
|
|
500
388
|
schemas: bundleSchemas(schemas),
|
|
501
389
|
securitySchemes
|
|
502
390
|
}
|
|
503
391
|
};
|
|
504
|
-
|
|
392
|
+
const spec = JSON.parse(JSON.stringify({
|
|
505
393
|
openapi: "3.1.0",
|
|
506
394
|
info: {
|
|
507
395
|
title: metadata.serviceName,
|
|
@@ -513,6 +401,7 @@ async function generateOpenApiSpec(schemas, {
|
|
|
513
401
|
security,
|
|
514
402
|
tags: []
|
|
515
403
|
}));
|
|
404
|
+
return (0, import_openapi_optimizer.optimizeOpenApiSpec)(spec);
|
|
516
405
|
}
|
|
517
406
|
|
|
518
407
|
// src/index.ts
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
7
7
|
|
|
8
8
|
// src/core/generateOpenApiSpec.ts
|
|
9
9
|
import path4 from "path";
|
|
10
|
+
import { optimizeOpenApiSpec } from "@omer-x/openapi-optimizer";
|
|
10
11
|
import getPackageMetadata from "@omer-x/package-metadata";
|
|
11
12
|
|
|
12
13
|
// src/utils/object.ts
|
|
@@ -252,54 +253,57 @@ function getRoutePathName(filePath, rootPath) {
|
|
|
252
253
|
return "/" + path3.relative(rootPath, dirName).replaceAll("[", "{").replaceAll("]", "}").replaceAll("\\", "/");
|
|
253
254
|
}
|
|
254
255
|
|
|
255
|
-
// src/
|
|
256
|
-
function
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
256
|
+
// src/core/route.ts
|
|
257
|
+
function createRouteRecord(method, filePath, rootPath, apiData) {
|
|
258
|
+
return {
|
|
259
|
+
method: method.toLocaleLowerCase(),
|
|
260
|
+
path: getRoutePathName(filePath, rootPath),
|
|
261
|
+
apiData
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function bundlePaths(source) {
|
|
265
|
+
source.sort((a, b) => a.path.localeCompare(b.path));
|
|
266
|
+
return source.reduce((collection, route) => ({
|
|
267
|
+
...collection,
|
|
268
|
+
[route.path]: {
|
|
269
|
+
...collection[route.path],
|
|
270
|
+
[route.method]: route.apiData
|
|
268
271
|
}
|
|
269
|
-
|
|
270
|
-
case "symbol":
|
|
271
|
-
return false;
|
|
272
|
-
default:
|
|
273
|
-
return a === b;
|
|
274
|
-
}
|
|
272
|
+
}), {});
|
|
275
273
|
}
|
|
276
274
|
|
|
277
275
|
// src/core/zod-to-openapi.ts
|
|
278
276
|
import { z as z2 } from "zod";
|
|
277
|
+
function alterSchema(schema, newShape) {
|
|
278
|
+
if (schema.description) {
|
|
279
|
+
newShape = newShape.describe(schema.description);
|
|
280
|
+
}
|
|
281
|
+
return newShape;
|
|
282
|
+
}
|
|
279
283
|
function fixSchema(schema) {
|
|
280
284
|
if ("unwrap" in schema && typeof schema.unwrap === "function") {
|
|
281
285
|
switch (schema._zod.def.type) {
|
|
282
286
|
case "nullable":
|
|
283
|
-
return fixSchema(schema.unwrap()).nullable();
|
|
287
|
+
return alterSchema(schema, fixSchema(schema.unwrap()).nullable());
|
|
284
288
|
case "optional":
|
|
285
|
-
return fixSchema(schema.unwrap()).optional();
|
|
289
|
+
return alterSchema(schema, fixSchema(schema.unwrap()).optional());
|
|
286
290
|
case "readonly":
|
|
287
|
-
return fixSchema(schema.unwrap()).readonly();
|
|
291
|
+
return alterSchema(schema, fixSchema(schema.unwrap()).readonly());
|
|
288
292
|
case "array":
|
|
289
|
-
return fixSchema(schema.unwrap()).array();
|
|
293
|
+
return alterSchema(schema, fixSchema(schema.unwrap()).array());
|
|
290
294
|
default:
|
|
291
295
|
throw new Error(`${schema._zod.def.type} type is not covered in fixSchema (@omer-x/next-openapi-json-generator")`);
|
|
292
296
|
}
|
|
293
297
|
}
|
|
294
298
|
if (schema._zod.def.type === "date") {
|
|
295
|
-
return z2.iso.datetime();
|
|
299
|
+
return alterSchema(schema, z2.iso.datetime());
|
|
296
300
|
}
|
|
297
301
|
if (schema._zod.def.type === "object") {
|
|
298
302
|
const { shape } = schema;
|
|
299
303
|
const entries = Object.entries(shape);
|
|
300
304
|
const alteredEntries = entries.map(([propName, prop]) => [propName, fixSchema(prop)]);
|
|
301
305
|
const newShape = Object.fromEntries(alteredEntries);
|
|
302
|
-
return z2.object(newShape);
|
|
306
|
+
return alterSchema(schema, z2.object(newShape));
|
|
303
307
|
}
|
|
304
308
|
return schema;
|
|
305
309
|
}
|
|
@@ -307,128 +311,12 @@ function convertToOpenAPI(schema, isArray) {
|
|
|
307
311
|
return z2.toJSONSchema(fixSchema(isArray ? schema.array() : schema));
|
|
308
312
|
}
|
|
309
313
|
|
|
310
|
-
// src/core/mask.ts
|
|
311
|
-
function maskWithReference(schema, storedSchemas, self) {
|
|
312
|
-
if (self) {
|
|
313
|
-
for (const [schemaName, zodSchema] of Object.entries(storedSchemas)) {
|
|
314
|
-
if (deepEqual(schema, convertToOpenAPI(zodSchema, false))) {
|
|
315
|
-
return {
|
|
316
|
-
$ref: `#/components/schemas/${schemaName}`
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
if ("$ref" in schema) return schema;
|
|
322
|
-
if (schema.oneOf) {
|
|
323
|
-
return {
|
|
324
|
-
...schema,
|
|
325
|
-
oneOf: schema.oneOf.map((i) => maskWithReference(i, storedSchemas, true))
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
if (schema.anyOf) {
|
|
329
|
-
return {
|
|
330
|
-
...schema,
|
|
331
|
-
anyOf: schema.anyOf.map((i) => maskWithReference(i, storedSchemas, true))
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
switch (schema.type) {
|
|
335
|
-
case "object":
|
|
336
|
-
return {
|
|
337
|
-
...schema,
|
|
338
|
-
properties: Object.entries(schema.properties ?? {}).reduce((props, [propName, prop]) => ({
|
|
339
|
-
...props,
|
|
340
|
-
[propName]: maskWithReference(prop, storedSchemas, true)
|
|
341
|
-
}), {})
|
|
342
|
-
};
|
|
343
|
-
case "array":
|
|
344
|
-
if (Array.isArray(schema.items)) {
|
|
345
|
-
return {
|
|
346
|
-
...schema,
|
|
347
|
-
items: schema.items.map((i) => maskWithReference(i, storedSchemas, true))
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
return {
|
|
351
|
-
...schema,
|
|
352
|
-
items: maskWithReference(schema.items, storedSchemas, true)
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
return schema;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// src/core/operation-mask.ts
|
|
359
|
-
function maskSchema(storedSchemas, schema) {
|
|
360
|
-
if (!schema) return schema;
|
|
361
|
-
return maskWithReference(schema, storedSchemas, true);
|
|
362
|
-
}
|
|
363
|
-
function maskParameterSchema(param, storedSchemas) {
|
|
364
|
-
if ("$ref" in param) return param;
|
|
365
|
-
return { ...param, schema: maskSchema(storedSchemas, param.schema) };
|
|
366
|
-
}
|
|
367
|
-
function maskContentSchema(storedSchemas, bodyContent) {
|
|
368
|
-
if (!bodyContent) return bodyContent;
|
|
369
|
-
return Object.entries(bodyContent).reduce((collection, [contentType, content]) => ({
|
|
370
|
-
...collection,
|
|
371
|
-
[contentType]: {
|
|
372
|
-
...content,
|
|
373
|
-
schema: maskSchema(storedSchemas, content.schema)
|
|
374
|
-
}
|
|
375
|
-
}), {});
|
|
376
|
-
}
|
|
377
|
-
function maskRequestBodySchema(storedSchemas, body) {
|
|
378
|
-
if (!body || "$ref" in body) return body;
|
|
379
|
-
return { ...body, content: maskContentSchema(storedSchemas, body.content) };
|
|
380
|
-
}
|
|
381
|
-
function maskResponseSchema(storedSchemas, response) {
|
|
382
|
-
if ("$ref" in response) return response;
|
|
383
|
-
return { ...response, content: maskContentSchema(storedSchemas, response.content) };
|
|
384
|
-
}
|
|
385
|
-
function maskSchemasInResponses(storedSchemas, responses) {
|
|
386
|
-
if (!responses) return responses;
|
|
387
|
-
return Object.entries(responses).reduce((collection, [key, response]) => ({
|
|
388
|
-
...collection,
|
|
389
|
-
[key]: maskResponseSchema(storedSchemas, response)
|
|
390
|
-
}), {});
|
|
391
|
-
}
|
|
392
|
-
function maskOperationSchemas(operation, storedSchemas) {
|
|
393
|
-
return {
|
|
394
|
-
...operation,
|
|
395
|
-
parameters: operation.parameters?.map((p) => maskParameterSchema(p, storedSchemas)),
|
|
396
|
-
requestBody: maskRequestBodySchema(storedSchemas, operation.requestBody),
|
|
397
|
-
responses: maskSchemasInResponses(storedSchemas, operation.responses)
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
// src/core/route.ts
|
|
402
|
-
function createRouteRecord(method, filePath, rootPath, apiData) {
|
|
403
|
-
return {
|
|
404
|
-
method: method.toLocaleLowerCase(),
|
|
405
|
-
path: getRoutePathName(filePath, rootPath),
|
|
406
|
-
apiData
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
function bundlePaths(source, storedSchemas) {
|
|
410
|
-
source.sort((a, b) => a.path.localeCompare(b.path));
|
|
411
|
-
return source.reduce((collection, route) => ({
|
|
412
|
-
...collection,
|
|
413
|
-
[route.path]: {
|
|
414
|
-
...collection[route.path],
|
|
415
|
-
[route.method]: maskOperationSchemas(route.apiData, storedSchemas)
|
|
416
|
-
}
|
|
417
|
-
}), {});
|
|
418
|
-
}
|
|
419
|
-
|
|
420
314
|
// src/core/schema.ts
|
|
421
315
|
function bundleSchemas(schemas) {
|
|
422
|
-
const
|
|
423
|
-
return
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
};
|
|
427
|
-
}, {});
|
|
428
|
-
return Object.entries(bundledSchemas).reduce((bundle, [schemaName, schema]) => ({
|
|
429
|
-
...bundle,
|
|
430
|
-
[schemaName]: maskWithReference(schema, schemas, false)
|
|
431
|
-
}), {});
|
|
316
|
+
const entries = Object.entries(schemas).map(([schemaName, schema]) => {
|
|
317
|
+
return [schemaName, convertToOpenAPI(schema, false)];
|
|
318
|
+
});
|
|
319
|
+
return Object.fromEntries(entries);
|
|
432
320
|
}
|
|
433
321
|
|
|
434
322
|
// src/core/generateOpenApiSpec.ts
|
|
@@ -466,13 +354,13 @@ async function generateOpenApiSpec(schemas, {
|
|
|
466
354
|
}
|
|
467
355
|
const metadata = getPackageMetadata();
|
|
468
356
|
const pathsAndComponents = {
|
|
469
|
-
paths: bundlePaths(validRoutes
|
|
357
|
+
paths: bundlePaths(validRoutes),
|
|
470
358
|
components: {
|
|
471
359
|
schemas: bundleSchemas(schemas),
|
|
472
360
|
securitySchemes
|
|
473
361
|
}
|
|
474
362
|
};
|
|
475
|
-
|
|
363
|
+
const spec = JSON.parse(JSON.stringify({
|
|
476
364
|
openapi: "3.1.0",
|
|
477
365
|
info: {
|
|
478
366
|
title: metadata.serviceName,
|
|
@@ -484,6 +372,7 @@ async function generateOpenApiSpec(schemas, {
|
|
|
484
372
|
security,
|
|
485
373
|
tags: []
|
|
486
374
|
}));
|
|
375
|
+
return optimizeOpenApiSpec(spec);
|
|
487
376
|
}
|
|
488
377
|
|
|
489
378
|
// src/index.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omer-x/next-openapi-json-generator",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.1.0-rc.2",
|
|
4
4
|
"description": "a Next.js plugin to generate OpenAPI documentation from route handlers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"next.js",
|
|
@@ -40,6 +40,8 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
|
+
"lint": "eslint --flag unstable_native_nodejs_ts_config",
|
|
44
|
+
"lint:fix": "eslint --fix --flag unstable_native_nodejs_ts_config",
|
|
43
45
|
"test": "vitest run --coverage",
|
|
44
46
|
"test:watch": "vitest --coverage",
|
|
45
47
|
"dev": "tsup --watch",
|
|
@@ -48,20 +50,21 @@
|
|
|
48
50
|
"peerDependencies": {
|
|
49
51
|
"@omer-x/next-openapi-route-handler": "^2",
|
|
50
52
|
"@omer-x/openapi-types": "^1",
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
+
"typescript": "^5",
|
|
54
|
+
"zod": "^4"
|
|
53
55
|
},
|
|
54
56
|
"dependencies": {
|
|
57
|
+
"@omer-x/openapi-optimizer": "alpha",
|
|
55
58
|
"@omer-x/package-metadata": "^1.0.2",
|
|
56
59
|
"minimatch": "^10.1.1"
|
|
57
60
|
},
|
|
58
61
|
"devDependencies": {
|
|
59
62
|
"@omer-x/eslint-config": "^2.2.6",
|
|
60
|
-
"@types/node": "^25.0.
|
|
61
|
-
"@vitest/coverage-v8": "^4.0.
|
|
63
|
+
"@types/node": "^25.0.3",
|
|
64
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
62
65
|
"eslint": "^9.39.2",
|
|
63
66
|
"semantic-release": "^25.0.2",
|
|
64
67
|
"tsup": "^8.5.1",
|
|
65
|
-
"vitest": "^4.0.
|
|
68
|
+
"vitest": "^4.0.16"
|
|
66
69
|
}
|
|
67
70
|
}
|