nestjs-openapi-parser 0.0.1

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.
Files changed (44) hide show
  1. package/README.md +213 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +54 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/config/defaults.d.ts +5 -0
  6. package/dist/config/defaults.js +14 -0
  7. package/dist/config/defaults.js.map +1 -0
  8. package/dist/config/index.d.ts +4 -0
  9. package/dist/config/index.js +24 -0
  10. package/dist/config/index.js.map +1 -0
  11. package/dist/config/loader.d.ts +11 -0
  12. package/dist/config/loader.js +160 -0
  13. package/dist/config/loader.js.map +1 -0
  14. package/dist/config/types.d.ts +139 -0
  15. package/dist/config/types.js +8 -0
  16. package/dist/config/types.js.map +1 -0
  17. package/dist/lib.d.ts +12 -0
  18. package/dist/lib.js +22 -0
  19. package/dist/lib.js.map +1 -0
  20. package/dist/parser/ast-index.d.ts +38 -0
  21. package/dist/parser/ast-index.js +124 -0
  22. package/dist/parser/ast-index.js.map +1 -0
  23. package/dist/parser/index.d.ts +20 -0
  24. package/dist/parser/index.js +95 -0
  25. package/dist/parser/index.js.map +1 -0
  26. package/dist/parser/path-builder.d.ts +87 -0
  27. package/dist/parser/path-builder.js +464 -0
  28. package/dist/parser/path-builder.js.map +1 -0
  29. package/dist/parser/schema-builder.d.ts +70 -0
  30. package/dist/parser/schema-builder.js +355 -0
  31. package/dist/parser/schema-builder.js.map +1 -0
  32. package/dist/parser/tags.d.ts +61 -0
  33. package/dist/parser/tags.js +163 -0
  34. package/dist/parser/tags.js.map +1 -0
  35. package/dist/types/openapi.d.ts +42 -0
  36. package/dist/types/openapi.js +3 -0
  37. package/dist/types/openapi.js.map +1 -0
  38. package/dist/validate.d.ts +13 -0
  39. package/dist/validate.js +30 -0
  40. package/dist/validate.js.map +1 -0
  41. package/docs/configuration.md +195 -0
  42. package/docs/library-usage.md +40 -0
  43. package/docs/parser.md +148 -0
  44. package/package.json +54 -0
