swagger-typescript-api 10.0.3 → 11.0.0--alpha

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 (53) hide show
  1. package/README.md +218 -0
  2. package/index.d.ts +93 -0
  3. package/index.js +230 -103
  4. package/package.json +121 -119
  5. package/src/code-formatter.js +101 -0
  6. package/src/code-gen-process.js +456 -0
  7. package/src/configuration.js +425 -0
  8. package/src/constants.js +14 -31
  9. package/src/index.js +6 -257
  10. package/src/schema-components-map.js +60 -0
  11. package/src/schema-parser/schema-formatters.js +145 -0
  12. package/src/schema-parser/schema-parser.js +497 -0
  13. package/src/schema-parser/schema-routes.js +902 -0
  14. package/src/swagger-schema-resolver.js +187 -0
  15. package/src/templates.js +141 -122
  16. package/src/translators/JavaScript.js +49 -49
  17. package/src/type-name.js +79 -0
  18. package/src/util/file-system.js +76 -0
  19. package/src/{utils → util}/id.js +0 -0
  20. package/src/util/internal-case.js +5 -0
  21. package/src/util/logger.js +100 -0
  22. package/src/{utils/resolveName.js → util/name-resolver.js} +1 -1
  23. package/src/util/object-assign.js +11 -0
  24. package/src/util/pascal-case.js +5 -0
  25. package/src/{utils → util}/random.js +1 -1
  26. package/templates/base/data-contract-jsdoc.ejs +29 -24
  27. package/templates/base/data-contracts.ejs +3 -3
  28. package/templates/base/interface-data-contract.ejs +1 -0
  29. package/templates/base/route-docs.ejs +2 -2
  30. package/templates/base/route-type.ejs +2 -2
  31. package/templates/default/route-types.ejs +2 -2
  32. package/templates/modular/api.ejs +2 -2
  33. package/templates/modular/route-types.ejs +2 -2
  34. package/src/apiConfig.js +0 -30
  35. package/src/common.js +0 -28
  36. package/src/components.js +0 -91
  37. package/src/config.js +0 -108
  38. package/src/filePrefix.js +0 -14
  39. package/src/files.js +0 -56
  40. package/src/formatFileContent.js +0 -81
  41. package/src/logger.js +0 -68
  42. package/src/modelNames.js +0 -74
  43. package/src/modelTypes.js +0 -31
  44. package/src/output.js +0 -165
  45. package/src/prettierOptions.js +0 -23
  46. package/src/render/utils/fmtToJSDocLine.js +0 -10
  47. package/src/render/utils/index.js +0 -31
  48. package/src/render/utils/templateRequire.js +0 -17
  49. package/src/routeNames.js +0 -46
  50. package/src/routes.js +0 -809
  51. package/src/schema.js +0 -474
  52. package/src/swagger.js +0 -152
  53. package/src/typeFormatters.js +0 -121
package/README.md CHANGED
@@ -71,6 +71,8 @@ Options:
71
71
  --clean-output clean output folder before generate api. WARNING: May cause data loss (default: false)
72
72
  --api-class-name <string> name of the api class
73
73
  --patch fix up small errors in the swagger source definition (default: false)
74
+ --debug additional information about processes inside this tool (default: false)
75
+ --another-array-type generate array types as Array<Type> (by default Type[]) (default: false)
74
76
  -h, --help display help for command
