adorn-api 1.0.11 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +318 -620
- package/dist/adapter/express/auth.d.ts +5 -0
- package/dist/adapter/express/auth.d.ts.map +1 -0
- package/dist/adapter/express/coercion.d.ts +22 -0
- package/dist/adapter/express/coercion.d.ts.map +1 -0
- package/dist/adapter/express/index.d.ts +3 -50
- package/dist/adapter/express/index.d.ts.map +1 -1
- package/dist/adapter/express/merge.d.ts +0 -3
- package/dist/adapter/express/merge.d.ts.map +1 -1
- package/dist/adapter/express/openapi.d.ts +11 -0
- package/dist/adapter/express/openapi.d.ts.map +1 -0
- package/dist/adapter/express/router.d.ts +4 -0
- package/dist/adapter/express/router.d.ts.map +1 -0
- package/dist/adapter/express/swagger.d.ts +4 -0
- package/dist/adapter/express/swagger.d.ts.map +1 -0
- package/dist/adapter/express/types.d.ts +64 -0
- package/dist/adapter/express/types.d.ts.map +1 -0
- package/dist/adapter/express/validation.d.ts +10 -0
- package/dist/adapter/express/validation.d.ts.map +1 -0
- package/dist/cli.cjs +332 -153
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +331 -152
- package/dist/cli.js.map +1 -1
- package/dist/compiler/analyze/scanControllers.d.ts +0 -1
- package/dist/compiler/analyze/scanControllers.d.ts.map +1 -1
- package/dist/compiler/manifest/emit.d.ts.map +1 -1
- package/dist/compiler/manifest/format.d.ts +1 -1
- package/dist/compiler/manifest/format.d.ts.map +1 -1
- package/dist/compiler/schema/openapi.d.ts.map +1 -1
- package/dist/compiler/schema/typeToJsonSchema.d.ts +7 -1
- package/dist/compiler/schema/typeToJsonSchema.d.ts.map +1 -1
- package/dist/decorators/index.d.ts +0 -1
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/express.cjs +619 -596
- package/dist/express.cjs.map +1 -1
- package/dist/express.js +616 -593
- package/dist/express.js.map +1 -1
- package/dist/http.d.ts +1 -9
- package/dist/http.d.ts.map +1 -1
- package/dist/index.cjs +2 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -33
- package/dist/index.js.map +1 -1
- package/dist/metal/applyListQuery.d.ts +27 -0
- package/dist/metal/applyListQuery.d.ts.map +1 -0
- package/dist/metal/index.cjs +59 -0
- package/dist/metal/index.cjs.map +1 -1
- package/dist/metal/index.d.ts +4 -0
- package/dist/metal/index.d.ts.map +1 -1
- package/dist/metal/index.js +55 -0
- package/dist/metal/index.js.map +1 -1
- package/dist/metal/listQuery.d.ts +7 -0
- package/dist/metal/listQuery.d.ts.map +1 -0
- package/dist/metal/queryOptions.d.ts +8 -0
- package/dist/metal/queryOptions.d.ts.map +1 -0
- package/dist/runtime/metadata/types.d.ts +0 -3
- package/dist/runtime/metadata/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/compiler/analyze/extractQueryStyle.d.ts +0 -8
- package/dist/compiler/analyze/extractQueryStyle.d.ts.map +0 -1
- package/dist/decorators/Paginated.d.ts +0 -5
- package/dist/decorators/Paginated.d.ts.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -171,7 +171,7 @@ function analyzeMethod(node, className, checker) {
|
|
|
171
171
|
}
|
|
172
172
|
const pathParamNames = extractPathParams(path4);
|
|
173
173
|
const pathParamIndices = matchPathParamsToIndices(pathParamNames, parameters);
|
|
174
|
-
const { bodyParamIndex, queryParamIndices, queryObjectParamIndex, headerObjectParamIndex, cookieObjectParamIndex,
|
|
174
|
+
const { bodyParamIndex, queryParamIndices, queryObjectParamIndex, headerObjectParamIndex, cookieObjectParamIndex, bodyContentType } = classifyParameters(parameters, httpMethod, pathParamIndices, checker);
|
|
175
175
|
return {
|
|
176
176
|
methodName,
|
|
177
177
|
httpMethod,
|
|
@@ -187,7 +187,6 @@ function analyzeMethod(node, className, checker) {
|
|
|
187
187
|
queryObjectParamIndex,
|
|
188
188
|
headerObjectParamIndex,
|
|
189
189
|
cookieObjectParamIndex,
|
|
190
|
-
paginationParamIndex,
|
|
191
190
|
bodyContentType
|
|
192
191
|
};
|
|
193
192
|
}
|
|
@@ -213,7 +212,6 @@ function classifyParameters(parameters, httpMethod, pathParamIndices, checker) {
|
|
|
213
212
|
let queryObjectParamIndex = null;
|
|
214
213
|
let headerObjectParamIndex = null;
|
|
215
214
|
let cookieObjectParamIndex = null;
|
|
216
|
-
let paginationParamIndex = null;
|
|
217
215
|
const isBodyMethod = ["POST", "PUT", "PATCH"].includes(httpMethod);
|
|
218
216
|
for (let i = 0; i < parameters.length; i++) {
|
|
219
217
|
const param = parameters[i];
|
|
@@ -240,11 +238,6 @@ function classifyParameters(parameters, httpMethod, pathParamIndices, checker) {
|
|
|
240
238
|
usedIndices.add(i);
|
|
241
239
|
continue;
|
|
242
240
|
}
|
|
243
|
-
if (typeStr === "PaginationParams") {
|
|
244
|
-
paginationParamIndex = i;
|
|
245
|
-
usedIndices.add(i);
|
|
246
|
-
continue;
|
|
247
|
-
}
|
|
248
241
|
if (isBodyMethod && bodyParamIndex === null) {
|
|
249
242
|
bodyParamIndex = i;
|
|
250
243
|
usedIndices.add(i);
|
|
@@ -265,19 +258,19 @@ function classifyParameters(parameters, httpMethod, pathParamIndices, checker) {
|
|
|
265
258
|
queryObjectParamIndex,
|
|
266
259
|
headerObjectParamIndex,
|
|
267
260
|
cookieObjectParamIndex,
|
|
268
|
-
paginationParamIndex,
|
|
269
261
|
bodyContentType: void 0
|
|
270
262
|
};
|
|
271
263
|
}
|
|
272
264
|
function isObjectType(type, checker) {
|
|
273
265
|
const objectFlags = (type.flags & import_typescript2.default.TypeFlags.Object) !== 0;
|
|
274
|
-
|
|
266
|
+
const intersectionFlags = (type.flags & import_typescript2.default.TypeFlags.Intersection) !== 0;
|
|
267
|
+
if (!objectFlags && !intersectionFlags) return false;
|
|
275
268
|
const symbol = type.getSymbol();
|
|
276
269
|
if (symbol?.getName() === "__object") return true;
|
|
277
270
|
const properties = checker.getPropertiesOfType(type);
|
|
278
271
|
if (properties.length > 0) return true;
|
|
279
|
-
const
|
|
280
|
-
if (
|
|
272
|
+
const callSigs = type.getCallSignatures?.();
|
|
273
|
+
if (callSigs && callSigs.length > 0) return false;
|
|
281
274
|
return true;
|
|
282
275
|
}
|
|
283
276
|
function getTypeName(type) {
|
|
@@ -329,7 +322,7 @@ function unwrapPromiseTypeNode(typeNode) {
|
|
|
329
322
|
}
|
|
330
323
|
|
|
331
324
|
// src/compiler/schema/openapi.ts
|
|
332
|
-
var
|
|
325
|
+
var import_typescript5 = __toESM(require("typescript"), 1);
|
|
333
326
|
|
|
334
327
|
// src/compiler/schema/typeToJsonSchema.ts
|
|
335
328
|
var import_typescript3 = __toESM(require("typescript"), 1);
|
|
@@ -348,7 +341,7 @@ function typeToJsonSchema(type, ctx, typeNode) {
|
|
|
348
341
|
return { type: "string" };
|
|
349
342
|
}
|
|
350
343
|
if (type.flags & import_typescript3.default.TypeFlags.Number) {
|
|
351
|
-
return
|
|
344
|
+
return normalizeNumericType(type, checker, typeNode);
|
|
352
345
|
}
|
|
353
346
|
if (type.flags & import_typescript3.default.TypeFlags.Boolean) {
|
|
354
347
|
return { type: "boolean" };
|
|
@@ -610,9 +603,12 @@ function getBranchSchemaName(type, ctx) {
|
|
|
610
603
|
return `Anonymous_${ctx.typeNameStack.length}`;
|
|
611
604
|
}
|
|
612
605
|
function handleObjectType(type, ctx, typeNode) {
|
|
613
|
-
const { checker, components, typeStack } = ctx;
|
|
606
|
+
const { checker, components, typeStack, mode } = ctx;
|
|
614
607
|
const symbol = type.getSymbol();
|
|
615
608
|
const typeName = symbol?.getName?.() ?? getTypeNameFromNode(typeNode, ctx);
|
|
609
|
+
if (isMetalOrmWrapperType(type, checker)) {
|
|
610
|
+
return handleMetalOrmWrapper(type, ctx);
|
|
611
|
+
}
|
|
616
612
|
if (typeName && typeName !== "__type") {
|
|
617
613
|
if (components.has(typeName)) {
|
|
618
614
|
return { $ref: `#/components/schemas/${typeName}` };
|
|
@@ -625,7 +621,8 @@ function handleObjectType(type, ctx, typeNode) {
|
|
|
625
621
|
const schema = buildObjectSchema(type, ctx, typeNode);
|
|
626
622
|
if (typeName && typeName !== "__type") {
|
|
627
623
|
typeStack.delete(type);
|
|
628
|
-
|
|
624
|
+
const existing = components.get(typeName);
|
|
625
|
+
if (!existing) {
|
|
629
626
|
components.set(typeName, schema);
|
|
630
627
|
}
|
|
631
628
|
return { $ref: `#/components/schemas/${typeName}` };
|
|
@@ -647,22 +644,44 @@ function getExplicitTypeNameFromNode(typeNode) {
|
|
|
647
644
|
}
|
|
648
645
|
return null;
|
|
649
646
|
}
|
|
647
|
+
function shouldBeIntegerType(typeName) {
|
|
648
|
+
if (!typeName) return false;
|
|
649
|
+
const lower = typeName.toLowerCase();
|
|
650
|
+
return lower === "id" || lower.endsWith("id") || lower === "primarykey" || lower === "pk";
|
|
651
|
+
}
|
|
652
|
+
function normalizeNumericType(type, checker, typeNode) {
|
|
653
|
+
const typeName = getExplicitTypeNameFromNode(typeNode) ?? null;
|
|
654
|
+
const symbol = getEffectiveSymbol(type, checker);
|
|
655
|
+
const symbolName = symbol?.getName() ?? null;
|
|
656
|
+
if (shouldBeIntegerType(typeName) || shouldBeIntegerType(symbolName)) {
|
|
657
|
+
return { type: "integer" };
|
|
658
|
+
}
|
|
659
|
+
return { type: "number" };
|
|
660
|
+
}
|
|
650
661
|
function getTypeNameFromNode(typeNode, ctx) {
|
|
651
662
|
const explicitName = getExplicitTypeNameFromNode(typeNode);
|
|
652
663
|
if (explicitName) return explicitName;
|
|
653
664
|
return `Anonymous_${ctx.typeNameStack.length}`;
|
|
654
665
|
}
|
|
655
666
|
function buildObjectSchema(type, ctx, typeNode) {
|
|
656
|
-
const { checker } = ctx;
|
|
667
|
+
const { checker, mode } = ctx;
|
|
657
668
|
const properties = {};
|
|
658
669
|
const required = [];
|
|
659
670
|
const props = checker.getPropertiesOfType(type);
|
|
660
671
|
for (const prop of props) {
|
|
661
672
|
const propName = prop.getName();
|
|
673
|
+
if (isIteratorOrSymbolProperty(propName)) {
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
662
676
|
const propType = checker.getTypeOfSymbol(prop);
|
|
677
|
+
if (isMethodLike(propType)) {
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
663
680
|
const isOptional = !!(prop.flags & import_typescript3.default.SymbolFlags.Optional);
|
|
681
|
+
const isRelation = isMetalOrmWrapperType(propType, checker);
|
|
664
682
|
properties[propName] = typeToJsonSchema(propType, ctx);
|
|
665
|
-
|
|
683
|
+
const shouldRequire = mode === "response" ? !isRelation && !isOptional : !isOptional;
|
|
684
|
+
if (shouldRequire) {
|
|
666
685
|
required.push(propName);
|
|
667
686
|
}
|
|
668
687
|
}
|
|
@@ -701,6 +720,56 @@ function getRecordValueType(type, checker) {
|
|
|
701
720
|
}
|
|
702
721
|
return null;
|
|
703
722
|
}
|
|
723
|
+
var METAL_ORM_WRAPPER_NAMES = ["HasManyCollection", "ManyToManyCollection", "BelongsToReference", "HasOneReference"];
|
|
724
|
+
function isMetalOrmWrapperType(type, checker) {
|
|
725
|
+
const aliasSymbol = type.aliasSymbol || type.symbol;
|
|
726
|
+
if (!aliasSymbol) return false;
|
|
727
|
+
return METAL_ORM_WRAPPER_NAMES.includes(aliasSymbol.getName());
|
|
728
|
+
}
|
|
729
|
+
function getWrapperTypeName(type, checker) {
|
|
730
|
+
const symbol = getEffectiveSymbol(type, checker);
|
|
731
|
+
if (!symbol) return null;
|
|
732
|
+
const name = symbol.getName();
|
|
733
|
+
return METAL_ORM_WRAPPER_NAMES.includes(name) ? name : null;
|
|
734
|
+
}
|
|
735
|
+
function getEffectiveSymbol(type, checker) {
|
|
736
|
+
const aliasSymbol = type.aliasSymbol ?? type.aliasSymbol;
|
|
737
|
+
if (aliasSymbol && aliasSymbol.flags & import_typescript3.default.SymbolFlags.Alias) {
|
|
738
|
+
return checker.getAliasedSymbol(aliasSymbol);
|
|
739
|
+
}
|
|
740
|
+
return type.getSymbol() ?? null;
|
|
741
|
+
}
|
|
742
|
+
function isMethodLike(type) {
|
|
743
|
+
const callSigs = type.getCallSignatures?.();
|
|
744
|
+
return !!(callSigs && callSigs.length > 0);
|
|
745
|
+
}
|
|
746
|
+
function isIteratorOrSymbolProperty(propName) {
|
|
747
|
+
return propName.startsWith("__@") || propName.startsWith("[") || propName === Symbol.iterator.toString();
|
|
748
|
+
}
|
|
749
|
+
function handleMetalOrmWrapper(type, ctx) {
|
|
750
|
+
const typeRef = type;
|
|
751
|
+
const typeArgs = typeRef.typeArguments;
|
|
752
|
+
const targetType = typeArgs?.[0] ?? null;
|
|
753
|
+
const wrapperName = getWrapperTypeName(type, ctx.checker);
|
|
754
|
+
if (!wrapperName) return {};
|
|
755
|
+
const wrapperRel = { wrapper: wrapperName };
|
|
756
|
+
if (wrapperName === "HasManyCollection" || wrapperName === "ManyToManyCollection") {
|
|
757
|
+
const items = targetType ? typeToJsonSchema(targetType, ctx) : {};
|
|
758
|
+
if (wrapperName === "ManyToManyCollection" && typeArgs?.[1]) {
|
|
759
|
+
wrapperRel.pivot = typeArgs[1];
|
|
760
|
+
}
|
|
761
|
+
return {
|
|
762
|
+
type: "array",
|
|
763
|
+
items,
|
|
764
|
+
"x-metal-orm-rel": wrapperRel
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
const targetSchema = targetType ? typeToJsonSchema(targetType, ctx) : {};
|
|
768
|
+
return {
|
|
769
|
+
...targetSchema,
|
|
770
|
+
"x-metal-orm-rel": wrapperRel
|
|
771
|
+
};
|
|
772
|
+
}
|
|
704
773
|
|
|
705
774
|
// src/compiler/schema/extractAnnotations.ts
|
|
706
775
|
var import_typescript4 = __toESM(require("typescript"), 1);
|
|
@@ -848,56 +917,6 @@ function mergeFragments(base, ...frags) {
|
|
|
848
917
|
return result;
|
|
849
918
|
}
|
|
850
919
|
|
|
851
|
-
// src/compiler/analyze/extractQueryStyle.ts
|
|
852
|
-
var import_typescript5 = __toESM(require("typescript"), 1);
|
|
853
|
-
function extractQueryStyleOptions(checker, method) {
|
|
854
|
-
if (!import_typescript5.default.canHaveDecorators(method)) return null;
|
|
855
|
-
const decorators = import_typescript5.default.getDecorators(method);
|
|
856
|
-
if (!decorators || decorators.length === 0) return null;
|
|
857
|
-
for (const decorator of decorators) {
|
|
858
|
-
const expr = decorator.expression;
|
|
859
|
-
const isCall = import_typescript5.default.isCallExpression(expr);
|
|
860
|
-
const callee = isCall ? expr.expression : expr;
|
|
861
|
-
const args = isCall ? expr.arguments : import_typescript5.default.factory.createNodeArray([]);
|
|
862
|
-
const sym = checker.getSymbolAtLocation(callee);
|
|
863
|
-
if (!sym) continue;
|
|
864
|
-
const resolved = sym.flags & import_typescript5.default.SymbolFlags.Alias ? checker.getAliasedSymbol(sym) : sym;
|
|
865
|
-
const name = resolved.getName();
|
|
866
|
-
if (name !== "QueryStyle") continue;
|
|
867
|
-
const optsNode = args[0];
|
|
868
|
-
if (!optsNode || !import_typescript5.default.isObjectLiteralExpression(optsNode)) {
|
|
869
|
-
return {};
|
|
870
|
-
}
|
|
871
|
-
return parseQueryStyleOptions(optsNode);
|
|
872
|
-
}
|
|
873
|
-
return null;
|
|
874
|
-
}
|
|
875
|
-
function parseQueryStyleOptions(node) {
|
|
876
|
-
const opts = {};
|
|
877
|
-
for (const prop of node.properties) {
|
|
878
|
-
if (!import_typescript5.default.isPropertyAssignment(prop)) continue;
|
|
879
|
-
const name = getPropName(prop.name);
|
|
880
|
-
if (!name) continue;
|
|
881
|
-
if (name === "style" && import_typescript5.default.isStringLiteral(prop.initializer)) {
|
|
882
|
-
const style = prop.initializer.text;
|
|
883
|
-
opts.style = style;
|
|
884
|
-
} else if (name === "explode" && isBooleanLiteral(prop.initializer)) {
|
|
885
|
-
opts.explode = prop.initializer.kind === import_typescript5.default.SyntaxKind.TrueKeyword;
|
|
886
|
-
} else if (name === "allowReserved" && isBooleanLiteral(prop.initializer)) {
|
|
887
|
-
opts.allowReserved = prop.initializer.kind === import_typescript5.default.SyntaxKind.TrueKeyword;
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
return opts;
|
|
891
|
-
}
|
|
892
|
-
function getPropName(name) {
|
|
893
|
-
if (import_typescript5.default.isIdentifier(name)) return name.text;
|
|
894
|
-
if (import_typescript5.default.isStringLiteral(name)) return name.text;
|
|
895
|
-
return null;
|
|
896
|
-
}
|
|
897
|
-
function isBooleanLiteral(node) {
|
|
898
|
-
return node.kind === import_typescript5.default.SyntaxKind.TrueKeyword || node.kind === import_typescript5.default.SyntaxKind.FalseKeyword;
|
|
899
|
-
}
|
|
900
|
-
|
|
901
920
|
// src/compiler/schema/openapi.ts
|
|
902
921
|
function generateOpenAPI(controllers, checker, options = {}) {
|
|
903
922
|
const components = /* @__PURE__ */ new Map();
|
|
@@ -905,7 +924,8 @@ function generateOpenAPI(controllers, checker, options = {}) {
|
|
|
905
924
|
checker,
|
|
906
925
|
components,
|
|
907
926
|
typeStack: /* @__PURE__ */ new Set(),
|
|
908
|
-
typeNameStack: []
|
|
927
|
+
typeNameStack: [],
|
|
928
|
+
mode: "response"
|
|
909
929
|
};
|
|
910
930
|
const paths = {};
|
|
911
931
|
for (const controller of controllers) {
|
|
@@ -933,7 +953,11 @@ function generateOpenAPI(controllers, checker, options = {}) {
|
|
|
933
953
|
function convertToOpenApiPath(basePath, path4) {
|
|
934
954
|
const base = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
|
|
935
955
|
const converted = path4.replace(/:([^/]+)/g, "{$1}");
|
|
936
|
-
|
|
956
|
+
let fullPath = base + converted || "/";
|
|
957
|
+
if (fullPath.endsWith("/") && fullPath !== "/") {
|
|
958
|
+
fullPath = fullPath.slice(0, -1);
|
|
959
|
+
}
|
|
960
|
+
return fullPath;
|
|
937
961
|
}
|
|
938
962
|
function buildOperation(operation, ctx, controllerConsumes) {
|
|
939
963
|
const op = {
|
|
@@ -948,7 +972,8 @@ function buildOperation(operation, ctx, controllerConsumes) {
|
|
|
948
972
|
if (parameters.length > 0) {
|
|
949
973
|
op.parameters = parameters;
|
|
950
974
|
}
|
|
951
|
-
const
|
|
975
|
+
const responseCtx = { ...ctx, mode: "response" };
|
|
976
|
+
const responseSchema = typeToJsonSchema(operation.returnType, responseCtx, operation.returnTypeNode);
|
|
952
977
|
const status = operation.httpMethod === "POST" ? 201 : 200;
|
|
953
978
|
op.responses[status] = {
|
|
954
979
|
description: status === 201 ? "Created" : "OK",
|
|
@@ -961,8 +986,9 @@ function buildOperation(operation, ctx, controllerConsumes) {
|
|
|
961
986
|
if (["POST", "PUT", "PATCH"].includes(operation.httpMethod) && operation.bodyParamIndex !== null) {
|
|
962
987
|
const bodyParam = operation.parameters[operation.bodyParamIndex];
|
|
963
988
|
if (bodyParam) {
|
|
964
|
-
|
|
965
|
-
bodySchema =
|
|
989
|
+
const requestCtx = { ...ctx, mode: "request" };
|
|
990
|
+
let bodySchema = typeToJsonSchema(bodyParam.type, requestCtx);
|
|
991
|
+
bodySchema = mergeBodySchemaAnnotations(bodyParam, requestCtx, bodySchema);
|
|
966
992
|
const contentType = operation.bodyContentType ?? controllerConsumes?.[0] ?? "application/json";
|
|
967
993
|
const requestBody = {
|
|
968
994
|
required: !bodyParam.isOptional,
|
|
@@ -989,12 +1015,12 @@ function mergeBodySchemaAnnotations(bodyParam, ctx, schema) {
|
|
|
989
1015
|
const declarations = typeSymbol.getDeclarations();
|
|
990
1016
|
if (!declarations || declarations.length === 0) return schema;
|
|
991
1017
|
const classDecl = declarations[0];
|
|
992
|
-
if (!
|
|
1018
|
+
if (!import_typescript5.default.isClassDeclaration(classDecl)) return schema;
|
|
993
1019
|
const result = { ...schema };
|
|
994
1020
|
const props = { ...result.properties };
|
|
995
1021
|
for (const member of classDecl.members) {
|
|
996
|
-
if (!
|
|
997
|
-
const propName =
|
|
1022
|
+
if (!import_typescript5.default.isPropertyDeclaration(member) || !member.name) continue;
|
|
1023
|
+
const propName = import_typescript5.default.isIdentifier(member.name) ? member.name.text : null;
|
|
998
1024
|
if (!propName) continue;
|
|
999
1025
|
if (!props[propName]) continue;
|
|
1000
1026
|
const frags = extractPropertySchemaFragments(ctx.checker, member);
|
|
@@ -1016,48 +1042,124 @@ function buildPathParameters(operation, ctx, parameters) {
|
|
|
1016
1042
|
paramSchema = mergeFragments(paramSchema, ...frags);
|
|
1017
1043
|
}
|
|
1018
1044
|
}
|
|
1045
|
+
const schema = paramSchema.$ref ? { $ref: paramSchema.$ref } : paramSchema;
|
|
1019
1046
|
parameters.push({
|
|
1020
1047
|
name: param.name,
|
|
1021
1048
|
in: "path",
|
|
1022
1049
|
required: !param.isOptional,
|
|
1023
|
-
schema
|
|
1050
|
+
schema
|
|
1024
1051
|
});
|
|
1025
1052
|
}
|
|
1026
1053
|
}
|
|
1027
1054
|
}
|
|
1055
|
+
function isObjectLikeSchema(schema, ctx) {
|
|
1056
|
+
const resolved = resolveSchemaRef(schema, ctx.components);
|
|
1057
|
+
if (resolved.type === "object" || resolved.properties || resolved.additionalProperties) {
|
|
1058
|
+
return true;
|
|
1059
|
+
}
|
|
1060
|
+
if (resolved.allOf) {
|
|
1061
|
+
for (const branch of resolved.allOf) {
|
|
1062
|
+
if (isObjectLikeSchema(branch, ctx)) {
|
|
1063
|
+
return true;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
if (resolved.type === "array" && resolved.items) {
|
|
1068
|
+
const itemsSchema = resolveSchemaRef(resolved.items, ctx.components);
|
|
1069
|
+
return isObjectLikeSchema(itemsSchema, ctx);
|
|
1070
|
+
}
|
|
1071
|
+
return false;
|
|
1072
|
+
}
|
|
1073
|
+
function resolveSchemaRef(schema, components) {
|
|
1074
|
+
const ref = schema.$ref;
|
|
1075
|
+
if (typeof ref !== "string" || !ref.startsWith("#/components/schemas/")) {
|
|
1076
|
+
return schema;
|
|
1077
|
+
}
|
|
1078
|
+
const name = ref.replace("#/components/schemas/", "");
|
|
1079
|
+
const next = components.get(name);
|
|
1080
|
+
if (!next) return schema;
|
|
1081
|
+
return resolveSchemaRef(next, components);
|
|
1082
|
+
}
|
|
1083
|
+
function resolveAndCollectObjectProps(schema, components) {
|
|
1084
|
+
const resolved = resolveSchemaRef(schema, components);
|
|
1085
|
+
const properties = {};
|
|
1086
|
+
const required = [];
|
|
1087
|
+
const processSchema = (s) => {
|
|
1088
|
+
const current = resolveSchemaRef(s, components);
|
|
1089
|
+
if (current.properties) {
|
|
1090
|
+
for (const [key, val] of Object.entries(current.properties)) {
|
|
1091
|
+
if (!properties[key]) {
|
|
1092
|
+
properties[key] = val;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
if (current.required) {
|
|
1097
|
+
for (const req of current.required) {
|
|
1098
|
+
if (!required.includes(req)) {
|
|
1099
|
+
required.push(req);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
if (current.allOf) {
|
|
1104
|
+
for (const branch of current.allOf) {
|
|
1105
|
+
processSchema(branch);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
processSchema(resolved);
|
|
1110
|
+
return { properties, required };
|
|
1111
|
+
}
|
|
1028
1112
|
function buildQueryParameters(operation, ctx, parameters) {
|
|
1029
1113
|
if (operation.queryObjectParamIndex !== null) {
|
|
1030
1114
|
const queryParam = operation.parameters[operation.queryObjectParamIndex];
|
|
1031
1115
|
if (!queryParam) return;
|
|
1032
|
-
const queryStyle = extractQueryStyleOptions(ctx.checker, operation.methodDeclaration);
|
|
1033
1116
|
const querySchema = typeToJsonSchema(queryParam.type, ctx);
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
const
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
schema: querySchema.$ref ? { $ref: querySchema.$ref } : querySchema,
|
|
1041
|
-
style: "deepObject",
|
|
1042
|
-
explode
|
|
1043
|
-
};
|
|
1044
|
-
if (queryStyle.allowReserved !== void 0) {
|
|
1045
|
-
deepParam.allowReserved = queryStyle.allowReserved;
|
|
1046
|
-
}
|
|
1047
|
-
parameters.push(deepParam);
|
|
1048
|
-
} else {
|
|
1049
|
-
if (!querySchema.properties) return;
|
|
1050
|
-
const queryObjProps = querySchema.properties;
|
|
1051
|
-
for (const [propName, propSchema] of Object.entries(queryObjProps)) {
|
|
1052
|
-
const isRequired = querySchema.required?.includes(propName) ?? false;
|
|
1053
|
-
const serialization = determineQuerySerialization(propSchema.type);
|
|
1117
|
+
const { properties: queryObjProps, required: queryRequired } = resolveAndCollectObjectProps(querySchema, ctx.components);
|
|
1118
|
+
for (const [propName, propSchema] of Object.entries(queryObjProps)) {
|
|
1119
|
+
const isRequired = queryRequired.includes(propName) ?? false;
|
|
1120
|
+
const isObjectLike = isObjectLikeSchema(propSchema, ctx);
|
|
1121
|
+
const serialization = determineQuerySerialization(propSchema.type);
|
|
1122
|
+
if (isObjectLike) {
|
|
1054
1123
|
parameters.push({
|
|
1055
1124
|
name: propName,
|
|
1056
1125
|
in: "query",
|
|
1057
1126
|
required: isRequired,
|
|
1058
|
-
|
|
1059
|
-
|
|
1127
|
+
content: {
|
|
1128
|
+
"application/json": {
|
|
1129
|
+
schema: propSchema.$ref ? { $ref: propSchema.$ref } : propSchema
|
|
1130
|
+
}
|
|
1131
|
+
},
|
|
1132
|
+
description: `URL-encoded JSON. Example: ${propName}=${encodeURIComponent(JSON.stringify({ example: "value" }))}`
|
|
1060
1133
|
});
|
|
1134
|
+
} else {
|
|
1135
|
+
const paramDef = {
|
|
1136
|
+
name: propName,
|
|
1137
|
+
in: "query",
|
|
1138
|
+
required: isRequired,
|
|
1139
|
+
schema: propSchema.$ref ? { $ref: propSchema.$ref } : propSchema
|
|
1140
|
+
};
|
|
1141
|
+
if (propName === "page") {
|
|
1142
|
+
paramDef.schema = { type: "integer", default: 1, minimum: 1 };
|
|
1143
|
+
} else if (propName === "pageSize") {
|
|
1144
|
+
paramDef.schema = { type: "integer", default: 10, minimum: 1 };
|
|
1145
|
+
} else if (propName === "totalItems") {
|
|
1146
|
+
paramDef.schema = { type: "integer", minimum: 0 };
|
|
1147
|
+
} else if (propName === "sort") {
|
|
1148
|
+
paramDef.schema = {
|
|
1149
|
+
oneOf: [
|
|
1150
|
+
{ type: "string" },
|
|
1151
|
+
{ type: "array", items: { type: "string" } }
|
|
1152
|
+
]
|
|
1153
|
+
};
|
|
1154
|
+
} else if (propName === "q") {
|
|
1155
|
+
paramDef.schema = { type: "string" };
|
|
1156
|
+
} else if (propName === "hasComments") {
|
|
1157
|
+
paramDef.schema = { type: "boolean" };
|
|
1158
|
+
}
|
|
1159
|
+
if (Object.keys(serialization).length > 0) {
|
|
1160
|
+
Object.assign(paramDef, serialization);
|
|
1161
|
+
}
|
|
1162
|
+
parameters.push(paramDef);
|
|
1061
1163
|
}
|
|
1062
1164
|
}
|
|
1063
1165
|
}
|
|
@@ -1071,14 +1173,28 @@ function buildQueryParameters(operation, ctx, parameters) {
|
|
|
1071
1173
|
paramSchema = mergeFragments(paramSchema, ...frags);
|
|
1072
1174
|
}
|
|
1073
1175
|
}
|
|
1074
|
-
const
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1176
|
+
const isObjectLike = isObjectLikeSchema(paramSchema, ctx);
|
|
1177
|
+
if (isObjectLike) {
|
|
1178
|
+
parameters.push({
|
|
1179
|
+
name: param.name,
|
|
1180
|
+
in: "query",
|
|
1181
|
+
required: !param.isOptional,
|
|
1182
|
+
content: {
|
|
1183
|
+
"application/json": {
|
|
1184
|
+
schema: paramSchema.$ref ? { $ref: paramSchema.$ref } : paramSchema
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
});
|
|
1188
|
+
} else {
|
|
1189
|
+
const serialization = determineQuerySerialization(paramSchema.type);
|
|
1190
|
+
parameters.push({
|
|
1191
|
+
name: param.name,
|
|
1192
|
+
in: "query",
|
|
1193
|
+
required: !param.isOptional,
|
|
1194
|
+
schema: paramSchema.$ref ? { $ref: paramSchema.$ref } : paramSchema,
|
|
1195
|
+
...Object.keys(serialization).length > 0 ? serialization : {}
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1082
1198
|
}
|
|
1083
1199
|
}
|
|
1084
1200
|
}
|
|
@@ -1128,14 +1244,15 @@ function buildCookieParameters(operation, ctx, parameters) {
|
|
|
1128
1244
|
}
|
|
1129
1245
|
|
|
1130
1246
|
// src/compiler/manifest/emit.ts
|
|
1131
|
-
var
|
|
1247
|
+
var import_typescript6 = __toESM(require("typescript"), 1);
|
|
1132
1248
|
function generateManifest(controllers, checker, version, validationMode = "ajv-runtime") {
|
|
1133
1249
|
const components = /* @__PURE__ */ new Map();
|
|
1134
1250
|
const ctx = {
|
|
1135
1251
|
checker,
|
|
1136
1252
|
components,
|
|
1137
1253
|
typeStack: /* @__PURE__ */ new Set(),
|
|
1138
|
-
typeNameStack: []
|
|
1254
|
+
typeNameStack: [],
|
|
1255
|
+
mode: "request"
|
|
1139
1256
|
};
|
|
1140
1257
|
const controllerEntries = controllers.map((ctrl) => ({
|
|
1141
1258
|
controllerId: ctrl.className,
|
|
@@ -1149,7 +1266,7 @@ function generateManifest(controllers, checker, version, validationMode = "ajv-r
|
|
|
1149
1266
|
generator: {
|
|
1150
1267
|
name: "adorn-api",
|
|
1151
1268
|
version,
|
|
1152
|
-
typescript:
|
|
1269
|
+
typescript: import_typescript6.default.version
|
|
1153
1270
|
},
|
|
1154
1271
|
schemas: {
|
|
1155
1272
|
kind: "openapi-3.1",
|
|
@@ -1160,14 +1277,70 @@ function generateManifest(controllers, checker, version, validationMode = "ajv-r
|
|
|
1160
1277
|
controllers: controllerEntries
|
|
1161
1278
|
};
|
|
1162
1279
|
}
|
|
1280
|
+
function resolveSchemaRef2(schema, components) {
|
|
1281
|
+
const ref = schema.$ref;
|
|
1282
|
+
if (typeof ref !== "string" || !ref.startsWith("#/components/schemas/")) {
|
|
1283
|
+
return schema;
|
|
1284
|
+
}
|
|
1285
|
+
const name = ref.replace("#/components/schemas/", "");
|
|
1286
|
+
const next = components.get(name);
|
|
1287
|
+
if (!next) return schema;
|
|
1288
|
+
return resolveSchemaRef2(next, components);
|
|
1289
|
+
}
|
|
1290
|
+
function resolveAndCollectObjectProps2(schema, components) {
|
|
1291
|
+
const resolved = resolveSchemaRef2(schema, components);
|
|
1292
|
+
const properties = {};
|
|
1293
|
+
const required = [];
|
|
1294
|
+
const processSchema = (s) => {
|
|
1295
|
+
const current = resolveSchemaRef2(s, components);
|
|
1296
|
+
if (current.properties) {
|
|
1297
|
+
for (const [key, val] of Object.entries(current.properties)) {
|
|
1298
|
+
if (!properties[key]) {
|
|
1299
|
+
properties[key] = val;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
if (current.required) {
|
|
1304
|
+
for (const req of current.required) {
|
|
1305
|
+
if (!required.includes(req)) {
|
|
1306
|
+
required.push(req);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
if (current.allOf) {
|
|
1311
|
+
for (const branch of current.allOf) {
|
|
1312
|
+
processSchema(branch);
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
processSchema(resolved);
|
|
1317
|
+
return { properties, required };
|
|
1318
|
+
}
|
|
1319
|
+
function isObjectLikeSchema2(schema, components) {
|
|
1320
|
+
const resolved = resolveSchemaRef2(schema, components);
|
|
1321
|
+
if (resolved.type === "object" || resolved.properties || resolved.additionalProperties) {
|
|
1322
|
+
return true;
|
|
1323
|
+
}
|
|
1324
|
+
if (resolved.allOf) {
|
|
1325
|
+
for (const branch of resolved.allOf) {
|
|
1326
|
+
if (isObjectLikeSchema2(branch, components)) {
|
|
1327
|
+
return true;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
if (resolved.type === "array" && resolved.items) {
|
|
1332
|
+
const itemsSchema = resolveSchemaRef2(resolved.items, components);
|
|
1333
|
+
return isObjectLikeSchema2(itemsSchema, components);
|
|
1334
|
+
}
|
|
1335
|
+
return false;
|
|
1336
|
+
}
|
|
1163
1337
|
function buildOperationEntry(op, ctx) {
|
|
1164
1338
|
const args = {
|
|
1165
1339
|
body: null,
|
|
1166
1340
|
path: [],
|
|
1167
1341
|
query: [],
|
|
1168
1342
|
headers: [],
|
|
1169
|
-
cookies: []
|
|
1170
|
-
paginationParamIndex: op.paginationParamIndex
|
|
1343
|
+
cookies: []
|
|
1171
1344
|
};
|
|
1172
1345
|
buildPathArgs(op, ctx, args);
|
|
1173
1346
|
buildQueryArgs(op, ctx, args);
|
|
@@ -1234,53 +1407,39 @@ function buildPathArgs(op, ctx, args) {
|
|
|
1234
1407
|
function buildQueryArgs(op, ctx, args) {
|
|
1235
1408
|
if (op.queryObjectParamIndex !== null) {
|
|
1236
1409
|
const queryParam = op.parameters[op.queryObjectParamIndex];
|
|
1237
|
-
if (queryParam)
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
schemaRef,
|
|
1247
|
-
schemaType: querySchema.type,
|
|
1248
|
-
serialization: {
|
|
1249
|
-
style: "deepObject",
|
|
1250
|
-
explode: queryStyle.explode ?? true,
|
|
1251
|
-
allowReserved: queryStyle.allowReserved
|
|
1252
|
-
}
|
|
1253
|
-
});
|
|
1254
|
-
} else {
|
|
1255
|
-
if (!querySchema.properties) return;
|
|
1256
|
-
for (const [propName, propSchema] of Object.entries(querySchema.properties)) {
|
|
1257
|
-
const isRequired = querySchema.required?.includes(propName) ?? false;
|
|
1258
|
-
let schemaRef = propSchema.$ref;
|
|
1259
|
-
if (!schemaRef) {
|
|
1260
|
-
schemaRef = "#/components/schemas/InlineQueryParam";
|
|
1261
|
-
}
|
|
1262
|
-
args.query.push({
|
|
1263
|
-
name: propName,
|
|
1264
|
-
index: queryParam.index,
|
|
1265
|
-
required: !isRequired,
|
|
1266
|
-
schemaRef,
|
|
1267
|
-
schemaType: propSchema.type
|
|
1268
|
-
});
|
|
1269
|
-
}
|
|
1410
|
+
if (!queryParam) return;
|
|
1411
|
+
const querySchema = typeToJsonSchema(queryParam.type, ctx);
|
|
1412
|
+
const { properties: queryObjProps, required: queryRequired } = resolveAndCollectObjectProps2(querySchema, ctx.components);
|
|
1413
|
+
for (const [propName, propSchema] of Object.entries(queryObjProps)) {
|
|
1414
|
+
const isRequired = queryRequired.includes(propName) ?? false;
|
|
1415
|
+
const isObjectLike = isObjectLikeSchema2(propSchema, ctx.components);
|
|
1416
|
+
let schemaRef = propSchema.$ref;
|
|
1417
|
+
if (!schemaRef) {
|
|
1418
|
+
schemaRef = "#/components/schemas/InlineQueryParam";
|
|
1270
1419
|
}
|
|
1420
|
+
args.query.push({
|
|
1421
|
+
name: propName,
|
|
1422
|
+
index: queryParam.index,
|
|
1423
|
+
required: !isRequired,
|
|
1424
|
+
schemaRef,
|
|
1425
|
+
schemaType: propSchema.type,
|
|
1426
|
+
content: isObjectLike ? "application/json" : void 0
|
|
1427
|
+
});
|
|
1271
1428
|
}
|
|
1272
1429
|
}
|
|
1273
1430
|
for (const paramIndex of op.queryParamIndices) {
|
|
1274
1431
|
const param = op.parameters[paramIndex];
|
|
1275
1432
|
if (param) {
|
|
1276
1433
|
const paramSchema = typeToJsonSchema(param.type, ctx);
|
|
1434
|
+
const isObjectLike = isObjectLikeSchema2(paramSchema, ctx.components);
|
|
1277
1435
|
const schemaRef = paramSchema.$ref ?? "#/components/schemas/InlineQueryParam";
|
|
1278
1436
|
args.query.push({
|
|
1279
1437
|
name: param.name,
|
|
1280
1438
|
index: param.index,
|
|
1281
1439
|
required: !param.isOptional,
|
|
1282
1440
|
schemaRef,
|
|
1283
|
-
schemaType: paramSchema.type
|
|
1441
|
+
schemaType: paramSchema.type,
|
|
1442
|
+
content: isObjectLike ? "application/json" : void 0
|
|
1284
1443
|
});
|
|
1285
1444
|
}
|
|
1286
1445
|
}
|
|
@@ -1469,7 +1628,7 @@ export function validateResponse(operationId, status, contentType, data) {
|
|
|
1469
1628
|
// src/compiler/cache/isStale.ts
|
|
1470
1629
|
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
1471
1630
|
var import_node_path3 = __toESM(require("path"), 1);
|
|
1472
|
-
var
|
|
1631
|
+
var import_typescript7 = require("typescript");
|
|
1473
1632
|
var import_meta = {};
|
|
1474
1633
|
function readJson(p) {
|
|
1475
1634
|
try {
|
|
@@ -1576,7 +1735,7 @@ async function isStale(params) {
|
|
|
1576
1735
|
// src/compiler/cache/writeCache.ts
|
|
1577
1736
|
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
1578
1737
|
var import_node_path4 = __toESM(require("path"), 1);
|
|
1579
|
-
var
|
|
1738
|
+
var import_typescript8 = __toESM(require("typescript"), 1);
|
|
1580
1739
|
function statMtimeMs2(p) {
|
|
1581
1740
|
return import_node_fs4.default.statSync(p).mtimeMs;
|
|
1582
1741
|
}
|
|
@@ -1609,7 +1768,7 @@ function writeCache(params) {
|
|
|
1609
1768
|
generator: {
|
|
1610
1769
|
name: "adorn-api",
|
|
1611
1770
|
version: params.adornVersion,
|
|
1612
|
-
typescript:
|
|
1771
|
+
typescript: import_typescript8.default.version
|
|
1613
1772
|
},
|
|
1614
1773
|
project: {
|
|
1615
1774
|
tsconfigPath: params.tsconfigAbs,
|
|
@@ -1622,7 +1781,7 @@ function writeCache(params) {
|
|
|
1622
1781
|
}
|
|
1623
1782
|
|
|
1624
1783
|
// src/cli.ts
|
|
1625
|
-
var
|
|
1784
|
+
var import_typescript9 = __toESM(require("typescript"), 1);
|
|
1626
1785
|
var import_node_process = __toESM(require("process"), 1);
|
|
1627
1786
|
var ADORN_VERSION = "0.1.0";
|
|
1628
1787
|
function log(msg) {
|
|
@@ -1633,6 +1792,26 @@ function debug(...args) {
|
|
|
1633
1792
|
console.error("[adorn-api]", ...args);
|
|
1634
1793
|
}
|
|
1635
1794
|
}
|
|
1795
|
+
function sanitizeForJson(obj) {
|
|
1796
|
+
if (obj === null || obj === void 0) return obj;
|
|
1797
|
+
if (typeof obj !== "object") return obj;
|
|
1798
|
+
if (Array.isArray(obj)) {
|
|
1799
|
+
return obj.map((item) => sanitizeForJson(item));
|
|
1800
|
+
}
|
|
1801
|
+
const result = {};
|
|
1802
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
1803
|
+
if (key.startsWith("__@") || key.startsWith("[")) continue;
|
|
1804
|
+
if (typeof value === "function") continue;
|
|
1805
|
+
if (value !== null && typeof value === "object") {
|
|
1806
|
+
const typeName = value.constructor?.name;
|
|
1807
|
+
if (typeName && !["Object", "Array", "String", "Number", "Boolean", "Date", "RegExp"].includes(typeName)) {
|
|
1808
|
+
continue;
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
result[key] = sanitizeForJson(value);
|
|
1812
|
+
}
|
|
1813
|
+
return result;
|
|
1814
|
+
}
|
|
1636
1815
|
async function buildCommand(args) {
|
|
1637
1816
|
const projectIndex = args.indexOf("-p");
|
|
1638
1817
|
const projectPath = projectIndex !== -1 ? args[projectIndex + 1] : "./tsconfig.json";
|
|
@@ -1650,7 +1829,7 @@ async function buildCommand(args) {
|
|
|
1650
1829
|
outDir: outputDir,
|
|
1651
1830
|
project: projectPath,
|
|
1652
1831
|
adornVersion: ADORN_VERSION,
|
|
1653
|
-
typescriptVersion:
|
|
1832
|
+
typescriptVersion: import_typescript9.default.version
|
|
1654
1833
|
});
|
|
1655
1834
|
if (!stale.stale) {
|
|
1656
1835
|
log("adorn-api: artifacts up-to-date");
|
|
@@ -1671,7 +1850,7 @@ async function buildCommand(args) {
|
|
|
1671
1850
|
const openapi = generateOpenAPI(controllers, checker, { title: "API", version: "1.0.0" });
|
|
1672
1851
|
const manifest = generateManifest(controllers, checker, ADORN_VERSION, validationMode);
|
|
1673
1852
|
(0, import_node_fs5.mkdirSync)(outputPath, { recursive: true });
|
|
1674
|
-
(0, import_node_fs5.writeFileSync)((0, import_node_path5.resolve)(outputPath, "openapi.json"), JSON.stringify(openapi, null, 2));
|
|
1853
|
+
(0, import_node_fs5.writeFileSync)((0, import_node_path5.resolve)(outputPath, "openapi.json"), JSON.stringify(sanitizeForJson(openapi), null, 2));
|
|
1675
1854
|
(0, import_node_fs5.writeFileSync)((0, import_node_path5.resolve)(outputPath, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
1676
1855
|
if (validationMode === "precompiled") {
|
|
1677
1856
|
log("Generating precompiled validators...");
|