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.
- package/README.md +213 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +54 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/defaults.d.ts +5 -0
- package/dist/config/defaults.js +14 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.js +24 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +11 -0
- package/dist/config/loader.js +160 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/types.d.ts +139 -0
- package/dist/config/types.js +8 -0
- package/dist/config/types.js.map +1 -0
- package/dist/lib.d.ts +12 -0
- package/dist/lib.js +22 -0
- package/dist/lib.js.map +1 -0
- package/dist/parser/ast-index.d.ts +38 -0
- package/dist/parser/ast-index.js +124 -0
- package/dist/parser/ast-index.js.map +1 -0
- package/dist/parser/index.d.ts +20 -0
- package/dist/parser/index.js +95 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/path-builder.d.ts +87 -0
- package/dist/parser/path-builder.js +464 -0
- package/dist/parser/path-builder.js.map +1 -0
- package/dist/parser/schema-builder.d.ts +70 -0
- package/dist/parser/schema-builder.js +355 -0
- package/dist/parser/schema-builder.js.map +1 -0
- package/dist/parser/tags.d.ts +61 -0
- package/dist/parser/tags.js +163 -0
- package/dist/parser/tags.js.map +1 -0
- package/dist/types/openapi.d.ts +42 -0
- package/dist/types/openapi.js +3 -0
- package/dist/types/openapi.js.map +1 -0
- package/dist/validate.d.ts +13 -0
- package/dist/validate.js +30 -0
- package/dist/validate.js.map +1 -0
- package/docs/configuration.md +195 -0
- package/docs/library-usage.md +40 -0
- package/docs/parser.md +148 -0
- package/package.json +54 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SchemaBuilder = 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
|
+
/**
|
|
8
|
+
* Converts TypeScript classes (entities & DTOs) into OpenAPI `components.schemas`.
|
|
9
|
+
* Handles:
|
|
10
|
+
* - required derived from `@IsOptional()` / `?` (configurable)
|
|
11
|
+
* - `@Exclude()` properties omitted (configurable)
|
|
12
|
+
* - union object types -> `oneOf`, string-literal unions -> enum
|
|
13
|
+
* - `PartialType / PickType / OmitType / IntersectionType` heritage
|
|
14
|
+
*/
|
|
15
|
+
class SchemaBuilder {
|
|
16
|
+
index;
|
|
17
|
+
schemas = {};
|
|
18
|
+
pending = new Set();
|
|
19
|
+
done = new Set();
|
|
20
|
+
activeScopes;
|
|
21
|
+
knownScopes;
|
|
22
|
+
constructor(index, options = {}) {
|
|
23
|
+
this.index = index;
|
|
24
|
+
this.activeScopes = options.activeScopes ?? new Set();
|
|
25
|
+
this.knownScopes = options.knownScopes;
|
|
26
|
+
}
|
|
27
|
+
/** Register a reference to a class schema and return the `$ref` fragment. */
|
|
28
|
+
registerRef(name) {
|
|
29
|
+
if (!this.index.hasClass(name))
|
|
30
|
+
return { type: 'object' };
|
|
31
|
+
if (!this.done.has(name))
|
|
32
|
+
this.pending.add(name);
|
|
33
|
+
return { $ref: `#/components/schemas/${name}` };
|
|
34
|
+
}
|
|
35
|
+
/** Process the queue until no schema remains to build. */
|
|
36
|
+
build() {
|
|
37
|
+
while (this.pending.size) {
|
|
38
|
+
const name = this.pending.values().next().value;
|
|
39
|
+
this.pending.delete(name);
|
|
40
|
+
if (this.done.has(name))
|
|
41
|
+
continue;
|
|
42
|
+
this.done.add(name);
|
|
43
|
+
const clazz = this.index.getClass(name);
|
|
44
|
+
if (!clazz)
|
|
45
|
+
continue;
|
|
46
|
+
const classScopes = (0, tags_1.getScopes)((0, tags_1.getTags)(clazz));
|
|
47
|
+
if (!(0, tags_1.isVisible)(classScopes, this.activeScopes)) {
|
|
48
|
+
throw new Error(`Scope conflict: class "${name}" is reached by the spec but has @Scope ${formatScopes(classScopes)} ` +
|
|
49
|
+
`which doesn't match the active scopes ${formatScopes(this.activeScopes)}. ` +
|
|
50
|
+
`Add a matching scope to --scope/config.scopes, or hide whatever referenced it.`);
|
|
51
|
+
}
|
|
52
|
+
const members = this.buildMembers(clazz);
|
|
53
|
+
const schema = { type: 'object', properties: members.properties };
|
|
54
|
+
if (members.required.length)
|
|
55
|
+
schema.required = members.required;
|
|
56
|
+
const rawDesc = clazz.getJsDocs()[0]?.getCommentText();
|
|
57
|
+
const desc = rawDesc
|
|
58
|
+
? (0, tags_1.filterScopedComments)(rawDesc, this.activeScopes, {
|
|
59
|
+
itemPath: name,
|
|
60
|
+
knownScopes: this.knownScopes,
|
|
61
|
+
})
|
|
62
|
+
: undefined;
|
|
63
|
+
if (desc)
|
|
64
|
+
schema.description = desc;
|
|
65
|
+
this.schemas[name] = schema;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
getSchemas() {
|
|
69
|
+
return this.schemas;
|
|
70
|
+
}
|
|
71
|
+
/** Public entry to map an arbitrary type to an OpenAPI schema fragment. */
|
|
72
|
+
typeToSchema(type) {
|
|
73
|
+
return this.schemaForType(type);
|
|
74
|
+
}
|
|
75
|
+
/** Flatten a class's properties (own + inherited / mapped-type heritage). */
|
|
76
|
+
buildMembers(clazz) {
|
|
77
|
+
const base = clazz.getBaseClass();
|
|
78
|
+
let inherited = { properties: {}, required: [] };
|
|
79
|
+
if (base) {
|
|
80
|
+
inherited = this.buildMembers(base);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const ext = clazz.getExtends();
|
|
84
|
+
if (ext)
|
|
85
|
+
inherited = this.resolveHeritage(ext.getExpression());
|
|
86
|
+
}
|
|
87
|
+
return this.mergeMembers(inherited, this.buildOwnMembers(clazz));
|
|
88
|
+
}
|
|
89
|
+
buildOwnMembers(clazz) {
|
|
90
|
+
const properties = {};
|
|
91
|
+
const required = [];
|
|
92
|
+
const excludeDecorator = this.index.excludeDecorator;
|
|
93
|
+
for (const prop of clazz.getInstanceProperties()) {
|
|
94
|
+
if (!ts_morph_1.Node.isPropertyDeclaration(prop))
|
|
95
|
+
continue;
|
|
96
|
+
if (prop.getDecorator(excludeDecorator))
|
|
97
|
+
continue;
|
|
98
|
+
if (!(0, tags_1.isVisible)((0, tags_1.getScopes)((0, tags_1.getTags)(prop)), this.activeScopes))
|
|
99
|
+
continue;
|
|
100
|
+
const name = prop.getName();
|
|
101
|
+
const schema = this.schemaForType(prop.getType());
|
|
102
|
+
this.applyValidatorConstraints(schema, prop);
|
|
103
|
+
const rawDesc = prop.getJsDocs()[0]?.getCommentText();
|
|
104
|
+
const desc = rawDesc
|
|
105
|
+
? (0, tags_1.filterScopedComments)(rawDesc, this.activeScopes, {
|
|
106
|
+
itemPath: `${clazz.getName() ?? '<anon>'}.${name}`,
|
|
107
|
+
knownScopes: this.knownScopes,
|
|
108
|
+
})
|
|
109
|
+
: undefined;
|
|
110
|
+
properties[name] = desc ? withDescription(schema, desc) : schema;
|
|
111
|
+
if (!this.index.isOptionalProperty(prop))
|
|
112
|
+
required.push(name);
|
|
113
|
+
}
|
|
114
|
+
return { properties, required };
|
|
115
|
+
}
|
|
116
|
+
/** Resolve `PartialType() / PickType() / OmitType() / IntersectionType()` heritage. */
|
|
117
|
+
resolveHeritage(expr) {
|
|
118
|
+
if (ts_morph_1.Node.isIdentifier(expr)) {
|
|
119
|
+
const cls = this.index.getClass(expr.getText());
|
|
120
|
+
return cls ? this.buildMembers(cls) : { properties: {}, required: [] };
|
|
121
|
+
}
|
|
122
|
+
if (ts_morph_1.Node.isCallExpression(expr)) {
|
|
123
|
+
const fnName = expr.getExpression().getText();
|
|
124
|
+
const args = expr.getArguments();
|
|
125
|
+
if (fnName === 'IntersectionType') {
|
|
126
|
+
let merged = { properties: {}, required: [] };
|
|
127
|
+
for (const arg of args)
|
|
128
|
+
merged = this.mergeMembers(merged, this.resolveHeritage(arg));
|
|
129
|
+
return merged;
|
|
130
|
+
}
|
|
131
|
+
const inner = args.length ? this.resolveHeritage(args[0]) : { properties: {}, required: [] };
|
|
132
|
+
if (fnName === 'PartialType')
|
|
133
|
+
return { properties: inner.properties, required: [] };
|
|
134
|
+
if (fnName === 'PickType')
|
|
135
|
+
return this.pick(inner, this.parseStringArray(args[1]));
|
|
136
|
+
if (fnName === 'OmitType')
|
|
137
|
+
return this.omit(inner, this.parseStringArray(args[1]));
|
|
138
|
+
return inner;
|
|
139
|
+
}
|
|
140
|
+
return { properties: {}, required: [] };
|
|
141
|
+
}
|
|
142
|
+
schemaForType(type) {
|
|
143
|
+
if (type.isString())
|
|
144
|
+
return { type: 'string' };
|
|
145
|
+
if (type.isNumber())
|
|
146
|
+
return { type: 'number' };
|
|
147
|
+
if (type.isBoolean())
|
|
148
|
+
return { type: 'boolean' };
|
|
149
|
+
const symbolName = ast_index_1.AstIndex.symbolName(type);
|
|
150
|
+
if (symbolName === 'Date')
|
|
151
|
+
return { type: 'string', format: 'date-time' };
|
|
152
|
+
if (type.isArray()) {
|
|
153
|
+
const element = type.getArrayElementType();
|
|
154
|
+
return { type: 'array', items: element ? this.schemaForType(element) : {} };
|
|
155
|
+
}
|
|
156
|
+
if (symbolName && this.index.hasEnum(symbolName)) {
|
|
157
|
+
return this.enumSchema(symbolName);
|
|
158
|
+
}
|
|
159
|
+
if (type.isUnion()) {
|
|
160
|
+
const members = type.getUnionTypes().filter((t) => !t.isUndefined() && !t.isNull());
|
|
161
|
+
if (members.length === 1)
|
|
162
|
+
return this.schemaForType(members[0]);
|
|
163
|
+
if (members.length && members.every((t) => t.isStringLiteral())) {
|
|
164
|
+
return { type: 'string', enum: members.map((t) => t.getLiteralValue()) };
|
|
165
|
+
}
|
|
166
|
+
const objectMembers = members.filter((t) => {
|
|
167
|
+
const n = ast_index_1.AstIndex.symbolName(t);
|
|
168
|
+
return n && this.index.hasClass(n);
|
|
169
|
+
});
|
|
170
|
+
if (members.length > 0 && objectMembers.length === members.length) {
|
|
171
|
+
return { oneOf: members.map((t) => this.registerRef(ast_index_1.AstIndex.symbolName(t))) };
|
|
172
|
+
}
|
|
173
|
+
return { type: 'object' };
|
|
174
|
+
}
|
|
175
|
+
if (symbolName && this.index.hasClass(symbolName)) {
|
|
176
|
+
return this.registerRef(symbolName);
|
|
177
|
+
}
|
|
178
|
+
return { type: 'object' };
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Build the schema for a named TS enum, deriving `type` from the member
|
|
182
|
+
* values rather than assuming strings:
|
|
183
|
+
* - all strings -> `string`
|
|
184
|
+
* - all integers -> `integer`
|
|
185
|
+
* - all numbers (some non-integer) -> `number`
|
|
186
|
+
* - mixed string/number -> `type` omitted (no single OpenAPI type fits)
|
|
187
|
+
*/
|
|
188
|
+
enumSchema(name) {
|
|
189
|
+
const values = this.index.getEnumValues(name) ?? [];
|
|
190
|
+
if (values.length === 0)
|
|
191
|
+
return { type: 'string', enum: values };
|
|
192
|
+
if (values.every((v) => typeof v === 'number')) {
|
|
193
|
+
const type = values.every((v) => Number.isInteger(v)) ? 'integer' : 'number';
|
|
194
|
+
return { type, enum: values };
|
|
195
|
+
}
|
|
196
|
+
if (values.every((v) => typeof v === 'string')) {
|
|
197
|
+
return { type: 'string', enum: values };
|
|
198
|
+
}
|
|
199
|
+
return { enum: values };
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Merge class-validator constraints from a property's decorators into its
|
|
203
|
+
* schema. Unknown decorators are ignored. A `$ref` is left untouched (its
|
|
204
|
+
* siblings are ignored by OpenAPI 3.0, so constraints don't belong on it).
|
|
205
|
+
*
|
|
206
|
+
* - `@Min/@Max` -> `minimum` / `maximum`
|
|
207
|
+
* - `@MinLength/@MaxLength` -> `minLength` / `maxLength`
|
|
208
|
+
* - `@Length(min, max)` -> `minLength` + `maxLength`
|
|
209
|
+
* - `@ArrayMinSize/@ArrayMaxSize` -> `minItems` / `maxItems`
|
|
210
|
+
* - `@IsEmail/@IsUrl/@IsUUID/@IsDateString` -> `format`
|
|
211
|
+
* - `@Matches(/re/)` -> `pattern`
|
|
212
|
+
* - `@IsInt` -> narrows `number` to `integer`
|
|
213
|
+
* - `@IsPositive/@IsNegative` -> exclusive `minimum` / `maximum` of 0
|
|
214
|
+
*/
|
|
215
|
+
applyValidatorConstraints(schema, prop) {
|
|
216
|
+
if ('$ref' in schema)
|
|
217
|
+
return;
|
|
218
|
+
for (const decorator of prop.getDecorators()) {
|
|
219
|
+
const args = decorator.getArguments();
|
|
220
|
+
const setNum = (key, value) => {
|
|
221
|
+
if (value !== undefined)
|
|
222
|
+
schema[key] = value;
|
|
223
|
+
};
|
|
224
|
+
switch (decorator.getName()) {
|
|
225
|
+
case 'Min':
|
|
226
|
+
setNum('minimum', literalNumber(args[0]));
|
|
227
|
+
break;
|
|
228
|
+
case 'Max':
|
|
229
|
+
setNum('maximum', literalNumber(args[0]));
|
|
230
|
+
break;
|
|
231
|
+
case 'MinLength':
|
|
232
|
+
setNum('minLength', literalNumber(args[0]));
|
|
233
|
+
break;
|
|
234
|
+
case 'MaxLength':
|
|
235
|
+
setNum('maxLength', literalNumber(args[0]));
|
|
236
|
+
break;
|
|
237
|
+
case 'Length':
|
|
238
|
+
setNum('minLength', literalNumber(args[0]));
|
|
239
|
+
setNum('maxLength', literalNumber(args[1]));
|
|
240
|
+
break;
|
|
241
|
+
case 'ArrayMinSize':
|
|
242
|
+
setNum('minItems', literalNumber(args[0]));
|
|
243
|
+
break;
|
|
244
|
+
case 'ArrayMaxSize':
|
|
245
|
+
setNum('maxItems', literalNumber(args[0]));
|
|
246
|
+
break;
|
|
247
|
+
case 'IsEmail':
|
|
248
|
+
schema.format = 'email';
|
|
249
|
+
break;
|
|
250
|
+
case 'IsUrl':
|
|
251
|
+
schema.format = 'uri';
|
|
252
|
+
break;
|
|
253
|
+
case 'IsUUID':
|
|
254
|
+
schema.format = 'uuid';
|
|
255
|
+
break;
|
|
256
|
+
case 'IsDateString':
|
|
257
|
+
schema.format = 'date-time';
|
|
258
|
+
break;
|
|
259
|
+
case 'IsInt':
|
|
260
|
+
if (schema.type === 'number')
|
|
261
|
+
schema.type = 'integer';
|
|
262
|
+
break;
|
|
263
|
+
case 'IsPositive':
|
|
264
|
+
schema.minimum = 0;
|
|
265
|
+
schema.exclusiveMinimum = true;
|
|
266
|
+
break;
|
|
267
|
+
case 'IsNegative':
|
|
268
|
+
schema.maximum = 0;
|
|
269
|
+
schema.exclusiveMaximum = true;
|
|
270
|
+
break;
|
|
271
|
+
case 'Matches': {
|
|
272
|
+
const pattern = regexLiteralPattern(args[0]);
|
|
273
|
+
if (pattern !== undefined)
|
|
274
|
+
schema.pattern = pattern;
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
mergeMembers(a, b) {
|
|
281
|
+
const properties = { ...a.properties, ...b.properties };
|
|
282
|
+
const required = [...new Set([...a.required, ...b.required])].filter((k) => k in properties);
|
|
283
|
+
return { properties, required };
|
|
284
|
+
}
|
|
285
|
+
pick(members, keys) {
|
|
286
|
+
const properties = {};
|
|
287
|
+
for (const key of keys)
|
|
288
|
+
if (key in members.properties)
|
|
289
|
+
properties[key] = members.properties[key];
|
|
290
|
+
return { properties, required: members.required.filter((k) => keys.includes(k)) };
|
|
291
|
+
}
|
|
292
|
+
omit(members, keys) {
|
|
293
|
+
const properties = {};
|
|
294
|
+
for (const key of Object.keys(members.properties)) {
|
|
295
|
+
if (!keys.includes(key))
|
|
296
|
+
properties[key] = members.properties[key];
|
|
297
|
+
}
|
|
298
|
+
return { properties, required: members.required.filter((k) => !keys.includes(k)) };
|
|
299
|
+
}
|
|
300
|
+
parseStringArray(arg) {
|
|
301
|
+
if (!arg)
|
|
302
|
+
return [];
|
|
303
|
+
let node = arg;
|
|
304
|
+
if (ts_morph_1.Node.isAsExpression(node))
|
|
305
|
+
node = node.getExpression();
|
|
306
|
+
if (ts_morph_1.Node.isArrayLiteralExpression(node)) {
|
|
307
|
+
return node
|
|
308
|
+
.getElements()
|
|
309
|
+
.map((el) => ts_morph_1.Node.isStringLiteral(el) ? el.getLiteralValue() : el.getText().replace(/['"]/g, ''));
|
|
310
|
+
}
|
|
311
|
+
return [];
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
exports.SchemaBuilder = SchemaBuilder;
|
|
315
|
+
function formatScopes(scopes) {
|
|
316
|
+
return scopes.size === 0 ? '{}' : `{${[...scopes].join(', ')}}`;
|
|
317
|
+
}
|
|
318
|
+
/** A numeric decorator argument, supporting a leading unary `-`/`+` (e.g. `@Min(-1)`). */
|
|
319
|
+
function literalNumber(arg) {
|
|
320
|
+
if (!arg)
|
|
321
|
+
return undefined;
|
|
322
|
+
if (ts_morph_1.Node.isNumericLiteral(arg))
|
|
323
|
+
return arg.getLiteralValue();
|
|
324
|
+
if (ts_morph_1.Node.isPrefixUnaryExpression(arg)) {
|
|
325
|
+
const operand = arg.getOperand();
|
|
326
|
+
if (ts_morph_1.Node.isNumericLiteral(operand)) {
|
|
327
|
+
const value = operand.getLiteralValue();
|
|
328
|
+
return arg.getOperatorToken() === ts_morph_1.SyntaxKind.MinusToken ? -value : value;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return undefined;
|
|
332
|
+
}
|
|
333
|
+
/** The pattern of a `@Matches(...)` argument — a regex literal `/re/flags` or a string. */
|
|
334
|
+
function regexLiteralPattern(arg) {
|
|
335
|
+
if (!arg)
|
|
336
|
+
return undefined;
|
|
337
|
+
if (ts_morph_1.Node.isStringLiteral(arg))
|
|
338
|
+
return arg.getLiteralValue();
|
|
339
|
+
const match = /^\/(.*)\/[dgimsuy]*$/s.exec(arg.getText());
|
|
340
|
+
return match ? match[1] : undefined;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Attach a `description` to a property schema. A `$ref` is a Reference Object
|
|
344
|
+
* whose sibling keys are ignored in OpenAPI 3.0, so a bare `$ref` is wrapped in
|
|
345
|
+
* `allOf` (a normal Schema Object) so the description is actually honored. Any
|
|
346
|
+
* other schema takes the description directly as a sibling.
|
|
347
|
+
*/
|
|
348
|
+
function withDescription(schema, description) {
|
|
349
|
+
if ('$ref' in schema) {
|
|
350
|
+
return { allOf: [schema], description };
|
|
351
|
+
}
|
|
352
|
+
schema.description = description;
|
|
353
|
+
return schema;
|
|
354
|
+
}
|
|
355
|
+
//# sourceMappingURL=schema-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-builder.js","sourceRoot":"","sources":["../../src/parser/schema-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Node } from 'ts-morph';
|
|
2
|
+
/** Tag name → values (one entry per `@TagName` occurrence in the node's JSDoc). */
|
|
3
|
+
export type TagBag = Record<string, string[]>;
|
|
4
|
+
/**
|
|
5
|
+
* Extract all custom JSDoc tags on a node.
|
|
6
|
+
*
|
|
7
|
+
* Only tags at line start (after the JSDoc `* ` prefix) are recognized — inline
|
|
8
|
+
* mentions like `Some text with @Scope inline` are description, not tags.
|
|
9
|
+
* That behavior comes from the TypeScript JSDoc parser; we just consume it.
|
|
10
|
+
*
|
|
11
|
+
* The value is taken from the SAME line as `@TagName`. ts-morph treats lines
|
|
12
|
+
* after a tag as continuation of the tag's body until the next tag, but we
|
|
13
|
+
* want subsequent comment lines to remain plain description — so we read only
|
|
14
|
+
* the first line.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getTags(node: Node): TagBag;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the `@Scope` tag values on a node into a flat set of scope names.
|
|
19
|
+
* Accepts comma-separated lists with optional whitespace
|
|
20
|
+
* (`@Scope internal,admin`, `@Scope internal, admin`) and multiple occurrences
|
|
21
|
+
* (`@Scope internal` on one line and `@Scope admin` on another).
|
|
22
|
+
*/
|
|
23
|
+
export declare function getScopes(bag: TagBag): Set<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Decide whether an item is visible under the active scopes.
|
|
26
|
+
*
|
|
27
|
+
* - Untagged items (`itemScopes` empty) are always visible.
|
|
28
|
+
* - When no scope is active, only untagged items are visible.
|
|
29
|
+
* - Otherwise, visible iff at least one of the item's scopes is active.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isVisible(itemScopes: Set<string>, activeScopes: Set<string>): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Normalize an `--scope a,b --scope c` style CLI input (or a `scopes` config
|
|
34
|
+
* array) into a flat string list — comma-split, trimmed, falsy filtered.
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseScopeList(raw: string | string[] | undefined): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Filter `<scope>…</scope>` fragments inside a JSDoc description.
|
|
39
|
+
*
|
|
40
|
+
* - Untagged text passes through unchanged.
|
|
41
|
+
* - `<X>…</X>` keeps its inner text when `X ∈ activeScopes`; otherwise the
|
|
42
|
+
* whole block (open tag → close tag) is removed.
|
|
43
|
+
* - The remaining text is normalized: lines that contained only an open/close
|
|
44
|
+
* tag are dropped (including their newline), runs of 3+ newlines collapse
|
|
45
|
+
* to 2, and the result is trimmed.
|
|
46
|
+
* - Nested fragments, mismatched close tags, and unclosed open tags throw.
|
|
47
|
+
*
|
|
48
|
+
* Only names that are *known scopes* are treated as fragment delimiters. Pass
|
|
49
|
+
* the project's scope vocabulary via `ctx.knownScopes`; any other angle-bracket
|
|
50
|
+
* token — generics in prose (`Array<string>`), placeholders (`<id>`, `<token>`),
|
|
51
|
+
* inline HTML (`<b>…</b>`) — passes through verbatim and never throws. When
|
|
52
|
+
* `ctx.knownScopes` is omitted, every `<name>` is treated as a fragment (legacy
|
|
53
|
+
* behavior, retained for direct callers and unit tests).
|
|
54
|
+
*
|
|
55
|
+
* The optional `ctx.itemPath` (e.g. `"User.email"`) is included in the error
|
|
56
|
+
* message so misconfigured comments are easy to locate.
|
|
57
|
+
*/
|
|
58
|
+
export declare function filterScopedComments(text: string, activeScopes: Set<string>, ctx?: {
|
|
59
|
+
itemPath?: string;
|
|
60
|
+
knownScopes?: Set<string>;
|
|
61
|
+
}): string;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTags = getTags;
|
|
4
|
+
exports.getScopes = getScopes;
|
|
5
|
+
exports.isVisible = isVisible;
|
|
6
|
+
exports.parseScopeList = parseScopeList;
|
|
7
|
+
exports.filterScopedComments = filterScopedComments;
|
|
8
|
+
function hasJsDocs(node) {
|
|
9
|
+
return typeof node.getJsDocs === 'function';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Extract all custom JSDoc tags on a node.
|
|
13
|
+
*
|
|
14
|
+
* Only tags at line start (after the JSDoc `* ` prefix) are recognized — inline
|
|
15
|
+
* mentions like `Some text with @Scope inline` are description, not tags.
|
|
16
|
+
* That behavior comes from the TypeScript JSDoc parser; we just consume it.
|
|
17
|
+
*
|
|
18
|
+
* The value is taken from the SAME line as `@TagName`. ts-morph treats lines
|
|
19
|
+
* after a tag as continuation of the tag's body until the next tag, but we
|
|
20
|
+
* want subsequent comment lines to remain plain description — so we read only
|
|
21
|
+
* the first line.
|
|
22
|
+
*/
|
|
23
|
+
function getTags(node) {
|
|
24
|
+
if (!hasJsDocs(node))
|
|
25
|
+
return {};
|
|
26
|
+
const bag = {};
|
|
27
|
+
for (const jsdoc of node.getJsDocs()) {
|
|
28
|
+
for (const tag of jsdoc.getTags()) {
|
|
29
|
+
const name = tag.getTagName();
|
|
30
|
+
const value = (tag.getCommentText() ?? '').split('\n')[0].trim();
|
|
31
|
+
(bag[name] ??= []).push(value);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return bag;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve the `@Scope` tag values on a node into a flat set of scope names.
|
|
38
|
+
* Accepts comma-separated lists with optional whitespace
|
|
39
|
+
* (`@Scope internal,admin`, `@Scope internal, admin`) and multiple occurrences
|
|
40
|
+
* (`@Scope internal` on one line and `@Scope admin` on another).
|
|
41
|
+
*/
|
|
42
|
+
function getScopes(bag) {
|
|
43
|
+
return new Set((bag.Scope ?? []).flatMap((v) => v
|
|
44
|
+
.split(',')
|
|
45
|
+
.map((s) => s.trim())
|
|
46
|
+
.filter(Boolean)));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Decide whether an item is visible under the active scopes.
|
|
50
|
+
*
|
|
51
|
+
* - Untagged items (`itemScopes` empty) are always visible.
|
|
52
|
+
* - When no scope is active, only untagged items are visible.
|
|
53
|
+
* - Otherwise, visible iff at least one of the item's scopes is active.
|
|
54
|
+
*/
|
|
55
|
+
function isVisible(itemScopes, activeScopes) {
|
|
56
|
+
if (itemScopes.size === 0)
|
|
57
|
+
return true;
|
|
58
|
+
if (activeScopes.size === 0)
|
|
59
|
+
return false;
|
|
60
|
+
for (const s of itemScopes)
|
|
61
|
+
if (activeScopes.has(s))
|
|
62
|
+
return true;
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Normalize an `--scope a,b --scope c` style CLI input (or a `scopes` config
|
|
67
|
+
* array) into a flat string list — comma-split, trimmed, falsy filtered.
|
|
68
|
+
*/
|
|
69
|
+
function parseScopeList(raw) {
|
|
70
|
+
if (raw === undefined)
|
|
71
|
+
return [];
|
|
72
|
+
const items = Array.isArray(raw) ? raw : [raw];
|
|
73
|
+
return items.flatMap((s) => s
|
|
74
|
+
.split(',')
|
|
75
|
+
.map((p) => p.trim())
|
|
76
|
+
.filter(Boolean));
|
|
77
|
+
}
|
|
78
|
+
// Matches an element-style open or close tag: <name> or </name>. The name must
|
|
79
|
+
// look like a scope identifier — letters/digits/underscore/hyphen, leading
|
|
80
|
+
// letter. Whether a match is an actual scope fragment (vs. literal prose) is
|
|
81
|
+
// decided downstream against the known-scope vocabulary.
|
|
82
|
+
const FRAGMENT_TAG = /<\/?([A-Za-z][A-Za-z0-9_-]*)>/g;
|
|
83
|
+
/**
|
|
84
|
+
* Filter `<scope>…</scope>` fragments inside a JSDoc description.
|
|
85
|
+
*
|
|
86
|
+
* - Untagged text passes through unchanged.
|
|
87
|
+
* - `<X>…</X>` keeps its inner text when `X ∈ activeScopes`; otherwise the
|
|
88
|
+
* whole block (open tag → close tag) is removed.
|
|
89
|
+
* - The remaining text is normalized: lines that contained only an open/close
|
|
90
|
+
* tag are dropped (including their newline), runs of 3+ newlines collapse
|
|
91
|
+
* to 2, and the result is trimmed.
|
|
92
|
+
* - Nested fragments, mismatched close tags, and unclosed open tags throw.
|
|
93
|
+
*
|
|
94
|
+
* Only names that are *known scopes* are treated as fragment delimiters. Pass
|
|
95
|
+
* the project's scope vocabulary via `ctx.knownScopes`; any other angle-bracket
|
|
96
|
+
* token — generics in prose (`Array<string>`), placeholders (`<id>`, `<token>`),
|
|
97
|
+
* inline HTML (`<b>…</b>`) — passes through verbatim and never throws. When
|
|
98
|
+
* `ctx.knownScopes` is omitted, every `<name>` is treated as a fragment (legacy
|
|
99
|
+
* behavior, retained for direct callers and unit tests).
|
|
100
|
+
*
|
|
101
|
+
* The optional `ctx.itemPath` (e.g. `"User.email"`) is included in the error
|
|
102
|
+
* message so misconfigured comments are easy to locate.
|
|
103
|
+
*/
|
|
104
|
+
function filterScopedComments(text, activeScopes, ctx = {}) {
|
|
105
|
+
const where = ctx.itemPath ? ` at ${ctx.itemPath}` : '';
|
|
106
|
+
const known = ctx.knownScopes;
|
|
107
|
+
const isScopeTag = (name) => known === undefined || known.has(name);
|
|
108
|
+
let currentScope;
|
|
109
|
+
let keep = true;
|
|
110
|
+
let out = '';
|
|
111
|
+
let cursor = 0;
|
|
112
|
+
FRAGMENT_TAG.lastIndex = 0;
|
|
113
|
+
for (let m = FRAGMENT_TAG.exec(text); m !== null; m = FRAGMENT_TAG.exec(text)) {
|
|
114
|
+
const before = text.slice(cursor, m.index);
|
|
115
|
+
if (keep)
|
|
116
|
+
out += before;
|
|
117
|
+
cursor = m.index + m[0].length;
|
|
118
|
+
const name = m[1];
|
|
119
|
+
const isClose = m[0].startsWith('</');
|
|
120
|
+
// Not a scope name — ordinary prose. Emit it verbatim (when we're keeping
|
|
121
|
+
// the surrounding text) and leave the fragment state untouched.
|
|
122
|
+
if (!isScopeTag(name)) {
|
|
123
|
+
if (keep)
|
|
124
|
+
out += m[0];
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (!isClose) {
|
|
128
|
+
if (currentScope !== undefined) {
|
|
129
|
+
throw new Error(`Nested scope fragments are not allowed${where}: <${name}> inside <${currentScope}>.`);
|
|
130
|
+
}
|
|
131
|
+
currentScope = name;
|
|
132
|
+
keep = activeScopes.has(name);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
if (currentScope === undefined) {
|
|
136
|
+
throw new Error(`Unmatched closing scope tag </${name}>${where}.`);
|
|
137
|
+
}
|
|
138
|
+
if (currentScope !== name) {
|
|
139
|
+
throw new Error(`Mismatched scope tag </${name}>${where} (expected </${currentScope}>).`);
|
|
140
|
+
}
|
|
141
|
+
currentScope = undefined;
|
|
142
|
+
keep = true;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (currentScope !== undefined) {
|
|
146
|
+
throw new Error(`Unclosed scope fragment <${currentScope}>${where}.`);
|
|
147
|
+
}
|
|
148
|
+
if (keep)
|
|
149
|
+
out += text.slice(cursor);
|
|
150
|
+
return normalizeFiltered(out);
|
|
151
|
+
}
|
|
152
|
+
function normalizeFiltered(text) {
|
|
153
|
+
// Drop lines whose remaining content is only whitespace AND that came from a
|
|
154
|
+
// removed tag — heuristic: any line that, after trim, is empty stays as a
|
|
155
|
+
// blank line, but we then collapse runs.
|
|
156
|
+
const noBlankLineRuns = text
|
|
157
|
+
.split('\n')
|
|
158
|
+
.map((line) => (line.trim() === '' ? '' : line))
|
|
159
|
+
.join('\n')
|
|
160
|
+
.replace(/\n{3,}/g, '\n\n');
|
|
161
|
+
return noBlankLineRuns.trim();
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/parser/tags.ts"],"names":[],"mappings":";;AAyBA,0BAWC;AAQD,8BASC;AASD,8BAKC;AAMD,wCASC;AA6BD,oDAwDC;AA9JD,SAAS,SAAS,CAAC,IAAU;IAC3B,OAAO,OAAQ,IAA+B,CAAC,SAAS,KAAK,UAAU,CAAC;AAC1E,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,OAAO,CAAC,IAAU;IAChC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QACrC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACjE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,GAAW;IACnC,OAAO,IAAI,GAAG,CACZ,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9B,CAAC;SACE,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CACnB,CACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,SAAS,CAAC,UAAuB,EAAE,YAAyB;IAC1E,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,UAAU;QAAE,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IACjE,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAAC,GAAkC;IAC/D,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACzB,CAAC;SACE,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CACnB,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,2EAA2E;AAC3E,6EAA6E;AAC7E,yDAAyD;AACzD,MAAM,YAAY,GAAG,gCAAgC,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,oBAAoB,CAClC,IAAY,EACZ,YAAyB,EACzB,MAAwD,EAAE;IAE1D,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,CAAC;IAC9B,MAAM,UAAU,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAErF,IAAI,YAAgC,CAAC;IACrC,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,IAAI;YAAE,GAAG,IAAI,MAAM,CAAC;QACxB,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAE/B,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtC,0EAA0E;QAC1E,gEAAgE;QAChE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,IAAI,IAAI;gBAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACtB,SAAS;QACX,CAAC;QAED,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CACb,yCAAyC,KAAK,MAAM,IAAI,aAAa,YAAY,IAAI,CACtF,CAAC;YACJ,CAAC;YACD,YAAY,GAAG,IAAI,CAAC;YACpB,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC;YACrE,CAAC;YACD,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,IAAI,KAAK,gBAAgB,YAAY,KAAK,CAAC,CAAC;YAC5F,CAAC;YACD,YAAY,GAAG,SAAS,CAAC;YACzB,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,4BAA4B,YAAY,IAAI,KAAK,GAAG,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,IAAI;QAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEpC,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,6EAA6E;IAC7E,0EAA0E;IAC1E,yCAAyC;IACzC,MAAM,eAAe,GAAG,IAAI;SACzB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAC/C,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,eAAe,CAAC,IAAI,EAAE,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type OpenApiSchema = Record<string, unknown>;
|
|
2
|
+
export interface OpenApiServer {
|
|
3
|
+
url: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
variables?: Record<string, {
|
|
6
|
+
default: string;
|
|
7
|
+
enum?: string[];
|
|
8
|
+
description?: string;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export interface OpenApiInfo {
|
|
12
|
+
title: string;
|
|
13
|
+
version: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
termsOfService?: string;
|
|
16
|
+
contact?: {
|
|
17
|
+
name?: string;
|
|
18
|
+
url?: string;
|
|
19
|
+
email?: string;
|
|
20
|
+
};
|
|
21
|
+
license?: {
|
|
22
|
+
name: string;
|
|
23
|
+
url?: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export type OpenApiSecurityScheme = Record<string, unknown>;
|
|
27
|
+
export type OpenApiSecurityRequirement = Record<string, string[]>;
|
|
28
|
+
export interface OpenApiDocument {
|
|
29
|
+
openapi: string;
|
|
30
|
+
info: OpenApiInfo;
|
|
31
|
+
servers?: OpenApiServer[];
|
|
32
|
+
paths: Record<string, Record<string, unknown>>;
|
|
33
|
+
components?: {
|
|
34
|
+
schemas?: Record<string, OpenApiSchema>;
|
|
35
|
+
securitySchemes?: Record<string, OpenApiSecurityScheme>;
|
|
36
|
+
};
|
|
37
|
+
security?: OpenApiSecurityRequirement[];
|
|
38
|
+
tags?: {
|
|
39
|
+
name: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
}[];
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../src/types/openapi.ts"],"names":[],"mappings":""}
|