@@ -0,0 +1,464 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PathBuilder = void 0;
4
+ const ts_morph_1 = require("ts-morph");
5
+ const ast_index_1 = require("./ast-index");
6
+ const tags_1 = require("./tags");
7
+ const HTTP_METHODS = {
8
+ Get: 'get',
9
+ Post: 'post',
10
+ Put: 'put',
11
+ Delete: 'delete',
12
+ Patch: 'patch',
13
+ };
14
+ // NestJS's `HttpStatus` enum (from `@nestjs/common`) member name → numeric code.
15
+ // Used to resolve `@HttpCode(HttpStatus.NO_CONTENT)` statically, since we can't
16
+ // import `@nestjs/common` to read the value at runtime.
17
+ const HTTP_STATUS_CODES = {
18
+ CONTINUE: 100,
19
+ SWITCHING_PROTOCOLS: 101,
20
+ PROCESSING: 102,
21
+ EARLYHINTS: 103,
22
+ OK: 200,
23
+ CREATED: 201,
24
+ ACCEPTED: 202,
25
+ NON_AUTHORITATIVE_INFORMATION: 203,
26
+ NO_CONTENT: 204,
27
+ RESET_CONTENT: 205,
28
+ PARTIAL_CONTENT: 206,
29
+ AMBIGUOUS: 300,
30
+ MOVED_PERMANENTLY: 301,
31
+ FOUND: 302,
32
+ SEE_OTHER: 303,
33
+ NOT_MODIFIED: 304,
34
+ TEMPORARY_REDIRECT: 307,
35
+ PERMANENT_REDIRECT: 308,
36
+ BAD_REQUEST: 400,
37
+ UNAUTHORIZED: 401,
38
+ PAYMENT_REQUIRED: 402,
39
+ FORBIDDEN: 403,
40
+ NOT_FOUND: 404,
41
+ METHOD_NOT_ALLOWED: 405,
42
+ NOT_ACCEPTABLE: 406,
43
+ PROXY_AUTHENTICATION_REQUIRED: 407,
44
+ REQUEST_TIMEOUT: 408,
45
+ CONFLICT: 409,
46
+ GONE: 410,
47
+ LENGTH_REQUIRED: 411,
48
+ PRECONDITION_FAILED: 412,
49
+ PAYLOAD_TOO_LARGE: 413,
50
+ URI_TOO_LONG: 414,
51
+ UNSUPPORTED_MEDIA_TYPE: 415,
52
+ REQUESTED_RANGE_NOT_SATISFIABLE: 416,
53
+ EXPECTATION_FAILED: 417,
54
+ I_AM_A_TEAPOT: 418,
55
+ MISDIRECTED: 421,
56
+ UNPROCESSABLE_ENTITY: 422,
57
+ FAILED_DEPENDENCY: 424,
58
+ PRECONDITION_REQUIRED: 428,
59
+ TOO_MANY_REQUESTS: 429,
60
+ INTERNAL_SERVER_ERROR: 500,
61
+ NOT_IMPLEMENTED: 501,
62
+ BAD_GATEWAY: 502,
63
+ SERVICE_UNAVAILABLE: 503,
64
+ GATEWAY_TIMEOUT: 504,
65
+ HTTP_VERSION_NOT_SUPPORTED: 505,
66
+ };
67
+ /** Humanize a method name: split camelCase/PascalCase boundaries and capitalize. */
68
+ function humanizeMethodName(name) {
69
+ const spaced = name
70
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
71
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2');
72
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1);
73
+ }
74
+ /**
75
+ * Converts NestJS controllers into the OpenAPI `paths` object by static analysis:
76
+ * `@Controller` + HTTP route decorators, `@Param/@Query/@Body/@Headers`, method
77
+ * return types, and pluggable hooks for response envelope and security.
78
+ */
79
+ class PathBuilder {
80
+ index;
81
+ schemaBuilder;
82
+ paths = {};
83
+ usedOperationIds = new Set();
84
+ tags = new Map();
85
+ /** Distinct method-level `@Tag` names seen, declared in root after controllers. */
86
+ methodTagNames = new Set();
87
+ globalPrefix;
88
+ hooks;
89
+ registeredSchemes;
90
+ activeScopes;
91
+ knownScopes;
92
+ constructor(index, schemaBuilder, options = {}) {
93
+ this.index = index;
94
+ this.schemaBuilder = schemaBuilder;
95
+ this.globalPrefix = options.globalPrefix ?? '';
96
+ this.hooks = options.hooks ?? {};
97
+ this.registeredSchemes = options.registeredSchemes ?? [];
98
+ this.activeScopes = options.activeScopes ?? new Set();
99
+ this.knownScopes = options.knownScopes;
100
+ }
101
+ build() {
102
+ for (const controller of this.index.getControllers()) {
103
+ this.processController(controller);
104
+ }
105
+ // Declare any method-level @Tag name no controller already declared, so the
106
+ // operation's tag isn't dangling. Done after all controllers so a controller's
107
+ // description always wins over a description-less method-tag placeholder.
108
+ for (const name of this.methodTagNames) {
109
+ if (!this.tags.has(name))
110
+ this.tags.set(name, undefined);
111
+ }
112
+ return this.paths;
113
+ }
114
+ /**
115
+ * Root `tags[]` entries: one per distinct tag name in play. Controller tags
116
+ * (name from `@Tag`/the default-tag hook, description from the class JSDoc;
117
+ * first controller wins on a shared name) come first, then any method-level
118
+ * `@Tag` name a controller didn't already declare — description-less, since a
119
+ * method's JSDoc is its operation description, not a tag description.
120
+ */
121
+ getTags() {
122
+ return [...this.tags.entries()].map(([name, description]) => description ? { name, description } : { name });
123
+ }
124
+ processController(controller) {
125
+ if (!(0, tags_1.isVisible)((0, tags_1.getScopes)((0, tags_1.getTags)(controller)), this.activeScopes))
126
+ return;
127
+ // @Controller and the route decorators each accept `string | string[]`; an
128
+ // array prefix/path means the handler is mapped to several routes at once.
129
+ const basePathArgs = this.stringArgs(controller.getDecorator('Controller'), 0);
130
+ const basePaths = basePathArgs.length ? basePathArgs : [''];
131
+ const controllerTagBag = (0, tags_1.getTags)(controller);
132
+ const tag = controllerTagBag.Tag?.[0] ?? (this.hooks.controllerTag ?? this.defaultTag)(controller);
133
+ if (!this.tags.has(tag)) {
134
+ const rawDesc = controller.getJsDocs()[0]?.getCommentText();
135
+ const desc = rawDesc
136
+ ? (0, tags_1.filterScopedComments)(rawDesc, this.activeScopes, {
137
+ itemPath: `${controller.getName() ?? '<anon>'} (tag)`,
138
+ knownScopes: this.knownScopes,
139
+ })
140
+ : undefined;
141
+ this.tags.set(tag, desc || undefined);
142
+ }
143
+ for (const method of controller.getInstanceMethods()) {
144
+ if (!(0, tags_1.isVisible)((0, tags_1.getScopes)((0, tags_1.getTags)(method)), this.activeScopes))
145
+ continue;
146
+ const httpDecorator = method.getDecorators().find((d) => HTTP_METHODS[d.getName()]);
147
+ if (!httpDecorator)
148
+ continue;
149
+ const httpMethod = HTTP_METHODS[httpDecorator.getName()];
150
+ const routeArgs = this.stringArgs(httpDecorator, 0);
151
+ const routePaths = routeArgs.length ? routeArgs : [''];
152
+ const methodTag = (0, tags_1.getTags)(method).Tag?.[0] ?? tag;
153
+ // One operation per (controller prefix × route path × optional-param
154
+ // expansion) combination. Each gets its own operationId (uniqueOperationId
155
+ // de-dups) and its own path params, since placeholders can differ per path.
156
+ for (const base of basePaths) {
157
+ for (const route of routePaths) {
158
+ const rawPath = this.joinPath(this.globalPrefix, base, route);
159
+ for (const fullPath of this.expandRoutePaths(rawPath, controller, method)) {
160
+ this.methodTagNames.add(methodTag);
161
+ const templateParams = this.pathParamNames(fullPath);
162
+ const operation = this.buildOperation(controller, method, httpMethod, methodTag, templateParams);
163
+ this.paths[fullPath] ??= {};
164
+ this.paths[fullPath][httpMethod] = operation;
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+ buildOperation(controller, method, httpMethod, tag, pathParamNames) {
171
+ const operation = {
172
+ operationId: this.uniqueOperationId(tag, method.getName()),
173
+ tags: [tag],
174
+ };
175
+ const summary = this.resolveSummary(controller, method, httpMethod);
176
+ if (summary)
177
+ operation.summary = summary;
178
+ const rawDesc = method.getJsDocs()[0]?.getCommentText();
179
+ const desc = rawDesc
180
+ ? (0, tags_1.filterScopedComments)(rawDesc, this.activeScopes, {
181
+ itemPath: `${controller.getName() ?? '<anon>'}.${method.getName()}`,
182
+ knownScopes: this.knownScopes,
183
+ })
184
+ : undefined;
185
+ if (desc)
186
+ operation.description = desc;
187
+ // Collect explicit @Param('name') schemas keyed by name, plus query/header
188
+ // params in declaration order. Path params are emitted from the route
189
+ // template below, not from this loop, so the spec can never reference a
190
+ // `{param}` that has no parameter object.
191
+ const explicitPathParams = new Map();
192
+ const otherParameters = [];
193
+ let requestBody;
194
+ for (const param of method.getParameters()) {
195
+ const decorator = param
196
+ .getDecorators()
197
+ .find((d) => ['Param', 'Query', 'Body', 'Headers'].includes(d.getName()));
198
+ if (!decorator)
199
+ continue;
200
+ switch (decorator.getName()) {
201
+ case 'Param': {
202
+ const name = this.stringArg(decorator, 0);
203
+ // A @Param('name') whose name isn't in the route template can't be a
204
+ // valid path parameter, so it's recorded here and only used if the
205
+ // template actually declares it.
206
+ if (name)
207
+ explicitPathParams.set(name, this.paramSchema(decorator, param));
208
+ break;
209
+ }
210
+ case 'Query':
211
+ otherParameters.push(...this.buildQueryParameters(decorator, param));
212
+ break;
213
+ case 'Headers': {
214
+ const headerName = this.stringArg(decorator, 0);
215
+ if (headerName) {
216
+ otherParameters.push({
217
+ name: headerName,
218
+ in: 'header',
219
+ required: false,
220
+ schema: { type: 'string' },
221
+ });
222
+ }
223
+ break;
224
+ }
225
+ case 'Body':
226
+ requestBody = this.buildRequestBody(param);
227
+ break;
228
+ }
229
+ }
230
+ // Every `{param}` in the route template must have a path-parameter entry, in
231
+ // template order — even when the handler never binds it with @Param('name')
232
+ // (e.g. it uses `@Param() all`, `@Req()`, or the name simply doesn't match).
233
+ // Such placeholders default to `string`.
234
+ const parameters = pathParamNames.map((name) => ({
235
+ name,
236
+ in: 'path',
237
+ required: true,
238
+ schema: explicitPathParams.get(name) ?? { type: 'string' },
239
+ }));
240
+ parameters.push(...otherParameters);
241
+ if (parameters.length)
242
+ operation.parameters = parameters;
243
+ if (requestBody)
244
+ operation.requestBody = requestBody;
245
+ operation.responses = this.buildResponses(method, httpMethod);
246
+ const security = this.buildSecurity(controller, method);
247
+ if (security !== undefined)
248
+ operation.security = security;
249
+ return operation;
250
+ }
251
+ /**
252
+ * The operation `summary`: a method-level `@Name` JSDoc tag (highest priority),
253
+ * else the `endpointSummary` hook when it returns a value, else the default —
254
+ * the method name humanized.
255
+ */
256
+ resolveSummary(controller, method, httpMethod) {
257
+ const named = (0, tags_1.getTags)(method).Name?.[0];
258
+ if (named)
259
+ return named;
260
+ const defaultSummary = humanizeMethodName(method.getName());
261
+ return (this.hooks.endpointSummary?.({ controller, method, httpMethod, defaultSummary }) ??
262
+ defaultSummary);
263
+ }
264
+ buildQueryParameters(decorator, param) {
265
+ const argName = this.stringArg(decorator, 0);
266
+ if (argName) {
267
+ return [
268
+ { name: argName, in: 'query', required: false, schema: this.paramSchema(decorator, param) },
269
+ ];
270
+ }
271
+ // `@Query() dto: SomeDTO` -> expand DTO properties into individual query params.
272
+ const className = ast_index_1.AstIndex.symbolName(param.getType());
273
+ const clazz = className ? this.index.getClass(className) : undefined;
274
+ if (!clazz)
275
+ return [];
276
+ const members = this.schemaBuilder.buildMembers(clazz);
277
+ return Object.entries(members.properties).map(([name, schema]) => ({
278
+ name,
279
+ in: 'query',
280
+ required: members.required.includes(name),
281
+ schema,
282
+ }));
283
+ }
284
+ buildRequestBody(param) {
285
+ const schema = this.schemaBuilder.typeToSchema(param.getType());
286
+ return { required: true, content: { 'application/json': { schema } } };
287
+ }
288
+ buildResponses(method, httpMethod) {
289
+ let returnType = method.getReturnType();
290
+ if (ast_index_1.AstIndex.symbolName(returnType) === 'Promise') {
291
+ const args = returnType.getTypeArguments();
292
+ if (args.length)
293
+ returnType = args[0];
294
+ }
295
+ const responseSchema = this.computeResponseSchema(method, returnType);
296
+ const status = this.responseStatus(method, httpMethod);
297
+ const response = { description: 'Successful response' };
298
+ if (responseSchema !== undefined) {
299
+ response.content = { 'application/json': { schema: responseSchema } };
300
+ }
301
+ return { [status]: response };
302
+ }
303
+ /**
304
+ * The success status code for an operation: an explicit `@HttpCode(...)` when
305
+ * present — either a numeric literal (`@HttpCode(204)`) or an `HttpStatus`
306
+ * member (`@HttpCode(HttpStatus.NO_CONTENT)`) — otherwise NestJS's default:
307
+ * 201 for POST, 200 for every other verb.
308
+ */
309
+ responseStatus(method, httpMethod) {
310
+ const arg = method.getDecorator('HttpCode')?.getArguments()[0];
311
+ if (arg) {
312
+ if (ts_morph_1.Node.isNumericLiteral(arg))
313
+ return String(arg.getLiteralValue());
314
+ if (ts_morph_1.Node.isPropertyAccessExpression(arg)) {
315
+ const code = HTTP_STATUS_CODES[arg.getName()];
316
+ if (code !== undefined)
317
+ return String(code);
318
+ }
319
+ }
320
+ return httpMethod === 'post' ? '201' : '200';
321
+ }
322
+ computeResponseSchema(method, returnType) {
323
+ const isEmpty = returnType.isVoid() || returnType.isUndefined();
324
+ if (!this.hooks.buildResponseSchema) {
325
+ return isEmpty ? undefined : this.schemaBuilder.typeToSchema(returnType);
326
+ }
327
+ return this.hooks.buildResponseSchema({
328
+ method,
329
+ returnType,
330
+ returnTypeName: ast_index_1.AstIndex.symbolName(returnType),
331
+ returnTypeArgs: returnType.getTypeArguments(),
332
+ defaultSchema: () => (isEmpty ? {} : this.schemaBuilder.typeToSchema(returnType)),
333
+ typeToSchema: (t) => this.schemaBuilder.typeToSchema(t),
334
+ });
335
+ }
336
+ buildSecurity(controller, method) {
337
+ if (this.hooks.resolveSecurity) {
338
+ return this.hooks.resolveSecurity({
339
+ controller,
340
+ method,
341
+ registeredSchemes: this.registeredSchemes,
342
+ });
343
+ }
344
+ // Default: every registered scheme applies (logical OR).
345
+ if (this.registeredSchemes.length === 0)
346
+ return undefined;
347
+ return this.registeredSchemes.map((name) => ({ [name]: [] }));
348
+ }
349
+ paramSchema(decorator, param) {
350
+ const argsText = decorator
351
+ .getArguments()
352
+ .map((a) => a.getText())
353
+ .join(' ');
354
+ if (argsText.includes('ParseUUIDPipe'))
355
+ return { type: 'string', format: 'uuid' };
356
+ if (argsText.includes('ParseIntPipe'))
357
+ return { type: 'integer' };
358
+ if (argsText.includes('ParseBoolPipe'))
359
+ return { type: 'boolean' };
360
+ return this.schemaBuilder.typeToSchema(param.getType());
361
+ }
362
+ stringArg(decorator, index) {
363
+ if (!decorator)
364
+ return undefined;
365
+ const arg = decorator.getArguments()[index];
366
+ return arg && ts_morph_1.Node.isStringLiteral(arg) ? arg.getLiteralValue() : undefined;
367
+ }
368
+ /**
369
+ * Read a decorator argument that may be a string literal or an array of string
370
+ * literals (`@Get('a')` or `@Get(['a', 'b'])`), returning the distinct values.
371
+ * Non-string and dynamic entries are skipped; the result is empty when absent.
372
+ */
373
+ stringArgs(decorator, index) {
374
+ if (!decorator)
375
+ return [];
376
+ const arg = decorator.getArguments()[index];
377
+ if (!arg)
378
+ return [];
379
+ let values = [];
380
+ if (ts_morph_1.Node.isStringLiteral(arg)) {
381
+ values = [arg.getLiteralValue()];
382
+ }
383
+ else if (ts_morph_1.Node.isArrayLiteralExpression(arg)) {
384
+ values = arg
385
+ .getElements()
386
+ .filter(ts_morph_1.Node.isStringLiteral)
387
+ .map((el) => el.getLiteralValue());
388
+ }
389
+ return [...new Set(values)];
390
+ }
391
+ defaultTag(controller) {
392
+ const base = (controller.getName() ?? 'Default').replace(/Controller$/, '');
393
+ return base.replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2');
394
+ }
395
+ uniqueOperationId(tag, methodName) {
396
+ const base = `${tag.replace(/\s+/g, '')}_${methodName}`;
397
+ let id = base;
398
+ let counter = 2;
399
+ while (this.usedOperationIds.has(id))
400
+ id = `${base}_${counter++}`;
401
+ this.usedOperationIds.add(id);
402
+ return id;
403
+ }
404
+ joinPath(...parts) {
405
+ return ('/' + parts.filter(Boolean).join('/')).replace(/\/{2,}/g, '/');
406
+ }
407
+ /**
408
+ * Turn a raw NestJS route (with `:params`) into the OpenAPI path(s) it maps to.
409
+ *
410
+ * - An optional param (`:id?`) expands into the with/without pair, because
411
+ * OpenAPI path params are always required (`a/:id?` → `/a` and `/a/{id}`).
412
+ * - Constructs OpenAPI can't represent — inline regex (`:id(\d+)`), wildcards
413
+ * (`*`, `:splat*`), `+`/`*` modifiers, and more than one optional param —
414
+ * cause the route to be skipped with a warning.
415
+ */
416
+ expandRoutePaths(rawPath, controller, method) {
417
+ const where = () => `${controller.getName() ?? '<anon>'}.${method.getName()}`;
418
+ const skip = (reason) => {
419
+ console.warn(`[nestparser] Skipping route "${rawPath}" (${where()}): ${reason}`);
420
+ return [];
421
+ };
422
+ if (/[*+()]/.test(rawPath)) {
423
+ return skip("unsupported path pattern (regex, wildcard or modifier). Only ':param' and optional ':param?' are handled.");
424
+ }
425
+ const segments = rawPath.split('/').filter(Boolean);
426
+ const optionalIdx = segments.flatMap((s, i) => (/^:[A-Za-z0-9_]+\?$/.test(s) ? [i] : []));
427
+ if (optionalIdx.length > 1) {
428
+ return skip("more than one optional ':param?' in a route is not supported.");
429
+ }
430
+ if (optionalIdx.length === 0) {
431
+ return [this.toOpenApiPath('/' + segments.join('/'))];
432
+ }
433
+ // Exactly one optional: emit the route without that segment, and with it
434
+ // present (the trailing `?` dropped so it's a normal required param).
435
+ const i = optionalIdx[0];
436
+ const without = segments.filter((_, idx) => idx !== i);
437
+ const present = segments.map((s, idx) => (idx === i ? s.slice(0, -1) : s));
438
+ return [
439
+ this.toOpenApiPath('/' + without.join('/')),
440
+ this.toOpenApiPath('/' + present.join('/')),
441
+ ];
442
+ }
443
+ toOpenApiPath(routePath) {
444
+ let out = routePath.replace(/:([A-Za-z0-9_]+)/g, '{$1}');
445
+ if (out.length > 1 && out.endsWith('/'))
446
+ out = out.slice(0, -1);
447
+ return out;
448
+ }
449
+ /** Names of the `{param}` placeholders in an OpenAPI path, in order, deduped. */
450
+ pathParamNames(openApiPath) {
451
+ const names = [];
452
+ const seen = new Set();
453
+ for (const match of openApiPath.matchAll(/\{([^}]+)\}/g)) {
454
+ const name = match[1];
455
+ if (!seen.has(name)) {
456
+ seen.add(name);
457
+ names.push(name);
458
+ }
459
+ }
460
+ return names;
461
+ }
462
+ }
463
+ exports.PathBuilder = PathBuilder;
464
+ //# sourceMappingURL=path-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-builder.js","sourceRoot":"","sources":["../../src/parser/path-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import { ClassDeclaration, Type } from 'ts-morph';
2
+ import type { OpenApiSchema } from '../types/openapi';
3
+ import { AstIndex } from './ast-index';
4
+ export interface SchemaBuilderOptions {
5
+ activeScopes?: Set<string>;
6
+ /** Scope vocabulary used to recognize `<scope>…</scope>` description fragments. */
7
+ knownScopes?: Set<string>;
8
+ }
9
+ export interface SchemaMembers {
10
+ properties: Record<string, OpenApiSchema>;
11
+ required: string[];
12
+ }
13
+ /**
14
+ * Converts TypeScript classes (entities & DTOs) into OpenAPI `components.schemas`.
15
+ * Handles:
16
+ * - required derived from `@IsOptional()` / `?` (configurable)
17
+ * - `@Exclude()` properties omitted (configurable)
18
+ * - union object types -> `oneOf`, string-literal unions -> enum
19
+ * - `PartialType / PickType / OmitType / IntersectionType` heritage
20
+ */
21
+ export declare class SchemaBuilder {
22
+ private readonly index;
23
+ private readonly schemas;
24
+ private readonly pending;
25
+ private readonly done;
26
+ private readonly activeScopes;
27
+ private readonly knownScopes;
28
+ constructor(index: AstIndex, options?: SchemaBuilderOptions);
29
+ /** Register a reference to a class schema and return the `$ref` fragment. */
30
+ registerRef(name: string): OpenApiSchema;
31
+ /** Process the queue until no schema remains to build. */
32
+ build(): void;
33
+ getSchemas(): Record<string, OpenApiSchema>;
34
+ /** Public entry to map an arbitrary type to an OpenAPI schema fragment. */
35
+ typeToSchema(type: Type): OpenApiSchema;
36
+ /** Flatten a class's properties (own + inherited / mapped-type heritage). */
37
+ buildMembers(clazz: ClassDeclaration): SchemaMembers;
38
+ private buildOwnMembers;
39
+ /** Resolve `PartialType() / PickType() / OmitType() / IntersectionType()` heritage. */
40
+ private resolveHeritage;
41
+ private schemaForType;
42
+ /**
43
+ * Build the schema for a named TS enum, deriving `type` from the member
44
+ * values rather than assuming strings:
45
+ * - all strings -> `string`
46
+ * - all integers -> `integer`
47
+ * - all numbers (some non-integer) -> `number`
48
+ * - mixed string/number -> `type` omitted (no single OpenAPI type fits)
49
+ */
50
+ private enumSchema;
51
+ /**
52
+ * Merge class-validator constraints from a property's decorators into its
53
+ * schema. Unknown decorators are ignored. A `$ref` is left untouched (its
54
+ * siblings are ignored by OpenAPI 3.0, so constraints don't belong on it).
55
+ *
56
+ * - `@Min/@Max` -> `minimum` / `maximum`
57
+ * - `@MinLength/@MaxLength` -> `minLength` / `maxLength`
58
+ * - `@Length(min, max)` -> `minLength` + `maxLength`
59
+ * - `@ArrayMinSize/@ArrayMaxSize` -> `minItems` / `maxItems`
60
+ * - `@IsEmail/@IsUrl/@IsUUID/@IsDateString` -> `format`
61
+ * - `@Matches(/re/)` -> `pattern`
62
+ * - `@IsInt` -> narrows `number` to `integer`
63
+ * - `@IsPositive/@IsNegative` -> exclusive `minimum` / `maximum` of 0
64
+ */
65
+ private applyValidatorConstraints;
66
+ private mergeMembers;
67
+ private pick;
68
+ private omit;
69
+ private parseStringArray;
70
+ }