@trapi/metadata 2.0.0-beta.1 → 2.0.0-beta.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.
package/dist/index.mjs CHANGED
@@ -1,247 +1,45 @@
1
- import path, { normalize } from "node:path";
2
1
  import { BaseError, isBaseError } from "@ebec/core";
3
- import * as ts from "typescript";
4
- import { NodeBuilderFlags, NodeFlags, SymbolFlags, SyntaxKind, canHaveDecorators, canHaveModifiers, convertCompilerOptionsFromJson, createProgram, displayPartsToString, forEachChild, getDecorators, getModifiers, isCallExpression, isClassDeclaration, isEnumDeclaration, isEnumMember, isJSDocParameterTag, isMethodDeclaration, isModuleBlock, isModuleDeclaration, isNumericLiteral, isStringLiteral } from "typescript";
5
- import { buildFilePath, hasOwnProperty as hasOwnProperty$1, isObject, load, locateMany } from "locter";
6
- import { Container } from "validup";
7
- import { createValidator } from "@validup/adapter-zod";
8
- import { z } from "zod";
2
+ import { NodeBuilderFlags, NodeFlags, SymbolFlags, SyntaxKind, canHaveDecorators, canHaveModifiers, convertCompilerOptionsFromJson, createProgram, displayPartsToString, factory, forEachChild, getDecorators, getModifiers, isArrayLiteralExpression, isArrayTypeNode, isCallExpression, isClassDeclaration, isConditionalTypeNode, isConstructorDeclaration, isEnumDeclaration, isEnumMember, isExpressionWithTypeArguments, isFunctionTypeNode, isIdentifier, isImportSpecifier, isIndexSignatureDeclaration, isIndexedAccessTypeNode, isInterfaceDeclaration, isIntersectionTypeNode, isJSDocParameterTag, isJSDocPropertyTag, isJSDocReturnTag, isJSDocThisTag, isJSDocTypeTag, isLiteralTypeNode, isMappedTypeNode, isMethodDeclaration, isMethodSignature, isModuleBlock, isModuleDeclaration, isNamedTupleMember, isNoSubstitutionTemplateLiteral, isNumericLiteral, isObjectLiteralExpression, isParameter, isParenthesizedTypeNode, isPrefixUnaryExpression, isPropertyAccessExpression, isPropertyDeclaration, isPropertySignature, isQualifiedName, isStringLiteral, isTupleTypeNode, isTypeAliasDeclaration, isTypeLiteralNode, isTypeOperatorNode, isTypeReferenceNode, isUnionTypeNode } from "typescript";
3
+ import path, { normalize } from "node:path";
4
+ import { CollectionFormat, NumericKind, ParamKind, ParameterSource, TypeName, UtilityTypeName, ValidatorName, createRegistry, isArrayType, isDeprecatedMarker, isExtensionMarker, isNestedObjectLiteralType, isRefAliasType, isRefEnumType, isRefObjectType, isStringType, isUnionType, isVoidType, loadRegistry, loadRegistryByName, matches, matchesJsDoc, mergeRegistries, namesForMarker, newControllerDraft, newMethodDraft, newParameterDraft, numericMarkerKind, resolvePresetByName, tagsForMarker } from "@trapi/core";
5
+ import { buildFilePath, isObject, load, locateMany } from "locter";
9
6
  import process from "node:process";
10
7
  import { parse, stringify } from "flatted";
11
8
  import crypto from "node:crypto";
12
9
  import fs from "node:fs";
13
10
  import { tmpdir } from "node:os";
14
11
  import { minimatch } from "minimatch";
15
- //#region src/core/resolver/constants.ts
16
- let TypeName = /* @__PURE__ */ function(TypeName) {
17
- TypeName["STRING"] = "string";
18
- TypeName["BOOLEAN"] = "boolean";
19
- TypeName["BIGINT"] = "bigint";
20
- TypeName["DOUBLE"] = "double";
21
- TypeName["FLOAT"] = "float";
22
- TypeName["FILE"] = "file";
23
- TypeName["INTEGER"] = "integer";
24
- TypeName["LONG"] = "long";
25
- TypeName["ENUM"] = "enum";
26
- TypeName["ARRAY"] = "array";
27
- TypeName["DATETIME"] = "datetime";
28
- TypeName["DATE"] = "date";
29
- TypeName["BINARY"] = "binary";
30
- TypeName["BUFFER"] = "buffer";
31
- TypeName["BYTE"] = "byte";
32
- TypeName["VOID"] = "void";
33
- TypeName["OBJECT"] = "object";
34
- TypeName["ANY"] = "any";
35
- TypeName["UNDEFINED"] = "undefined";
36
- TypeName["NEVER"] = "never";
37
- TypeName["REF_ENUM"] = "refEnum";
38
- TypeName["REF_OBJECT"] = "refObject";
39
- TypeName["REF_ALIAS"] = "refAlias";
40
- TypeName["NESTED_OBJECT_LITERAL"] = "nestedObjectLiteral";
41
- TypeName["UNION"] = "union";
42
- TypeName["INTERSECTION"] = "intersection";
43
- TypeName["TUPLE"] = "tuple";
44
- return TypeName;
45
- }({});
46
- let UtilityTypeName = /* @__PURE__ */ function(UtilityTypeName) {
47
- UtilityTypeName["NON_NULLABLE"] = "NonNullable";
48
- UtilityTypeName["OMIT"] = "Omit";
49
- UtilityTypeName["PARTIAL"] = "Partial";
50
- UtilityTypeName["READONLY"] = "Readonly";
51
- UtilityTypeName["RECORD"] = "Record";
52
- UtilityTypeName["REQUIRED"] = "Required";
53
- UtilityTypeName["PICK"] = "Pick";
54
- UtilityTypeName["EXTRACT"] = "Extract";
55
- UtilityTypeName["EXCLUDE"] = "Exclude";
56
- UtilityTypeName["RETURN_TYPE"] = "ReturnType";
57
- UtilityTypeName["PARAMETERS"] = "Parameters";
58
- UtilityTypeName["AWAITED"] = "Awaited";
59
- UtilityTypeName["INSTANCE_TYPE"] = "InstanceType";
60
- UtilityTypeName["CONSTRUCTOR_PARAMETERS"] = "ConstructorParameters";
61
- return UtilityTypeName;
62
- }({});
63
- //#endregion
64
- //#region src/core/resolver/type-guards.ts
65
- function isAnyType(param) {
66
- return param.typeName === "any";
67
- }
68
- function isUndefinedType(param) {
69
- return param.typeName === "undefined";
70
- }
71
- function isStringType(param) {
72
- return param.typeName === "string";
73
- }
74
- function isBooleanType(param) {
75
- return param.typeName === "boolean";
76
- }
77
- function isBigintType(param) {
78
- return param.typeName === "bigint";
79
- }
80
- function isDoubleType(param) {
81
- return param.typeName === "double";
82
- }
83
- function isFloatType(param) {
84
- return param.typeName === "float";
85
- }
86
- function isIntegerType(param) {
87
- return param.typeName === "integer";
88
- }
89
- function isLongType(param) {
90
- return param.typeName === "long";
91
- }
92
- function isVoidType(param) {
93
- return typeof param === "undefined" || param.typeName === "void";
94
- }
95
- function isNeverType(param) {
96
- return param.typeName === "never";
97
- }
98
- function isDateType(param) {
99
- return param.typeName === "date";
100
- }
101
- function isFileType(param) {
102
- return param.typeName === "file";
103
- }
104
- function isDateTimeType(param) {
105
- return param.typeName === "datetime";
106
- }
107
- function isBinaryType(param) {
108
- return param.typeName === "binary";
109
- }
110
- function isBufferType(param) {
111
- return param.typeName === "buffer";
112
- }
113
- function isByteType(param) {
114
- return param.typeName === "byte";
115
- }
116
- function isObjectType(param) {
117
- return param.typeName === "object";
118
- }
119
- function isEnumType(param) {
120
- return param.typeName === "enum";
121
- }
122
- function isArrayType(param) {
123
- return param.typeName === "array";
124
- }
125
- function isNestedObjectLiteralType(param) {
126
- return param.typeName === "nestedObjectLiteral";
127
- }
128
- function isIntersectionType(param) {
129
- return param.typeName === "intersection";
130
- }
131
- function isUnionType(param) {
132
- return param.typeName === "union";
133
- }
134
- function isTupleType(param) {
135
- return param.typeName === "tuple";
136
- }
137
- function isRefEnumType(param) {
138
- return param.typeName === "refEnum";
139
- }
140
- function isRefObjectType(param) {
141
- return param.typeName === "refObject";
142
- }
143
- function isRefAliasType(param) {
144
- return param.typeName === "refAlias";
145
- }
146
- function isReferenceType(param) {
147
- return param.typeName === "refAlias" || param.typeName === "refEnum" || param.typeName === "refObject";
148
- }
149
- function isPrimitiveType(type) {
150
- return isAnyType(type) || isBinaryType(type) || isBooleanType(type) || isBufferType(type) || isByteType(type) || isDateType(type) || isDateTimeType(type) || isBigintType(type) || isDoubleType(type) || isFloatType(type) || isFileType(type) || isIntegerType(type) || isLongType(type) || isObjectType(type) || isStringType(type) || isUndefinedType(type);
151
- }
152
- //#endregion
153
12
  //#region src/core/error/base.ts
154
13
  var MetadataError = class extends BaseError {};
155
14
  //#endregion
