swaggie 1.7.1 → 1.8.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 +24 -0
- package/dist/cli.js +12 -1
- package/dist/gen/genTypes.js +31 -6
- package/dist/gen/index.js +8 -2
- package/dist/index.js +15 -2
- package/dist/swagger/typesExtractor.js +4 -0
- package/dist/types.d.ts +10 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,6 +78,8 @@ swaggie -s https://petstore3.swagger.io/api/v3/openapi.json -o ./client/petstore
|
|
|
78
78
|
-o, --out <filePath> Output file path (omit to print to stdout)
|
|
79
79
|
-b, --baseUrl <string> Default base URL for the generated client (default: "")
|
|
80
80
|
-t, --template <string> Template to use for code generation (default: "axios")
|
|
81
|
+
-m, --mode <mode> Generation mode: "full" or "schemas" (default: "full")
|
|
82
|
+
-d, --schemaStyle <style> Schema object style: "interface" or "type" (default: "interface")
|
|
81
83
|
--preferAny Use "any" instead of "unknown" for untyped values (default: false)
|
|
82
84
|
--skipDeprecated Exclude deprecated operations from the output (default: false)
|
|
83
85
|
--servicePrefix Prefix for service names — useful when generating multiple APIs
|
|
@@ -119,6 +121,8 @@ swaggie -c swaggie.config.json
|
|
|
119
121
|
"servicePrefix": "",
|
|
120
122
|
"dateFormat": "Date",
|
|
121
123
|
"nullableStrategy": "ignore",
|
|
124
|
+
"generationMode": "full",
|
|
125
|
+
"schemaDeclarationStyle": "interface",
|
|
122
126
|
"queryParamsSerialization": {
|
|
123
127
|
"arrayFormat": "repeat",
|
|
124
128
|
"allowDots": true
|
|
@@ -255,6 +259,26 @@ OpenAPI 3.0 allows fields to be marked as `nullable: true`. Swaggie gives you th
|
|
|
255
259
|
// nullableStrategy: "nullableAsOptional" → tenant?: string;
|
|
256
260
|
```
|
|
257
261
|
|
|
262
|
+
### Generation Mode
|
|
263
|
+
|
|
264
|
+
Use `generationMode` (or CLI `--mode`) to control what gets generated:
|
|
265
|
+
|
|
266
|
+
| Value | Behavior |
|
|
267
|
+
| ----------- | ------------------------------------------------------------------------------ |
|
|
268
|
+
| `"full"` | Generates full client code + used schemas (default, existing behavior) |
|
|
269
|
+
| `"schemas"`| Generates only schemas and includes all component schemas by default |
|
|
270
|
+
|
|
271
|
+
`"schemas"` mode intentionally does not run the used-schema heuristic.
|
|
272
|
+
|
|
273
|
+
### Schema Declaration Style
|
|
274
|
+
|
|
275
|
+
Use `schemaDeclarationStyle` (or CLI `--schemaStyle`) to control object schema output:
|
|
276
|
+
|
|
277
|
+
| Value | Behavior |
|
|
278
|
+
| ------------- | ------------------------------------------------------------------------ |
|
|
279
|
+
| `"interface"`| `export interface Tag { ... }` (default) |
|
|
280
|
+
| `"type"` | `export type Tag = { ... };` |
|
|
281
|
+
|
|
258
282
|
### Parameter Modifiers
|
|
259
283
|
|
|
260
284
|
Sometimes an API spec marks a parameter as required, but your client handles it in an interceptor and you don't want it cluttering every method signature. Parameter modifiers let you override this globally without touching the spec.
|
package/dist/cli.js
CHANGED
|
@@ -15,6 +15,15 @@ const arrayFormatOption = new (0, _commander.Option)(
|
|
|
15
15
|
|
|
16
16
|
const packageJson = readPackageJson();
|
|
17
17
|
|
|
18
|
+
const modeOption = new (0, _commander.Option)('-m, --mode <mode>', 'Generation mode').choices([
|
|
19
|
+
'full',
|
|
20
|
+
'schemas',
|
|
21
|
+
]);
|
|
22
|
+
const schemaStyleOption = new (0, _commander.Option)(
|
|
23
|
+
'-d, --schemaStyle <style>',
|
|
24
|
+
'Schema object declaration style'
|
|
25
|
+
).choices(['interface', 'type']);
|
|
26
|
+
|
|
18
27
|
const program = new (0, _commander.Command)();
|
|
19
28
|
program
|
|
20
29
|
.version(packageJson.version)
|
|
@@ -53,7 +62,9 @@ program
|
|
|
53
62
|
'--allowDots <bool>',
|
|
54
63
|
'Determines if dots should be used for serialization object properties'
|
|
55
64
|
)
|
|
56
|
-
.addOption(arrayFormatOption)
|
|
65
|
+
.addOption(arrayFormatOption)
|
|
66
|
+
.addOption(modeOption)
|
|
67
|
+
.addOption(schemaStyleOption);
|
|
57
68
|
|
|
58
69
|
program.parse(process.argv);
|
|
59
70
|
|
package/dist/gen/genTypes.js
CHANGED
|
@@ -46,6 +46,7 @@ function renderSchema(
|
|
|
46
46
|
schema,
|
|
47
47
|
options
|
|
48
48
|
) {
|
|
49
|
+
const useTypeAliases = options.schemaDeclarationStyle === 'type';
|
|
49
50
|
const safeName = _swagger.getSafeIdentifier.call(void 0, name);
|
|
50
51
|
if (!safeName) {
|
|
51
52
|
console.warn(`Skipping schema ${name} because it is not a valid identifier`);
|
|
@@ -81,11 +82,18 @@ function renderSchema(
|
|
|
81
82
|
|
|
82
83
|
if ('allOf' in schema) {
|
|
83
84
|
const types = _swagger.getRefCompositeTypes.call(void 0, schema);
|
|
85
|
+
const mergedSchema = getMergedCompositeObjects(schema);
|
|
86
|
+
const objectContents = generateObjectTypeContents(mergedSchema, options);
|
|
87
|
+
|
|
88
|
+
if (useTypeAliases) {
|
|
89
|
+
const compositeTypes = [...types, `{${objectContents ? `\n${objectContents}\n` : ''}}`].join(' & ');
|
|
90
|
+
result.push(`export type ${safeName} = ${compositeTypes};`);
|
|
91
|
+
return `${result.join('\n')}\n`;
|
|
92
|
+
}
|
|
93
|
+
|
|
84
94
|
const extensions = types ? `extends ${types.join(', ')} ` : '';
|
|
85
95
|
result.push(`export interface ${safeName} ${extensions}{`);
|
|
86
|
-
|
|
87
|
-
const mergedSchema = getMergedCompositeObjects(schema);
|
|
88
|
-
result.push(generateObjectTypeContents(mergedSchema, options));
|
|
96
|
+
result.push(objectContents);
|
|
89
97
|
} else if ('oneOf' in schema || 'anyOf' in schema) {
|
|
90
98
|
const typeDefinition = getTypesFromAnyOrOneOf(schema, options);
|
|
91
99
|
result.push(`export type ${safeName} = ${typeDefinition};`);
|
|
@@ -97,11 +105,18 @@ function renderSchema(
|
|
|
97
105
|
result.push(`export type ${safeName} = ${generateItemsType(schema.items, options)}[];`);
|
|
98
106
|
return result.join('\n');
|
|
99
107
|
} else {
|
|
108
|
+
const objectContents = generateObjectTypeContents(schema, options);
|
|
109
|
+
if (useTypeAliases) {
|
|
110
|
+
result.push(`export type ${safeName} = {`);
|
|
111
|
+
result.push(objectContents);
|
|
112
|
+
return `${result.join('\n')}\n};\n`;
|
|
113
|
+
}
|
|
114
|
+
|
|
100
115
|
result.push(`export interface ${safeName} {`);
|
|
101
|
-
result.push(
|
|
116
|
+
result.push(objectContents);
|
|
102
117
|
}
|
|
103
118
|
|
|
104
|
-
return `${result.join('\n')}}\n`;
|
|
119
|
+
return `${result.join('\n')}\n}\n`;
|
|
105
120
|
}
|
|
106
121
|
|
|
107
122
|
/**
|
|
@@ -198,7 +213,10 @@ function renderTypeProp(
|
|
|
198
213
|
const type = _swagger.getTypeFromSchema.call(void 0, definition, options);
|
|
199
214
|
|
|
200
215
|
if ('description' in definition || 'title' in definition) {
|
|
201
|
-
|
|
216
|
+
const renderedComment = _jsDocs.renderComment.call(void 0, _nullishCoalesce(definition.description, () => ( definition.title)));
|
|
217
|
+
if (renderedComment) {
|
|
218
|
+
lines.push(indentComment(renderedComment, ' '));
|
|
219
|
+
}
|
|
202
220
|
}
|
|
203
221
|
|
|
204
222
|
const isOptional = !required || isNullableAsOptional(definition, options);
|
|
@@ -211,6 +229,13 @@ function renderTypeProp(
|
|
|
211
229
|
return lines.join('\n');
|
|
212
230
|
}
|
|
213
231
|
|
|
232
|
+
function indentComment(comment, indent) {
|
|
233
|
+
return comment
|
|
234
|
+
.split('\n')
|
|
235
|
+
.map((line) => `${indent}${line}`)
|
|
236
|
+
.join('\n');
|
|
237
|
+
}
|
|
238
|
+
|
|
214
239
|
/**
|
|
215
240
|
* When nullableAsOptional strategy is set, nullable properties are treated as optional.
|
|
216
241
|
* Supports both OA3.0 (nullable: true) and OA3.1 (type: ["string", "null"]).
|
package/dist/gen/index.js
CHANGED
|
@@ -9,8 +9,14 @@ var _utils = require('../utils');
|
|
|
9
9
|
spec,
|
|
10
10
|
options
|
|
11
11
|
) {
|
|
12
|
-
let fileContents =
|
|
13
|
-
|
|
12
|
+
let fileContents = '';
|
|
13
|
+
|
|
14
|
+
if (options.generationMode === 'schemas') {
|
|
15
|
+
fileContents = _genTypes2.default.call(void 0, spec, options, false);
|
|
16
|
+
} else {
|
|
17
|
+
fileContents = await _genOperations2.default.call(void 0, spec, options);
|
|
18
|
+
fileContents += _genTypes2.default.call(void 0, spec, options);
|
|
19
|
+
}
|
|
14
20
|
|
|
15
21
|
if (options.out) {
|
|
16
22
|
const destFile = _utils.prepareOutputFilename.call(void 0, options.out);
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,9 @@ function verifyOptions(options) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
function gen(spec, options) {
|
|
37
|
-
|
|
37
|
+
if (options.generationMode === 'full') {
|
|
38
|
+
_utils.loadAllTemplateFiles.call(void 0, options.template);
|
|
39
|
+
}
|
|
38
40
|
|
|
39
41
|
return _gen2.default.call(void 0, spec, options);
|
|
40
42
|
}
|
|
@@ -76,7 +78,15 @@ function readFile(filePath) {
|
|
|
76
78
|
* object where every defaultable field is guaranteed to be present.
|
|
77
79
|
*/
|
|
78
80
|
function prepareAppOptions(cliOpts) {
|
|
79
|
-
const {
|
|
81
|
+
const {
|
|
82
|
+
allowDots,
|
|
83
|
+
arrayFormat,
|
|
84
|
+
mode,
|
|
85
|
+
schemaStyle,
|
|
86
|
+
template,
|
|
87
|
+
queryParamsSerialization = {},
|
|
88
|
+
...rest
|
|
89
|
+
} = cliOpts;
|
|
80
90
|
const mergedQueryParamsSerialization = {
|
|
81
91
|
..._swagger.APP_DEFAULTS.queryParamsSerialization,
|
|
82
92
|
...Object.fromEntries(
|
|
@@ -91,6 +101,9 @@ function readFile(filePath) {
|
|
|
91
101
|
template: _nullishCoalesce(template, () => ( _swagger.APP_DEFAULTS.template)),
|
|
92
102
|
servicePrefix: _nullishCoalesce(rest.servicePrefix, () => ( _swagger.APP_DEFAULTS.servicePrefix)),
|
|
93
103
|
nullableStrategy: _nullishCoalesce(rest.nullableStrategy, () => ( _swagger.APP_DEFAULTS.nullableStrategy)),
|
|
104
|
+
generationMode: _nullishCoalesce(_nullishCoalesce(mode, () => ( rest.generationMode)), () => ( _swagger.APP_DEFAULTS.generationMode)),
|
|
105
|
+
schemaDeclarationStyle:
|
|
106
|
+
_nullishCoalesce(_nullishCoalesce(schemaStyle, () => ( rest.schemaDeclarationStyle)), () => ( _swagger.APP_DEFAULTS.schemaDeclarationStyle)),
|
|
94
107
|
queryParamsSerialization: mergedQueryParamsSerialization,
|
|
95
108
|
};
|
|
96
109
|
} exports.prepareAppOptions = prepareAppOptions;
|
|
@@ -262,6 +262,8 @@ function getTypeFromComposites(schema, options) {
|
|
|
262
262
|
template: 'axios',
|
|
263
263
|
servicePrefix: '',
|
|
264
264
|
nullableStrategy: 'ignore',
|
|
265
|
+
generationMode: 'full',
|
|
266
|
+
schemaDeclarationStyle: 'interface',
|
|
265
267
|
queryParamsSerialization: {
|
|
266
268
|
allowDots: true,
|
|
267
269
|
arrayFormat: 'repeat',
|
|
@@ -279,6 +281,8 @@ function getTypeFromComposites(schema, options) {
|
|
|
279
281
|
template: _nullishCoalesce(opts.template, () => ( exports.APP_DEFAULTS.template)),
|
|
280
282
|
servicePrefix: _nullishCoalesce(opts.servicePrefix, () => ( exports.APP_DEFAULTS.servicePrefix)),
|
|
281
283
|
nullableStrategy: _nullishCoalesce(opts.nullableStrategy, () => ( exports.APP_DEFAULTS.nullableStrategy)),
|
|
284
|
+
generationMode: _nullishCoalesce(opts.generationMode, () => ( exports.APP_DEFAULTS.generationMode)),
|
|
285
|
+
schemaDeclarationStyle: _nullishCoalesce(opts.schemaDeclarationStyle, () => ( exports.APP_DEFAULTS.schemaDeclarationStyle)),
|
|
282
286
|
queryParamsSerialization: {
|
|
283
287
|
...exports.APP_DEFAULTS.queryParamsSerialization,
|
|
284
288
|
...opts.queryParamsSerialization,
|
package/dist/types.d.ts
CHANGED
|
@@ -29,6 +29,10 @@ export interface ClientOptions {
|
|
|
29
29
|
nullableStrategy?: NullableStrategy;
|
|
30
30
|
/** Options for query parameters serialization */
|
|
31
31
|
queryParamsSerialization: QueryParamsSerializationOptions;
|
|
32
|
+
/** Controls whether to generate full client code or only component schemas */
|
|
33
|
+
generationMode?: GenerationMode;
|
|
34
|
+
/** Controls whether object schemas are emitted as interfaces or type aliases */
|
|
35
|
+
schemaDeclarationStyle?: SchemaDeclarationStyle;
|
|
32
36
|
/** Offers ability to adjust the OpenAPI spec before it is processed */
|
|
33
37
|
modifiers?: {
|
|
34
38
|
/** Global-level modifiers for parameter with a given name */
|
|
@@ -40,6 +44,8 @@ export interface ClientOptions {
|
|
|
40
44
|
export interface CliOptions extends FullAppOptions {
|
|
41
45
|
allowDots?: boolean;
|
|
42
46
|
arrayFormat?: ArrayFormat;
|
|
47
|
+
mode?: GenerationMode;
|
|
48
|
+
schemaStyle?: SchemaDeclarationStyle;
|
|
43
49
|
}
|
|
44
50
|
export interface FullAppOptions extends ClientOptions {
|
|
45
51
|
/** Path to the configuration file that contains actual config to be used */
|
|
@@ -50,6 +56,8 @@ export type HttpMethod = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head'
|
|
|
50
56
|
export type DateSupport = 'string' | 'Date';
|
|
51
57
|
export type ArrayFormat = 'indices' | 'repeat' | 'brackets';
|
|
52
58
|
export type NullableStrategy = 'include' | 'nullableAsOptional' | 'ignore';
|
|
59
|
+
export type GenerationMode = 'full' | 'schemas';
|
|
60
|
+
export type SchemaDeclarationStyle = 'interface' | 'type';
|
|
53
61
|
/**
|
|
54
62
|
* Internal options type used throughout the app after `prepareAppOptions` has run.
|
|
55
63
|
* All fields that have defaults are required here so the rest of the codebase never
|
|
@@ -59,6 +67,8 @@ export interface AppOptions extends ClientOptions {
|
|
|
59
67
|
template: Template;
|
|
60
68
|
servicePrefix: string;
|
|
61
69
|
nullableStrategy: NullableStrategy;
|
|
70
|
+
generationMode: GenerationMode;
|
|
71
|
+
schemaDeclarationStyle: SchemaDeclarationStyle;
|
|
62
72
|
queryParamsSerialization: {
|
|
63
73
|
allowDots: boolean;
|
|
64
74
|
arrayFormat: ArrayFormat;
|