75
77
  ```
76
78
 
@@ -122,6 +124,17 @@ generateApi({
122
124
  generateUnionEnums: false,
123
125
  addReadonly: false,
124
126
  extraTemplates: [],
127
+ anotherArrayType: false,
128
+ codeGenConstructs: (constructs) => ({
129
+ ...constructs,
130
+ RecordType: (key, value) => `MyRecord<key, value>`
131
+ }),
132
+ primitiveTypeConstructs: (constructs) => ({
133
+ ...constructs,
134
+ string: {
135
+ 'date-time': 'Date'
136
+ }
137
+ }),
125
138
  hooks: {
126
139
  onCreateComponent: (component) => {},
127
140
  onCreateRequestParams: (rawType) => {},
@@ -203,8 +216,213 @@ When we change it to `--module-name-index 1` then Api class have two properties
203
216
  This option will group your API operations based on their first tag - mirroring how the Swagger UI groups displayed operations
204
217
 
205
218
 
219
+ ## Modification internal codegen structs with NodeJS API:
220
+
221
+ You are able to modify TypeScript internal structs using for generating output with using `generateApi` options `codeGenConstructs` and `primitiveTypeConstructs`.
222
+
223
+ ### `codeGenConstructs`
224
+
225
+ This option has type `(struct: CodeGenConstruct) => Partial<CodeGenConstruct>`.
226
+
227
+ ```ts
228
+ generateApi({
229
+ // ...
230
+ codeGenConstructs: (struct) => ({
231
+ Keyword: {
232
+ Number: "number",
233
+ String: "string",
234
+ Boolean: "boolean",
235
+ Any: "any",
236
+ Void: "void",
237
+ Unknown: "unknown",
238
+ Null: "null",
239
+ Undefined: "undefined",
240
+ Object: "object",
241
+ File: "File",
242
+ Date: "Date",
243
+ Type: "type",
244
+ Enum: "enum",
245
+ Interface: "interface",
246
+ Array: "Array",
247
+ Record: "Record",
248
+ Intersection: "&",
249
+ Union: "|",
250
+ },
251
+ CodeGenKeyword: {
252
+ UtilRequiredKeys: "UtilRequiredKeys",
253
+ },
254
+ /**
255
+ * $A[] or Array<$A>
256
+ */
257
+ ArrayType: (content) => {
258
+ if (this.anotherArrayType) {
259
+ return `Array<${content}>`;
260
+ }
261
+
262
+ return `(${content})[]`;
263
+ },
264
+ /**
265
+ * "$A"
266
+ */
267
+ StringValue: (content) => `"${content}"`,
268
+ /**
269
+ * $A
270
+ */
271
+ BooleanValue: (content) => `${content}`,
272
+ /**
273
+ * $A
274
+ */
275
+ NumberValue: (content) => `${content}`,
276
+ /**
277
+ * $A
278
+ */
279
+ NullValue: (content) => content,
280
+ /**
281
+ * $A1 | $A2
282
+ */
283
+ UnionType: (contents) => _.join(_.uniq(contents), ` | `),
284
+ /**
285
+ * ($A1)
286
+ */
287
+ ExpressionGroup: (content) => (content ? `(${content})` : ""),
288
+ /**
289
+ * $A1 & $A2
290
+ */
291
+ IntersectionType: (contents) => _.join(_.uniq(contents), ` & `),
292
+ /**
293
+ * Record<$A1, $A2>
294
+ */
295
+ RecordType: (key, value) => `Record<${key}, ${value}>`,
296
+ /**
297
+ * readonly $key?:$value
298
+ */
299
+ TypeField: ({ readonly, key, optional, value }) =>
300
+ _.compact([readonly && "readonly ", key, optional && "?", ": ", value]).join(""),
301
+ /**
302
+ * [key: $A1]: $A2
303
+ */
304
+ InterfaceDynamicField: (key, value) => `[key: ${key}]: ${value}`,
305
+ /**
306
+ * $A1 = $A2
307
+ */
308
+ EnumField: (key, value) => `${key} = ${value}`,
309
+ /**
310
+ * $A0.key = $A0.value,
311
+ * $A1.key = $A1.value,
312
+ * $AN.key = $AN.value,
313
+ */
314
+ EnumFieldsWrapper: (contents) =>
315
+ _.map(contents, ({ key, value }) => ` ${key} = ${value}`).join(",\n"),
316
+ /**
317
+ * {\n $A \n}
318
+ */
319
+ ObjectWrapper: (content) => `{\n${content}\n}`,
320
+ /**
321
+ * /** $A *\/
322
+ */
323
+ MultilineComment: (contents, formatFn) =>
324
+ [
325
+ ...(contents.length === 1
326
+ ? [`/** ${contents[0]} */`]
327
+ : ["/**", ...contents.map((content) => ` * ${content}`), " */"]),
328
+ ].map((part) => `${formatFn ? formatFn(part) : part}\n`),
329
+ /**
330
+ * $A1<...$A2.join(,)>
331
+ */
332
+ TypeWithGeneric: (typeName, genericArgs) => {
333
+ return `${typeName}${genericArgs.length ? `<${genericArgs.join(",")}>` : ""}`;
334
+ },
335
+ })
336
+ })
337
+ ```
338
+
339
+ For example, if you need to generate output `Record<string, any>` instead of `object` you can do it with using following code:
340
+
341
+ ```ts
342
+ generateApi({
343
+ // ...
344
+ codeGenConstructs: (struct) => ({
345
+ Keyword: {
346
+ Object: "Record<string, any>",
347
+ }
348
+ })
349
+ })
350
+ ```
351
+
352
+ ### `primitiveTypeConstructs`
353
+
354
+ It is type mapper or translator swagger schema objects. `primitiveTypeConstructs` translates `type`/`format` schema fields to typescript structs.
355
+ This option has type
356
+ ```ts
357
+ type PrimitiveTypeStructValue =
358
+ | string
359
+ | ((schema: Record<string, any>, parser: import("./src/schema-parser/schema-parser").SchemaParser) => string);
360
+
361
+ type PrimitiveTypeStruct = Record<
362
+ "integer" | "number" | "boolean" | "object" | "file" | "string" | "array",
363
+ string | ({ $default: PrimitiveTypeStructValue } & Record<string, PrimitiveTypeStructValue>)
364
+ >
365
+
366
+ declare const primitiveTypeConstructs: (struct: PrimitiveTypeStruct) => Partial<PrimitiveTypeStruct>
367
+
368
+ generateApi({
369
+ // ...
370
+ primitiveTypeConstructs: (struct) => ({
371
+ integer: () => "number",
372
+ number: () => "number",
373
+ boolean: () => "boolean",
374
+ object: () => "object",
375
+ file: () => "File",
376
+ string: {
377
+ $default: () => "string",
378
+
379
+ /** formats */
380
+ binary: () => "File",
381
+ file: () => "File",
382
+ "date-time": () => "string",
383
+ time: () => "string",
384
+ date: () => "string",
385
+ duration: () => "string",
386
+ email: () => "string",
387
+ "idn-email": () => "string",
388
+ "idn-hostname": () => "string",
389
+ ipv4: () => "string",
390
+ ipv6: () => "string",
391
+ uuid: () => "string",
392
+ uri: () => "string",
393
+ "uri-reference": () => "string",
394
+ "uri-template": () => "string",
395
+ "json-pointer": () => "string",
396
+ "relative-json-pointer": () => "string",
397
+ regex: () => "string",
398
+ },
399
+ array: (schema, parser) => {
400
+ const content = parser.getInlineParseContent(schema.items);
401
+ return parser.checkAndAddNull(schema, `(${content})[]`);
402
+ },
403
+ })
404
+ })
405
+ ```
406
+
407
+ For example, if you need to change `"string"/"date-time"` default output as `string` to `Date` you can do it with using following code:
408
+
409
+ ```ts
410
+
411
+ generateApi({
412
+ primitiveTypeConstructs: (struct) => ({
413
+ string: {
414
+ "date-time": "Date",
415
+ },
416
+ })
417
+ })
418
+
419
+ ```
420
+
421
+ See more about [swagger schema type/format data here](https://json-schema.org/understanding-json-schema/reference/string.html#dates-and-times)
422
+
206
423
  ## 📄 Mass media
207
424
 
425
+ - [5 Lessons learned about swagger-typescript-api](https://christo8989.medium.com/5-lessons-learned-about-swagger-typescript-api-511240b34c1)
208
426
  - [Why Swagger schemes are needed in frontend development ?](https://dev.to/js2me/why-swagger-schemes-are-needed-in-frontend-development-2cb4)
209
427
  - [Migration en douceur vers TypeScript (French)](https://www.premieroctet.com/blog/migration-typescript/)
210
428
  - [swagger-typescript-api usage (Japanese)](https://zenn.dev/watahaya/articles/2f4a716c47903b)
package/index.d.ts CHANGED
@@ -127,8 +127,63 @@ interface GenerateApiParamsBase {
127
127
  * generate readonly properties (default: false)
128
128
  */
129
129
  addReadonly?: boolean;
130
+
131
+ primitiveTypeConstructs?: (struct: PrimitiveTypeStruct) => Partial<PrimitiveTypeStruct>;
132
+
133
+ codeGenConstructs?: (struct: CodeGenConstruct) => Partial<CodeGenConstruct>;
130
134
  }
131
135
 
136
+ type CodeGenConstruct = {
137
+ Keyword: {
138
+ Number: string;
139
+ String: string;
140
+ Boolean: string;
141
+ Any: string;
142
+ Void: string;
143
+ Unknown: string;
144
+ Null: string;
145
+ Undefined: string;
146
+ Object: string;
147
+ File: string;
148
+ Date: string;
149
+ Type: string;
150
+ Enum: string;
151
+ Interface: string;
152
+ Array: string;
153
+ Record: string;
154
+ Intersection: string;
155
+ Union: string;
156
+ };
157
+ CodeGenKeyword: {
158
+ UtilRequiredKeys: string;
159
+ };
160
+ ArrayType: (content: any) => string;
161
+ StringValue: (content: any) => string;
162
+ BooleanValue: (content: any) => string;
163
+ NumberValue: (content: any) => string;
164
+ NullValue: (content: any) => string;
165
+ UnionType: (content: any) => string;
166
+ ExpressionGroup: (content: any) => string;
167
+ IntersectionType: (content: any) => string;
168
+ RecordType: (content: any) => string;
169
+ TypeField: (content: any) => string;
170
+ InterfaceDynamicField: (content: any) => string;
171
+ EnumField: (content: any) => string;
172
+ EnumFieldsWrapper: (content: any) => string;
173
+ ObjectWrapper: (content: any) => string;
174
+ MultilineComment: (content: any) => string;
175
+ TypeWithGeneric: (content: any) => string;
176
+ };
177
+
178
+ type PrimitiveTypeStructValue =
179
+ | string
180
+ | ((schema: Record<string, any>, parser: import("./src/schema-parser/schema-parser").SchemaParser) => string);
181
+
182
+ type PrimitiveTypeStruct = Record<
183
+ "integer" | "number" | "boolean" | "object" | "file" | "string" | "array",
184
+ string | ({ $default: PrimitiveTypeStructValue } & Record<string, PrimitiveTypeStructValue>)
185
+ >;
186
+
132
187
  interface GenerateApiParamsFromPath extends GenerateApiParamsBase {
133
188
  /**
134
189
  * path to swagger schema
@@ -324,6 +379,12 @@ export interface GenerateApiConfiguration {
324
379
  hasDescription: boolean;
325
380
  };
326
381
  config: {
382
+ input: string;
383
+ output: string;
384
+ url: string;
385
+ spec: any;
386
+ fileName: string;
387
+ authorizationToken?: string;
327
388
  generateResponses: boolean;
328
389
  defaultResponseAsSuccess: boolean;
329
390
  generateRouteTypes: boolean;
@@ -335,10 +396,35 @@ export interface GenerateApiConfiguration {
335
396
  convertedFromSwagger2: boolean;
336
397
  moduleNameIndex: number;
337
398
  moduleNameFirstTag: boolean;
399
+ extraTemplates: { name: string; path: string }[];
338
400
  disableStrictSSL: boolean;
339
401
  disableProxy: boolean;
340
402
  extractRequestParams: boolean;
341
403
  unwrapResponseData: boolean;
404
+ sortTypes: boolean;
405
+ singleHttpClient: boolean;
406
+ typePrefix: string;
407
+ typeSuffix: string;
408
+ patch: boolean;
409
+ cleanOutput: boolean;
410
+ debug: boolean;
411
+ anotherArrayType: boolean;
412
+ extractRequestBody: boolean;
413
+ httpClientType: "axios" | "fetch";
414
+ addReadonly: boolean;
415
+ extractResponseBody: boolean;
416
+ extractResponseError: boolean;
417
+ defaultResponseType: boolean;
418
+ toJS: boolean;
419
+ disableThrowOnError: boolean;
420
+ silent: boolean;
421
+ hooks: Hooks;
422
+ enumNamesAsValues: boolean;
423
+ version: string;
424
+ internalTemplateOptions: {
425
+ addUtilRequiredKeysType: boolean;
426
+ };
427
+ componentTypeNameResolver: typeof import("./src/util/name-resolver").ComponentTypeNameResolver;
342
428
  fileNames: {
343
429
  dataContracts: string;
344
430
  routeTypes: string;
@@ -351,6 +437,11 @@ export interface GenerateApiConfiguration {
351
437
  httpClient: string;
352
438
  routeTypes: string;
353
439
  routeName: string;
440
+ dataContractJsDoc: string;
441
+ interfaceDataContract: string;
442
+ typeDataContract: string;
443
+ enumDataContract: string;
444
+ objectFieldJsDoc: string;
354
445
  };
355
446
  routeNameDuplicatesMap: Map<string, string>;
356
447
  apiClassName: string;
@@ -371,7 +462,9 @@ export interface GenerateApiConfiguration {
371
462
  utils: {
372
463
  formatDescription: (description: string, inline?: boolean) => string;
373
464
  internalCase: (value: string) => string;
465
+ /** @deprecated */
374
466
  classNameCase: (value: string) => string;
467
+ pascalCase: (value: string) => string;
375
468
  getInlineParseContent: (rawTypeData: SchemaComponent["rawTypeData"], typeName?: string) => string;
376
469
  getParseContent: (rawTypeData: SchemaComponent["rawTypeData"], typeName?: string) => ModelType;
377
470
  getComponentByRef: (ref: string) => SchemaComponent;