156
- //#region src/core/resolver/error.ts
157
- var ResolverError = class extends MetadataError {
158
- file;
159
- line;
160
- constructor(message, node, options) {
161
- const opts = typeof options === "boolean" ? { onlyCurrent: options } : options;
162
- const onlyCurrent = opts?.onlyCurrent ?? false;
163
- const parts = [message];
164
- let file;
165
- let line;
166
- if (node) {
167
- const location = prettyLocationOfNode(node);
168
- if (location) {
169
- parts.push(location.text);
170
- file = location.file;
171
- line = location.line;
172
- }
173
- parts.push(prettyTroubleCause(node, onlyCurrent));
174
- }
175
- super({
176
- message: parts.join("\n"),
177
- cause: opts?.cause
178
- });
179
- this.file = file;
180
- this.line = line;
181
- }
15
+ //#region src/core/error/config.ts
16
+ var ConfigError = class extends MetadataError {};
17
+ //#endregion
18
+ //#region src/core/error/config-codes.ts
19
+ const ConfigErrorCode = {
20
+ TSCONFIG_MALFORMED: "CONFIG_TSCONFIG_MALFORMED",
21
+ PRESET_NOT_FOUND: "CONFIG_PRESET_NOT_FOUND",
22
+ PRESET_MISSING: "CONFIG_PRESET_MISSING"
182
23
  };
183
- function isResolverError(input) {
24
+ //#endregion
25
+ //#region src/core/error/generator.ts
26
+ var GeneratorError = class extends MetadataError {};
27
+ function isGeneratorError(input) {
184
28
  if (!isBaseError(input)) return false;
185
- return "file" in input && "line" in input;
186
- }
187
- function prettyLocationOfNode(node) {
188
- try {
189
- const sourceFile = node.getSourceFile();
190
- if (!sourceFile) return void 0;
191
- const token = node.getFirstToken() || node.parent?.getFirstToken();
192
- const start = token ? sourceFile.getLineAndCharacterOfPosition(token.getStart()).line + 1 : void 0;
193
- const end = token ? sourceFile.getLineAndCharacterOfPosition(token.getEnd()).line + 1 : void 0;
194
- return {
195
- text: `At: ${normalize(sourceFile.fileName)}${start ? `:${start}` : ""}${end ? `:${end}` : ""}.`,
196
- file: sourceFile.fileName,
197
- line: start
198
- };
199
- } catch {
200
- return;
201
- }
202
- }
203
- function prettyTroubleCause(node, onlyCurrent = false) {
204
- try {
205
- let name;
206
- if (onlyCurrent || !node.parent) name = node.pos !== -1 ? node.getText() : node.name.text;
207
- else name = node.parent.pos !== -1 ? node.parent.getText() : node.parent.name.text;
208
- return `This was caused by '${name}'`;
209
- } catch {
210
- return "This was caused by an unknown node";
211
- }
29
+ return typeof input.code === "string";
212
30
  }
213
31
  //#endregion
214
- //#region src/core/method/constants.ts
215
- const MethodName = {
216
- ALL: "ALL",
217
- GET: "GET",
218
- POST: "POST",
219
- PUT: "PUT",
220
- DELETE: "DELETE",
221
- PATCH: "PATCH",
222
- OPTIONS: "OPTIONS",
223
- HEAD: "HEAD"
32
+ //#region src/core/error/generator-codes.ts
33
+ const GeneratorErrorCode = {
34
+ CONTROLLER_NO_SOURCE_FILE: "GENERATOR_CONTROLLER_NO_SOURCE_FILE",
35
+ CONTROLLER_NO_NAME: "GENERATOR_CONTROLLER_NO_NAME",
36
+ PARAMETER_GENERATION_FAILED: "GENERATOR_PARAMETER_GENERATION_FAILED",
37
+ BODY_PARAMETER_DUPLICATE: "GENERATOR_BODY_PARAMETER_DUPLICATE",
38
+ BODY_FORM_CONFLICT: "GENERATOR_BODY_FORM_CONFLICT",
39
+ STRICT_UNMATCHED_DECORATORS: "GENERATOR_STRICT_UNMATCHED_DECORATORS"
224
40
  };
225
41
  //#endregion
226
- //#region src/core/parameter/constants.ts
227
- const ParameterSource = {
228
- BODY: "body",
229
- BODY_PROP: "bodyProp",
230
- CONTEXT: "context",
231
- COOKIE: "cookie",
232
- HEADER: "header",
233
- FORM_DATA: "formData",
234
- QUERY: "query",
235
- QUERY_PROP: "queryProp",
236
- PATH: "path"
237
- };
238
- const CollectionFormat = {
239
- CSV: "csv",
240
- SSV: "ssv",
241
- TSV: "tsv",
242
- PIPES: "pipes",
243
- MULTI: "multi"
244
- };
42
+ //#region src/core/error/parameter-codes.ts
245
43
  const ParameterErrorCode = {
246
44
  TYPE_UNSUPPORTED: "PARAMETER_TYPE_UNSUPPORTED",
247
45
  METHOD_UNSUPPORTED: "PARAMETER_METHOD_UNSUPPORTED",
@@ -250,7 +48,7 @@ const ParameterErrorCode = {
250
48
  INVALID_EXAMPLE: "PARAMETER_INVALID_EXAMPLE"
251
49
  };
252
50
  //#endregion
253
- //#region src/core/parameter/error.ts
51
+ //#region src/core/error/parameter.ts
254
52
  var ParameterError = class ParameterError extends MetadataError {
255
53
  static typeUnsupported(context) {
256
54
  const location = context.node ? ParameterError.getCurrentLocation(context.node) : void 0;
@@ -296,664 +94,74 @@ var ParameterError = class ParameterError extends MetadataError {
296
94
  }
297
95
  };
298
96
  //#endregion
299
- //#region src/core/generator/error.ts
300
- var GeneratorError = class extends MetadataError {};
301
- function isGeneratorError(input) {
97
+ //#region src/core/error/resolver.ts
98
+ var ResolverError = class extends MetadataError {
99
+ file;
100
+ line;
101
+ constructor(message, node, options) {
102
+ const opts = typeof options === "boolean" ? { onlyCurrent: options } : options;
103
+ const onlyCurrent = opts?.onlyCurrent ?? false;
104
+ const parts = [message];
105
+ let file;
106
+ let line;
107
+ if (node) {
108
+ const location = prettyLocationOfNode(node);
109
+ if (location) {
110
+ parts.push(location.text);
111
+ file = location.file;
112
+ line = location.line;
113
+ }
114
+ parts.push(prettyTroubleCause(node, onlyCurrent));
115
+ }
116
+ super({
117
+ message: parts.join("\n"),
118
+ cause: opts?.cause
119
+ });
120
+ this.file = file;
121
+ this.line = line;
122
+ }
123
+ };
124
+ function isResolverError(input) {
302
125
  if (!isBaseError(input)) return false;
303
- return typeof input.code === "string";
126
+ return "file" in input && "line" in input;
127
+ }
128
+ function prettyLocationOfNode(node) {
129
+ try {
130
+ const sourceFile = node.getSourceFile();
131
+ if (!sourceFile) return void 0;
132
+ const token = node.getFirstToken() || node.parent?.getFirstToken();
133
+ const start = token ? sourceFile.getLineAndCharacterOfPosition(token.getStart()).line + 1 : void 0;
134
+ const end = token ? sourceFile.getLineAndCharacterOfPosition(token.getEnd()).line + 1 : void 0;
135
+ return {
136
+ text: `At: ${normalize(sourceFile.fileName)}${start ? `:${start}` : ""}${end ? `:${end}` : ""}.`,
137
+ file: sourceFile.fileName,
138
+ line: start
139
+ };
140
+ } catch {
141
+ return;
142
+ }
143
+ }
144
+ function prettyTroubleCause(node, onlyCurrent = false) {
145
+ try {
146
+ let name;
147
+ if (onlyCurrent || !node.parent) name = node.pos !== -1 ? node.getText() : node.name.text;
148
+ else name = node.parent.pos !== -1 ? node.parent.getText() : node.parent.name.text;
149
+ return `This was caused by '${name}'`;
150
+ } catch {
151
+ return "This was caused by an unknown node";
152
+ }
304
153
  }
305
154
  //#endregion
306
- //#region src/core/generator/constants.ts
307
- const GeneratorErrorCode = {
308
- CONTROLLER_NO_SOURCE_FILE: "GENERATOR_CONTROLLER_NO_SOURCE_FILE",
309
- CONTROLLER_NO_NAME: "GENERATOR_CONTROLLER_NO_NAME",
310
- PARAMETER_GENERATION_FAILED: "GENERATOR_PARAMETER_GENERATION_FAILED",
311
- BODY_PARAMETER_DUPLICATE: "GENERATOR_BODY_PARAMETER_DUPLICATE",
312
- BODY_FORM_CONFLICT: "GENERATOR_BODY_FORM_CONFLICT"
313
- };
314
- //#endregion
315
- //#region src/core/validator/error.ts
155
+ //#region src/core/error/validator.ts
316
156
  var ValidatorError = class extends MetadataError {};
317
157
  //#endregion
318
- //#region src/core/validator/constants.ts
319
- let ValidatorName = /* @__PURE__ */ function(ValidatorName) {
320
- ValidatorName["UNIQUE_ITEMS"] = "uniqueItems";
321
- ValidatorName["MINIMUM"] = "minimum";
322
- ValidatorName["MAXIMUM"] = "maximum";
323
- ValidatorName["MIN_ITEMS"] = "minItems";
324
- ValidatorName["MAX_ITEMS"] = "maxItems";
325
- ValidatorName["MIN_LENGTH"] = "minLength";
326
- ValidatorName["MAX_LENGTH"] = "maxLength";
327
- ValidatorName["MIN_DATE"] = "minDate";
328
- ValidatorName["MAX_DATE"] = "maxDate";
329
- ValidatorName["PATTERN"] = "pattern";
330
- return ValidatorName;
331
- }({});
158
+ //#region src/core/error/validator-codes.ts
332
159
  const ValidatorErrorCode = {
333
160
  EXPECTED_NUMBER: "VALIDATOR_EXPECTED_NUMBER",
334
161
  EXPECTED_DATE: "VALIDATOR_EXPECTED_DATE",
335
162
  EXPECTED_STRING: "VALIDATOR_EXPECTED_STRING"
336
163
  };
337
164
  //#endregion
338
- //#region src/core/error/config.ts
339
- var ConfigError = class extends MetadataError {};
340
- //#endregion
341
- //#region src/core/error/config-codes.ts
342
- const ConfigErrorCode = {
343
- TSCONFIG_MALFORMED: "CONFIG_TSCONFIG_MALFORMED",
344
- PRESET_NOT_FOUND: "CONFIG_PRESET_NOT_FOUND",
345
- PRESET_MISSING: "CONFIG_PRESET_MISSING"
346
- };
347
- //#endregion
348
- //#region src/adapters/decorator/constants.ts
349
- const ParamKind = {
350
- Body: "body",
351
- BodyProp: "bodyProp",
352
- Context: "context",
353
- Cookie: "cookie",
354
- Header: "header",
355
- FormData: "formData",
356
- Query: "query",
357
- QueryProp: "queryProp",
358
- Path: "path"
359
- };
360
- const CollectionKind = {
361
- Csv: "csv",
362
- Ssv: "ssv",
363
- Tsv: "tsv",
364
- Pipes: "pipes",
365
- Multi: "multi"
366
- };
367
- const DecoratorTargetKind = {
368
- Class: "class",
369
- Method: "method",
370
- Parameter: "parameter",
371
- Property: "property"
372
- };
373
- const DecoratorArgumentKindName = {
374
- Literal: "literal",
375
- Object: "object",
376
- Array: "array",
377
- Identifier: "identifier",
378
- Unresolvable: "unresolvable"
379
- };
380
- const MarkerName = {
381
- Hidden: "hidden",
382
- Deprecated: "deprecated",
383
- Extension: "extension"
384
- };
385
- const NumericKind = {
386
- Int: "int",
387
- Long: "long",
388
- Float: "float",
389
- Double: "double"
390
- };
391
- //#endregion
392
- //#region src/adapters/decorator/helpers.ts
393
- /**
394
- * Read a positional argument as a string. Accepts both literal string args
395
- * (`@Foo('value')`) and identifier references that resolve to a string
396
- * (`@Foo(SOME_CONSTANT)`). Returns `undefined` for any other argument shape.
397
- */
398
- function readString(arg) {
399
- if (!arg) return void 0;
400
- if (arg.kind === "literal" && typeof arg.raw === "string") return arg.raw;
401
- if (arg.kind === "identifier" && typeof arg.raw === "string") return arg.raw;
402
- }
403
- /**
404
- * Read a positional argument as a number. Only matches numeric literals.
405
- */
406
- function readNumber(arg) {
407
- if (!arg) return void 0;
408
- if (arg.kind === "literal" && typeof arg.raw === "number") return arg.raw;
409
- }
410
- /**
411
- * Read a positional argument as a boolean. Only matches boolean literals.
412
- */
413
- function readBoolean(arg) {
414
- if (!arg) return void 0;
415
- if (arg.kind === "literal" && typeof arg.raw === "boolean") return arg.raw;
416
- }
417
- /**
418
- * Read a positional argument that may be either a single string or an array
419
- * of strings. Returns `undefined` when the argument is missing, when any
420
- * array element is non-string, or otherwise unresolvable. All-or-nothing:
421
- * never returns a partial array with non-string items silently dropped.
422
- */
423
- function readStringOrStringArray(arg) {
424
- const single = readString(arg);
425
- if (single !== void 0) return [single];
426
- if (arg?.kind === "array" && Array.isArray(arg.raw)) {
427
- if (arg.raw.every((item) => typeof item === "string")) return arg.raw;
428
- return;
429
- }
430
- }
431
- /**
432
- * Convenience for the common controller path assignment. Reads the first
433
- * argument as a string-or-string-array and writes it to `draft.paths`,
434
- * defaulting to `['']` when the argument is missing or unresolvable. Use this
435
- * inside a `controller({ match, apply })` handler to declare a class as a
436
- * controller.
437
- */
438
- function setControllerPaths(draft, arg) {
439
- draft.paths = readStringOrStringArray(arg) ?? [""];
440
- }
441
- /**
442
- * Convenience for the common method path assignment. Reads the first argument
443
- * as a string and writes it to `draft.path` if present; leaves the field
444
- * untouched otherwise (the orchestrator initialises it to `''`).
445
- */
446
- function setMethodPath(draft, arg) {
447
- const path = readString(arg);
448
- if (path !== void 0) draft.path = path;
449
- }
450
- //#endregion
451
- //#region src/adapters/decorator/utils.ts
452
- function matches(match, source) {
453
- if (match.name !== source.name) return false;
454
- if (match.on && match.on !== source.target) return false;
455
- return true;
456
- }
457
- function matchesJsDoc(match, source) {
458
- if (match.tag !== source.tag) return false;
459
- if (match.on && match.on !== source.target) return false;
460
- return true;
461
- }
462
- function newControllerDraft(input) {
463
- return {
464
- name: input.name,
465
- location: input.location,
466
- hidden: false,
467
- consumes: [],
468
- produces: [],
469
- tags: [],
470
- responses: [],
471
- security: [],
472
- extensions: []
473
- };
474
- }
475
- function newMethodDraft(input) {
476
- return {
477
- name: input.name,
478
- path: "",
479
- description: "",
480
- hidden: false,
481
- consumes: [],
482
- produces: [],
483
- tags: [],
484
- responses: [],
485
- security: [],
486
- extensions: [],
487
- parameters: [],
488
- defaultResponseExamples: []
489
- };
490
- }
491
- function newParameterDraft(input) {
492
- return {
493
- parameterName: input.parameterName,
494
- name: input.parameterName,
495
- description: "",
496
- required: true,
497
- examples: [],
498
- exampleLabels: [],
499
- extensions: [],
500
- validators: {}
501
- };
502
- }
503
- function createRegistry() {
504
- return {
505
- controllers: [],
506
- methods: [],
507
- parameters: [],
508
- controllerJsDoc: [],
509
- methodJsDoc: [],
510
- parameterJsDoc: []
511
- };
512
- }
513
- function generatePresetLookupPaths(input) {
514
- if (path.isAbsolute(input) || input.startsWith("./") || input.startsWith("../")) return [input];
515
- if (input.startsWith("module:")) return [input.substring(7)];
516
- if (!input.startsWith("@")) return [input, `@trapi/${input}`];
517
- return [input];
518
- }
519
- /**
520
- * Collect the unique decorator names of every handler whose `marker` matches
521
- * the given predicate. Lets the type resolver discover preset-renamed
522
- * decorators without hard-coding canonical names.
523
- */
524
- function namesForMarker(registry, predicate) {
525
- const names = /* @__PURE__ */ new Set();
526
- const all = [
527
- ...registry.controllers,
528
- ...registry.methods,
529
- ...registry.parameters
530
- ];
531
- for (const handler of all) if (handler.marker !== void 0 && predicate(handler.marker)) names.add(handler.match.name);
532
- return names;
533
- }
534
- /**
535
- * Collect the unique JSDoc tag names of every JSDoc handler whose `marker`
536
- * matches the given predicate. JSDoc analogue of `namesForMarker`.
537
- */
538
- function tagsForMarker(registry, predicate) {
539
- const tags = /* @__PURE__ */ new Set();
540
- const all = [
541
- ...registry.controllerJsDoc,
542
- ...registry.methodJsDoc,
543
- ...registry.parameterJsDoc
544
- ];
545
- for (const handler of all) if (handler.marker !== void 0 && predicate(handler.marker)) tags.add(handler.match.tag);
546
- return tags;
547
- }
548
- function isHiddenMarker(marker) {
549
- return marker === "hidden";
550
- }
551
- function isDeprecatedMarker(marker) {
552
- return marker === "deprecated";
553
- }
554
- function isExtensionMarker(marker) {
555
- return marker === "extension";
556
- }
557
- function numericMarkerKind(marker) {
558
- if (typeof marker === "object" && marker !== null && "numeric" in marker) return marker.numeric;
559
- }
560
- const controller = (handler) => handler;
561
- const method = (handler) => handler;
562
- const parameter = (handler) => handler;
563
- const controllerJsDoc = (handler) => handler;
564
- const methodJsDoc = (handler) => handler;
565
- const parameterJsDoc = (handler) => handler;
566
- function isLiteralLike(kind) {
567
- return kind === "literal" || kind === "identifier";
568
- }
569
- function readArray(draft, key) {
570
- const record = draft;
571
- const existing = record[key];
572
- if (Array.isArray(existing)) return existing;
573
- if (typeof existing !== "undefined") throw new TypeError(`append(): cannot append to draft key "${key}": existing value is not an array (got ${typeof existing}).`);
574
- const created = [];
575
- record[key] = created;
576
- return created;
577
- }
578
- function into(key) {
579
- return {
580
- positional(index) {
581
- return (ctx, draft) => {
582
- const arg = ctx.argument(index);
583
- if (arg && isLiteralLike(arg.kind)) draft[key] = arg.raw;
584
- };
585
- },
586
- typeArgument(index = 0) {
587
- return (ctx, draft) => {
588
- const ta = ctx.typeArgument(index);
589
- if (ta) draft[key] = ta.resolve();
590
- };
591
- }
592
- };
593
- }
594
- function append(key) {
595
- return {
596
- positional(index) {
597
- return (ctx, draft) => {
598
- const arg = ctx.argument(index);
599
- if (!arg) return;
600
- const target = readArray(draft, key);
601
- if (arg.kind === "array" && Array.isArray(arg.raw)) target.push(...arg.raw);
602
- else if (isLiteralLike(arg.kind)) target.push(arg.raw);
603
- };
604
- },
605
- positionalAll() {
606
- return (ctx, draft) => {
607
- const target = readArray(draft, key);
608
- for (const arg of ctx.arguments()) if (arg.kind === "array" && Array.isArray(arg.raw)) target.push(...arg.raw);
609
- else if (isLiteralLike(arg.kind)) target.push(arg.raw);
610
- };
611
- }
612
- };
613
- }
614
- function flag(key, value = true) {
615
- return (_ctx, draft) => {
616
- draft[key] = value;
617
- };
618
- }
619
- //#endregion
620
- //#region src/adapters/decorator/validation/module.ts
621
- const decoratorTargetSchema = z.enum([
622
- "class",
623
- "method",
624
- "parameter",
625
- "property"
626
- ]);
627
- const replacesPolicySchema = z.union([z.literal(true), z.string().min(1)]);
628
- function matchSchemaForKind(allowedOn) {
629
- return z.object({
630
- name: z.string().min(1),
631
- on: decoratorTargetSchema.optional()
632
- }).refine((m) => m.on === void 0 || m.on === allowedOn, {
633
- message: `match.on is incompatible with the handler array it lives in — expected '${allowedOn}' or omit 'on' entirely.`,
634
- path: ["on"]
635
- });
636
- }
637
- function jsDocMatchSchemaForKind(allowedOn) {
638
- return z.object({
639
- tag: z.string().min(1),
640
- on: decoratorTargetSchema.optional()
641
- }).refine((m) => m.on === void 0 || m.on === allowedOn, {
642
- message: `match.on is incompatible with the JSDoc handler array it lives in — expected '${allowedOn}' or omit 'on' entirely.`,
643
- path: ["on"]
644
- });
645
- }
646
- const matchSchema = z.object({
647
- name: z.string().min(1),
648
- on: decoratorTargetSchema.optional()
649
- });
650
- const jsDocMatchSchema = z.object({
651
- tag: z.string().min(1),
652
- on: decoratorTargetSchema.optional()
653
- });
654
- const numericMarkerSchema = z.object({ numeric: z.enum([
655
- "int",
656
- "long",
657
- "float",
658
- "double"
659
- ]) });
660
- const resolverMarkerSchema = z.union([
661
- z.literal("hidden"),
662
- z.literal("deprecated"),
663
- z.literal("extension"),
664
- numericMarkerSchema
665
- ]);
666
- const handlerBaseShape = {
667
- replaces: replacesPolicySchema.optional(),
668
- marker: resolverMarkerSchema.optional(),
669
- apply: z.custom((value) => typeof value === "function", { message: "apply must be a function" })
670
- };
671
- const controllerHandlerSchema = z.object({
672
- match: matchSchemaForKind("class"),
673
- ...handlerBaseShape
674
- });
675
- const methodHandlerSchema = z.object({
676
- match: matchSchemaForKind("method"),
677
- ...handlerBaseShape
678
- });
679
- const parameterHandlerSchema = z.object({
680
- match: matchSchemaForKind("parameter"),
681
- ...handlerBaseShape
682
- });
683
- const controllerJsDocHandlerSchema = z.object({
684
- match: jsDocMatchSchemaForKind("class"),
685
- ...handlerBaseShape
686
- });
687
- const methodJsDocHandlerSchema = z.object({
688
- match: jsDocMatchSchemaForKind("method"),
689
- ...handlerBaseShape
690
- });
691
- const parameterJsDocHandlerSchema = z.object({
692
- match: jsDocMatchSchemaForKind("parameter"),
693
- ...handlerBaseShape
694
- });
695
- const presetSchema = z.object({
696
- name: z.string().min(1),
697
- extends: z.array(z.string().min(1)).optional(),
698
- controllers: z.array(controllerHandlerSchema).optional(),
699
- methods: z.array(methodHandlerSchema).optional(),
700
- parameters: z.array(parameterHandlerSchema).optional(),
701
- controllerJsDoc: z.array(controllerJsDocHandlerSchema).optional(),
702
- methodJsDoc: z.array(methodJsDocHandlerSchema).optional(),
703
- parameterJsDoc: z.array(parameterJsDocHandlerSchema).optional()
704
- });
705
- function createPresetContainer() {
706
- const container = new Container();
707
- container.mount("name", createValidator(presetSchema.shape.name));
708
- container.mount("extends", { optional: true }, createValidator(presetSchema.shape.extends));
709
- container.mount("controllers", { optional: true }, createValidator(presetSchema.shape.controllers));
710
- container.mount("methods", { optional: true }, createValidator(presetSchema.shape.methods));
711
- container.mount("parameters", { optional: true }, createValidator(presetSchema.shape.parameters));
712
- container.mount("controllerJsDoc", { optional: true }, createValidator(presetSchema.shape.controllerJsDoc));
713
- container.mount("methodJsDoc", { optional: true }, createValidator(presetSchema.shape.methodJsDoc));
714
- container.mount("parameterJsDoc", { optional: true }, createValidator(presetSchema.shape.parameterJsDoc));
715
- return container;
716
- }
717
- const sharedContainer = createPresetContainer();
718
- async function validatePreset(input) {
719
- if (input === null || typeof input !== "object" || Array.isArray(input)) throw new TypeError("preset input must be an object");
720
- return sharedContainer.run(input);
721
- }
722
- //#endregion
723
- //#region src/adapters/decorator/module.ts
724
- const decoratorKinds = [
725
- "controllers",
726
- "methods",
727
- "parameters"
728
- ];
729
- const jsDocKinds = [
730
- "controllerJsDoc",
731
- "methodJsDoc",
732
- "parameterJsDoc"
733
- ];
734
- function emptyTaggedRegistry() {
735
- return {
736
- controllers: [],
737
- methods: [],
738
- parameters: [],
739
- controllerJsDoc: [],
740
- methodJsDoc: [],
741
- parameterJsDoc: []
742
- };
743
- }
744
- async function loadRegistry(preset, options) {
745
- return stripOrigins(await loadTaggedRegistry(preset, options, /* @__PURE__ */ new Set()));
746
- }
747
- async function loadTaggedRegistry(preset, options, visited) {
748
- const validated = await validatePreset(preset);
749
- if (visited.has(validated.name)) throw new MetadataError({ message: `Preset cycle detected: ${[...visited, validated.name].join(" -> ")}` });
750
- const nextVisited = new Set(visited);
751
- nextVisited.add(validated.name);
752
- const merged = emptyTaggedRegistry();
753
- for (const extendsName of validated.extends ?? []) appendTagged(merged, await loadTaggedRegistry(await options.resolver(extendsName), options, nextVisited));
754
- applyOwnHandlers(merged, validated, !!options.strict);
755
- return merged;
756
- }
757
- function applyOwnHandlers(merged, preset, strict) {
758
- for (const kind of decoratorKinds) {
759
- const handlers = preset[kind] ?? [];
760
- for (const handler of handlers) {
761
- if (handler.replaces) applyReplacesDecorator(merged, kind, handler, preset.name, strict);
762
- merged[kind].push({
763
- origin: preset.name,
764
- handler
765
- });
766
- }
767
- }
768
- for (const kind of jsDocKinds) {
769
- const handlers = preset[kind] ?? [];
770
- for (const handler of handlers) {
771
- if (handler.replaces) applyReplacesJsDoc(merged, kind, handler, preset.name, strict);
772
- merged[kind].push({
773
- origin: preset.name,
774
- handler
775
- });
776
- }
777
- }
778
- }
779
- function applyReplacesDecorator(merged, kind, handler, presetName, strict) {
780
- const list = merged[kind];
781
- const remaining = [];
782
- let removed = 0;
783
- for (const entry of list) {
784
- if (entry.origin !== presetName && handlerMatches(handler, entry.handler.match.name, entry.handler.match.on) && originMatches(handler.replaces, entry.origin)) {
785
- removed += 1;
786
- continue;
787
- }
788
- remaining.push(entry);
789
- }
790
- if (removed === 0 && strict) throw new MetadataError({ message: `Preset '${presetName}': handler with replaces=${describeReplaces(handler.replaces)} on '${handler.match.name}' did not match any parent handler` });
791
- merged[kind] = remaining;
792
- }
793
- function applyReplacesJsDoc(merged, kind, handler, presetName, strict) {
794
- const list = merged[kind];
795
- const remaining = [];
796
- let removed = 0;
797
- for (const entry of list) {
798
- if (entry.origin !== presetName && handlerMatches(handler, entry.handler.match.tag, entry.handler.match.on) && originMatches(handler.replaces, entry.origin)) {
799
- removed += 1;
800
- continue;
801
- }
802
- remaining.push(entry);
803
- }
804
- if (removed === 0 && strict) throw new MetadataError({ message: `Preset '${presetName}': JSDoc handler with replaces=${describeReplaces(handler.replaces)} on '@${handler.match.tag}' did not match any parent handler` });
805
- merged[kind] = remaining;
806
- }
807
- function handlerMatches(handler, targetName, targetOn) {
808
- if (("name" in handler.match ? handler.match.name : handler.match.tag) !== targetName) return false;
809
- if (handler.match.on && handler.match.on !== targetOn) return false;
810
- return true;
811
- }
812
- function originMatches(replaces, origin) {
813
- if (replaces === true) return true;
814
- return replaces === origin;
815
- }
816
- function describeReplaces(replaces) {
817
- return replaces === true ? "true" : `'${replaces}'`;
818
- }
819
- function appendTagged(target, source) {
820
- for (const kind of decoratorKinds) target[kind].push(...source[kind]);
821
- for (const kind of jsDocKinds) target[kind].push(...source[kind]);
822
- }
823
- function stripOrigins(tagged) {
824
- const registry = createRegistry();
825
- registry.controllers = tagged.controllers.map((e) => e.handler);
826
- registry.methods = tagged.methods.map((e) => e.handler);
827
- registry.parameters = tagged.parameters.map((e) => e.handler);
828
- registry.controllerJsDoc = tagged.controllerJsDoc.map((e) => e.handler);
829
- registry.methodJsDoc = tagged.methodJsDoc.map((e) => e.handler);
830
- registry.parameterJsDoc = tagged.parameterJsDoc.map((e) => e.handler);
831
- return registry;
832
- }
833
- /**
834
- * Resolve a preset by string identifier (npm package, relative path, etc.) and
835
- * return the v2 Preset object. Looks for a `preset` named export, then the
836
- * default export, then the module itself.
837
- */
838
- async function resolvePresetByName(input) {
839
- const lookupPaths = generatePresetLookupPaths(input);
840
- let lastError;
841
- for (const lookupPath of lookupPaths) try {
842
- const moduleExport = await load(lookupPath);
843
- const candidates = [
844
- moduleExport.preset,
845
- moduleExport.default,
846
- moduleExport
847
- ];
848
- for (const candidate of candidates) if (isV2Preset(candidate)) return candidate;
849
- } catch (e) {
850
- lastError = e;
851
- }
852
- throw new ConfigError({
853
- message: `Preset '${input}' could not be resolved.`,
854
- code: ConfigErrorCode.PRESET_NOT_FOUND,
855
- cause: lastError
856
- });
857
- }
858
- /**
859
- * Resolve a preset by name and immediately materialize its registry, recursively
860
- * loading `extends` parents through the same resolver.
861
- */
862
- async function loadRegistryByName(input) {
863
- return loadRegistry(await resolvePresetByName(input), { resolver: resolvePresetByName });
864
- }
865
- function isV2Preset(input) {
866
- return typeof input === "object" && input !== null && typeof input.name === "string" && !("items" in input);
867
- }
868
- //#endregion
869
- //#region src/adapters/decorator/test-helpers.ts
870
- /**
871
- * Build a literal-kind {@link DecoratorArgument} from a primitive value.
872
- * Use this in unit tests to feed handlers a mock argument:
873
- *
874
- * ```ts
875
- * const ctx = createHandlerContext({ args: [literalArg('users')] });
876
- * controllerHandler.apply(ctx, draft);
877
- * ```
878
- */
879
- function literalArg(raw) {
880
- return {
881
- kind: "literal",
882
- raw
883
- };
884
- }
885
- /**
886
- * Build an identifier-kind {@link DecoratorArgument} (e.g. `@Foo(SOME_CONSTANT)`).
887
- * `raw` is the resolved value the identifier points to — typically a string.
888
- */
889
- function identifierArg(raw) {
890
- return {
891
- kind: "identifier",
892
- raw
893
- };
894
- }
895
- /**
896
- * Build an array-kind {@link DecoratorArgument} (e.g. `@Foo(['a', 'b'])`).
897
- */
898
- function arrayArg(raw) {
899
- return {
900
- kind: "array",
901
- raw
902
- };
903
- }
904
- /**
905
- * Build an object-kind {@link DecoratorArgument} (e.g. `@Foo({ key: 'value' })`).
906
- */
907
- function objectArg(raw) {
908
- return {
909
- kind: "object",
910
- raw
911
- };
912
- }
913
- /**
914
- * Build an unresolvable-kind {@link DecoratorArgument} — represents arguments
915
- * the source extractor couldn't statically evaluate (e.g. function calls,
916
- * unknown identifiers).
917
- */
918
- function unresolvableArg() {
919
- return {
920
- kind: "unresolvable",
921
- raw: void 0
922
- };
923
- }
924
- /**
925
- * Build a {@link DecoratorTypeArgument} stub that returns the supplied type
926
- * when `resolve()` is called.
927
- */
928
- function typeArg(type) {
929
- return { resolve: () => type };
930
- }
931
- /**
932
- * Construct a {@link HandlerContext} for unit-testing handlers in isolation
933
- * without spinning up the full TypeScript compiler / `generateMetadata`
934
- * pipeline. Combine with the `*Arg(...)` builders to feed a handler a
935
- * controlled mock decorator source.
936
- *
937
- * ```ts
938
- * const ctx = createHandlerContext({ args: [literalArg('users')] });
939
- * const draft = newControllerDraft({ name: 'UserController', location: '/x.ts' });
940
- * myHandler.apply(ctx, draft);
941
- * expect(draft.paths).toEqual(['users']);
942
- * ```
943
- */
944
- function createHandlerContext(input = {}) {
945
- const args = input.args ?? [];
946
- const typeArgs = input.typeArgs ?? [];
947
- return {
948
- host: input.host ?? { name: "TestHost" },
949
- argument: (index) => args[index],
950
- arguments: () => [...args],
951
- typeArgument: (index) => typeArgs[index],
952
- typeArguments: () => [...typeArgs],
953
- parameterType: () => input.parameterType
954
- };
955
- }
956
- //#endregion
957
165
  //#region src/adapters/typescript/js-doc/constants.ts
958
166
  let JSDocTagName = /* @__PURE__ */ function(JSDocTagName) {
959
167
  JSDocTagName["ABSTRACT"] = "abstract";
@@ -1053,22 +261,22 @@ function getJSDocTagNames(node, requireTagName = false) {
1053
261
  function getInitializerValue(initializer, typeChecker, type) {
1054
262
  if (!initializer) return;
1055
263
  switch (initializer.kind) {
1056
- case ts.SyntaxKind.ArrayLiteralExpression: return initializer.elements.map((element) => getInitializerValue(element, typeChecker));
1057
- case ts.SyntaxKind.StringLiteral:
1058
- case ts.SyntaxKind.NoSubstitutionTemplateLiteral: return initializer.text;
1059
- case ts.SyntaxKind.TrueKeyword: return true;
1060
- case ts.SyntaxKind.FalseKeyword: return false;
1061
- case ts.SyntaxKind.PrefixUnaryExpression: {
264
+ case SyntaxKind.ArrayLiteralExpression: return initializer.elements.map((element) => getInitializerValue(element, typeChecker));
265
+ case SyntaxKind.StringLiteral:
266
+ case SyntaxKind.NoSubstitutionTemplateLiteral: return initializer.text;
267
+ case SyntaxKind.TrueKeyword: return true;
268
+ case SyntaxKind.FalseKeyword: return false;
269
+ case SyntaxKind.PrefixUnaryExpression: {
1062
270
  const prefixUnary = initializer;
1063
271
  switch (prefixUnary.operator) {
1064
- case ts.SyntaxKind.PlusToken: return Number(prefixUnary.operand.text);
1065
- case ts.SyntaxKind.MinusToken: return Number(`-${prefixUnary.operand.text}`);
272
+ case SyntaxKind.PlusToken: return Number(prefixUnary.operand.text);
273
+ case SyntaxKind.MinusToken: return Number(`-${prefixUnary.operand.text}`);
1066
274
  default: throw new MetadataError(`Unsupported prefix operator token: ${prefixUnary.operator}`);
1067
275
  }
1068
276
  }
1069
- case ts.SyntaxKind.NumberKeyword:
1070
- case ts.SyntaxKind.FirstLiteralToken: return Number(initializer.text);
1071
- case ts.SyntaxKind.NewExpression: {
277
+ case SyntaxKind.NumberKeyword:
278
+ case SyntaxKind.FirstLiteralToken: return Number(initializer.text);
279
+ case SyntaxKind.NewExpression: {
1072
280
  const newExpression = initializer;
1073
281
  if (newExpression.expression.text === "Date") {
1074
282
  let date = /* @__PURE__ */ new Date();
@@ -1082,8 +290,8 @@ function getInitializerValue(initializer, typeChecker, type) {
1082
290
  }
1083
291
  return;
1084
292
  }
1085
- case ts.SyntaxKind.NullKeyword: return null;
1086
- case ts.SyntaxKind.ObjectLiteralExpression: {
293
+ case SyntaxKind.NullKeyword: return null;
294
+ case SyntaxKind.ObjectLiteralExpression: {
1087
295
  const objectLiteral = initializer;
1088
296
  const nestedObject = {};
1089
297
  objectLiteral.properties.forEach((p) => {
@@ -1091,7 +299,7 @@ function getInitializerValue(initializer, typeChecker, type) {
1091
299
  });
1092
300
  return nestedObject;
1093
301
  }
1094
- case ts.SyntaxKind.ImportSpecifier: {
302
+ case SyntaxKind.ImportSpecifier: {
1095
303
  if (typeof typeChecker === "undefined") return;
1096
304
  const importSpecifier = initializer;
1097
305
  const importSymbol = typeChecker.getSymbolAtLocation(importSpecifier.name);
@@ -1112,7 +320,7 @@ function getInitializerValue(initializer, typeChecker, type) {
1112
320
  }
1113
321
  const hasInitializer = (node) => Object.prototype.hasOwnProperty.call(node, "initializer");
1114
322
  const extractInitializer = (valueDeclaration) => valueDeclaration && hasInitializer(valueDeclaration) && valueDeclaration.initializer || void 0;
1115
- const extractImportSpecifier = (symbol) => symbol?.declarations && symbol.declarations.length > 0 && ts.isImportSpecifier(symbol.declarations[0]) && symbol.declarations[0] || void 0;
323
+ const extractImportSpecifier = (symbol) => symbol?.declarations && symbol.declarations.length > 0 && isImportSpecifier(symbol.declarations[0]) && symbol.declarations[0] || void 0;
1116
324
  //#endregion
1117
325
  //#region src/adapters/decorator/typescript/utils.ts
1118
326
  /**
@@ -1121,15 +329,15 @@ const extractImportSpecifier = (symbol) => symbol?.declarations && symbol.declar
1121
329
  * extension extraction) that only need decorator names + argument values.
1122
330
  */
1123
331
  function readNodeDecorators(node, typeChecker) {
1124
- if (!ts.canHaveDecorators(node)) return [];
1125
- const decorators = ts.getDecorators(node);
332
+ if (!canHaveDecorators(node)) return [];
333
+ const decorators = getDecorators(node);
1126
334
  if (!decorators || decorators.length === 0) return [];
1127
335
  const output = [];
1128
336
  for (const decorator of decorators) {
1129
337
  const { expression } = decorator;
1130
338
  let name;
1131
339
  let argumentExpressions = [];
1132
- if (ts.isCallExpression(expression)) {
340
+ if (isCallExpression(expression)) {
1133
341
  argumentExpressions = expression.arguments;
1134
342
  name = readDecoratorName$1(expression.expression);
1135
343
  } else name = readDecoratorName$1(expression);
@@ -1151,39 +359,39 @@ function hasDecoratorNamed(node, name, typeChecker) {
1151
359
  return readNodeDecorators(node, typeChecker).some((d) => d.name === name);
1152
360
  }
1153
361
  function readDecoratorName$1(expression) {
1154
- if (ts.isIdentifier(expression)) return expression.text;
1155
- if (ts.isPropertyAccessExpression(expression)) return expression.name.text;
362
+ if (isIdentifier(expression)) return expression.text;
363
+ if (isPropertyAccessExpression(expression)) return expression.name.text;
1156
364
  }
1157
365
  function buildDecoratorArgument(expr, typeChecker) {
1158
- if (ts.isStringLiteral(expr) || ts.isNumericLiteral(expr) || ts.isNoSubstitutionTemplateLiteral(expr)) return {
366
+ if (isStringLiteral(expr) || isNumericLiteral(expr) || isNoSubstitutionTemplateLiteral(expr)) return {
1159
367
  raw: getInitializerValue(expr, typeChecker),
1160
368
  kind: "literal"
1161
369
  };
1162
- if (expr.kind === ts.SyntaxKind.TrueKeyword) return {
370
+ if (expr.kind === SyntaxKind.TrueKeyword) return {
1163
371
  raw: true,
1164
372
  kind: "literal"
1165
373
  };
1166
- if (expr.kind === ts.SyntaxKind.FalseKeyword) return {
374
+ if (expr.kind === SyntaxKind.FalseKeyword) return {
1167
375
  raw: false,
1168
376
  kind: "literal"
1169
377
  };
1170
- if (expr.kind === ts.SyntaxKind.NullKeyword) return {
378
+ if (expr.kind === SyntaxKind.NullKeyword) return {
1171
379
  raw: null,
1172
380
  kind: "literal"
1173
381
  };
1174
- if (ts.isPrefixUnaryExpression(expr) && (expr.operator === ts.SyntaxKind.PlusToken || expr.operator === ts.SyntaxKind.MinusToken) && ts.isNumericLiteral(expr.operand)) return {
382
+ if (isPrefixUnaryExpression(expr) && (expr.operator === SyntaxKind.PlusToken || expr.operator === SyntaxKind.MinusToken) && isNumericLiteral(expr.operand)) return {
1175
383
  raw: getInitializerValue(expr, typeChecker),
1176
384
  kind: "literal"
1177
385
  };
1178
- if (ts.isObjectLiteralExpression(expr)) return {
386
+ if (isObjectLiteralExpression(expr)) return {
1179
387
  raw: getInitializerValue(expr, typeChecker),
1180
388
  kind: "object"
1181
389
  };
1182
- if (ts.isArrayLiteralExpression(expr)) return {
390
+ if (isArrayLiteralExpression(expr)) return {
1183
391
  raw: getInitializerValue(expr, typeChecker),
1184
392
  kind: "array"
1185
393
  };
1186
- if (ts.isIdentifier(expr) || ts.isPropertyAccessExpression(expr)) {
394
+ if (isIdentifier(expr) || isPropertyAccessExpression(expr)) {
1187
395
  const value = getInitializerValue(expr, typeChecker);
1188
396
  if (typeof value !== "undefined") return {
1189
397
  raw: value,
@@ -1202,8 +410,8 @@ function buildDecoratorArgument(expr, typeChecker) {
1202
410
  //#endregion
1203
411
  //#region src/adapters/decorator/typescript/module.ts
1204
412
  function buildDecoratorSources(node, options) {
1205
- if (!ts.canHaveDecorators(node)) return [];
1206
- const decorators = ts.getDecorators(node);
413
+ if (!canHaveDecorators(node)) return [];
414
+ const decorators = getDecorators(node);
1207
415
  if (!decorators || decorators.length === 0) return [];
1208
416
  const output = [];
1209
417
  for (const decorator of decorators) {
@@ -1217,7 +425,7 @@ function buildDecoratorSource(decorator, options) {
1217
425
  let name;
1218
426
  let argumentExpressions = [];
1219
427
  let typeArgumentNodes = [];
1220
- if (ts.isCallExpression(expression)) {
428
+ if (isCallExpression(expression)) {
1221
429
  argumentExpressions = expression.arguments;
1222
430
  typeArgumentNodes = expression.typeArguments ?? [];
1223
431
  name = readDecoratorName(expression.expression);
@@ -1240,8 +448,8 @@ function buildDecoratorSource(decorator, options) {
1240
448
  };
1241
449
  }
1242
450
  function readDecoratorName(expression) {
1243
- if (ts.isIdentifier(expression)) return expression.text;
1244
- if (ts.isPropertyAccessExpression(expression)) return expression.name.text;
451
+ if (isIdentifier(expression)) return expression.text;
452
+ if (isPropertyAccessExpression(expression)) return expression.name.text;
1245
453
  }
1246
454
  function buildJsDocSources(node, options) {
1247
455
  const tags = getJSDocTags(node);
@@ -1255,10 +463,10 @@ function buildJsDocSource(tag, options) {
1255
463
  const text = transformJSDocComment(tag.comment);
1256
464
  let parameterName;
1257
465
  let typeNode;
1258
- if (ts.isJSDocParameterTag(tag) || ts.isJSDocPropertyTag(tag)) {
466
+ if (isJSDocParameterTag(tag) || isJSDocPropertyTag(tag)) {
1259
467
  if (tag.name) parameterName = readEntityName(tag.name);
1260
468
  typeNode = tag.typeExpression?.type;
1261
- } else if (ts.isJSDocReturnTag(tag) || ts.isJSDocTypeTag(tag) || ts.isJSDocThisTag(tag)) typeNode = tag.typeExpression?.type;
469
+ } else if (isJSDocReturnTag(tag) || isJSDocTypeTag(tag) || isJSDocThisTag(tag)) typeNode = tag.typeExpression?.type;
1262
470
  const source = {
1263
471
  tag: tagName,
1264
472
  target: options.target,
@@ -1273,8 +481,8 @@ function buildJsDocSource(tag, options) {
1273
481
  return source;
1274
482
  }
1275
483
  function readEntityName(name) {
1276
- if (ts.isIdentifier(name)) return name.text;
1277
- if (ts.isQualifiedName(name)) {
484
+ if (isIdentifier(name)) return name.text;
485
+ if (isQualifiedName(name)) {
1278
486
  const left = readEntityName(name.left);
1279
487
  return left ? `${left}.${name.right.text}` : name.right.text;
1280
488
  }
@@ -1336,16 +544,6 @@ function applyJsDocHandlers(node, handlers, draft, options) {
1336
544
  for (const source of sources) for (const handler of handlers) if (matchesJsDoc(handler.match, source)) handler.apply(buildJsDocHandlerContext(source, options), draft);
1337
545
  }
1338
546
  //#endregion
1339
- //#region src/core/error/validator.ts
1340
- var ValidatorError$1 = class extends MetadataError {};
1341
- //#endregion
1342
- //#region src/core/error/validator-codes.ts
1343
- const ValidatorErrorCode$1 = {
1344
- EXPECTED_NUMBER: "VALIDATOR_EXPECTED_NUMBER",
1345
- EXPECTED_DATE: "VALIDATOR_EXPECTED_DATE",
1346
- EXPECTED_STRING: "VALIDATOR_EXPECTED_STRING"
1347
- };
1348
- //#endregion
1349
547
  //#region src/adapters/typescript/validator/module.ts
1350
548
  function getDeclarationValidators(declaration, name) {
1351
549
  if (!declaration.parent) return {};
@@ -1378,23 +576,23 @@ function getDeclarationValidators(declaration, name) {
1378
576
  comment = comment.substring(comment.indexOf(" ") + 1).trim();
1379
577
  const value = getCommentValue(comment);
1380
578
  switch (name) {
1381
- case "uniqueItems":
579
+ case ValidatorName.UNIQUE_ITEMS:
1382
580
  validators[name] = {
1383
581
  message: getErrorMsg(comment, false),
1384
582
  value: void 0
1385
583
  };
1386
584
  break;
1387
- case "minimum":
1388
- case "maximum":
1389
- case "minItems":
1390
- case "maxItems":
1391
- case "minLength":
1392
- case "maxLength":
585
+ case ValidatorName.MINIMUM:
586
+ case ValidatorName.MAXIMUM:
587
+ case ValidatorName.MIN_ITEMS:
588
+ case ValidatorName.MAX_ITEMS:
589
+ case ValidatorName.MIN_LENGTH:
590
+ case ValidatorName.MAX_LENGTH:
1393
591
  {
1394
592
  const parsed = Number(value);
1395
- if (!Number.isFinite(parsed)) throw new ValidatorError$1({
593
+ if (!Number.isFinite(parsed)) throw new ValidatorError({
1396
594
  message: `@${name} validator expects a numeric value, got '${value}'.`,
1397
- code: ValidatorErrorCode$1.EXPECTED_NUMBER
595
+ code: ValidatorErrorCode.EXPECTED_NUMBER
1398
596
  });
1399
597
  validators[name] = {
1400
598
  message: getErrorMsg(comment),
@@ -1402,21 +600,21 @@ function getDeclarationValidators(declaration, name) {
1402
600
  };
1403
601
  }
1404
602
  break;
1405
- case "minDate":
1406
- case "maxDate":
1407
- if (typeof value !== "string") throw new ValidatorError$1({
603
+ case ValidatorName.MIN_DATE:
604
+ case ValidatorName.MAX_DATE:
605
+ if (typeof value !== "string") throw new ValidatorError({
1408
606
  message: `@${name} validator expects a date string, got '${typeof value}'.`,
1409
- code: ValidatorErrorCode$1.EXPECTED_DATE
607
+ code: ValidatorErrorCode.EXPECTED_DATE
1410
608
  });
1411
609
  validators[name] = {
1412
610
  message: getErrorMsg(comment),
1413
611
  value
1414
612
  };
1415
613
  break;
1416
- case "pattern":
1417
- if (typeof value !== "string") throw new ValidatorError$1({
614
+ case ValidatorName.PATTERN:
615
+ if (typeof value !== "string") throw new ValidatorError({
1418
616
  message: `@${name} validator expects a string pattern, got '${value}'.`,
1419
- code: ValidatorErrorCode$1.EXPECTED_STRING
617
+ code: ValidatorErrorCode.EXPECTED_STRING
1420
618
  });
1421
619
  validators[name] = {
1422
620
  message: getErrorMsg(comment),
@@ -1464,64 +662,6 @@ function removeSurroundingQuotes(str) {
1464
662
  return str;
1465
663
  }
1466
664
  //#endregion
1467
- //#region src/core/error/resolver.ts
1468
- var ResolverError$1 = class extends MetadataError {
1469
- file;
1470
- line;
1471
- constructor(message, node, options) {
1472
- const opts = typeof options === "boolean" ? { onlyCurrent: options } : options;
1473
- const onlyCurrent = opts?.onlyCurrent ?? false;
1474
- const parts = [message];
1475
- let file;
1476
- let line;
1477
- if (node) {
1478
- const location = prettyLocationOfNode$1(node);
1479
- if (location) {
1480
- parts.push(location.text);
1481
- file = location.file;
1482
- line = location.line;
1483
- }
1484
- parts.push(prettyTroubleCause$1(node, onlyCurrent));
1485
- }
1486
- super({
1487
- message: parts.join("\n"),
1488
- cause: opts?.cause
1489
- });
1490
- this.file = file;
1491
- this.line = line;
1492
- }
1493
- };
1494
- function isResolverError$1(input) {
1495
- if (!isBaseError(input)) return false;
1496
- return "file" in input && "line" in input;
1497
- }
1498
- function prettyLocationOfNode$1(node) {
1499
- try {
1500
- const sourceFile = node.getSourceFile();
1501
- if (!sourceFile) return void 0;
1502
- const token = node.getFirstToken() || node.parent?.getFirstToken();
1503
- const start = token ? sourceFile.getLineAndCharacterOfPosition(token.getStart()).line + 1 : void 0;
1504
- const end = token ? sourceFile.getLineAndCharacterOfPosition(token.getEnd()).line + 1 : void 0;
1505
- return {
1506
- text: `At: ${normalize(sourceFile.fileName)}${start ? `:${start}` : ""}${end ? `:${end}` : ""}.`,
1507
- file: sourceFile.fileName,
1508
- line: start
1509
- };
1510
- } catch {
1511
- return;
1512
- }
1513
- }
1514
- function prettyTroubleCause$1(node, onlyCurrent = false) {
1515
- try {
1516
- let name;
1517
- if (onlyCurrent || !node.parent) name = node.pos !== -1 ? node.getText() : node.name.text;
1518
- else name = node.parent.pos !== -1 ? node.parent.getText() : node.parent.name.text;
1519
- return `This was caused by '${name}'`;
1520
- } catch {
1521
- return "This was caused by an unknown node";
1522
- }
1523
- }
1524
- //#endregion
1525
665
  //#region src/adapters/typescript/resolver/extension/module.ts
1526
666
  function getNodeExtensions(node, registry) {
1527
667
  const names = namesForMarker(registry, isExtensionMarker);
@@ -1545,9 +685,9 @@ function getNodeExtensions(node, registry) {
1545
685
  //#endregion
1546
686
  //#region src/adapters/typescript/resolver/sub/array.ts
1547
687
  function resolveArrayType(typeNode, ctx) {
1548
- if (!ts.isArrayTypeNode(typeNode)) return;
688
+ if (!isArrayTypeNode(typeNode)) return;
1549
689
  return {
1550
- typeName: "array",
690
+ typeName: TypeName.ARRAY,
1551
691
  elementType: ctx.resolveType(typeNode.elementType, ctx.parentNode, ctx.context)
1552
692
  };
1553
693
  }
@@ -1591,92 +731,93 @@ function getNodeDescription(node, typeChecker) {
1591
731
  }
1592
732
  function toTypeNodeOrFail(typeChecker, ...args) {
1593
733
  const output = typeChecker.typeToTypeNode(...args);
1594
- if (typeof output === "undefined") throw new ResolverError$1("Type could not be transformed to TypeNode.");
734
+ if (typeof output === "undefined") throw new ResolverError("Type could not be transformed to TypeNode.");
1595
735
  return output;
1596
736
  }
1597
737
  //#endregion
1598
738
  //#region src/adapters/typescript/resolver/sub/indexed-access.ts
1599
739
  function resolveIndexedAccessType(typeNode, ctx) {
1600
- if (!ts.isIndexedAccessTypeNode(typeNode)) return;
1601
- if (typeNode.indexType.kind === ts.SyntaxKind.NumberKeyword || typeNode.indexType.kind === ts.SyntaxKind.StringKeyword) {
1602
- const numberIndexType = typeNode.indexType.kind === ts.SyntaxKind.NumberKeyword;
740
+ if (!isIndexedAccessTypeNode(typeNode)) return;
741
+ if (typeNode.indexType.kind === SyntaxKind.NumberKeyword || typeNode.indexType.kind === SyntaxKind.StringKeyword) {
742
+ const numberIndexType = typeNode.indexType.kind === SyntaxKind.NumberKeyword;
1603
743
  const objectType = ctx.typeChecker.getTypeFromTypeNode(typeNode.objectType);
1604
744
  const type = numberIndexType ? objectType.getNumberIndexType() : objectType.getStringIndexType();
1605
- if (type === void 0) throw new ResolverError$1(`Could not determine ${numberIndexType ? "number" : "string"} index on ${ctx.typeChecker.typeToString(objectType)}`, typeNode);
745
+ if (type === void 0) throw new ResolverError(`Could not determine ${numberIndexType ? "number" : "string"} index on ${ctx.typeChecker.typeToString(objectType)}`, typeNode);
1606
746
  return ctx.resolveType(toTypeNodeOrFail(ctx.typeChecker, type, void 0, void 0), typeNode, ctx.context, ctx.referencer);
1607
747
  }
1608
- if (ts.isLiteralTypeNode(typeNode.indexType) && (ts.isStringLiteral(typeNode.indexType.literal) || ts.isNumericLiteral(typeNode.indexType.literal))) {
748
+ if (isLiteralTypeNode(typeNode.indexType) && (isStringLiteral(typeNode.indexType.literal) || isNumericLiteral(typeNode.indexType.literal))) {
1609
749
  const hasType = (node) => node !== void 0 && Object.prototype.hasOwnProperty.call(node, "type");
1610
750
  const symbol = ctx.typeChecker.getPropertyOfType(ctx.typeChecker.getTypeFromTypeNode(typeNode.objectType), typeNode.indexType.literal.text);
1611
- if (symbol === void 0) throw new ResolverError$1(`Could not determine the keys on ${ctx.typeChecker.typeToString(ctx.typeChecker.getTypeFromTypeNode(typeNode.objectType))}`, typeNode);
751
+ if (symbol === void 0) throw new ResolverError(`Could not determine the keys on ${ctx.typeChecker.typeToString(ctx.typeChecker.getTypeFromTypeNode(typeNode.objectType))}`, typeNode);
1612
752
  if (hasType(symbol.valueDeclaration) && symbol.valueDeclaration.type) return ctx.resolveType(symbol.valueDeclaration.type, typeNode, ctx.context, ctx.referencer);
1613
753
  const declaration = ctx.typeChecker.getTypeOfSymbolAtLocation(symbol, typeNode.objectType);
1614
754
  try {
1615
755
  return ctx.resolveType(toTypeNodeOrFail(ctx.typeChecker, declaration, void 0, void 0), typeNode, ctx.context, ctx.referencer);
1616
756
  } catch (err) {
1617
- throw new ResolverError$1(`Could not determine the keys on ${ctx.typeChecker.typeToString(declaration)}`, typeNode, { cause: err });
757
+ throw new ResolverError(`Could not determine the keys on ${ctx.typeChecker.typeToString(declaration)}`, typeNode, { cause: err });
1618
758
  }
1619
759
  }
1620
760
  }
1621
761
  //#endregion
1622
762
  //#region src/adapters/typescript/resolver/sub/intersection.ts
1623
763
  function resolveIntersectionType(typeNode, ctx) {
1624
- if (!ts.isIntersectionTypeNode(typeNode)) return;
764
+ if (!isIntersectionTypeNode(typeNode)) return;
765
+ const members = typeNode.types.map((type) => ctx.resolveType(type, ctx.parentNode, ctx.context));
1625
766
  return {
1626
- typeName: "intersection",
1627
- members: typeNode.types.map((type) => ctx.resolveType(type, ctx.parentNode, ctx.context))
767
+ typeName: TypeName.INTERSECTION,
768
+ members
1628
769
  };
1629
770
  }
1630
771
  //#endregion
1631
772
  //#region src/adapters/typescript/resolver/sub/literal.ts
1632
773
  function resolveLiteralType(typeNode, ctx) {
1633
- if (typeNode.kind === ts.SyntaxKind.NullKeyword) return {
1634
- typeName: "enum",
774
+ if (typeNode.kind === SyntaxKind.NullKeyword) return {
775
+ typeName: TypeName.ENUM,
1635
776
  members: [null]
1636
777
  };
1637
- if (typeNode.kind === ts.SyntaxKind.AnyKeyword || typeNode.kind === ts.SyntaxKind.UnknownKeyword) return { typeName: "any" };
1638
- if (ts.isLiteralTypeNode(typeNode)) return {
1639
- typeName: "enum",
778
+ if (typeNode.kind === SyntaxKind.AnyKeyword || typeNode.kind === SyntaxKind.UnknownKeyword) return { typeName: TypeName.ANY };
779
+ if (isLiteralTypeNode(typeNode)) return {
780
+ typeName: TypeName.ENUM,
1640
781
  members: [getLiteralValue(typeNode)]
1641
782
  };
1642
- if (typeNode.kind === ts.SyntaxKind.TemplateLiteralType) {
783
+ if (typeNode.kind === SyntaxKind.TemplateLiteralType) {
1643
784
  const type = ctx.typeChecker.getTypeFromTypeNode(ctx.referencer || typeNode);
1644
785
  if (type.isUnion() && type.types.every((t) => t.isStringLiteral())) return {
1645
- typeName: "enum",
786
+ typeName: TypeName.ENUM,
1646
787
  members: type.types.map((t) => t.value)
1647
788
  };
1648
- throw new ResolverError$1(`Could not resolve type: ${ctx.typeChecker.typeToString(ctx.typeChecker.getTypeFromTypeNode(typeNode), typeNode)}`, typeNode);
789
+ throw new ResolverError(`Could not resolve type: ${ctx.typeChecker.typeToString(ctx.typeChecker.getTypeFromTypeNode(typeNode), typeNode)}`, typeNode);
1649
790
  }
1650
- if (ts.isParenthesizedTypeNode(typeNode)) return ctx.resolveType(typeNode.type, typeNode, ctx.context, ctx.referencer);
1651
- if (typeNode.kind === ts.SyntaxKind.ObjectKeyword || ts.isFunctionTypeNode(typeNode)) return { typeName: "object" };
791
+ if (isParenthesizedTypeNode(typeNode)) return ctx.resolveType(typeNode.type, typeNode, ctx.context, ctx.referencer);
792
+ if (typeNode.kind === SyntaxKind.ObjectKeyword || isFunctionTypeNode(typeNode)) return { typeName: TypeName.OBJECT };
1652
793
  }
1653
794
  function getLiteralValue(typeNode) {
1654
795
  let value;
1655
796
  switch (typeNode.literal.kind) {
1656
- case ts.SyntaxKind.TrueKeyword:
797
+ case SyntaxKind.TrueKeyword:
1657
798
  value = true;
1658
799
  break;
1659
- case ts.SyntaxKind.FalseKeyword:
800
+ case SyntaxKind.FalseKeyword:
1660
801
  value = false;
1661
802
  break;
1662
- case ts.SyntaxKind.StringLiteral:
803
+ case SyntaxKind.StringLiteral:
1663
804
  value = typeNode.literal.text;
1664
805
  break;
1665
- case ts.SyntaxKind.NumericLiteral:
806
+ case SyntaxKind.NumericLiteral:
1666
807
  value = Number.parseFloat(typeNode.literal.text);
1667
808
  break;
1668
- case ts.SyntaxKind.NullKeyword:
809
+ case SyntaxKind.NullKeyword:
1669
810
  value = null;
1670
811
  break;
1671
812
  default: if (Object.prototype.hasOwnProperty.call(typeNode.literal, "text")) value = typeNode.literal.text;
1672
- else throw new ResolverError$1(`Couldn't resolve literal node: ${typeNode.literal.getText()}`, typeNode.literal);
813
+ else throw new ResolverError(`Couldn't resolve literal node: ${typeNode.literal.getText()}`, typeNode.literal);
1673
814
  }
1674
815
  return value;
1675
816
  }
1676
817
  //#endregion
1677
818
  //#region src/adapters/typescript/resolver/sub/mapped.ts
1678
819
  function resolveMappedType(typeNode, ctx) {
1679
- if (!ts.isMappedTypeNode(typeNode) || !ctx.referencer) return;
820
+ if (!isMappedTypeNode(typeNode) || !ctx.referencer) return;
1680
821
  const type = ctx.typeChecker.getTypeFromTypeNode(ctx.referencer);
1681
822
  const mappedTypeNode = typeNode;
1682
823
  const { typeChecker } = ctx;
@@ -1684,41 +825,42 @@ function resolveMappedType(typeNode, ctx) {
1684
825
  const isIgnored = (prop) => {
1685
826
  const declaration = getDeclaration(prop);
1686
827
  if (prop.getJsDocTags().findIndex((tag) => tag.name === "ignore") >= 0) return true;
1687
- return !!declaration && !ts.isPropertyDeclaration(declaration) && !ts.isPropertySignature(declaration) && !ts.isParameter(declaration);
828
+ return !!declaration && !isPropertyDeclaration(declaration) && !isPropertySignature(declaration) && !isParameter(declaration);
1688
829
  };
830
+ const properties = type.getProperties().filter((property) => !isIgnored(property)).map((property) => {
831
+ const declaration = getDeclaration(property);
832
+ const overrideToken = mappedTypeNode.questionToken?.kind === SyntaxKind.PlusToken ? factory.createToken(SyntaxKind.QuestionToken) : mappedTypeNode.questionToken;
833
+ if (declaration && isPropertySignature(declaration)) return {
834
+ ...ctx.propertyFromSignature(declaration, overrideToken),
835
+ name: property.getName()
836
+ };
837
+ if (declaration && (isPropertyDeclaration(declaration) || isParameter(declaration))) return {
838
+ ...ctx.propertyFromDeclaration(declaration, overrideToken),
839
+ name: property.getName()
840
+ };
841
+ let required = (property.flags & SymbolFlags.Optional) === 0;
842
+ const typeNode2 = toTypeNodeOrFail(typeChecker, typeChecker.getTypeOfSymbolAtLocation(property, typeNode), void 0, NodeBuilderFlags.NoTruncation);
843
+ if (mappedTypeNode.questionToken && mappedTypeNode.questionToken.kind === SyntaxKind.MinusToken) required = true;
844
+ else if (mappedTypeNode.questionToken && (mappedTypeNode.questionToken.kind === SyntaxKind.QuestionToken || mappedTypeNode.questionToken.kind === SyntaxKind.PlusToken)) required = false;
845
+ return {
846
+ name: property.getName(),
847
+ required,
848
+ deprecated: false,
849
+ type: ctx.resolveType(typeNode2, typeNode, ctx.context, ctx.referencer),
850
+ validators: {}
851
+ };
852
+ });
1689
853
  return {
1690
- typeName: "nestedObjectLiteral",
1691
- properties: type.getProperties().filter((property) => !isIgnored(property)).map((property) => {
1692
- const declaration = getDeclaration(property);
1693
- const overrideToken = mappedTypeNode.questionToken?.kind === ts.SyntaxKind.PlusToken ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) : mappedTypeNode.questionToken;
1694
- if (declaration && ts.isPropertySignature(declaration)) return {
1695
- ...ctx.propertyFromSignature(declaration, overrideToken),
1696
- name: property.getName()
1697
- };
1698
- if (declaration && (ts.isPropertyDeclaration(declaration) || ts.isParameter(declaration))) return {
1699
- ...ctx.propertyFromDeclaration(declaration, overrideToken),
1700
- name: property.getName()
1701
- };
1702
- let required = (property.flags & ts.SymbolFlags.Optional) === 0;
1703
- const typeNode2 = toTypeNodeOrFail(typeChecker, typeChecker.getTypeOfSymbolAtLocation(property, typeNode), void 0, ts.NodeBuilderFlags.NoTruncation);
1704
- if (mappedTypeNode.questionToken && mappedTypeNode.questionToken.kind === ts.SyntaxKind.MinusToken) required = true;
1705
- else if (mappedTypeNode.questionToken && (mappedTypeNode.questionToken.kind === ts.SyntaxKind.QuestionToken || mappedTypeNode.questionToken.kind === ts.SyntaxKind.PlusToken)) required = false;
1706
- return {
1707
- name: property.getName(),
1708
- required,
1709
- deprecated: false,
1710
- type: ctx.resolveType(typeNode2, typeNode, ctx.context, ctx.referencer),
1711
- validators: {}
1712
- };
1713
- })
854
+ typeName: TypeName.NESTED_OBJECT_LITERAL,
855
+ properties
1714
856
  };
1715
857
  }
1716
858
  //#endregion
1717
859
  //#region src/adapters/typescript/resolver/sub/object-literal.ts
1718
860
  function resolveObjectLiteralType(typeNode, ctx) {
1719
- if (!ts.isTypeLiteralNode(typeNode)) return;
1720
- const properties = typeNode.members.filter((member) => ts.isPropertySignature(member)).reduce((res, propertySignature) => {
1721
- if (!propertySignature.type) throw new ResolverError$1("No valid type found for property declaration.", propertySignature);
861
+ if (!isTypeLiteralNode(typeNode)) return;
862
+ const properties = typeNode.members.filter((member) => isPropertySignature(member)).reduce((res, propertySignature) => {
863
+ if (!propertySignature.type) throw new ResolverError("No valid type found for property declaration.", propertySignature);
1722
864
  const type = ctx.resolveType(propertySignature.type, propertySignature, ctx.context);
1723
865
  return [{
1724
866
  deprecated: hasJSDocTag(propertySignature, "deprecated"),
@@ -1733,16 +875,16 @@ function resolveObjectLiteralType(typeNode, ctx) {
1733
875
  validators: getDeclarationValidators(propertySignature) || {}
1734
876
  }, ...res];
1735
877
  }, []);
1736
- const indexMember = typeNode.members.find((member) => ts.isIndexSignatureDeclaration(member));
878
+ const indexMember = typeNode.members.find((member) => isIndexSignatureDeclaration(member));
1737
879
  let additionalType;
1738
880
  if (indexMember) {
1739
881
  const indexSignatureDeclaration = indexMember;
1740
- if (!isStringType(ctx.resolveType(indexSignatureDeclaration.parameters[0].type, ctx.parentNode, ctx.context))) throw new ResolverError$1("Only string indexes are supported.", typeNode);
882
+ if (!isStringType(ctx.resolveType(indexSignatureDeclaration.parameters[0].type, ctx.parentNode, ctx.context))) throw new ResolverError("Only string indexes are supported.", typeNode);
1741
883
  additionalType = ctx.resolveType(indexSignatureDeclaration.type, ctx.parentNode, ctx.context);
1742
884
  }
1743
885
  return {
1744
886
  additionalProperties: indexMember && additionalType,
1745
- typeName: "nestedObjectLiteral",
887
+ typeName: TypeName.NESTED_OBJECT_LITERAL,
1746
888
  properties
1747
889
  };
1748
890
  }
@@ -1750,17 +892,17 @@ function getNodeFormat(node) {
1750
892
  return getJSDocTagComment(node, "format");
1751
893
  }
1752
894
  function getPropertyName(node) {
1753
- if (ts.isIdentifier(node.name)) return node.name.text;
1754
- if (ts.isStringLiteral(node.name) || ts.isNumericLiteral(node.name)) return node.name.text;
895
+ if (isIdentifier(node.name)) return node.name.text;
896
+ if (isStringLiteral(node.name) || isNumericLiteral(node.name)) return node.name.text;
1755
897
  return node.name.getText();
1756
898
  }
1757
899
  //#endregion
1758
900
  //#region src/adapters/typescript/resolver/sub/primitive.ts
1759
901
  const NUMERIC_KIND_TO_TYPE_NAME = {
1760
- [NumericKind.Int]: "integer",
1761
- [NumericKind.Long]: "long",
1762
- [NumericKind.Float]: "float",
1763
- [NumericKind.Double]: "double"
902
+ [NumericKind.Int]: TypeName.INTEGER,
903
+ [NumericKind.Long]: TypeName.LONG,
904
+ [NumericKind.Float]: TypeName.FLOAT,
905
+ [NumericKind.Double]: TypeName.DOUBLE
1764
906
  };
1765
907
  var PrimitiveResolver = class {
1766
908
  registry;
@@ -1770,15 +912,15 @@ var PrimitiveResolver = class {
1770
912
  resolve(node, parentNode) {
1771
913
  const resolved = this.resolveSyntaxKind(node.kind);
1772
914
  if (resolved) {
1773
- if (resolved === "string") return { typeName: "string" };
1774
- if (resolved === "void") return { typeName: "void" };
1775
- if (resolved === "boolean") return { typeName: "boolean" };
1776
- if (resolved === "undefined") return { typeName: "undefined" };
915
+ if (resolved === "string") return { typeName: TypeName.STRING };
916
+ if (resolved === "void") return { typeName: TypeName.VOID };
917
+ if (resolved === "boolean") return { typeName: TypeName.BOOLEAN };
918
+ if (resolved === "undefined") return { typeName: TypeName.UNDEFINED };
1777
919
  if (resolved === "null") return;
1778
- if (resolved === "never") return { typeName: "never" };
1779
- if (resolved === "bigint") return { typeName: "bigint" };
920
+ if (resolved === "never") return { typeName: TypeName.NEVER };
921
+ if (resolved === "bigint") return { typeName: TypeName.BIGINT };
1780
922
  if (resolved === "number") {
1781
- if (!parentNode) return { typeName: "double" };
923
+ if (!parentNode) return { typeName: TypeName.DOUBLE };
1782
924
  const presentJsDocTags = new Set(getJSDocTagNames(parentNode).map((tag) => tag.toLowerCase()));
1783
925
  for (const kind of [
1784
926
  NumericKind.Int,
@@ -1792,7 +934,7 @@ var PrimitiveResolver = class {
1792
934
  const jsDocTags = tagsForMarker(this.registry, matchKind);
1793
935
  for (const tag of jsDocTags) if (presentJsDocTags.has(tag.toLowerCase())) return { typeName: NUMERIC_KIND_TO_TYPE_NAME[kind] };
1794
936
  }
1795
- return { typeName: "double" };
937
+ return { typeName: TypeName.DOUBLE };
1796
938
  }
1797
939
  }
1798
940
  }
@@ -1820,9 +962,9 @@ var ReferenceResolver = class extends ResolverBase {
1820
962
  }
1821
963
  merge(referenceTypes) {
1822
964
  if (referenceTypes.length === 1) return referenceTypes[0];
1823
- if (referenceTypes.every((refType) => refType.refName === "refEnum")) return this.mergeManyRefEnums(referenceTypes);
1824
- if (referenceTypes.every((refType) => refType.refName === "refObject")) return this.mergeManyRefObjects(referenceTypes);
1825
- throw new ResolverError$1(`These resolved type merge rules are not defined: ${JSON.stringify(referenceTypes)}`);
965
+ if (referenceTypes.every((refType) => refType.refName === TypeName.REF_ENUM)) return this.mergeManyRefEnums(referenceTypes);
966
+ if (referenceTypes.every((refType) => refType.refName === TypeName.REF_OBJECT)) return this.mergeManyRefObjects(referenceTypes);
967
+ throw new ResolverError(`These resolved type merge rules are not defined: ${JSON.stringify(referenceTypes)}`);
1826
968
  }
1827
969
  mergeManyRefEnums(many) {
1828
970
  let merged = this.mergeRefEnums(many[0], many[1]);
@@ -1835,7 +977,7 @@ var ReferenceResolver = class extends ResolverBase {
1835
977
  else if (!second.description) description = first.description;
1836
978
  else description = `${first.description}\n${second.description}`;
1837
979
  return {
1838
- typeName: "refEnum",
980
+ typeName: TypeName.REF_ENUM,
1839
981
  example: first.example || second.example,
1840
982
  description,
1841
983
  members: [...first.members || [], ...second.members || []],
@@ -1859,11 +1001,11 @@ var ReferenceResolver = class extends ResolverBase {
1859
1001
  if (first.additionalProperties || second.additionalProperties) if (!first.additionalProperties) additionalProperties = second.additionalProperties;
1860
1002
  else if (!second.additionalProperties) additionalProperties = first.additionalProperties;
1861
1003
  else additionalProperties = {
1862
- typeName: "union",
1004
+ typeName: TypeName.UNION,
1863
1005
  members: [first.additionalProperties, second.additionalProperties]
1864
1006
  };
1865
1007
  return {
1866
- typeName: "refObject",
1008
+ typeName: TypeName.REF_OBJECT,
1867
1009
  description,
1868
1010
  properties,
1869
1011
  additionalProperties,
@@ -1877,7 +1019,7 @@ var ReferenceResolver = class extends ResolverBase {
1877
1019
  const enums = declaration.members.map(this.typeChecker.getConstantValue.bind(this.typeChecker)).filter(isNotUndefined);
1878
1020
  const enumNames = declaration.members.map((e) => e.name.getText()).filter(isNotUndefined);
1879
1021
  return {
1880
- typeName: "refEnum",
1022
+ typeName: TypeName.REF_ENUM,
1881
1023
  description: getNodeDescription(declaration, this.typeChecker),
1882
1024
  members: enums,
1883
1025
  memberNames: enumNames,
@@ -1887,7 +1029,7 @@ var ReferenceResolver = class extends ResolverBase {
1887
1029
  }
1888
1030
  transformEnumMember(declaration, enumName) {
1889
1031
  return {
1890
- typeName: "refEnum",
1032
+ typeName: TypeName.REF_ENUM,
1891
1033
  refName: enumName,
1892
1034
  members: [this.typeChecker.getConstantValue(declaration)],
1893
1035
  memberNames: [declaration.name.getText()],
@@ -1898,40 +1040,42 @@ var ReferenceResolver = class extends ResolverBase {
1898
1040
  //#endregion
1899
1041
  //#region src/adapters/typescript/resolver/sub/tuple.ts
1900
1042
  function resolveTupleType(typeNode, ctx) {
1901
- if (!ts.isTupleTypeNode(typeNode)) return;
1043
+ if (!isTupleTypeNode(typeNode)) return;
1044
+ const elements = typeNode.elements.map((element) => {
1045
+ const isNamed = isNamedTupleMember(element);
1046
+ const actualType = isNamed ? element.type : element;
1047
+ return {
1048
+ type: ctx.resolveType(actualType, ctx.parentNode, ctx.context),
1049
+ ...isNamed && { name: element.name.text }
1050
+ };
1051
+ });
1902
1052
  return {
1903
- typeName: "tuple",
1904
- elements: typeNode.elements.map((element) => {
1905
- const isNamed = ts.isNamedTupleMember(element);
1906
- const actualType = isNamed ? element.type : element;
1907
- return {
1908
- type: ctx.resolveType(actualType, ctx.parentNode, ctx.context),
1909
- ...isNamed && { name: element.name.text }
1910
- };
1911
- })
1053
+ typeName: TypeName.TUPLE,
1054
+ elements
1912
1055
  };
1913
1056
  }
1914
1057
  //#endregion
1915
1058
  //#region src/adapters/typescript/resolver/sub/type-operator.ts
1916
1059
  function resolveTypeOperatorType(typeNode, ctx) {
1917
- if (!ts.isTypeOperatorNode(typeNode)) return;
1918
- if (typeNode.operator === ts.SyntaxKind.KeyOfKeyword) {
1060
+ if (!isTypeOperatorNode(typeNode)) return;
1061
+ if (typeNode.operator === SyntaxKind.KeyOfKeyword) {
1919
1062
  const type = ctx.typeChecker.getTypeFromTypeNode(typeNode);
1920
1063
  try {
1921
- return ctx.resolveType(toTypeNodeOrFail(ctx.typeChecker, type, void 0, ts.NodeBuilderFlags.NoTruncation), typeNode, ctx.context, ctx.referencer);
1064
+ return ctx.resolveType(toTypeNodeOrFail(ctx.typeChecker, type, void 0, NodeBuilderFlags.NoTruncation), typeNode, ctx.context, ctx.referencer);
1922
1065
  } catch (err) {
1923
- throw new ResolverError$1(`Could not determine the keys on ${ctx.typeChecker.typeToString(ctx.typeChecker.getTypeFromTypeNode(typeNode.type))}`, typeNode, { cause: err });
1066
+ throw new ResolverError(`Could not determine the keys on ${ctx.typeChecker.typeToString(ctx.typeChecker.getTypeFromTypeNode(typeNode.type))}`, typeNode, { cause: err });
1924
1067
  }
1925
1068
  }
1926
- if (typeNode.operator === ts.SyntaxKind.ReadonlyKeyword) return ctx.resolveType(typeNode.type, typeNode, ctx.context, ctx.referencer);
1069
+ if (typeNode.operator === SyntaxKind.ReadonlyKeyword) return ctx.resolveType(typeNode.type, typeNode, ctx.context, ctx.referencer);
1927
1070
  }
1928
1071
  //#endregion
1929
1072
  //#region src/adapters/typescript/resolver/sub/union.ts
1930
1073
  function resolveUnionType(typeNode, ctx) {
1931
- if (!ts.isUnionTypeNode(typeNode)) return;
1074
+ if (!isUnionTypeNode(typeNode)) return;
1075
+ const members = typeNode.types.map((type) => ctx.resolveType(type, ctx.parentNode, ctx.context));
1932
1076
  return {
1933
- typeName: "union",
1934
- members: typeNode.types.map((type) => ctx.resolveType(type, ctx.parentNode, ctx.context))
1077
+ typeName: TypeName.UNION,
1078
+ members
1935
1079
  };
1936
1080
  }
1937
1081
  //#endregion
@@ -1963,7 +1107,7 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
1963
1107
  */
1964
1108
  static clearCache() {}
1965
1109
  resolve() {
1966
- if (this.depth > TypeNodeResolver.MAX_DEPTH) throw new ResolverError$1(`Type resolution exceeded maximum depth of ${TypeNodeResolver.MAX_DEPTH}. This usually indicates deeply nested or circular generics.`, this.typeNode);
1110
+ if (this.depth > TypeNodeResolver.MAX_DEPTH) throw new ResolverError(`Type resolution exceeded maximum depth of ${TypeNodeResolver.MAX_DEPTH}. This usually indicates deeply nested or circular generics.`, this.typeNode);
1967
1111
  const ctx = this.createSubResolverContext();
1968
1112
  const result = this.primitiveResolver.resolve(this.typeNode, this.parentNode) ?? resolveLiteralType(this.typeNode, ctx) ?? resolveArrayType(this.typeNode, ctx) ?? resolveUnionType(this.typeNode, ctx) ?? resolveIntersectionType(this.typeNode, ctx) ?? resolveObjectLiteralType(this.typeNode, ctx) ?? resolveTupleType(this.typeNode, ctx) ?? resolveMappedType(this.typeNode, ctx) ?? this.resolveConditionalType() ?? resolveTypeOperatorType(this.typeNode, ctx) ?? resolveIndexedAccessType(this.typeNode, ctx) ?? this.resolveTypeReference();
1969
1113
  if (!result) this.throwUnknownType();
@@ -1988,32 +1132,32 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
1988
1132
  return new TypeNodeResolver(typeNode, this.current, parentNode, context, referencer, this.depth + 1).resolve();
1989
1133
  }
1990
1134
  throwUnknownType() {
1991
- throw new ResolverError$1(`Unknown type: ${ts.SyntaxKind[this.typeNode.kind]}`, this.typeNode);
1135
+ throw new ResolverError(`Unknown type: ${SyntaxKind[this.typeNode.kind]}`, this.typeNode);
1992
1136
  }
1993
1137
  resolveConditionalType() {
1994
- if (!ts.isConditionalTypeNode(this.typeNode)) return;
1138
+ if (!isConditionalTypeNode(this.typeNode)) return;
1995
1139
  if (Object.keys(this.context).length > 0 && this.referencer) return this.resolveTypeViaChecker(this.referencer);
1996
1140
  return this.resolveTypeViaChecker(this.typeNode);
1997
1141
  }
1998
1142
  resolveTypeReference() {
1999
- if (this.typeNode.kind !== ts.SyntaxKind.TypeReference) return;
1143
+ if (this.typeNode.kind !== SyntaxKind.TypeReference) return;
2000
1144
  const typeReference = this.typeNode;
2001
- if (typeReference.typeName.kind === ts.SyntaxKind.Identifier) {
1145
+ if (typeReference.typeName.kind === SyntaxKind.Identifier) {
2002
1146
  if (typeReference.typeName.text === "Record" && typeReference.typeArguments) return {
2003
1147
  additionalProperties: this.resolveNestedType(typeReference.typeArguments[1], this.parentNode, this.context),
2004
- typeName: "nestedObjectLiteral",
1148
+ typeName: TypeName.NESTED_OBJECT_LITERAL,
2005
1149
  properties: []
2006
1150
  };
2007
1151
  const specialReference = TypeNodeResolver.resolveSpecialReference(typeReference.typeName);
2008
1152
  if (typeof specialReference !== "undefined") return specialReference;
2009
1153
  if (typeReference.typeName.text === "Date") return this.getDateType(this.parentNode);
2010
- if (typeReference.typeName.text === "Buffer" || typeReference.typeName.text === "Readable") return { typeName: "buffer" };
1154
+ if (typeReference.typeName.text === "Buffer" || typeReference.typeName.text === "Readable") return { typeName: TypeName.BUFFER };
2011
1155
  if (typeReference.typeName.text === "Array" && typeReference.typeArguments && typeReference.typeArguments.length >= 1) return {
2012
- typeName: "array",
1156
+ typeName: TypeName.ARRAY,
2013
1157
  elementType: this.resolveNestedType(typeReference.typeArguments[0], this.parentNode, this.context)
2014
1158
  };
2015
1159
  if (typeReference.typeName.text === "Promise" && typeReference.typeArguments && typeReference.typeArguments.length === 1) return this.resolveNestedType(typeReference.typeArguments[0], this.parentNode, this.context);
2016
- if (typeReference.typeName.text === "String") return { typeName: "string" };
1160
+ if (typeReference.typeName.text === "String") return { typeName: TypeName.STRING };
2017
1161
  if (this.context[typeReference.typeName.text]) return this.resolveNestedType(this.context[typeReference.typeName.text], this.parentNode, this.context);
2018
1162
  if (TypeNodeResolver.isCheckerResolvableUtilityType(typeReference.typeName.text)) return this.resolveUtilityTypeViaChecker(typeReference);
2019
1163
  }
@@ -2030,19 +1174,19 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2030
1174
  }
2031
1175
  }
2032
1176
  static CHECKER_RESOLVABLE_UTILITY_TYPES = new Set([
2033
- "NonNullable",
2034
- "Omit",
2035
- "Partial",
2036
- "Readonly",
2037
- "Required",
2038
- "Pick",
2039
- "Extract",
2040
- "Exclude",
2041
- "ReturnType",
2042
- "Parameters",
2043
- "Awaited",
2044
- "InstanceType",
2045
- "ConstructorParameters"
1177
+ UtilityTypeName.NON_NULLABLE,
1178
+ UtilityTypeName.OMIT,
1179
+ UtilityTypeName.PARTIAL,
1180
+ UtilityTypeName.READONLY,
1181
+ UtilityTypeName.REQUIRED,
1182
+ UtilityTypeName.PICK,
1183
+ UtilityTypeName.EXTRACT,
1184
+ UtilityTypeName.EXCLUDE,
1185
+ UtilityTypeName.RETURN_TYPE,
1186
+ UtilityTypeName.PARAMETERS,
1187
+ UtilityTypeName.AWAITED,
1188
+ UtilityTypeName.INSTANCE_TYPE,
1189
+ UtilityTypeName.CONSTRUCTOR_PARAMETERS
2046
1190
  ]);
2047
1191
  static isCheckerResolvableUtilityType(name) {
2048
1192
  return TypeNodeResolver.CHECKER_RESOLVABLE_UTILITY_TYPES.has(name);
@@ -2058,9 +1202,9 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2058
1202
  */
2059
1203
  resolveTypeViaChecker(typeNode) {
2060
1204
  const type = this.current.typeChecker.getTypeFromTypeNode(typeNode);
2061
- const resolvedTypeNode = this.current.typeChecker.typeToTypeNode(type, void 0, ts.NodeBuilderFlags.NoTruncation | ts.NodeBuilderFlags.InTypeAlias);
1205
+ const resolvedTypeNode = this.current.typeChecker.typeToTypeNode(type, void 0, NodeBuilderFlags.NoTruncation | NodeBuilderFlags.InTypeAlias);
2062
1206
  if (!resolvedTypeNode) return {
2063
- typeName: "tuple",
1207
+ typeName: TypeName.TUPLE,
2064
1208
  elements: []
2065
1209
  };
2066
1210
  return this.resolveNestedType(resolvedTypeNode, this.parentNode, this.context);
@@ -2072,23 +1216,23 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2072
1216
  */
2073
1217
  hasUnboundContextArgs(typeReference) {
2074
1218
  if (!typeReference.typeArguments || Object.keys(this.context).length === 0) return false;
2075
- return typeReference.typeArguments.some((arg) => ts.isTypeReferenceNode(arg) && ts.isIdentifier(arg.typeName) && arg.typeName.text in this.context);
1219
+ return typeReference.typeArguments.some((arg) => isTypeReferenceNode(arg) && isIdentifier(arg.typeName) && arg.typeName.text in this.context);
2076
1220
  }
2077
1221
  static resolveSpecialReference(node) {
2078
1222
  switch (node.text) {
2079
1223
  case "Buffer":
2080
1224
  case "DownloadBinaryData":
2081
- case "DownloadResource": return { typeName: "buffer" };
1225
+ case "DownloadResource": return { typeName: TypeName.BUFFER };
2082
1226
  default: return;
2083
1227
  }
2084
1228
  }
2085
1229
  getDateType(parentNode) {
2086
- if (!parentNode) return { typeName: "datetime" };
1230
+ if (!parentNode) return { typeName: TypeName.DATETIME };
2087
1231
  const tags = getJSDocTagNames(parentNode).filter((name) => ["isDate", "isDateTime"].includes(name));
2088
- if (tags.length === 0) return { typeName: "datetime" };
1232
+ if (tags.length === 0) return { typeName: TypeName.DATETIME };
2089
1233
  switch (tags[0]) {
2090
- case "isDate": return { typeName: "date" };
2091
- default: return { typeName: "datetime" };
1234
+ case "isDate": return { typeName: TypeName.DATE };
1235
+ default: return { typeName: TypeName.DATETIME };
2092
1236
  }
2093
1237
  }
2094
1238
  static getDesignatedModels(nodes, _typeName) {
@@ -2096,16 +1240,16 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2096
1240
  }
2097
1241
  getEnumerateType(typeName) {
2098
1242
  const enumName = typeName.text;
2099
- let enumNodes = this.current.nodes.filter((node) => node.kind === ts.SyntaxKind.EnumDeclaration && node.name.text === enumName);
1243
+ let enumNodes = this.current.nodes.filter((node) => node.kind === SyntaxKind.EnumDeclaration && node.name.text === enumName);
2100
1244
  if (!enumNodes.length) return;
2101
1245
  enumNodes = TypeNodeResolver.getDesignatedModels(enumNodes, enumName);
2102
- if (enumNodes.length > 1) throw new ResolverError$1(`Multiple matching enum found for enum ${enumName}; please make enum names unique.`);
1246
+ if (enumNodes.length > 1) throw new ResolverError(`Multiple matching enum found for enum ${enumName}; please make enum names unique.`);
2103
1247
  const enumDeclaration = enumNodes[0];
2104
1248
  const isNotUndefined = (item) => item !== void 0;
2105
1249
  const enums = enumDeclaration.members.map(this.current.typeChecker.getConstantValue.bind(this.current.typeChecker)).filter(isNotUndefined);
2106
1250
  const enumNames = enumDeclaration.members.map((e) => e.name.getText()).filter(isNotUndefined);
2107
1251
  return {
2108
- typeName: "refEnum",
1252
+ typeName: TypeName.REF_ENUM,
2109
1253
  description: this.getNodeDescription(enumDeclaration),
2110
1254
  members: enums,
2111
1255
  memberNames: enumNames,
@@ -2115,13 +1259,13 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2115
1259
  }
2116
1260
  getReferenceType(node) {
2117
1261
  let type;
2118
- if (ts.isTypeReferenceNode(node)) type = node.typeName;
2119
- else if (ts.isExpressionWithTypeArguments(node)) type = node.expression;
2120
- else throw new ResolverError$1("Can't resolve reference type.");
1262
+ if (isTypeReferenceNode(node)) type = node.typeName;
1263
+ else if (isExpressionWithTypeArguments(node)) type = node.expression;
1264
+ else throw new ResolverError("Can't resolve reference type.");
2121
1265
  let resolvableName = node.pos !== -1 ? node.getText() : type.text;
2122
1266
  if (node.pos === -1 && "typeArguments" in node && Array.isArray(node.typeArguments)) {
2123
1267
  const argumentsString = node.typeArguments.map((arg) => {
2124
- if (ts.isLiteralTypeNode(arg)) return `'${String(getLiteralValue(arg))}'`;
1268
+ if (isLiteralTypeNode(arg)) return `'${String(getLiteralValue(arg))}'`;
2125
1269
  const resolvedType = this.primitiveResolver.resolveSyntaxKind(arg.kind);
2126
1270
  if (typeof resolvedType === "undefined") return "any";
2127
1271
  return resolvedType;
@@ -2139,7 +1283,7 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2139
1283
  const refName = TypeNodeResolver.getRefTypeName(name);
2140
1284
  const declarations = this.getModelTypeDeclarations(type);
2141
1285
  const referenceTypes = [];
2142
- for (const declaration of declarations) if (ts.isTypeAliasDeclaration(declaration)) referenceTypes.push(this.getTypeAliasReference(declaration, name, node));
1286
+ for (const declaration of declarations) if (isTypeAliasDeclaration(declaration)) referenceTypes.push(this.getTypeAliasReference(declaration, name, node));
2143
1287
  else if (isEnumDeclaration(declaration)) referenceTypes.push(this.referenceResolver.transformEnum(declaration, refName));
2144
1288
  else if (isEnumMember(declaration)) referenceTypes.push(this.referenceResolver.transformEnumMember(declaration, refName));
2145
1289
  else referenceTypes.push(this.getModelReference(declaration, name));
@@ -2150,15 +1294,15 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2150
1294
  this.current.resolverCache.clearInProgress(name);
2151
1295
  }
2152
1296
  } catch (err) {
2153
- throw new ResolverError$1(`There was a problem resolving type of '${name}'.`, node, { cause: err });
1297
+ throw new ResolverError(`There was a problem resolving type of '${name}'.`, node, { cause: err });
2154
1298
  }
2155
1299
  }
2156
1300
  getTypeAliasReference(declaration, name, referencer) {
2157
1301
  const refName = TypeNodeResolver.getRefTypeName(name);
2158
- if (declaration.type.kind === ts.SyntaxKind.TypeReference) {
1302
+ if (declaration.type.kind === SyntaxKind.TypeReference) {
2159
1303
  const innerRef = declaration.type;
2160
- const innerName = ts.isIdentifier(innerRef.typeName) ? innerRef.typeName.text : void 0;
2161
- if (!(innerName === "Record" || innerName !== void 0 && TypeNodeResolver.isCheckerResolvableUtilityType(innerName))) {
1304
+ const innerName = isIdentifier(innerRef.typeName) ? innerRef.typeName.text : void 0;
1305
+ if (!(innerName === UtilityTypeName.RECORD || innerName !== void 0 && TypeNodeResolver.isCheckerResolvableUtilityType(innerName))) {
2162
1306
  const referenceType = this.getReferenceType(innerRef);
2163
1307
  if (referenceType.refName === refName) return referenceType;
2164
1308
  }
@@ -2166,7 +1310,7 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2166
1310
  const type = this.resolveNestedType(declaration.type, declaration, this.context, this.referencer || referencer);
2167
1311
  const example = this.getNodeExample(declaration);
2168
1312
  return {
2169
- typeName: "refAlias",
1313
+ typeName: TypeName.REF_ALIAS,
2170
1314
  default: getJSDocTagComment(declaration, "default"),
2171
1315
  description: this.getNodeDescription(declaration),
2172
1316
  refName,
@@ -2182,21 +1326,21 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2182
1326
  const description = this.getNodeDescription(modelType);
2183
1327
  const deprecatedDecoratorNames = namesForMarker(this.current.registry, isDeprecatedMarker);
2184
1328
  const deprecated = [...tagsForMarker(this.current.registry, isDeprecatedMarker)].some((tag) => hasJSDocTag(modelType, tag)) || [...deprecatedDecoratorNames].some((name) => hasDecoratorNamed(modelType, name));
2185
- if (!modelType.name) throw new ResolverError$1("Can't get Symbol from anonymous class", modelType);
1329
+ if (!modelType.name) throw new ResolverError("Can't get Symbol from anonymous class", modelType);
2186
1330
  const type = this.current.typeChecker.getTypeAtLocation(modelType.name);
2187
1331
  const toJSON = this.current.typeChecker.getPropertyOfType(type, "toJSON");
2188
- if (toJSON && toJSON.valueDeclaration && (ts.isMethodDeclaration(toJSON.valueDeclaration) || ts.isMethodSignature(toJSON.valueDeclaration))) {
1332
+ if (toJSON && toJSON.valueDeclaration && (isMethodDeclaration(toJSON.valueDeclaration) || isMethodSignature(toJSON.valueDeclaration))) {
2189
1333
  let nodeType = toJSON.valueDeclaration.type;
2190
1334
  if (!nodeType) {
2191
1335
  const signature = this.current.typeChecker.getSignatureFromDeclaration(toJSON.valueDeclaration);
2192
1336
  if (signature) {
2193
1337
  const implicitType = this.current.typeChecker.getReturnTypeOfSignature(signature);
2194
- nodeType = this.current.typeChecker.typeToTypeNode(implicitType, void 0, ts.NodeBuilderFlags.NoTruncation);
2195
- } else throw new ResolverError$1("Can't get signature from toJson value declaration", modelType);
1338
+ nodeType = this.current.typeChecker.typeToTypeNode(implicitType, void 0, NodeBuilderFlags.NoTruncation);
1339
+ } else throw new ResolverError("Can't get signature from toJson value declaration", modelType);
2196
1340
  }
2197
1341
  return {
2198
1342
  refName: `${TypeNodeResolver.getRefTypeName(name)}Alias`,
2199
- typeName: "refAlias",
1343
+ typeName: TypeName.REF_ALIAS,
2200
1344
  description,
2201
1345
  type: this.resolveNestedType(nodeType),
2202
1346
  deprecated,
@@ -2205,11 +1349,13 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2205
1349
  };
2206
1350
  }
2207
1351
  const properties = this.getModelProperties(modelType);
1352
+ const additionalProperties = this.getModelAdditionalProperties(modelType);
1353
+ const inheritedProperties = this.getModelInheritedProperties(modelType) || [];
2208
1354
  const referenceType = {
2209
- additionalProperties: this.getModelAdditionalProperties(modelType),
2210
- typeName: "refObject",
1355
+ additionalProperties,
1356
+ typeName: TypeName.REF_OBJECT,
2211
1357
  description,
2212
- properties: this.getModelInheritedProperties(modelType) || [],
1358
+ properties: inheritedProperties,
2213
1359
  refName: TypeNodeResolver.getRefTypeName(name),
2214
1360
  deprecated,
2215
1361
  ...example && { example }
@@ -2239,14 +1385,14 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2239
1385
  this.current.resolverCache.clearInProgress(name);
2240
1386
  }
2241
1387
  } catch (err) {
2242
- throw new ResolverError$1(`There was a problem resolving type of '${name}'.`, this.typeNode, { cause: err });
1388
+ throw new ResolverError(`There was a problem resolving type of '${name}'.`, this.typeNode, { cause: err });
2243
1389
  }
2244
1390
  }
2245
1391
  createCircularDependencyResolver(refName) {
2246
1392
  const referenceType = {
2247
1393
  deprecated: false,
2248
1394
  properties: [],
2249
- typeName: "refObject",
1395
+ typeName: TypeName.REF_OBJECT,
2250
1396
  refName
2251
1397
  };
2252
1398
  this.current.registerDependencyResolver((referenceTypes) => {
@@ -2261,27 +1407,27 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2261
1407
  }
2262
1408
  static nodeIsUsable(node) {
2263
1409
  switch (node.kind) {
2264
- case ts.SyntaxKind.InterfaceDeclaration:
2265
- case ts.SyntaxKind.ClassDeclaration:
2266
- case ts.SyntaxKind.TypeAliasDeclaration:
2267
- case ts.SyntaxKind.EnumDeclaration:
2268
- case ts.SyntaxKind.EnumMember: return true;
1410
+ case SyntaxKind.InterfaceDeclaration:
1411
+ case SyntaxKind.ClassDeclaration:
1412
+ case SyntaxKind.TypeAliasDeclaration:
1413
+ case SyntaxKind.EnumDeclaration:
1414
+ case SyntaxKind.EnumMember: return true;
2269
1415
  default: return false;
2270
1416
  }
2271
1417
  }
2272
1418
  getModelTypeDeclarations(type) {
2273
- let typeName = type.kind === ts.SyntaxKind.Identifier ? type.text : type.right.text;
1419
+ let typeName = type.kind === SyntaxKind.Identifier ? type.text : type.right.text;
2274
1420
  let symbol = this.getSymbolAtLocation(type);
2275
- if (!symbol && type.kind === ts.SyntaxKind.QualifiedName) symbol = this.getSymbolAtLocation(type.left).exports?.get(typeName);
2276
- if (!symbol) throw new ResolverError$1(`No symbol found for referenced type ${typeName}.`);
1421
+ if (!symbol && type.kind === SyntaxKind.QualifiedName) symbol = this.getSymbolAtLocation(type.left).exports?.get(typeName);
1422
+ if (!symbol) throw new ResolverError(`No symbol found for referenced type ${typeName}.`);
2277
1423
  const declarations = symbol.getDeclarations();
2278
- if (!declarations || declarations.length === 0) throw new ResolverError$1(`No declarations found for referenced type ${typeName}.`);
1424
+ if (!declarations || declarations.length === 0) throw new ResolverError(`No declarations found for referenced type ${typeName}.`);
2279
1425
  if (symbol.escapedName !== typeName && symbol.escapedName !== "default") typeName = symbol.escapedName;
2280
1426
  let modelTypes = declarations.filter((node) => {
2281
1427
  if (!TypeNodeResolver.nodeIsUsable(node) || !this.current.isExportedNode(node)) return false;
2282
1428
  return node.name?.text === typeName;
2283
1429
  });
2284
- if (!modelTypes.length) throw new ResolverError$1(`No matching model found for referenced type ${typeName}. If ${typeName} comes from a dependency, please create an interface in your own code that has the same structure. The compiler can not utilize interfaces from external dependencies.`);
1430
+ if (!modelTypes.length) throw new ResolverError(`No matching model found for referenced type ${typeName}. If ${typeName} comes from a dependency, please create an interface in your own code that has the same structure. The compiler can not utilize interfaces from external dependencies.`);
2285
1431
  if (modelTypes.length > 1) {
2286
1432
  modelTypes = modelTypes.filter((modelType) => modelType.getSourceFile().fileName.replace(/\\/g, "/").toLowerCase().indexOf("node_modules/typescript") <= -1);
2287
1433
  modelTypes = TypeNodeResolver.getDesignatedModels(modelTypes, typeName);
@@ -2289,23 +1435,23 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2289
1435
  return modelTypes;
2290
1436
  }
2291
1437
  getModelTypeDeclaration(type) {
2292
- let typeName = type.kind === ts.SyntaxKind.Identifier ? type.text : type.right.text;
1438
+ let typeName = type.kind === SyntaxKind.Identifier ? type.text : type.right.text;
2293
1439
  const symbol = this.getSymbolAtLocation(type);
2294
1440
  const declarations = symbol.getDeclarations();
2295
- if (!declarations || declarations.length === 0) throw new ResolverError$1(`No models found for referenced type ${typeName}.`);
1441
+ if (!declarations || declarations.length === 0) throw new ResolverError(`No models found for referenced type ${typeName}.`);
2296
1442
  if (symbol.escapedName !== typeName && symbol.escapedName !== "default") typeName = symbol.escapedName;
2297
1443
  let modelTypes = declarations.filter((node) => {
2298
1444
  if (!TypeNodeResolver.nodeIsUsable(node) || !this.current.isExportedNode(node)) return false;
2299
1445
  return node.name?.text === typeName;
2300
1446
  });
2301
- if (!modelTypes.length) throw new ResolverError$1(`No matching model found for referenced type ${typeName}. If ${typeName} comes from a dependency, please create an interface in your own code that has the same structure. The compiler can not utilize interfaces from external dependencies.`);
1447
+ if (!modelTypes.length) throw new ResolverError(`No matching model found for referenced type ${typeName}. If ${typeName} comes from a dependency, please create an interface in your own code that has the same structure. The compiler can not utilize interfaces from external dependencies.`);
2302
1448
  if (modelTypes.length > 1) {
2303
1449
  modelTypes = modelTypes.filter((modelType) => modelType.getSourceFile().fileName.replace(/\\/g, "/").toLowerCase().indexOf("node_modules/typescript") <= -1);
2304
1450
  modelTypes = TypeNodeResolver.getDesignatedModels(modelTypes, typeName);
2305
1451
  }
2306
1452
  if (modelTypes.length > 1) {
2307
1453
  const conflicts = modelTypes.map((modelType) => modelType.getSourceFile().fileName).join("\"; \"");
2308
- throw new ResolverError$1(`Multiple matching models found for referenced type ${typeName}; please make model names unique. Conflicts found: "${conflicts}".`);
1454
+ throw new ResolverError(`Multiple matching models found for referenced type ${typeName}; please make model names unique. Conflicts found: "${conflicts}".`);
2309
1455
  }
2310
1456
  return modelTypes[0];
2311
1457
  }
@@ -2314,13 +1460,13 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2314
1460
  }
2315
1461
  getSymbolAtLocation(type) {
2316
1462
  const symbol = this.current.typeChecker.getSymbolAtLocation(type) || type.symbol;
2317
- return symbol && this.hasFlag(symbol, ts.SymbolFlags.Alias) && this.current.typeChecker.getAliasedSymbol(symbol) || symbol;
1463
+ return symbol && this.hasFlag(symbol, SymbolFlags.Alias) && this.current.typeChecker.getAliasedSymbol(symbol) || symbol;
2318
1464
  }
2319
1465
  getModelProperties(node, overrideToken) {
2320
1466
  const isIgnored = (e) => hasJSDocTag(e, "ignore");
2321
- if (ts.isInterfaceDeclaration(node)) return node.members.filter((member) => !isIgnored(member) && ts.isPropertySignature(member)).map((member) => this.propertyFromSignature(member, overrideToken));
2322
- const properties = node.members.filter((member) => !isIgnored(member) && member.kind === ts.SyntaxKind.PropertyDeclaration && !this.hasStaticModifier(member) && this.hasPublicModifier(member));
2323
- const classConstructor = node.members.find((member) => ts.isConstructorDeclaration(member));
1467
+ if (isInterfaceDeclaration(node)) return node.members.filter((member) => !isIgnored(member) && isPropertySignature(member)).map((member) => this.propertyFromSignature(member, overrideToken));
1468
+ const properties = node.members.filter((member) => !isIgnored(member) && member.kind === SyntaxKind.PropertyDeclaration && !this.hasStaticModifier(member) && this.hasPublicModifier(member));
1469
+ const classConstructor = node.members.find((member) => isConstructorDeclaration(member));
2324
1470
  if (classConstructor && classConstructor.parameters) {
2325
1471
  const constructorProperties = classConstructor.parameters.filter((parameter) => this.isAccessibleParameter(parameter));
2326
1472
  properties.push(...constructorProperties);
@@ -2329,10 +1475,10 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2329
1475
  }
2330
1476
  propertyFromSignature(propertySignature, overrideToken) {
2331
1477
  const identifier = propertySignature.name;
2332
- if (!propertySignature.type) throw new ResolverError$1("No valid type found for property declaration.");
1478
+ if (!propertySignature.type) throw new ResolverError("No valid type found for property declaration.");
2333
1479
  let required = !propertySignature.questionToken;
2334
- if (overrideToken && overrideToken.kind === ts.SyntaxKind.MinusToken) required = true;
2335
- else if (overrideToken && overrideToken.kind === ts.SyntaxKind.QuestionToken) required = false;
1480
+ if (overrideToken && overrideToken.kind === SyntaxKind.MinusToken) required = true;
1481
+ else if (overrideToken && overrideToken.kind === SyntaxKind.QuestionToken) required = false;
2336
1482
  return {
2337
1483
  deprecated: hasJSDocTag(propertySignature, "deprecated"),
2338
1484
  default: getJSDocTagComment(propertySignature, "default"),
@@ -2351,13 +1497,13 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2351
1497
  let typeNode = propertyDeclaration.type;
2352
1498
  if (!typeNode) {
2353
1499
  const tsType = this.current.typeChecker.getTypeAtLocation(propertyDeclaration);
2354
- typeNode = this.current.typeChecker.typeToTypeNode(tsType, void 0, ts.NodeBuilderFlags.NoTruncation);
1500
+ typeNode = this.current.typeChecker.typeToTypeNode(tsType, void 0, NodeBuilderFlags.NoTruncation);
2355
1501
  }
2356
- if (!typeNode) throw new ResolverError$1("No valid type found for property declaration.");
1502
+ if (!typeNode) throw new ResolverError("No valid type found for property declaration.");
2357
1503
  const type = this.resolveNestedType(typeNode, propertyDeclaration, this.context, typeNode);
2358
1504
  let required = !propertyDeclaration.questionToken && !propertyDeclaration.initializer;
2359
- if (overrideToken && overrideToken.kind === ts.SyntaxKind.MinusToken) required = true;
2360
- else if (overrideToken && overrideToken.kind === ts.SyntaxKind.QuestionToken) required = false;
1505
+ if (overrideToken && overrideToken.kind === SyntaxKind.MinusToken) required = true;
1506
+ else if (overrideToken && overrideToken.kind === SyntaxKind.QuestionToken) required = false;
2361
1507
  return {
2362
1508
  deprecated: hasJSDocTag(propertyDeclaration, "deprecated"),
2363
1509
  default: getInitializerValue(propertyDeclaration.initializer, this.current.typeChecker),
@@ -2372,11 +1518,11 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2372
1518
  };
2373
1519
  }
2374
1520
  getModelAdditionalProperties(node) {
2375
- if (node.kind === ts.SyntaxKind.InterfaceDeclaration) {
2376
- const indexMember = node.members.find((member) => member.kind === ts.SyntaxKind.IndexSignature);
1521
+ if (node.kind === SyntaxKind.InterfaceDeclaration) {
1522
+ const indexMember = node.members.find((member) => member.kind === SyntaxKind.IndexSignature);
2377
1523
  if (!indexMember) return;
2378
1524
  const indexSignatureDeclaration = indexMember;
2379
- if (this.resolveNestedType(indexSignatureDeclaration.parameters[0].type, this.parentNode, this.context).typeName !== "string") throw new ResolverError$1("Only string indexers are supported.", this.typeNode);
1525
+ if (this.resolveNestedType(indexSignatureDeclaration.parameters[0].type, this.parentNode, this.context).typeName !== "string") throw new ResolverError("Only string indexers are supported.", this.typeNode);
2380
1526
  return this.resolveNestedType(indexSignatureDeclaration.type, this.parentNode, this.context);
2381
1527
  }
2382
1528
  }
@@ -2387,10 +1533,10 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2387
1533
  if (typeParameters) for (const [index, typeParameter] of typeParameters.entries()) {
2388
1534
  const typeArg = type.typeArguments && type.typeArguments[index];
2389
1535
  let resolvedType;
2390
- if (typeArg && ts.isTypeReferenceNode(typeArg) && ts.isIdentifier(typeArg.typeName) && context[typeArg.typeName.text]) resolvedType = context[typeArg.typeName.text];
1536
+ if (typeArg && isTypeReferenceNode(typeArg) && isIdentifier(typeArg.typeName) && context[typeArg.typeName.text]) resolvedType = context[typeArg.typeName.text];
2391
1537
  else if (typeArg) resolvedType = typeArg;
2392
1538
  else if (typeParameter.default) resolvedType = typeParameter.default;
2393
- else throw new ResolverError$1(`Could not find a value for type parameter ${typeParameter.name.text}`, type);
1539
+ else throw new ResolverError(`Could not find a value for type parameter ${typeParameter.name.text}`, type);
2394
1540
  this.context = {
2395
1541
  ...this.context,
2396
1542
  [typeParameter.name.text]: resolvedType
@@ -2412,8 +1558,8 @@ var TypeNodeResolver = class TypeNodeResolver extends ResolverBase {
2412
1558
  if (isRefAliasType(referenceType)) {
2413
1559
  let type = referenceType;
2414
1560
  while (isRefAliasType(type)) type = type.type;
2415
- if (type.typeName === "refObject") properties = [...properties, ...type.properties];
2416
- else if (type.typeName === "nestedObjectLiteral") properties = [...properties, ...type.properties];
1561
+ if (type.typeName === TypeName.REF_OBJECT) properties = [...properties, ...type.properties];
1562
+ else if (type.typeName === TypeName.NESTED_OBJECT_LITERAL) properties = [...properties, ...type.properties];
2417
1563
  }
2418
1564
  if (isRefObjectType(referenceType)) referenceType.properties.forEach((property) => properties.push(property));
2419
1565
  }
@@ -2726,69 +1872,6 @@ var CacheClient = class {
2726
1872
  };
2727
1873
  const CACHE_KEY_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;
2728
1874
  //#endregion
2729
- //#region src/core/error/generator.ts
2730
- var GeneratorError$1 = class extends MetadataError {};
2731
- function isGeneratorError$1(input) {
2732
- if (!isBaseError(input)) return false;
2733
- return typeof input.code === "string";
2734
- }
2735
- //#endregion
2736
- //#region src/core/error/generator-codes.ts
2737
- const GeneratorErrorCode$1 = {
2738
- CONTROLLER_NO_SOURCE_FILE: "GENERATOR_CONTROLLER_NO_SOURCE_FILE",
2739
- CONTROLLER_NO_NAME: "GENERATOR_CONTROLLER_NO_NAME",
2740
- PARAMETER_GENERATION_FAILED: "GENERATOR_PARAMETER_GENERATION_FAILED",
2741
- BODY_PARAMETER_DUPLICATE: "GENERATOR_BODY_PARAMETER_DUPLICATE",
2742
- BODY_FORM_CONFLICT: "GENERATOR_BODY_FORM_CONFLICT",
2743
- STRICT_UNMATCHED_DECORATORS: "GENERATOR_STRICT_UNMATCHED_DECORATORS"
2744
- };
2745
- //#endregion
2746
- //#region src/core/error/parameter.ts
2747
- var ParameterError$1 = class ParameterError$1 extends MetadataError {
2748
- static typeUnsupported(context) {
2749
- const location = context.node ? ParameterError$1.getCurrentLocation(context.node) : void 0;
2750
- return new ParameterError$1({
2751
- message: `@${context.decoratorName}('${context.propertyName}') does not support '${context.type.typeName}' type${location ? ` at ${location}` : ""}.`,
2752
- code: ParameterErrorCode.TYPE_UNSUPPORTED
2753
- });
2754
- }
2755
- static methodUnsupported(context) {
2756
- const location = context.node ? ParameterError$1.getCurrentLocation(context.node) : void 0;
2757
- return new ParameterError$1({
2758
- message: `@${context.decoratorName}('${context.propertyName}') does not support method '${context.method}'${location ? ` at ${location}` : ""}.`,
2759
- code: ParameterErrorCode.METHOD_UNSUPPORTED
2760
- });
2761
- }
2762
- static invalidPathMatch(context) {
2763
- const location = context.node ? ParameterError$1.getCurrentLocation(context.node) : void 0;
2764
- return new ParameterError$1({
2765
- message: `@${context.decoratorName}('${context.propertyName}') does not exist in path '${context.path}'${location ? ` at ${location}` : ""}.`,
2766
- code: ParameterErrorCode.PATH_MISMATCH
2767
- });
2768
- }
2769
- static scopeRequired(context) {
2770
- const location = context.node ? ParameterError$1.getCurrentLocation(context.node) : void 0;
2771
- return new ParameterError$1({
2772
- message: `@${context.decoratorName}() requires a scope argument${location ? ` at ${location}` : ""}.`,
2773
- code: ParameterErrorCode.SCOPE_REQUIRED
2774
- });
2775
- }
2776
- static invalidExampleSchema() {
2777
- return new ParameterError$1({
2778
- message: "The @example JSDoc tag contains invalid JSON.",
2779
- code: ParameterErrorCode.INVALID_EXAMPLE
2780
- });
2781
- }
2782
- static getCurrentLocation(node) {
2783
- const parts = [];
2784
- if (isMethodDeclaration(node.parent)) {
2785
- parts.push(node.parent.name.getText());
2786
- if (isClassDeclaration(node.parent.parent)) parts.unshift(node.parent.parent.name.text);
2787
- }
2788
- return parts.join(".");
2789
- }
2790
- };
2791
- //#endregion
2792
1875
  //#region src/app/generator/parameter/module.ts
2793
1876
  const BODY_SUPPORTED_METHODS = new Set([
2794
1877
  "delete",
@@ -2798,16 +1881,16 @@ const BODY_SUPPORTED_METHODS = new Set([
2798
1881
  "get"
2799
1882
  ]);
2800
1883
  const SUPPORTED_LEAF_TYPES = new Set([
2801
- "string",
2802
- "integer",
2803
- "long",
2804
- "float",
2805
- "double",
2806
- "date",
2807
- "datetime",
2808
- "buffer",
2809
- "boolean",
2810
- "enum"
1884
+ TypeName.STRING,
1885
+ TypeName.INTEGER,
1886
+ TypeName.LONG,
1887
+ TypeName.FLOAT,
1888
+ TypeName.DOUBLE,
1889
+ TypeName.DATE,
1890
+ TypeName.DATETIME,
1891
+ TypeName.BUFFER,
1892
+ TypeName.BOOLEAN,
1893
+ TypeName.ENUM
2811
1894
  ]);
2812
1895
  var ParameterGenerator = class {
2813
1896
  parameter;
@@ -2841,7 +1924,7 @@ var ParameterGenerator = class {
2841
1924
  }
2842
1925
  Object.assign(draft.validators, getDeclarationValidators(this.parameter, parameterName));
2843
1926
  if (!draft.in) {
2844
- if (!BODY_SUPPORTED_METHODS.has(this.method)) throw ParameterError$1.methodUnsupported({
1927
+ if (!BODY_SUPPORTED_METHODS.has(this.method)) throw ParameterError.methodUnsupported({
2845
1928
  decoratorName: "Body",
2846
1929
  propertyName: parameterName,
2847
1930
  method: this.method,
@@ -2849,7 +1932,7 @@ var ParameterGenerator = class {
2849
1932
  });
2850
1933
  draft.in = ParamKind.Body;
2851
1934
  }
2852
- if ((draft.in === ParamKind.Body || draft.in === ParamKind.BodyProp) && !BODY_SUPPORTED_METHODS.has(this.method)) throw ParameterError$1.methodUnsupported({
1935
+ if ((draft.in === ParamKind.Body || draft.in === ParamKind.BodyProp) && !BODY_SUPPORTED_METHODS.has(this.method)) throw ParameterError.methodUnsupported({
2853
1936
  decoratorName: "Body",
2854
1937
  propertyName: draft.name,
2855
1938
  method: this.method,
@@ -2872,7 +1955,7 @@ var ParameterGenerator = class {
2872
1955
  return decomposed;
2873
1956
  }
2874
1957
  if ((kind === ParameterSource.QUERY || kind === ParameterSource.QUERY_PROP) && isArrayType(type)) {
2875
- if (!this.isLeafTypeSupported(type.elementType)) throw ParameterError$1.typeUnsupported({
1958
+ if (!this.isLeafTypeSupported(type.elementType)) throw ParameterError.typeUnsupported({
2876
1959
  decoratorName: kind === ParameterSource.QUERY ? "Query" : "QueryProp",
2877
1960
  propertyName: draft.name,
2878
1961
  type: type.elementType,
@@ -2884,7 +1967,7 @@ var ParameterGenerator = class {
2884
1967
  type
2885
1968
  }];
2886
1969
  }
2887
- if ((kind === ParameterSource.QUERY || kind === ParameterSource.QUERY_PROP) && !this.isLeafOrEnumOrUnion(type)) throw ParameterError$1.typeUnsupported({
1970
+ if ((kind === ParameterSource.QUERY || kind === ParameterSource.QUERY_PROP) && !this.isLeafOrEnumOrUnion(type)) throw ParameterError.typeUnsupported({
2888
1971
  decoratorName: kind === ParameterSource.QUERY ? "Query" : "QueryProp",
2889
1972
  propertyName: draft.name,
2890
1973
  type,
@@ -2950,7 +2033,7 @@ var ParameterGenerator = class {
2950
2033
  return false;
2951
2034
  }
2952
2035
  validatePathDecomposition(decomposed) {
2953
- for (const element of decomposed) if (!this.pathContainsParam(element.name)) throw ParameterError$1.invalidPathMatch({
2036
+ for (const element of decomposed) if (!this.pathContainsParam(element.name)) throw ParameterError.invalidPathMatch({
2954
2037
  decoratorName: "Path",
2955
2038
  propertyName: element.name,
2956
2039
  path: this.paths.join(" | "),
@@ -2959,7 +2042,7 @@ var ParameterGenerator = class {
2959
2042
  }
2960
2043
  validatePathName(name, parameterName) {
2961
2044
  const candidate = name || parameterName;
2962
- if (!this.pathContainsParam(candidate)) throw ParameterError$1.invalidPathMatch({
2045
+ if (!this.pathContainsParam(candidate)) throw ParameterError.invalidPathMatch({
2963
2046
  decoratorName: "Path",
2964
2047
  propertyName: candidate,
2965
2048
  path: this.paths.join(" | "),
@@ -2976,20 +2059,20 @@ var ParameterGenerator = class {
2976
2059
  let typeNode = this.parameter.type;
2977
2060
  if (!typeNode) {
2978
2061
  const t = this.current.typeChecker.getTypeAtLocation(this.parameter);
2979
- typeNode = this.current.typeChecker.typeToTypeNode(t, void 0, ts.NodeBuilderFlags.NoTruncation);
2062
+ typeNode = this.current.typeChecker.typeToTypeNode(t, void 0, NodeBuilderFlags.NoTruncation);
2980
2063
  }
2981
- if (!typeNode) throw new ParameterError$1({ message: `Could not resolve type for parameter '${this.getParameterName()}'.` });
2064
+ if (!typeNode) throw new ParameterError({ message: `Could not resolve type for parameter '${this.getParameterName()}'.` });
2982
2065
  return new TypeNodeResolver(typeNode, this.current, this.parameter).resolve();
2983
2066
  }
2984
2067
  getParameterName() {
2985
- if (!ts.isIdentifier(this.parameter.name)) throw new ParameterError$1({ message: "Destructured parameters are not supported. Use a simple identifier name." });
2068
+ if (!isIdentifier(this.parameter.name)) throw new ParameterError({ message: "Destructured parameters are not supported. Use a simple identifier name." });
2986
2069
  return this.parameter.name.text;
2987
2070
  }
2988
2071
  getDescription() {
2989
2072
  const symbol = this.current.typeChecker.getSymbolAtLocation(this.parameter.name);
2990
2073
  if (symbol) {
2991
2074
  const comments = symbol.getDocumentationComment(this.current.typeChecker);
2992
- if (comments.length > 0) return ts.displayPartsToString(comments);
2075
+ if (comments.length > 0) return displayPartsToString(comments);
2993
2076
  }
2994
2077
  return "";
2995
2078
  }
@@ -3014,7 +2097,7 @@ var ParameterGenerator = class {
3014
2097
  exampleLabels
3015
2098
  };
3016
2099
  } catch {
3017
- throw ParameterError$1.invalidExampleSchema();
2100
+ throw ParameterError.invalidExampleSchema();
3018
2101
  }
3019
2102
  }
3020
2103
  applyOptions(parameterName) {
@@ -3114,19 +2197,19 @@ var MethodGenerator = class {
3114
2197
  }
3115
2198
  } catch (e) {
3116
2199
  const causeMsg = e instanceof Error ? `: ${e.message}` : "";
3117
- throw new GeneratorError$1({
2200
+ throw new GeneratorError({
3118
2201
  message: `Parameter generation failed for '${controllerId.text}.${methodId.text}' argument index ${i}${causeMsg}`,
3119
- code: GeneratorErrorCode$1.PARAMETER_GENERATION_FAILED,
2202
+ code: GeneratorErrorCode.PARAMETER_GENERATION_FAILED,
3120
2203
  cause: e
3121
2204
  });
3122
2205
  }
3123
- if (bodyParameterCount > 1) throw new GeneratorError$1({
2206
+ if (bodyParameterCount > 1) throw new GeneratorError({
3124
2207
  message: `Only one body parameter allowed in '${controllerId.text}.${methodId.text}' method.`,
3125
- code: GeneratorErrorCode$1.BODY_PARAMETER_DUPLICATE
2208
+ code: GeneratorErrorCode.BODY_PARAMETER_DUPLICATE
3126
2209
  });
3127
- if (bodyParameterCount > 0 && formParameterCount > 0) throw new GeneratorError$1({
2210
+ if (bodyParameterCount > 0 && formParameterCount > 0) throw new GeneratorError({
3128
2211
  message: `Cannot mix body and form parameters in '${controllerId.text}.${methodId.text}' method.`,
3129
- code: GeneratorErrorCode$1.BODY_FORM_CONFLICT
2212
+ code: GeneratorErrorCode.BODY_FORM_CONFLICT
3130
2213
  });
3131
2214
  return output;
3132
2215
  }
@@ -3164,13 +2247,13 @@ var ControllerGenerator = class {
3164
2247
  return !!this.node.name;
3165
2248
  }
3166
2249
  generate() {
3167
- if (!this.node.parent) throw new GeneratorError$1({
2250
+ if (!this.node.parent) throw new GeneratorError({
3168
2251
  message: "Controller node doesn't have a valid parent source file.",
3169
- code: GeneratorErrorCode$1.CONTROLLER_NO_SOURCE_FILE
2252
+ code: GeneratorErrorCode.CONTROLLER_NO_SOURCE_FILE
3170
2253
  });
3171
- if (!this.node.name) throw new GeneratorError$1({
2254
+ if (!this.node.name) throw new GeneratorError({
3172
2255
  message: "Controller node doesn't have a valid name.",
3173
- code: GeneratorErrorCode$1.CONTROLLER_NO_NAME
2256
+ code: GeneratorErrorCode.CONTROLLER_NO_NAME
3174
2257
  });
3175
2258
  const sourceFile = this.node.parent.getSourceFile();
3176
2259
  const draft = newControllerDraft({
@@ -3232,7 +2315,7 @@ var ControllerGenerator = class {
3232
2315
  set.add(methodName);
3233
2316
  output.push(method);
3234
2317
  } catch (error) {
3235
- if (isResolverError$1(error) || isGeneratorError$1(error) && error.code === GeneratorErrorCode$1.PARAMETER_GENERATION_FAILED) continue;
2318
+ if (isResolverError(error) || isGeneratorError(error) && error.code === GeneratorErrorCode.PARAMETER_GENERATION_FAILED) continue;
3236
2319
  throw error;
3237
2320
  }
3238
2321
  }
@@ -3287,13 +2370,24 @@ var MetadataGenerator = class {
3287
2370
  }
3288
2371
  async generate() {
3289
2372
  const sourceFilesHash = this.buildNodesFromSourceFiles();
3290
- if (this.config.preset) this.registry = await loadRegistryByName(this.config.preset);
2373
+ let presetRegistry;
2374
+ let presetName;
2375
+ if (typeof this.config.preset === "string") {
2376
+ presetName = this.config.preset;
2377
+ presetRegistry = await loadRegistryByName(this.config.preset);
2378
+ } else if (this.config.preset) {
2379
+ presetName = this.config.preset.name;
2380
+ presetRegistry = await loadRegistry(this.config.preset, { resolver: resolvePresetByName });
2381
+ }
2382
+ if (presetRegistry && this.config.registry) this.registry = mergeRegistries(presetRegistry, this.config.registry);
2383
+ else if (presetRegistry) this.registry = presetRegistry;
2384
+ else if (this.config.registry) this.registry = this.config.registry;
3291
2385
  const cacheKey = composeCacheKey({
3292
2386
  schemaVersion: "3",
3293
2387
  sourceFilesHash,
3294
2388
  compilerOptionsHash: hashCompilerOptions(this.program.getCompilerOptions()),
3295
2389
  registryHash: hashRegistry(this.registry),
3296
- presetName: this.config.preset
2390
+ presetName
3297
2391
  });
3298
2392
  const bypassCache = !!(this.config.strict || this.config.onUnmatchedDecorator);
3299
2393
  let cache = bypassCache ? void 0 : await this.cache.get(cacheKey);
@@ -3316,10 +2410,10 @@ var MetadataGenerator = class {
3316
2410
  };
3317
2411
  }
3318
2412
  assertPresetProducedControllers() {
3319
- if (this.config.preset || this.controllers.length > 0) return;
2413
+ if (this.config.preset || this.config.registry || this.controllers.length > 0) return;
3320
2414
  if (this.nodes.length === 0) return;
3321
2415
  throw new ConfigError({
3322
- message: "No preset configured and no controllers detected. Provide `preset: '@trapi/preset-decorators-express'` (or another preset) so handlers can match your decorators.",
2416
+ message: "No preset or registry configured and no controllers detected. Provide `preset: '@trapi/preset-decorators-express'` (or another preset), or pass an inline `registry`, so handlers can match your decorators.",
3323
2417
  code: ConfigErrorCode.PRESET_MISSING
3324
2418
  });
3325
2419
  }
@@ -3341,9 +2435,9 @@ var MetadataGenerator = class {
3341
2435
  return;
3342
2436
  }
3343
2437
  const summary = this.formatUnmatchedSummary();
3344
- if (this.config.strict === "throw") throw new GeneratorError$1({
2438
+ if (this.config.strict === "throw") throw new GeneratorError({
3345
2439
  message: summary,
3346
- code: GeneratorErrorCode$1.STRICT_UNMATCHED_DECORATORS
2440
+ code: GeneratorErrorCode.STRICT_UNMATCHED_DECORATORS
3347
2441
  });
3348
2442
  console.warn(summary);
3349
2443
  }
@@ -3431,11 +2525,6 @@ var MetadataGenerator = class {
3431
2525
  }
3432
2526
  };
3433
2527
  //#endregion
3434
- //#region src/app/generator/metadata/utils.ts
3435
- function isMetadata(input) {
3436
- return isObject(input) && hasOwnProperty$1(input, "controllers") && Array.isArray(input.controllers) && hasOwnProperty$1(input, "referenceTypes") && isObject(input.referenceTypes);
3437
- }
3438
- //#endregion
3439
2528
  //#region src/app/generate.ts
3440
2529
  async function generateMetadata(options) {
3441
2530
  let compilerOptions;
@@ -3453,6 +2542,6 @@ async function generateMetadata(options) {
3453
2542
  }).generate();
3454
2543
  }
3455
2544
  //#endregion
3456
- export { CACHE_DEFAULT_MAX_AGE_MS, CACHE_FILE_PREFIX, CACHE_FILE_SUFFIX, CACHE_SCHEMA_VERSION, CacheClient, CollectionFormat, CollectionKind, ConfigError, ConfigErrorCode, ControllerGenerator, DecoratorArgumentKindName, DecoratorTargetKind, GeneratorError, GeneratorErrorCode, JSDocTagName, MarkerName, MetadataError, MetadataGenerator, MethodGenerator, MethodName, NumericKind, ParamKind, ParameterError, ParameterErrorCode, ParameterGenerator, ParameterSource, PrimitiveResolver, ReferenceResolver, ResolverBase, ResolverCache, ResolverError, TypeName, TypeNodeResolver, UtilityTypeName, ValidatorError, ValidatorErrorCode, ValidatorName, append, applyDecoratorHandlers, applyJsDocHandlers, arrayArg, buildCacheOptions, buildDecoratorArgument, buildDecoratorSources, buildHandlerContext, buildJsDocHandlerContext, buildJsDocSources, composeCacheKey, controller, controllerHandlerSchema, controllerJsDoc, controllerJsDocHandlerSchema, createHandlerContext, createPresetContainer, createRegistry, findDecoratorByName, findDecoratorsByName, flag, generateMetadata, generatePresetLookupPaths, getDeclarationValidators, getInitializerValue, getJSDoc, getJSDocDescription, getJSDocTagComment, getJSDocTagNames, getJSDocTags, getLiteralValue, getNodeDecorators, getNodeDescription, getNodeExtensions, hasDecoratorNamed, hasInitializer, hasJSDocTag, hasOwnProperty, hashCompilerOptions, hashRegistry, identifierArg, into, isAnyType, isArrayType, isBigintType, isBinaryType, isBooleanType, isBufferType, isByteType, isDateTimeType, isDateType, isDeprecatedMarker, isDoubleType, isEnumType, isExtensionMarker, isFileType, isFloatType, isGeneratorError, isHiddenMarker, isIntegerType, isIntersectionType, isLongType, isMetadata, isNestedObjectLiteralType, isNeverType, isObjectType, isPrimitiveType, isRefAliasType, isRefEnumType, isRefObjectType, isReferenceType, isResolverError, isStringArray, isStringType, isTupleType, isUndefinedType, isUnionType, isVoidType, jsDocMatchSchema, literalArg, loadRegistry, loadRegistryByName, loadTSConfig, matchSchema, matches, matchesJsDoc, method, methodHandlerSchema, methodJsDoc, methodJsDocHandlerSchema, namesForMarker, newControllerDraft, newMethodDraft, newParameterDraft, normalizePath, numericMarkerKind, objectArg, parameter, parameterHandlerSchema, parameterJsDoc, parameterJsDocHandlerSchema, presetSchema, prettyLocationOfNode, prettyTroubleCause, readBoolean, readNodeDecorators, readNumber, readString, readStringOrStringArray, resolveArrayType, resolveIndexedAccessType, resolveIntersectionType, resolveLiteralType, resolveMappedType, resolveObjectLiteralType, resolvePresetByName, resolveTupleType, resolveTypeOperatorType, resolveUnionType, scanSourceFiles, setControllerPaths, setMethodPath, softLoadTsconfig, tagsForMarker, toTypeNodeOrFail, transformJSDocComment, typeArg, unresolvableArg, validatePreset };
2545
+ export { CACHE_DEFAULT_MAX_AGE_MS, CACHE_FILE_PREFIX, CACHE_FILE_SUFFIX, CACHE_SCHEMA_VERSION, CacheClient, ConfigError, ConfigErrorCode, ControllerGenerator, GeneratorError, GeneratorErrorCode, JSDocTagName, MetadataError, MetadataGenerator, MethodGenerator, ParameterError, ParameterErrorCode, ParameterGenerator, PrimitiveResolver, ReferenceResolver, ResolverBase, ResolverCache, ResolverError, TypeNodeResolver, ValidatorError, ValidatorErrorCode, applyDecoratorHandlers, applyJsDocHandlers, buildCacheOptions, buildDecoratorArgument, buildDecoratorSources, buildHandlerContext, buildJsDocHandlerContext, buildJsDocSources, composeCacheKey, findDecoratorByName, findDecoratorsByName, generateMetadata, getDeclarationValidators, getInitializerValue, getJSDoc, getJSDocDescription, getJSDocTagComment, getJSDocTagNames, getJSDocTags, getLiteralValue, getNodeDecorators, getNodeDescription, getNodeExtensions, hasDecoratorNamed, hasInitializer, hasJSDocTag, hasOwnProperty, hashCompilerOptions, hashRegistry, isGeneratorError, isResolverError, isStringArray, loadTSConfig, normalizePath, prettyLocationOfNode, prettyTroubleCause, readNodeDecorators, resolveArrayType, resolveIndexedAccessType, resolveIntersectionType, resolveLiteralType, resolveMappedType, resolveObjectLiteralType, resolveTupleType, resolveTypeOperatorType, resolveUnionType, scanSourceFiles, softLoadTsconfig, toTypeNodeOrFail, transformJSDocComment };
3457
2546
 
3458
2547
  //# sourceMappingURL=index.mjs.map