adorn-api 1.0.9 → 1.0.11
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/adapter/express/index.d.ts.map +1 -1
- package/dist/adapter/express/merge.d.ts +3 -0
- package/dist/adapter/express/merge.d.ts.map +1 -1
- package/dist/cli.cjs +117 -52
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +117 -52
- package/dist/cli.js.map +1 -1
- package/dist/compiler/analyze/scanControllers.d.ts +2 -0
- package/dist/compiler/analyze/scanControllers.d.ts.map +1 -1
- package/dist/compiler/manifest/format.d.ts +1 -0
- package/dist/compiler/manifest/format.d.ts.map +1 -1
- package/dist/compiler/schema/typeToJsonSchema.d.ts.map +1 -1
- package/dist/decorators/Paginated.d.ts +5 -0
- package/dist/decorators/Paginated.d.ts.map +1 -0
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/express.cjs +10 -1
- package/dist/express.cjs.map +1 -1
- package/dist/express.js +10 -1
- package/dist/express.js.map +1 -1
- package/dist/http.d.ts +10 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/index.cjs +25 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/dist/metal/searchWhere.d.ts +20 -9
- package/dist/metal/searchWhere.d.ts.map +1 -1
- package/dist/runtime/metadata/types.d.ts +3 -0
- package/dist/runtime/metadata/types.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -137,6 +137,7 @@ function analyzeMethod(node, className, checker) {
|
|
|
137
137
|
if (!signature) return null;
|
|
138
138
|
let returnType = checker.getReturnTypeOfSignature(signature);
|
|
139
139
|
returnType = unwrapPromise(returnType, checker);
|
|
140
|
+
const returnTypeNode = unwrapPromiseTypeNode(node.type);
|
|
140
141
|
const parameters = [];
|
|
141
142
|
for (let i = 0; i < node.parameters.length; i++) {
|
|
142
143
|
const param = node.parameters[i];
|
|
@@ -153,7 +154,7 @@ function analyzeMethod(node, className, checker) {
|
|
|
153
154
|
}
|
|
154
155
|
const pathParamNames = extractPathParams(path4);
|
|
155
156
|
const pathParamIndices = matchPathParamsToIndices(pathParamNames, parameters);
|
|
156
|
-
const { bodyParamIndex, queryParamIndices, queryObjectParamIndex, headerObjectParamIndex, cookieObjectParamIndex, bodyContentType } = classifyParameters(parameters, httpMethod, pathParamIndices, checker);
|
|
157
|
+
const { bodyParamIndex, queryParamIndices, queryObjectParamIndex, headerObjectParamIndex, cookieObjectParamIndex, paginationParamIndex, bodyContentType } = classifyParameters(parameters, httpMethod, pathParamIndices, checker);
|
|
157
158
|
return {
|
|
158
159
|
methodName,
|
|
159
160
|
httpMethod,
|
|
@@ -161,6 +162,7 @@ function analyzeMethod(node, className, checker) {
|
|
|
161
162
|
operationId: defaultOperationId(className, methodName),
|
|
162
163
|
methodDeclaration: node,
|
|
163
164
|
returnType,
|
|
165
|
+
returnTypeNode,
|
|
164
166
|
parameters,
|
|
165
167
|
pathParamIndices,
|
|
166
168
|
bodyParamIndex,
|
|
@@ -168,6 +170,7 @@ function analyzeMethod(node, className, checker) {
|
|
|
168
170
|
queryObjectParamIndex,
|
|
169
171
|
headerObjectParamIndex,
|
|
170
172
|
cookieObjectParamIndex,
|
|
173
|
+
paginationParamIndex,
|
|
171
174
|
bodyContentType
|
|
172
175
|
};
|
|
173
176
|
}
|
|
@@ -193,6 +196,7 @@ function classifyParameters(parameters, httpMethod, pathParamIndices, checker) {
|
|
|
193
196
|
let queryObjectParamIndex = null;
|
|
194
197
|
let headerObjectParamIndex = null;
|
|
195
198
|
let cookieObjectParamIndex = null;
|
|
199
|
+
let paginationParamIndex = null;
|
|
196
200
|
const isBodyMethod = ["POST", "PUT", "PATCH"].includes(httpMethod);
|
|
197
201
|
for (let i = 0; i < parameters.length; i++) {
|
|
198
202
|
const param = parameters[i];
|
|
@@ -219,6 +223,11 @@ function classifyParameters(parameters, httpMethod, pathParamIndices, checker) {
|
|
|
219
223
|
usedIndices.add(i);
|
|
220
224
|
continue;
|
|
221
225
|
}
|
|
226
|
+
if (typeStr === "PaginationParams") {
|
|
227
|
+
paginationParamIndex = i;
|
|
228
|
+
usedIndices.add(i);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
222
231
|
if (isBodyMethod && bodyParamIndex === null) {
|
|
223
232
|
bodyParamIndex = i;
|
|
224
233
|
usedIndices.add(i);
|
|
@@ -239,6 +248,7 @@ function classifyParameters(parameters, httpMethod, pathParamIndices, checker) {
|
|
|
239
248
|
queryObjectParamIndex,
|
|
240
249
|
headerObjectParamIndex,
|
|
241
250
|
cookieObjectParamIndex,
|
|
251
|
+
paginationParamIndex,
|
|
242
252
|
bodyContentType: void 0
|
|
243
253
|
};
|
|
244
254
|
}
|
|
@@ -291,6 +301,15 @@ function unwrapPromise(type, checker) {
|
|
|
291
301
|
}
|
|
292
302
|
return type;
|
|
293
303
|
}
|
|
304
|
+
function unwrapPromiseTypeNode(typeNode) {
|
|
305
|
+
if (!typeNode) return void 0;
|
|
306
|
+
if (ts2.isTypeReferenceNode(typeNode)) {
|
|
307
|
+
if (ts2.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise") {
|
|
308
|
+
return typeNode.typeArguments?.[0] ?? typeNode;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return typeNode;
|
|
312
|
+
}
|
|
294
313
|
|
|
295
314
|
// src/compiler/schema/openapi.ts
|
|
296
315
|
import ts6 from "typescript";
|
|
@@ -337,10 +356,10 @@ function typeToJsonSchema(type, ctx, typeNode) {
|
|
|
337
356
|
return { type: "boolean", enum: [intrinsic === "true"] };
|
|
338
357
|
}
|
|
339
358
|
if (type.isUnion()) {
|
|
340
|
-
return handleUnion(type
|
|
359
|
+
return handleUnion(type, ctx, typeNode);
|
|
341
360
|
}
|
|
342
361
|
if (type.isIntersection()) {
|
|
343
|
-
return handleIntersection(type
|
|
362
|
+
return handleIntersection(type, ctx, typeNode);
|
|
344
363
|
}
|
|
345
364
|
if (checker.isArrayType(type)) {
|
|
346
365
|
const typeArgs = type.typeArguments;
|
|
@@ -377,56 +396,96 @@ function isSetType(type, checker) {
|
|
|
377
396
|
if (name === "Set") return true;
|
|
378
397
|
return false;
|
|
379
398
|
}
|
|
380
|
-
function
|
|
381
|
-
const
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const enumValues = otherTypes.map((t) => t.value);
|
|
386
|
-
const schema = { type: "string", enum: enumValues };
|
|
387
|
-
if (nullType) {
|
|
388
|
-
schema.type = ["string", "null"];
|
|
389
|
-
}
|
|
390
|
-
return schema;
|
|
399
|
+
function getSchemaName(type, typeNode) {
|
|
400
|
+
const aliasSymbol = type.aliasSymbol ?? type.aliasSymbol;
|
|
401
|
+
const aliasName = aliasSymbol?.getName();
|
|
402
|
+
if (aliasName && aliasName !== "__type") {
|
|
403
|
+
return aliasName;
|
|
391
404
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
}
|
|
397
|
-
return innerSchema;
|
|
398
|
-
}
|
|
399
|
-
if (otherTypes.length > 1) {
|
|
400
|
-
const branches = otherTypes.map((t) => typeToJsonSchema(t, ctx));
|
|
401
|
-
const hasNull = !!nullType;
|
|
402
|
-
const result = {};
|
|
403
|
-
if (hasNull) {
|
|
404
|
-
result.anyOf = [...branches, { type: "null" }];
|
|
405
|
-
} else {
|
|
406
|
-
result.anyOf = branches;
|
|
407
|
-
}
|
|
408
|
-
const discriminatorResult = detectDiscriminatedUnion(otherTypes, ctx, branches);
|
|
409
|
-
if (discriminatorResult) {
|
|
410
|
-
result.oneOf = branches;
|
|
411
|
-
result.discriminator = discriminatorResult;
|
|
412
|
-
}
|
|
413
|
-
return result;
|
|
405
|
+
const symbol = type.getSymbol();
|
|
406
|
+
const symbolName = symbol?.getName?.();
|
|
407
|
+
if (symbolName && symbolName !== "__type") {
|
|
408
|
+
return symbolName;
|
|
414
409
|
}
|
|
415
|
-
|
|
416
|
-
|
|
410
|
+
const nodeName = getExplicitTypeNameFromNode(typeNode);
|
|
411
|
+
if (nodeName && nodeName !== "__type") {
|
|
412
|
+
return nodeName;
|
|
417
413
|
}
|
|
418
|
-
return
|
|
414
|
+
return null;
|
|
419
415
|
}
|
|
420
|
-
function
|
|
421
|
-
const
|
|
422
|
-
if (
|
|
423
|
-
return
|
|
416
|
+
function buildNamedSchema(type, ctx, typeNode, build) {
|
|
417
|
+
const name = getSchemaName(type, typeNode);
|
|
418
|
+
if (!name) {
|
|
419
|
+
return build();
|
|
424
420
|
}
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
421
|
+
const { components, typeStack } = ctx;
|
|
422
|
+
if (components.has(name) || typeStack.has(type)) {
|
|
423
|
+
return { $ref: `#/components/schemas/${name}` };
|
|
428
424
|
}
|
|
429
|
-
|
|
425
|
+
typeStack.add(type);
|
|
426
|
+
const schema = build();
|
|
427
|
+
typeStack.delete(type);
|
|
428
|
+
if (!components.has(name)) {
|
|
429
|
+
components.set(name, schema);
|
|
430
|
+
}
|
|
431
|
+
return { $ref: `#/components/schemas/${name}` };
|
|
432
|
+
}
|
|
433
|
+
function handleUnion(type, ctx, typeNode) {
|
|
434
|
+
return buildNamedSchema(type, ctx, typeNode, () => {
|
|
435
|
+
const types = type.types;
|
|
436
|
+
const nullType = types.find((t) => t.flags & ts3.TypeFlags.Null);
|
|
437
|
+
const otherTypes = types.filter((t) => !(t.flags & ts3.TypeFlags.Null) && !(t.flags & ts3.TypeFlags.Undefined));
|
|
438
|
+
const allStringLiterals = otherTypes.every((t) => t.flags & ts3.TypeFlags.StringLiteral);
|
|
439
|
+
if (allStringLiterals && otherTypes.length > 0) {
|
|
440
|
+
const enumValues = otherTypes.map((t) => t.value);
|
|
441
|
+
const schema = { type: "string", enum: enumValues };
|
|
442
|
+
if (nullType) {
|
|
443
|
+
schema.type = ["string", "null"];
|
|
444
|
+
}
|
|
445
|
+
return schema;
|
|
446
|
+
}
|
|
447
|
+
if (otherTypes.length === 1 && nullType) {
|
|
448
|
+
const innerSchema = typeToJsonSchema(otherTypes[0], ctx);
|
|
449
|
+
if (typeof innerSchema.type === "string") {
|
|
450
|
+
innerSchema.type = [innerSchema.type, "null"];
|
|
451
|
+
}
|
|
452
|
+
return innerSchema;
|
|
453
|
+
}
|
|
454
|
+
if (otherTypes.length > 1) {
|
|
455
|
+
const branches = otherTypes.map((t) => typeToJsonSchema(t, ctx));
|
|
456
|
+
const hasNull = !!nullType;
|
|
457
|
+
const result = {};
|
|
458
|
+
if (hasNull) {
|
|
459
|
+
result.anyOf = [...branches, { type: "null" }];
|
|
460
|
+
} else {
|
|
461
|
+
result.anyOf = branches;
|
|
462
|
+
}
|
|
463
|
+
const discriminatorResult = detectDiscriminatedUnion(otherTypes, ctx, branches);
|
|
464
|
+
if (discriminatorResult) {
|
|
465
|
+
result.oneOf = branches;
|
|
466
|
+
result.discriminator = discriminatorResult;
|
|
467
|
+
}
|
|
468
|
+
return result;
|
|
469
|
+
}
|
|
470
|
+
if (otherTypes.length === 1) {
|
|
471
|
+
return typeToJsonSchema(otherTypes[0], ctx);
|
|
472
|
+
}
|
|
473
|
+
return {};
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
function handleIntersection(type, ctx, typeNode) {
|
|
477
|
+
return buildNamedSchema(type, ctx, typeNode, () => {
|
|
478
|
+
const types = type.types;
|
|
479
|
+
const brandCollapsed = tryCollapseBrandedIntersection(types, ctx, typeNode);
|
|
480
|
+
if (brandCollapsed) {
|
|
481
|
+
return brandCollapsed;
|
|
482
|
+
}
|
|
483
|
+
const allOf = [];
|
|
484
|
+
for (const t of types) {
|
|
485
|
+
allOf.push(typeToJsonSchema(t, ctx));
|
|
486
|
+
}
|
|
487
|
+
return { allOf };
|
|
488
|
+
});
|
|
430
489
|
}
|
|
431
490
|
function tryCollapseBrandedIntersection(types, ctx, typeNode) {
|
|
432
491
|
const { checker } = ctx;
|
|
@@ -557,8 +616,8 @@ function handleObjectType(type, ctx, typeNode) {
|
|
|
557
616
|
typeStack.delete(type);
|
|
558
617
|
return schema;
|
|
559
618
|
}
|
|
560
|
-
function
|
|
561
|
-
if (!typeNode) return
|
|
619
|
+
function getExplicitTypeNameFromNode(typeNode) {
|
|
620
|
+
if (!typeNode) return null;
|
|
562
621
|
if (ts3.isTypeReferenceNode(typeNode)) {
|
|
563
622
|
if (ts3.isIdentifier(typeNode.typeName)) {
|
|
564
623
|
return typeNode.typeName.text;
|
|
@@ -569,6 +628,11 @@ function getTypeNameFromNode(typeNode, ctx) {
|
|
|
569
628
|
return typeNode.parent.name.text;
|
|
570
629
|
}
|
|
571
630
|
}
|
|
631
|
+
return null;
|
|
632
|
+
}
|
|
633
|
+
function getTypeNameFromNode(typeNode, ctx) {
|
|
634
|
+
const explicitName = getExplicitTypeNameFromNode(typeNode);
|
|
635
|
+
if (explicitName) return explicitName;
|
|
572
636
|
return `Anonymous_${ctx.typeNameStack.length}`;
|
|
573
637
|
}
|
|
574
638
|
function buildObjectSchema(type, ctx, typeNode) {
|
|
@@ -867,7 +931,7 @@ function buildOperation(operation, ctx, controllerConsumes) {
|
|
|
867
931
|
if (parameters.length > 0) {
|
|
868
932
|
op.parameters = parameters;
|
|
869
933
|
}
|
|
870
|
-
const responseSchema = typeToJsonSchema(operation.returnType, ctx);
|
|
934
|
+
const responseSchema = typeToJsonSchema(operation.returnType, ctx, operation.returnTypeNode);
|
|
871
935
|
const status = operation.httpMethod === "POST" ? 201 : 200;
|
|
872
936
|
op.responses[status] = {
|
|
873
937
|
description: status === 201 ? "Created" : "OK",
|
|
@@ -1085,7 +1149,8 @@ function buildOperationEntry(op, ctx) {
|
|
|
1085
1149
|
path: [],
|
|
1086
1150
|
query: [],
|
|
1087
1151
|
headers: [],
|
|
1088
|
-
cookies: []
|
|
1152
|
+
cookies: [],
|
|
1153
|
+
paginationParamIndex: op.paginationParamIndex
|
|
1089
1154
|
};
|
|
1090
1155
|
buildPathArgs(op, ctx, args);
|
|
1091
1156
|
buildQueryArgs(op, ctx, args);
|
|
@@ -1104,7 +1169,7 @@ function buildOperationEntry(op, ctx) {
|
|
|
1104
1169
|
};
|
|
1105
1170
|
}
|
|
1106
1171
|
}
|
|
1107
|
-
const responseSchema = typeToJsonSchema(op.returnType, ctx);
|
|
1172
|
+
const responseSchema = typeToJsonSchema(op.returnType, ctx, op.returnTypeNode);
|
|
1108
1173
|
const status = op.httpMethod === "POST" ? 201 : 200;
|
|
1109
1174
|
let schemaRef = responseSchema.$ref;
|
|
1110
1175
|
let isArray = false;
|