swagger-typescript-api 13.0.27 → 13.1.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 CHANGED
@@ -1,4 +1,4 @@
1
- # swagger-typescript-api
1
+ # Swagger TypeScript API
2
2
 
3
3
  - Support for OpenAPI 3.0, 2.0, JSON and YAML
4
4
  - Generate the API Client for Fetch or Axios from an OpenAPI Specification
@@ -11,464 +11,36 @@ All examples you can find [**here**](https://github.com/acacode/swagger-typescri
11
11
 
12
12
  ## Usage
13
13
 
14
- ```muse
15
- Usage: sta [options]
16
- Usage: swagger-typescript-api [options]
17
- Usage: swagger-typescript-api generate-templates [options]
14
+ You can use this package in two ways:
18
15
 
19
- Options:
20
- -v, --version output the current version
21
- -p, --path <string> path/url to swagger scheme
22
- -o, --output <string> output path of typescript api file (default: "./")
23
- -n, --name <string> name of output typescript api file (default: "Api.ts")
24
- -t, --templates <string> path to folder containing templates
25
- -d, --default-as-success use "default" response status code as success response too.
26
- some swagger schemas use "default" response status code as success response type by default. (default: false)
27
- -r, --responses generate additional information about request responses
28
- also add typings for bad responses (default: false)
29
- --union-enums generate all "enum" types as union types (T1 | T2 | TN) (default: false)
30
- --add-readonly generate readonly properties (default: false)
31
- --route-types generate type definitions for API routes (default: false)
32
- --no-client do not generate an API class
33
- --enum-names-as-values use values in 'x-enumNames' as enum values (not only as keys) (default: false)
34
- --extract-request-params extract request params to data contract (Also combine path params and query params into one object) (default: false)
35
- --extract-request-body extract request body type to data contract (default: false)
36
- --extract-response-body extract response body type to data contract (default: false)
37
- --extract-response-error extract response error type to data contract (default: false)
38
- --modular generate separated files for http client, data contracts, and routes (default: false)
39
- --js generate js api module with declaration file (default: false)
40
- --module-name-index <number> determines which path index should be used for routes separation (example: GET:/fruits/getFruit -> index:0 -> moduleName -> fruits) (default: 0)
41
- --module-name-first-tag splits routes based on the first tag (default: false)
42
- --axios generate axios http client (default: false)
43
- --unwrap-response-data unwrap the data item from the response (default: false)
44
- --disable-throw-on-error Do not throw an error when response.ok is not true (default: false)
45
- --single-http-client Ability to send HttpClient instance to Api constructor (default: false)
46
- --silent Output only errors to console (default: false)
47
- --default-response <type> default type for empty response schema (default: "void")
48
- --type-prefix <string> data contract name prefix (default: "")
49
- --type-suffix <string> data contract name suffix (default: "")
50
- --clean-output clean output folder before generate api. WARNING: May cause data loss (default: false)
51
- --api-class-name <string> name of the api class (default: "Api")
52
- --patch fix up small errors in the swagger source definition (default: false)
53
- --debug additional information about processes inside this tool (default: false)
54
- --another-array-type generate array types as Array<Type> (by default Type[]) (default: false)
55
- --sort-types sort fields and types (default: false)
56
- --sort-routes sort routes in alphabetical order (default: false)
57
- --custom-config <string> custom config: primitiveTypeConstructs, hooks, ... (default: "")
58
- --extract-enums extract all enums from inline interface\type content to typescript enum construction (default: false)
59
- -h, --help display help for command
16
+ ### CLI
60
17
 
61
- Commands:
62
- generate-templates Generate ".ejs" templates needed for generate api
63
- -o, --output <string> output path of generated templates
64
- -m, --modular generate templates needed to separate files for http client, data contracts, and routes (default: false)
65
- --http-client <string> http client type (possible values: "fetch", "axios") (default: "fetch")
66
- -c, --clean-output clean output folder before generate template. WARNING: May cause data loss (default: false)
67
- -r, --rewrite rewrite content in existing templates (default: false)
68
- --silent Output only errors to console (default: false)
69
- -h, --help display help for command
18
+ ```bash
19
+ npx swagger-typescript-api generate --path ./swagger.json
70
20
  ```
71
21
 
72
- Also you can use `npx`:
22
+ Or install locally in your project:
73
23
 
24
+ ```bash
25
+ npm install --save-dev swagger-typescript-api
26
+ npx swagger-typescript-api generate --path ./swagger.json
74
27
  ```
75
- npx swagger-typescript-api -p ./swagger.json -o ./src -n myApi.ts
76
- ```
77
-
78
- You can use this package from nodejs:
79
-
80
- ```js
81
- import fs from "node:fs";
82
- import path from "node:path";
83
- import { generateApi, generateTemplates } from "swagger-typescript-api";
84
-
85
- /* NOTE: all fields are optional expect one of `input`, `url`, `spec` */
86
- generateApi({
87
- fileName: "MySuperbApi.ts",
88
- // set to `false` to prevent the tool from writing to disk
89
- output: path.resolve(process.cwd(), "./src/__generated__"),
90
- url: "http://api.com/swagger.json",
91
- input: path.resolve(process.cwd(), "./foo/swagger.json"),
92
- spec: {
93
- swagger: "2.0",
94
- info: {
95
- version: "1.0.0",
96
- title: "Swagger Petstore",
97
- },
98
- // ...
99
- },
100
- templates: path.resolve(process.cwd(), "./api-templates"),
101
- httpClientType: "axios", // or "fetch"
102
- defaultResponseAsSuccess: false,
103
- generateClient: true,
104
- generateRouteTypes: false,
105
- generateResponses: true,
106
- toJS: false,
107
- extractRequestParams: false,
108
- extractRequestBody: false,
109
- extractEnums: false,
110
- unwrapResponseData: false,
111
- prettier: {
112
- // By default prettier config is load from your project
113
- printWidth: 120,
114
- tabWidth: 2,
115
- trailingComma: "all",
116
- parser: "typescript",
117
- },
118
- defaultResponseType: "void",
119
- singleHttpClient: true,
120
- cleanOutput: false,
121
- enumNamesAsValues: false,
122
- moduleNameFirstTag: false,
123
- generateUnionEnums: false,
124
- typePrefix: "",
125
- typeSuffix: "",
126
- enumKeyPrefix: "",
127
- enumKeySuffix: "",
128
- addReadonly: false,
129
- sortTypes: false,
130
- sortRouters: false,
131
- extractingOptions: {
132
- requestBodySuffix: ["Payload", "Body", "Input"],
133
- requestParamsSuffix: ["Params"],
134
- responseBodySuffix: ["Data", "Result", "Output"],
135
- responseErrorSuffix: [
136
- "Error",
137
- "Fail",
138
- "Fails",
139
- "ErrorData",
140
- "HttpError",
141
- "BadResponse",
142
- ],
143
- },
144
- /** allow to generate extra files based with this extra templates, see more below */
145
- extraTemplates: [],
146
- anotherArrayType: false,
147
- fixInvalidTypeNamePrefix: "Type",
148
- fixInvalidEnumKeyPrefix: "Value",
149
- codeGenConstructs: (constructs) => ({
150
- ...constructs,
151
- RecordType: (key, value) => `MyRecord<key, value>`,
152
- }),
153
- primitiveTypeConstructs: (constructs) => ({
154
- ...constructs,
155
- string: {
156
- "date-time": "Date",
157
- },
158
- }),
159
- hooks: {
160
- onCreateComponent: (component) => {},
161
- onCreateRequestParams: (rawType) => {},
162
- onCreateRoute: (routeData) => {},
163
- onCreateRouteName: (routeNameInfo, rawRouteInfo) => {},
164
- onFormatRouteName: (routeInfo, templateRouteName) => {},
165
- onFormatTypeName: (typeName, rawTypeName, schemaType) => {},
166
- onInit: (configuration) => {},
167
- onPreParseSchema: (originalSchema, typeName, schemaType) => {},
168
- onParseSchema: (originalSchema, parsedSchema) => {},
169
- onPrepareConfig: (currentConfiguration) => {},
170
- },
171
- })
172
- .then(({ files, configuration }) => {
173
- files.forEach(({ content, name }) => {
174
- fs.writeFile(path, content);
175
- });
176
- })
177
- .catch((e) => console.error(e));
178
-
179
- generateTemplates({
180
- cleanOutput: false,
181
- output: PATH_TO_OUTPUT_DIR,
182
- httpClientType: "fetch",
183
- modular: false,
184
- silent: false,
185
- rewrite: false,
186
- });
187
- ```
188
-
189
- ## Options
190
-
191
- ### **`--templates`**
192
-
193
- This option needed for cases when you don't want to use the default `swagger-typescript-api` output structure
194
- You can create custom templates with extensions `.ejs` or `.eta`
195
-
196
- Templates:
197
-
198
- - `api.ejs` - _(generates file)_ Api class module (locations: [/templates/default](https://github.com/acacode/swagger-typescript-api/tree/main/templates/default/api.ejs), [/templates/modular](https://github.com/acacode/swagger-typescript-api/tree/main/templates/modular/api.ejs))
199
- - `data-contracts.ejs` - _(generates file)_ all types (data contracts) from swagger schema (locations: [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base/data-contracts.ejs))
200
- - `http-client.ejs` - _(generates file)_ HttpClient class module (locations: [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base/http-client.ejs))
201
- - `procedure-call.ejs` - _(subtemplate)_ route in Api class (locations: [/templates/default](https://github.com/acacode/swagger-typescript-api/tree/main/templates/default/procedure-call.ejs), [/templates/modular](https://github.com/acacode/swagger-typescript-api/tree/main/templates/modular/procedure-call.ejs))
202
- - `route-docs.ejs` - _(generates file)_ documentation for route in Api class (locations: [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base/route-docs.ejs))
203
- - `route-name.ejs` - _(subtemplate)_ route name for route in Api class (locations: [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base/route-name.ejs))
204
- - `route-type.ejs` - _(`--route-types` option)_ _(subtemplate)_ (locations: [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base/route-type.ejs))
205
- - `route-types.ejs` - _(`--route-types` option)_ _(subtemplate)_ (locations: [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base/route-types.ejs))
206
- - `data-contract-jsdoc.ejs` - _(subtemplate)_ generates JSDOC for data contract (locations: [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base/data-contract-jsdoc.ejs))
207
-
208
- [//]: # "- `enum-data-contract.ejs` - *(subtemplate)* generates `enum` data contract (locations: [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base/enum-data-contract.ejs))"
209
- [//]: # "- `interface-data-contract.ejs` - *(subtemplate)* generates `interface` data contract (locations: [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base/interface-data-contract.ejs))"
210
- [//]: # "- `type-data-contract.ejs` - *(subtemplate)* generates `type` data contract (locations: [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base/type-data-contract.ejs))"
211
-
212
- How to use it:
213
-
214
- 1. copy `swagger-typescript-api` templates into your place in project
215
- - from [/templates/default](https://github.com/acacode/swagger-typescript-api/tree/main/templates/default) for single api file
216
- - from [/templates/modular](https://github.com/acacode/swagger-typescript-api/tree/main/templates/modular) for multiple api files (with `--modular` option)
217
- - from [/templates/base](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base) for base templates (templates using both in default and modular)
218
- 1. add `--templates PATH_TO_YOUR_TEMPLATES` option
219
- 1. modify [ETA](https://eta.js.org/docs/syntax) templates as you like
220
-
221
- NOTE:
222
- Eta has special directive to render template in your Eta templates - `includeFile(pathToTemplate, payload)`
223
- If you want to use some default templates from this tool you can use path prefixes: `@base`, `@default`, `@modular`.
224
- `@base` - [path to base templates](https://github.com/acacode/swagger-typescript-api/tree/main/templates/base)
225
- `@default` - [path to single api file templates](https://github.com/acacode/swagger-typescript-api/tree/main/templates/default)
226
- `@modular` - [path to multiple api files templates](https://github.com/acacode/swagger-typescript-api/tree/main/templates/modular)
227
- Examples: - `includeFile("@base/data-contracts.ejs", { ...yourData, ...it })` - `includeFile("@default/api.ejs", { ...yourData, ...it })` - `includeFile("@default/procedure-call.ejs", { ...yourData, ...it })` - `includeFile("@modular/api.ejs", { ...yourData, ...it })` - `includeFile("@modular/procedure-call.ejs", { ...yourData, ...it })` - `includeFile("@base/route-docs.ejs", { ...yourData, ...it })` - `includeFile("@base/route-name.ejs", { ...yourData, ...it })` - `includeFile("@base/route-type.ejs", { ...yourData, ...it })` - `includeFile("@base/route-types.ejs", { ...yourData, ...it })`
228
-
229
- ### **`--module-name-index`**
230
-
231
- This option should be used in cases when you have api with one global prefix like `/api`
232
- Example:
233
- `GET:/api/fruits/getFruits`
234
- `POST:/api/fruits/addFruits`
235
- `GET:/api/vegetables/addVegetable`
236
- with `--module-name-index 0` Api class will have one property `api`
237
- When we change it to `--module-name-index 1` then Api class have two properties `fruits` and `vegetables`
238
-
239
- ### **`--module-name-first-tag`**
240
-
241
- This option will group your API operations based on their first tag - mirroring how the Swagger UI groups displayed operations
242
-
243
- ### `extraTemplates` (NodeJS option)
244
-
245
- type `(Record<string, any> & { name: string, path: string })[]`
246
- This thing allow you to generate extra ts\js files based on extra templates (one extra template for one ts\js file)
247
- [Example here](https://github.com/acacode/swagger-typescript-api/tree/main/tests/spec/extra-templates)
248
-
249
- ## `generate-templates` command
250
-
251
- This command allows you to generate source templates which using with option `--templates`
252
-
253
- ## Modification internal codegen structs with NodeJS API:
254
-
255
- You are able to modify TypeScript internal structs using for generating output with using `generateApi` options `codeGenConstructs` and `primitiveTypeConstructs`.
256
-
257
- ### `codeGenConstructs`
258
-
259
- This option has type `(struct: CodeGenConstruct) => Partial<CodeGenConstruct>`.
260
-
261
- ```ts
262
- generateApi({
263
- // ...
264
- codeGenConstructs: (struct) => ({
265
- Keyword: {
266
- Number: "number",
267
- String: "string",
268
- Boolean: "boolean",
269
- Any: "any",
270
- Void: "void",
271
- Unknown: "unknown",
272
- Null: "null",
273
- Undefined: "undefined",
274
- Object: "object",
275
- File: "File",
276
- Date: "Date",
277
- Type: "type",
278
- Enum: "enum",
279
- Interface: "interface",
280
- Array: "Array",
281
- Record: "Record",
282
- Intersection: "&",
283
- Union: "|",
284
- },
285
- CodeGenKeyword: {
286
- UtilRequiredKeys: "UtilRequiredKeys",
287
- },
288
- /**
289
- * $A[] or Array<$A>
290
- */
291
- ArrayType: (content) => {
292
- if (this.anotherArrayType) {
293
- return `Array<${content}>`;
294
- }
295
-
296
- return `(${content})[]`;
297
- },
298
- /**
299
- * "$A"
300
- */
301
- StringValue: (content) => `"${content}"`,
302
- /**
303
- * $A
304
- */
305
- BooleanValue: (content) => `${content}`,
306
- /**
307
- * $A
308
- */
309
- NumberValue: (content) => `${content}`,
310
- /**
311
- * $A
312
- */
313
- NullValue: (content) => content,
314
- /**
315
- * $A1 | $A2
316
- */
317
- UnionType: (contents) => _.join(_.uniq(contents), ` | `),
318
- /**
319
- * ($A1)
320
- */
321
- ExpressionGroup: (content) => (content ? `(${content})` : ""),
322
- /**
323
- * $A1 & $A2
324
- */
325
- IntersectionType: (contents) => _.join(_.uniq(contents), ` & `),
326
- /**
327
- * Record<$A1, $A2>
328
- */
329
- RecordType: (key, value) => `Record<${key}, ${value}>`,
330
- /**
331
- * readonly $key?:$value
332
- */
333
- TypeField: ({ readonly, key, optional, value }) =>
334
- _.compact([
335
- readonly && "readonly ",
336
- key,
337
- optional && "?",
338
- ": ",
339
- value,
340
- ]).join(""),
341
- /**
342
- * [key: $A1]: $A2
343
- */
344
- InterfaceDynamicField: (key, value) => `[key: ${key}]: ${value}`,
345
- /**
346
- * $A1 = $A2
347
- */
348
- EnumField: (key, value) => `${key} = ${value}`,
349
- /**
350
- * $A0.key = $A0.value,
351
- * $A1.key = $A1.value,
352
- * $AN.key = $AN.value,
353
- */
354
- EnumFieldsWrapper: (contents) =>
355
- _.map(contents, ({ key, value }) => ` ${key} = ${value}`).join(",\n"),
356
- /**
357
- * {\n $A \n}
358
- */
359
- ObjectWrapper: (content) => `{\n${content}\n}`,
360
- /**
361
- * /** $A *\/
362
- */
363
- MultilineComment: (contents, formatFn) =>
364
- [
365
- ...(contents.length === 1
366
- ? [`/** ${contents[0]} */`]
367
- : ["/**", ...contents.map((content) => ` * ${content}`), " */"]),
368
- ].map((part) => `${formatFn ? formatFn(part) : part}\n`),
369
- /**
370
- * $A1<...$A2.join(,)>
371
- */
372
- TypeWithGeneric: (typeName, genericArgs) => {
373
- return `${typeName}${
374
- genericArgs.length ? `<${genericArgs.join(",")}>` : ""
375
- }`;
376
- },
377
- }),
378
- });
379
- ```
380
-
381
- For example, if you need to generate output `Record<string, any>` instead of `object` you can do it with using following code:
382
-
383
- ```ts
384
- generateApi({
385
- // ...
386
- codeGenConstructs: (struct) => ({
387
- Keyword: {
388
- Object: "Record<string, any>",
389
- },
390
- }),
391
- });
392
- ```
393
-
394
- ### `primitiveTypeConstructs`
395
-
396
- It is type mapper or translator swagger schema objects. `primitiveTypeConstructs` translates `type`/`format` schema fields to typescript structs.
397
- This option has type
398
-
399
- ```ts
400
- type PrimitiveTypeStructValue =
401
- | string
402
- | ((
403
- schema: Record<string, any>,
404
- parser: import("./src/schema-parser/schema-parser").SchemaParser
405
- ) => string);
406
-
407
- type PrimitiveTypeStruct = Record<
408
- "integer" | "number" | "boolean" | "object" | "file" | "string" | "array",
409
- | string
410
- | ({ $default: PrimitiveTypeStructValue } & Record<
411
- string,
412
- PrimitiveTypeStructValue
413
- >)
414
- >;
415
-
416
- declare const primitiveTypeConstructs: (
417
- struct: PrimitiveTypeStruct
418
- ) => Partial<PrimitiveTypeStruct>;
419
28
 
420
- generateApi({
421
- // ...
422
- primitiveTypeConstructs: (struct) => ({
423
- integer: () => "number",
424
- number: () => "number",
425
- boolean: () => "boolean",
426
- object: () => "object",
427
- file: () => "File",
428
- string: {
429
- $default: () => "string",
29
+ ### Library
430
30
 
431
- /** formats */
432
- binary: () => "File",
433
- file: () => "File",
434
- "date-time": () => "string",
435
- time: () => "string",
436
- date: () => "string",
437
- duration: () => "string",
438
- email: () => "string",
439
- "idn-email": () => "string",
440
- "idn-hostname": () => "string",
441
- ipv4: () => "string",
442
- ipv6: () => "string",
443
- uuid: () => "string",
444
- uri: () => "string",
445
- "uri-reference": () => "string",
446
- "uri-template": () => "string",
447
- "json-pointer": () => "string",
448
- "relative-json-pointer": () => "string",
449
- regex: () => "string",
450
- },
451
- array: (schema, parser) => {
452
- const content = parser.getInlineParseContent(schema.items);
453
- return parser.safeAddNullToType(schema, `(${content})[]`);
454
- },
455
- }),
456
- });
31
+ ```bash
32
+ npm install --save-dev swagger-typescript-api
457
33
  ```
458
34
 
459
- For example, if you need to change `"string"/"date-time"` default output as `string` to `Date` you can do it with using following code:
35
+ ```typescript
36
+ import * as path from "node:path";
37
+ import * as process from "node:process";
38
+ import { generateApi } from "swagger-typescript-api";
460
39
 
461
- ```ts
462
- generateApi({
463
- primitiveTypeConstructs: (struct) => ({
464
- string: {
465
- "date-time": "Date",
466
- },
467
- }),
468
- });
40
+ await generateApi({ input: path.resolve(process.cwd(), "./swagger.json") });
469
41
  ```
470
42
 
471
- See more about [swagger schema type/format data here](https://json-schema.org/understanding-json-schema/reference/string.html#dates-and-times)
43
+ For more detailed configuration options, please consult the documentation.
472
44
 
473
45
  ## Mass media
474
46