swaggie 2.2.2 → 2.3.0
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 +15 -0
- package/dist/gen/genMocks.js +1 -6
- package/dist/gen/genOperations.js +34 -5
- package/dist/index.js +39 -0
- package/dist/types.d.ts +14 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -396,6 +396,21 @@ Sometimes an API spec marks a parameter as required, but your client handles it
|
|
|
396
396
|
- `"optional"` — the parameter becomes optional regardless of what the spec says
|
|
397
397
|
- `"required"` — the parameter is always required (generally better to just fix the spec)
|
|
398
398
|
|
|
399
|
+
### Excluding Operations
|
|
400
|
+
|
|
401
|
+
Use `exclude` to drop entire operations from the generated output by tag or `operationId` — without modifying the spec. Types used exclusively by excluded operations are pruned automatically. Both fields support `*` and `?` wildcards.
|
|
402
|
+
|
|
403
|
+
```json
|
|
404
|
+
{
|
|
405
|
+
"exclude": {
|
|
406
|
+
"tags": ["admin", "internal"],
|
|
407
|
+
"operationIds": ["deleteAccount", "admin*"]
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
See the [full documentation](https://yhnavein.github.io/swaggie/guide/advanced#excluding-operations) for details and examples.
|
|
413
|
+
|
|
399
414
|
### Code Quality
|
|
400
415
|
|
|
401
416
|
Swaggie's output is functional but not always perfectly formatted, since it uses a templating engine internally. It is strongly recommended to run the output through a formatter to ensure consistent style across regenerations.
|
package/dist/gen/genMocks.js
CHANGED
|
@@ -287,14 +287,9 @@ function withMockSWR<Fn extends (...args: never[]) => unknown>(spy: ${ref}.Spied
|
|
|
287
287
|
/** Augments a spy with a \`mockSWRMutation\` shorthand for useSWRMutation hooks. */
|
|
288
288
|
function withMockSWRMutation<Fn extends (...args: never[]) => unknown>(spy: ${ref}.SpiedFunction<Fn>) {
|
|
289
289
|
return Object.assign(spy, {
|
|
290
|
-
mockSWRMutation({
|
|
291
|
-
data,
|
|
292
|
-
...rest
|
|
293
|
-
}: MockSWRMutationReturn) {
|
|
290
|
+
mockSWRMutation({ ...rest }: MockSWRMutationReturn) {
|
|
294
291
|
spy.mockReturnValue({
|
|
295
292
|
...defaultSWRMutationReturn,
|
|
296
|
-
trigger: ${ref}.fn(() => Promise.resolve(undefined)),
|
|
297
|
-
data,
|
|
298
293
|
...rest,
|
|
299
294
|
} as ReturnType<Fn>);
|
|
300
295
|
},
|
|
@@ -255,6 +255,18 @@ function prepareClient(
|
|
|
255
255
|
ops = ops.filter((op) => !op.deprecated);
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
+
if (_optionalChain([options, 'access', _2 => _2.exclude, 'optionalAccess', _3 => _3.tags, 'optionalAccess', _4 => _4.length])) {
|
|
259
|
+
ops = ops.filter(
|
|
260
|
+
(op) => !_optionalChain([op, 'access', _5 => _5.tags, 'optionalAccess', _6 => _6.some, 'call', _7 => _7((t) => options.exclude.tags.some((p) => matchesPattern(t, p)))])
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (_optionalChain([options, 'access', _8 => _8.exclude, 'optionalAccess', _9 => _9.operationIds, 'optionalAccess', _10 => _10.length])) {
|
|
265
|
+
ops = ops.filter(
|
|
266
|
+
(op) => !options.exclude.operationIds.some((p) => matchesPattern(_nullishCoalesce(op.operationId, () => ( '')), p))
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
258
270
|
return ops.map((op) => {
|
|
259
271
|
const operationContext = `${op.method.toUpperCase()} ${op.path} (${op.operationId || 'unknown operationId'})`;
|
|
260
272
|
|
|
@@ -295,9 +307,9 @@ function prepareClient(
|
|
|
295
307
|
|
|
296
308
|
const headers = getParams(op.parameters , options, ['header']);
|
|
297
309
|
// Some libraries need explicit Content-Type for request bodies.
|
|
298
|
-
if (_optionalChain([body, 'optionalAccess',
|
|
310
|
+
if (_optionalChain([body, 'optionalAccess', _11 => _11.contentType]) === 'urlencoded') {
|
|
299
311
|
upsertFixedHeader(headers, 'Content-Type', 'application/x-www-form-urlencoded');
|
|
300
|
-
} else if (_optionalChain([body, 'optionalAccess',
|
|
312
|
+
} else if (_optionalChain([body, 'optionalAccess', _12 => _12.contentType]) === 'json' && _templateValidator.getL1Template.call(void 0, options.template) === 'fetch') {
|
|
301
313
|
upsertFixedHeader(headers, 'Content-Type', 'application/json');
|
|
302
314
|
}
|
|
303
315
|
|
|
@@ -485,10 +497,10 @@ function prepareUrl(path) {
|
|
|
485
497
|
type: _swagger.getParameterType.call(void 0, p, options),
|
|
486
498
|
optional: p.required === undefined || p.required === null ? true : !p.required,
|
|
487
499
|
original: p,
|
|
488
|
-
jsDoc: _optionalChain([p, 'access',
|
|
500
|
+
jsDoc: _optionalChain([p, 'access', _13 => _13.description, 'optionalAccess', _14 => _14.trim, 'call', _15 => _15()]),
|
|
489
501
|
}));
|
|
490
502
|
|
|
491
|
-
if (_optionalChain([options, 'access',
|
|
503
|
+
if (_optionalChain([options, 'access', _16 => _16.modifiers, 'optionalAccess', _17 => _17.parameters])) {
|
|
492
504
|
for (const [name, modifier] of Object.entries(options.modifiers.parameters)) {
|
|
493
505
|
const paramIndex = result.findIndex(
|
|
494
506
|
(p) => p.original.in !== 'path' && (p.originalName === name || p.name === name)
|
|
@@ -539,7 +551,7 @@ function getRequestBody(
|
|
|
539
551
|
let reqBody;
|
|
540
552
|
if ('$ref' in rawReqBody) {
|
|
541
553
|
const refName = rawReqBody.$ref.replace('#/components/requestBodies/', '');
|
|
542
|
-
const resolved = _optionalChain([components, 'optionalAccess',
|
|
554
|
+
const resolved = _optionalChain([components, 'optionalAccess', _18 => _18.requestBodies, 'optionalAccess', _19 => _19[refName]]);
|
|
543
555
|
if (!resolved || '$ref' in resolved) {
|
|
544
556
|
console.error(`RequestBody $ref '${rawReqBody.$ref}' not found in components/requestBodies`);
|
|
545
557
|
return null;
|
|
@@ -673,6 +685,23 @@ function getL1HttpTypeImport(template) {
|
|
|
673
685
|
}
|
|
674
686
|
}
|
|
675
687
|
|
|
688
|
+
/**
|
|
689
|
+
* Matches a value against a pattern that may contain `*` (any sequence of
|
|
690
|
+
* characters) or `?` (any single character). Falls back to exact equality for
|
|
691
|
+
* patterns that contain neither wildcard (fast path).
|
|
692
|
+
*/
|
|
693
|
+
function matchesPattern(value, pattern) {
|
|
694
|
+
if (!pattern.includes('*') && !pattern.includes('?')) {
|
|
695
|
+
return value === pattern;
|
|
696
|
+
}
|
|
697
|
+
const regex = new RegExp(
|
|
698
|
+
'^' +
|
|
699
|
+
pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*').replace(/\?/g, '.') +
|
|
700
|
+
'$'
|
|
701
|
+
);
|
|
702
|
+
return regex.test(value);
|
|
703
|
+
} exports.matchesPattern = matchesPattern;
|
|
704
|
+
|
|
676
705
|
function upsertFixedHeader(headers, headerName, value) {
|
|
677
706
|
const headerIndex = headers.findIndex(
|
|
678
707
|
(header) => header.originalName.toLowerCase() === headerName.toLowerCase()
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ var _gen = require('./gen'); var _gen2 = _interopRequireDefault(_gen);
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
|
|
13
14
|
var _utils = require('./utils');
|
|
14
15
|
var _templateValidator = require('./utils/templateValidator');
|
|
15
16
|
var _swagger = require('./swagger');
|
|
@@ -86,6 +87,7 @@ function verifyOptions(options) {
|
|
|
86
87
|
);
|
|
87
88
|
}
|
|
88
89
|
}
|
|
90
|
+
verifyExcludeOptions(options.exclude);
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
/**
|
|
@@ -126,6 +128,43 @@ function verifyEntryOptions(opts) {
|
|
|
126
128
|
);
|
|
127
129
|
}
|
|
128
130
|
}
|
|
131
|
+
verifyExcludeOptions(opts.exclude);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Returns true when a pattern looks like a regex (starts with `/` or contains
|
|
136
|
+
* regex-specific metacharacters that are not our supported wildcards).
|
|
137
|
+
* Our supported wildcards are `*` and `?` only.
|
|
138
|
+
*/
|
|
139
|
+
function isRegexPattern(pattern) {
|
|
140
|
+
if (pattern.startsWith('/')) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
// Characters that are regex metacharacters but are NOT our supported wildcards
|
|
144
|
+
const regexOnlyChars = /[\\^$.|+()[\]{}]/;
|
|
145
|
+
return regexOnlyChars.test(pattern);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Throws if any pattern in `exclude.tags` or `exclude.operationIds` looks like
|
|
150
|
+
* a regex. Only plain strings and * / ? wildcards are supported.
|
|
151
|
+
*/
|
|
152
|
+
function verifyExcludeOptions(exclude) {
|
|
153
|
+
if (!exclude) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const allPatterns = [
|
|
157
|
+
...(_nullishCoalesce(exclude.tags, () => ( []))).map((p) => ['exclude.tags', p]),
|
|
158
|
+
...(_nullishCoalesce(exclude.operationIds, () => ( []))).map((p) => ['exclude.operationIds', p]),
|
|
159
|
+
];
|
|
160
|
+
for (const [field, pattern] of allPatterns) {
|
|
161
|
+
if (isRegexPattern(pattern)) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
`Invalid pattern "${pattern}" in ${field}: regex patterns are not supported. ` +
|
|
164
|
+
'Use plain strings or wildcard patterns with * and ? only.'
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
129
168
|
}
|
|
130
169
|
|
|
131
170
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -4,6 +4,18 @@ interface QueryParamsSerializationOptions {
|
|
|
4
4
|
arrayFormat?: ArrayFormat;
|
|
5
5
|
queryParamsAsObject?: boolean | number;
|
|
6
6
|
}
|
|
7
|
+
export interface ExcludeOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Exclude operations whose first tag matches any of these values.
|
|
10
|
+
* Supports * (any sequence of characters) and ? (any single character) wildcards.
|
|
11
|
+
*/
|
|
12
|
+
tags?: string[];
|
|
13
|
+
/**
|
|
14
|
+
* Exclude operations whose operationId matches any of these values.
|
|
15
|
+
* Supports * (any sequence of characters) and ? (any single character) wildcards.
|
|
16
|
+
*/
|
|
17
|
+
operationIds?: string[];
|
|
18
|
+
}
|
|
7
19
|
export interface ClientOptions {
|
|
8
20
|
/**
|
|
9
21
|
* Path or URL to the Swagger specification file (JSON or YAML).
|
|
@@ -106,6 +118,8 @@ export interface ClientOptions {
|
|
|
106
118
|
[key: string]: 'optional' | 'required' | 'ignore';
|
|
107
119
|
};
|
|
108
120
|
};
|
|
121
|
+
/** Excludes specific operations from code generation by tag or operationId */
|
|
122
|
+
exclude?: ExcludeOptions;
|
|
109
123
|
}
|
|
110
124
|
export interface CliOptions extends Omit<FullAppOptions, 'enumNamesStyle'> {
|
|
111
125
|
allowDots?: boolean;
|