adorn-api 1.0.8 → 1.0.10
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/cli.cjs +106 -50
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +106 -50
- package/dist/cli.js.map +1 -1
- package/dist/compiler/analyze/scanControllers.d.ts +1 -0
- package/dist/compiler/analyze/scanControllers.d.ts.map +1 -1
- package/dist/compiler/schema/typeToJsonSchema.d.ts.map +1 -1
- package/dist/metal/index.cjs.map +1 -1
- package/dist/metal/searchWhere.d.ts +25 -9
- package/dist/metal/searchWhere.d.ts.map +1 -1
- package/dist/scripts/adorn-example.cjs +28 -4
- package/dist/scripts/adorn-example.cjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -154,6 +154,7 @@ function analyzeMethod(node, className, checker) {
|
|
|
154
154
|
if (!signature) return null;
|
|
155
155
|
let returnType = checker.getReturnTypeOfSignature(signature);
|
|
156
156
|
returnType = unwrapPromise(returnType, checker);
|
|
157
|
+
const returnTypeNode = unwrapPromiseTypeNode(node.type);
|
|
157
158
|
const parameters = [];
|
|
158
159
|
for (let i = 0; i < node.parameters.length; i++) {
|
|
159
160
|
const param = node.parameters[i];
|
|
@@ -178,6 +179,7 @@ function analyzeMethod(node, className, checker) {
|
|
|
178
179
|
operationId: defaultOperationId(className, methodName),
|
|
179
180
|
methodDeclaration: node,
|
|
180
181
|
returnType,
|
|
182
|
+
returnTypeNode,
|
|
181
183
|
parameters,
|
|
182
184
|
pathParamIndices,
|
|
183
185
|
bodyParamIndex,
|
|
@@ -308,6 +310,15 @@ function unwrapPromise(type, checker) {
|
|
|
308
310
|
}
|
|
309
311
|
return type;
|
|
310
312
|
}
|
|
313
|
+
function unwrapPromiseTypeNode(typeNode) {
|
|
314
|
+
if (!typeNode) return void 0;
|
|
315
|
+
if (import_typescript2.default.isTypeReferenceNode(typeNode)) {
|
|
316
|
+
if (import_typescript2.default.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise") {
|
|
317
|
+
return typeNode.typeArguments?.[0] ?? typeNode;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return typeNode;
|
|
321
|
+
}
|
|
311
322
|
|
|
312
323
|
// src/compiler/schema/openapi.ts
|
|
313
324
|
var import_typescript6 = __toESM(require("typescript"), 1);
|
|
@@ -354,10 +365,10 @@ function typeToJsonSchema(type, ctx, typeNode) {
|
|
|
354
365
|
return { type: "boolean", enum: [intrinsic === "true"] };
|
|
355
366
|
}
|
|
356
367
|
if (type.isUnion()) {
|
|
357
|
-
return handleUnion(type
|
|
368
|
+
return handleUnion(type, ctx, typeNode);
|
|
358
369
|
}
|
|
359
370
|
if (type.isIntersection()) {
|
|
360
|
-
return handleIntersection(type
|
|
371
|
+
return handleIntersection(type, ctx, typeNode);
|
|
361
372
|
}
|
|
362
373
|
if (checker.isArrayType(type)) {
|
|
363
374
|
const typeArgs = type.typeArguments;
|
|
@@ -394,56 +405,96 @@ function isSetType(type, checker) {
|
|
|
394
405
|
if (name === "Set") return true;
|
|
395
406
|
return false;
|
|
396
407
|
}
|
|
397
|
-
function
|
|
398
|
-
const
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
const enumValues = otherTypes.map((t) => t.value);
|
|
403
|
-
const schema = { type: "string", enum: enumValues };
|
|
404
|
-
if (nullType) {
|
|
405
|
-
schema.type = ["string", "null"];
|
|
406
|
-
}
|
|
407
|
-
return schema;
|
|
408
|
+
function getSchemaName(type, typeNode) {
|
|
409
|
+
const aliasSymbol = type.aliasSymbol ?? type.aliasSymbol;
|
|
410
|
+
const aliasName = aliasSymbol?.getName();
|
|
411
|
+
if (aliasName && aliasName !== "__type") {
|
|
412
|
+
return aliasName;
|
|
408
413
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
return innerSchema;
|
|
415
|
-
}
|
|
416
|
-
if (otherTypes.length > 1) {
|
|
417
|
-
const branches = otherTypes.map((t) => typeToJsonSchema(t, ctx));
|
|
418
|
-
const hasNull = !!nullType;
|
|
419
|
-
const result = {};
|
|
420
|
-
if (hasNull) {
|
|
421
|
-
result.anyOf = [...branches, { type: "null" }];
|
|
422
|
-
} else {
|
|
423
|
-
result.anyOf = branches;
|
|
424
|
-
}
|
|
425
|
-
const discriminatorResult = detectDiscriminatedUnion(otherTypes, ctx, branches);
|
|
426
|
-
if (discriminatorResult) {
|
|
427
|
-
result.oneOf = branches;
|
|
428
|
-
result.discriminator = discriminatorResult;
|
|
429
|
-
}
|
|
430
|
-
return result;
|
|
414
|
+
const symbol = type.getSymbol();
|
|
415
|
+
const symbolName = symbol?.getName?.();
|
|
416
|
+
if (symbolName && symbolName !== "__type") {
|
|
417
|
+
return symbolName;
|
|
431
418
|
}
|
|
432
|
-
|
|
433
|
-
|
|
419
|
+
const nodeName = getExplicitTypeNameFromNode(typeNode);
|
|
420
|
+
if (nodeName && nodeName !== "__type") {
|
|
421
|
+
return nodeName;
|
|
434
422
|
}
|
|
435
|
-
return
|
|
423
|
+
return null;
|
|
436
424
|
}
|
|
437
|
-
function
|
|
438
|
-
const
|
|
439
|
-
if (
|
|
440
|
-
return
|
|
425
|
+
function buildNamedSchema(type, ctx, typeNode, build) {
|
|
426
|
+
const name = getSchemaName(type, typeNode);
|
|
427
|
+
if (!name) {
|
|
428
|
+
return build();
|
|
441
429
|
}
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
430
|
+
const { components, typeStack } = ctx;
|
|
431
|
+
if (components.has(name) || typeStack.has(type)) {
|
|
432
|
+
return { $ref: `#/components/schemas/${name}` };
|
|
445
433
|
}
|
|
446
|
-
|
|
434
|
+
typeStack.add(type);
|
|
435
|
+
const schema = build();
|
|
436
|
+
typeStack.delete(type);
|
|
437
|
+
if (!components.has(name)) {
|
|
438
|
+
components.set(name, schema);
|
|
439
|
+
}
|
|
440
|
+
return { $ref: `#/components/schemas/${name}` };
|
|
441
|
+
}
|
|
442
|
+
function handleUnion(type, ctx, typeNode) {
|
|
443
|
+
return buildNamedSchema(type, ctx, typeNode, () => {
|
|
444
|
+
const types = type.types;
|
|
445
|
+
const nullType = types.find((t) => t.flags & import_typescript3.default.TypeFlags.Null);
|
|
446
|
+
const otherTypes = types.filter((t) => !(t.flags & import_typescript3.default.TypeFlags.Null) && !(t.flags & import_typescript3.default.TypeFlags.Undefined));
|
|
447
|
+
const allStringLiterals = otherTypes.every((t) => t.flags & import_typescript3.default.TypeFlags.StringLiteral);
|
|
448
|
+
if (allStringLiterals && otherTypes.length > 0) {
|
|
449
|
+
const enumValues = otherTypes.map((t) => t.value);
|
|
450
|
+
const schema = { type: "string", enum: enumValues };
|
|
451
|
+
if (nullType) {
|
|
452
|
+
schema.type = ["string", "null"];
|
|
453
|
+
}
|
|
454
|
+
return schema;
|
|
455
|
+
}
|
|
456
|
+
if (otherTypes.length === 1 && nullType) {
|
|
457
|
+
const innerSchema = typeToJsonSchema(otherTypes[0], ctx);
|
|
458
|
+
if (typeof innerSchema.type === "string") {
|
|
459
|
+
innerSchema.type = [innerSchema.type, "null"];
|
|
460
|
+
}
|
|
461
|
+
return innerSchema;
|
|
462
|
+
}
|
|
463
|
+
if (otherTypes.length > 1) {
|
|
464
|
+
const branches = otherTypes.map((t) => typeToJsonSchema(t, ctx));
|
|
465
|
+
const hasNull = !!nullType;
|
|
466
|
+
const result = {};
|
|
467
|
+
if (hasNull) {
|
|
468
|
+
result.anyOf = [...branches, { type: "null" }];
|
|
469
|
+
} else {
|
|
470
|
+
result.anyOf = branches;
|
|
471
|
+
}
|
|
472
|
+
const discriminatorResult = detectDiscriminatedUnion(otherTypes, ctx, branches);
|
|
473
|
+
if (discriminatorResult) {
|
|
474
|
+
result.oneOf = branches;
|
|
475
|
+
result.discriminator = discriminatorResult;
|
|
476
|
+
}
|
|
477
|
+
return result;
|
|
478
|
+
}
|
|
479
|
+
if (otherTypes.length === 1) {
|
|
480
|
+
return typeToJsonSchema(otherTypes[0], ctx);
|
|
481
|
+
}
|
|
482
|
+
return {};
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
function handleIntersection(type, ctx, typeNode) {
|
|
486
|
+
return buildNamedSchema(type, ctx, typeNode, () => {
|
|
487
|
+
const types = type.types;
|
|
488
|
+
const brandCollapsed = tryCollapseBrandedIntersection(types, ctx, typeNode);
|
|
489
|
+
if (brandCollapsed) {
|
|
490
|
+
return brandCollapsed;
|
|
491
|
+
}
|
|
492
|
+
const allOf = [];
|
|
493
|
+
for (const t of types) {
|
|
494
|
+
allOf.push(typeToJsonSchema(t, ctx));
|
|
495
|
+
}
|
|
496
|
+
return { allOf };
|
|
497
|
+
});
|
|
447
498
|
}
|
|
448
499
|
function tryCollapseBrandedIntersection(types, ctx, typeNode) {
|
|
449
500
|
const { checker } = ctx;
|
|
@@ -574,8 +625,8 @@ function handleObjectType(type, ctx, typeNode) {
|
|
|
574
625
|
typeStack.delete(type);
|
|
575
626
|
return schema;
|
|
576
627
|
}
|
|
577
|
-
function
|
|
578
|
-
if (!typeNode) return
|
|
628
|
+
function getExplicitTypeNameFromNode(typeNode) {
|
|
629
|
+
if (!typeNode) return null;
|
|
579
630
|
if (import_typescript3.default.isTypeReferenceNode(typeNode)) {
|
|
580
631
|
if (import_typescript3.default.isIdentifier(typeNode.typeName)) {
|
|
581
632
|
return typeNode.typeName.text;
|
|
@@ -586,6 +637,11 @@ function getTypeNameFromNode(typeNode, ctx) {
|
|
|
586
637
|
return typeNode.parent.name.text;
|
|
587
638
|
}
|
|
588
639
|
}
|
|
640
|
+
return null;
|
|
641
|
+
}
|
|
642
|
+
function getTypeNameFromNode(typeNode, ctx) {
|
|
643
|
+
const explicitName = getExplicitTypeNameFromNode(typeNode);
|
|
644
|
+
if (explicitName) return explicitName;
|
|
589
645
|
return `Anonymous_${ctx.typeNameStack.length}`;
|
|
590
646
|
}
|
|
591
647
|
function buildObjectSchema(type, ctx, typeNode) {
|
|
@@ -884,7 +940,7 @@ function buildOperation(operation, ctx, controllerConsumes) {
|
|
|
884
940
|
if (parameters.length > 0) {
|
|
885
941
|
op.parameters = parameters;
|
|
886
942
|
}
|
|
887
|
-
const responseSchema = typeToJsonSchema(operation.returnType, ctx);
|
|
943
|
+
const responseSchema = typeToJsonSchema(operation.returnType, ctx, operation.returnTypeNode);
|
|
888
944
|
const status = operation.httpMethod === "POST" ? 201 : 200;
|
|
889
945
|
op.responses[status] = {
|
|
890
946
|
description: status === 201 ? "Created" : "OK",
|
|
@@ -1121,7 +1177,7 @@ function buildOperationEntry(op, ctx) {
|
|
|
1121
1177
|
};
|
|
1122
1178
|
}
|
|
1123
1179
|
}
|
|
1124
|
-
const responseSchema = typeToJsonSchema(op.returnType, ctx);
|
|
1180
|
+
const responseSchema = typeToJsonSchema(op.returnType, ctx, op.returnTypeNode);
|
|
1125
1181
|
const status = op.httpMethod === "POST" ? 201 : 200;
|
|
1126
1182
|
let schemaRef = responseSchema.$ref;
|
|
1127
1183
|
let isArray = false;
|