klasik 1.0.16 → 1.0.17

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
@@ -6,7 +6,7 @@ Download OpenAPI specifications from remote URLs and generate TypeScript clients
6
6
 
7
7
  - 📥 **Download OpenAPI specs** from remote URLs or local files
8
8
  - 📁 **Multiple input formats** - HTTP/HTTPS URLs, file:// URLs, absolute/relative paths
9
- - 📄 **JSON and YAML support** - Automatically parse and handle both formats
9
+ - 📄 **JSON and YAML support** - Automatically parse and handle both formats (YAML specs are converted to JSON for code generation)
10
10
  - 🔐 **Authentication support** - Custom headers including Bearer tokens and API keys
11
11
  - 🔗 **External reference resolution** - Automatically download referenced schema files (`$ref`)
12
12
  - 🔄 **Automatic transformation** - Converts API responses to class instances using class-transformer
@@ -99,7 +99,7 @@ Generate a TypeScript client from an OpenAPI spec (remote URL or local file).
99
99
  - Can be used multiple times for multiple headers
100
100
  - Perfect for authorization: `--header "Authorization: Bearer token"`
101
101
  - `-r, --resolve-refs` - Resolve and download external `$ref` references
102
- - `-t, --template <dir>` - Custom template directory
102
+ - `-t, --template <dir>` - Custom template directory (klasik includes enhanced TSDoc templates by default)
103
103
  - `-k, --keep-spec` - Keep the downloaded spec file after generation
104
104
  - `--timeout <ms>` - Request timeout in milliseconds for HTTP requests (default: 30000)
105
105
 
@@ -220,40 +220,93 @@ The generated TypeScript client includes:
220
220
  - ✅ **Automatic response transformation** - API responses converted to class instances
221
221
  - ✅ **Runtime type metadata** - Static `attributeTypeMap` on all models
222
222
  - ✅ **Union type support** - `anyOf` schemas become TypeScript unions
223
+ - ✅ **Rich TSDoc comments** - Comprehensive documentation from OpenAPI spec metadata
223
224
  - ✅ **Vendor extensions** - Preserved in JSDoc comments and metadata
224
225
  - ✅ **Error handling** - Configurable transformation error handlers
225
226
  - ✅ **Configuration options** - Enable/disable transformation, custom error handlers
226
227
 
227
- ### Example Generated Model
228
+ ### Enhanced TSDoc Documentation
228
229
 
229
- ```typescript
230
- import { Expose, Type } from 'class-transformer';
230
+ Klasik includes enhanced Mustache templates that generate rich TSDoc comments from your OpenAPI specification. The generated code includes:
231
+
232
+ **For Models:**
233
+ - Class-level documentation with description
234
+ - Property descriptions from OpenAPI schema
235
+ - Type information with `@type` tags
236
+ - Validation constraints (`@minimum`, `@maximum`, `@minLength`, `@maxLength`, `@pattern`)
237
+ - Format specifications (`@format`)
238
+ - Example values (`@example`)
239
+ - Required field markers (`@required`)
240
+ - Deprecation warnings (`@deprecated`)
241
+
242
+ **For API Endpoints:**
243
+ - Method name and HTTP verb (`@method`)
244
+ - Summary and detailed descriptions
245
+ - Parameter documentation with types and requirements
246
+ - Return type information
247
+ - Error scenarios (`@throws`)
248
+ - Deprecation notices
249
+
250
+ Example generated model with rich TSDoc:
231
251
 
252
+ ```typescript
253
+ /**
254
+ * User
255
+ *
256
+ * Represents a user in the system
257
+ *
258
+ * @export
259
+ * @class User
260
+ */
232
261
  export class User {
262
+ /**
263
+ * id - Unique identifier for the user
264
+ *
265
+ * @type {string}
266
+ * @memberof User
267
+ * @required
268
+ * @format uuid
269
+ * @example "550e8400-e29b-41d4-a716-446655440000"
270
+ */
233
271
  @Expose()
234
272
  'id': string;
235
273
 
274
+ /**
275
+ * email - User's email address
276
+ *
277
+ * @type {string}
278
+ * @memberof User
279
+ * @required
280
+ * @format email
281
+ * @pattern ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
282
+ */
236
283
  @Expose()
237
- 'name': string;
238
-
239
- @Expose()
240
- @Type(() => Profile)
241
- 'profile'?: Profile;
242
-
243
- static readonly attributeTypeMap = [
244
- {
245
- "name": "id",
246
- "baseName": "id",
247
- "type": "string",
248
- "format": "",
249
- "description": "User ID",
250
- "vendorExtensions": {}
251
- },
252
- // ... more properties
253
- ];
284
+ 'email': string;
254
285
  }
255
286
  ```
256
287
 
288
+ Example generated API method:
289
+
290
+ ```typescript
291
+ /**
292
+ * getUserById - Get user by ID
293
+ *
294
+ * Retrieves a single user by their unique identifier
295
+ *
296
+ * @method GET
297
+ * @summary Get user by ID
298
+ * @param {string} userId - The user's unique identifier (required)
299
+ * @param {RawAxiosRequestConfig} [options] Override http request option.
300
+ * @throws {RequiredError} When required parameters are missing
301
+ * @returns {Promise<AxiosResponse<User>>}
302
+ */
303
+ async getUserById(userId: string, options?: RawAxiosRequestConfig): Promise<AxiosResponse<User>>
304
+ ```
305
+
306
+ These templates automatically extract metadata from your OpenAPI spec and format it as proper TSDoc comments, making your generated client code well-documented and IDE-friendly with IntelliSense support.
307
+
308
+ **Note:** Klasik's templates automatically handle special characters in descriptions by using proper escaping, ensuring your TSDoc comments are always valid even when OpenAPI descriptions contain characters like `*`, `/`, `@`, etc.
309
+
257
310
  ### Using the Generated Client
258
311
 
259
312
  ```typescript
@@ -50,6 +50,11 @@ export declare class K8sClientGenerator {
50
50
  * Prepare the output directory
51
51
  */
52
52
  private prepareOutputDirectory;
53
+ /**
54
+ * Ensure the spec file is in JSON format (convert YAML if needed)
55
+ * openapi-class-transformer requires JSON format
56
+ */
57
+ private ensureJsonFormat;
53
58
  /**
54
59
  * Clean up the downloaded spec file
55
60
  */
@@ -38,6 +38,7 @@ const openapi_class_transformer_1 = require("openapi-class-transformer");
38
38
  const spec_downloader_1 = require("./spec-downloader");
39
39
  const fs = __importStar(require("fs"));
40
40
  const path = __importStar(require("path"));
41
+ const yaml = __importStar(require("js-yaml"));
41
42
  class K8sClientGenerator {
42
43
  constructor() {
43
44
  this.downloader = new spec_downloader_1.SpecDownloader();
@@ -63,11 +64,13 @@ class K8sClientGenerator {
63
64
  // Step 2: Validate output directory
64
65
  console.log('Step 2: Preparing output directory...');
65
66
  this.prepareOutputDirectory(outputDir);
67
+ // Step 2.5: Ensure spec is in JSON format for openapi-class-transformer
68
+ const jsonSpecPath = await this.ensureJsonFormat(specPath, outputDir, keepSpec);
66
69
  // Step 3: Generate client using openapi-class-transformer
67
70
  const modeLabel = mode === 'models-only' ? 'models only' : 'full client';
68
71
  console.log(`Step 3: Generating TypeScript ${modeLabel}...`);
69
72
  const generatorOptions = {
70
- inputSpec: specPath,
73
+ inputSpec: jsonSpecPath,
71
74
  outputDir,
72
75
  modelsOnly: mode === 'models-only',
73
76
  };
@@ -103,6 +106,49 @@ class K8sClientGenerator {
103
106
  console.log(`Using existing output directory: ${outputDir}`);
104
107
  }
105
108
  }
109
+ /**
110
+ * Ensure the spec file is in JSON format (convert YAML if needed)
111
+ * openapi-class-transformer requires JSON format
112
+ */
113
+ async ensureJsonFormat(specPath, outputDir, keepSpec) {
114
+ const content = fs.readFileSync(specPath, 'utf-8');
115
+ let spec;
116
+ // Try to parse as JSON first
117
+ try {
118
+ spec = JSON.parse(content);
119
+ // Already JSON, return as-is
120
+ return specPath;
121
+ }
122
+ catch {
123
+ // Not JSON, try YAML
124
+ try {
125
+ spec = yaml.load(content);
126
+ }
127
+ catch {
128
+ throw new Error('Failed to parse spec: not valid JSON or YAML');
129
+ }
130
+ }
131
+ // Convert YAML to JSON
132
+ console.log('Converting YAML spec to JSON format for code generation...');
133
+ const jsonContent = JSON.stringify(spec, null, 2);
134
+ // Determine output path for JSON spec
135
+ let jsonSpecPath;
136
+ if (keepSpec) {
137
+ // Save as openapi-spec.json in output directory
138
+ jsonSpecPath = path.join(outputDir, 'openapi-spec.json');
139
+ }
140
+ else {
141
+ // Create a temporary JSON file
142
+ const tempDir = path.join(process.cwd(), '.tmp');
143
+ if (!fs.existsSync(tempDir)) {
144
+ fs.mkdirSync(tempDir, { recursive: true });
145
+ }
146
+ jsonSpecPath = path.join(tempDir, `openapi-${Date.now()}.json`);
147
+ }
148
+ fs.writeFileSync(jsonSpecPath, jsonContent, 'utf-8');
149
+ console.log(`JSON spec saved to: ${jsonSpecPath}`);
150
+ return jsonSpecPath;
151
+ }
106
152
  /**
107
153
  * Clean up the downloaded spec file
108
154
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "klasik",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
4
4
  "description": "Download OpenAPI specs from remote URLs and generate TypeScript clients with class-transformer support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,526 @@
1
+ {{#withSeparateModelsAndApi}}
2
+ /* tslint:disable */
3
+ /* eslint-disable */
4
+ {{>licenseInfo}}
5
+
6
+ import type { Configuration } from '{{apiRelativeToRoot}}configuration';
7
+ import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';
8
+ import globalAxios, { type AxiosResponse } from 'axios';
9
+ import { plainToInstance } from 'class-transformer';
10
+ {{#withNodeImports}}
11
+ // URLSearchParams not necessarily used
12
+ // @ts-ignore
13
+ import { URL, URLSearchParams } from 'url';
14
+ {{#multipartFormData}}
15
+ import FormData from 'form-data'
16
+ {{/multipartFormData}}
17
+ {{/withNodeImports}}
18
+ // Some imports not used depending on template conditions
19
+ // @ts-ignore
20
+ import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '{{apiRelativeToRoot}}common';
21
+ // @ts-ignore
22
+ import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '{{apiRelativeToRoot}}base';
23
+ {{#imports}}
24
+ // @ts-ignore
25
+ import { {{classname}} } from '{{apiRelativeToRoot}}{{tsModelPackage}}';
26
+ {{/imports}}
27
+ {{/withSeparateModelsAndApi}}
28
+ {{^withSeparateModelsAndApi}}
29
+ {{/withSeparateModelsAndApi}}
30
+ {{#operations}}
31
+ /**
32
+ * {{classname}} - Axios parameter creator
33
+ *{{#description}}
34
+ * {{&description}}
35
+ *{{/description}}
36
+ * Generates request parameters for {{classname}} API endpoints.
37
+ *
38
+ * @export
39
+ * @returns Parameter creators for each API endpoint
40
+ */
41
+ export const {{classname}}AxiosParamCreator = function (configuration?: Configuration) {
42
+ return {
43
+ {{#operation}}
44
+ /**
45
+ * {{nickname}}{{#summary}} - {{&summary}}{{/summary}}
46
+ *
47
+ {{#notes}}
48
+ * {{&notes}}
49
+ *
50
+ {{/notes}}
51
+ * @method {{httpMethod}}{{#summary}}
52
+ * @summary {{&summary}}{{/summary}}
53
+ {{#allParams}}
54
+ * @param {{=<% %>=}}{<%#isEnum%><%&datatypeWithEnum%><%/isEnum%><%^isEnum%><%&dataType%><%#isNullable%> | null<%/isNullable%><%/isEnum%>}<%={{ }}=%> {{^required}}[{{/required}}{{paramName}}{{^required}}]{{/required}}{{#description}} - {{&description}}{{/description}}{{#required}} (required){{/required}}
55
+ {{/allParams}}
56
+ * @param {RawAxiosRequestConfig} [options] Override http request option.{{#isDeprecated}}
57
+ * @deprecated This endpoint is deprecated{{/isDeprecated}}
58
+ * @throws {RequiredError} When required parameters are missing
59
+ * @returns {Promise<RequestArgs>} Request configuration
60
+ */
61
+ {{nickname}}: async ({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}, {{/allParams}}options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
62
+ {{#allParams}}
63
+ {{#required}}
64
+ // verify required parameter '{{paramName}}' is not null or undefined
65
+ assertParamExists('{{nickname}}', '{{paramName}}', {{paramName}})
66
+ {{/required}}
67
+ {{/allParams}}
68
+ const localVarPath = `{{{path}}}`{{#pathParams}}
69
+ .replace(`{${"{{baseName}}"}}`, encodeURIComponent(String({{paramName}}))){{/pathParams}};
70
+ // use dummy base URL string because the URL constructor only accepts absolute URLs.
71
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
72
+ let baseOptions;
73
+ if (configuration) {
74
+ baseOptions = configuration.baseOptions;
75
+ }
76
+
77
+ const localVarRequestOptions = { method: '{{httpMethod}}', ...baseOptions, ...options};
78
+ const localVarHeaderParameter = {} as any;
79
+ const localVarQueryParameter = {} as any;{{#vendorExtensions}}{{#hasFormParams}}
80
+ const localVarFormParams = new {{^multipartFormData}}URLSearchParams(){{/multipartFormData}}{{#multipartFormData}}((configuration && configuration.formDataCtor) || FormData)(){{/multipartFormData}};{{/hasFormParams}}{{/vendorExtensions}}
81
+
82
+ {{#authMethods}}
83
+ // authentication {{name}} required
84
+ {{#isApiKey}}
85
+ {{#isKeyInHeader}}
86
+ await setApiKeyToObject(localVarHeaderParameter, "{{keyParamName}}", configuration)
87
+ {{/isKeyInHeader}}
88
+ {{#isKeyInQuery}}
89
+ await setApiKeyToObject(localVarQueryParameter, "{{keyParamName}}", configuration)
90
+ {{/isKeyInQuery}}
91
+ {{/isApiKey}}
92
+ {{#isBasicBasic}}
93
+ // http basic authentication required
94
+ setBasicAuthToObject(localVarRequestOptions, configuration)
95
+ {{/isBasicBasic}}
96
+ {{#isBasicBearer}}
97
+ // http bearer authentication required
98
+ await setBearerAuthToObject(localVarHeaderParameter, configuration)
99
+ {{/isBasicBearer}}
100
+ {{#isOAuth}}
101
+ // oauth required
102
+ await setOAuthToObject(localVarHeaderParameter, "{{name}}", [{{#scopes}}"{{{scope}}}"{{^-last}}, {{/-last}}{{/scopes}}], configuration)
103
+ {{/isOAuth}}
104
+
105
+ {{/authMethods}}
106
+ {{#queryParams}}
107
+ {{#isArray}}
108
+ if ({{paramName}}) {
109
+ {{#isCollectionFormatMulti}}
110
+ {{#uniqueItems}}
111
+ localVarQueryParameter['{{baseName}}'] = Array.from({{paramName}});
112
+ {{/uniqueItems}}
113
+ {{^uniqueItems}}
114
+ localVarQueryParameter['{{baseName}}'] = {{paramName}};
115
+ {{/uniqueItems}}
116
+ {{/isCollectionFormatMulti}}
117
+ {{^isCollectionFormatMulti}}
118
+ {{#uniqueItems}}
119
+ localVarQueryParameter['{{baseName}}'] = Array.from({{paramName}}).join(COLLECTION_FORMATS.{{collectionFormat}});
120
+ {{/uniqueItems}}
121
+ {{^uniqueItems}}
122
+ localVarQueryParameter['{{baseName}}'] = {{paramName}}.join(COLLECTION_FORMATS.{{collectionFormat}});
123
+ {{/uniqueItems}}
124
+ {{/isCollectionFormatMulti}}
125
+ }
126
+ {{/isArray}}
127
+ {{^isArray}}
128
+ if ({{paramName}} !== undefined) {
129
+ {{#isDateTime}}
130
+ localVarQueryParameter['{{baseName}}'] = ({{paramName}} as any instanceof Date) ?
131
+ ({{paramName}} as any).toISOString() :
132
+ {{paramName}};
133
+ {{/isDateTime}}
134
+ {{^isDateTime}}
135
+ {{#isDate}}
136
+ localVarQueryParameter['{{baseName}}'] = ({{paramName}} as any instanceof Date) ?
137
+ ({{paramName}} as any).toISOString().substring(0,10) :
138
+ {{paramName}};
139
+ {{/isDate}}
140
+ {{^isDate}}
141
+ {{#isExplode}}
142
+ {{#isPrimitiveType}}
143
+ localVarQueryParameter['{{baseName}}'] = {{paramName}};
144
+ {{/isPrimitiveType}}
145
+ {{^isPrimitiveType}}
146
+ {{^isEnumRef}}
147
+ {{^isEnum}}
148
+ for (const [key, value] of Object.entries({{paramName}})) {
149
+ localVarQueryParameter[key] = value;
150
+ }
151
+ {{/isEnum}}
152
+ {{/isEnumRef}}
153
+ {{#isEnum}}
154
+ localVarQueryParameter['{{baseName}}'] = {{paramName}};
155
+ {{/isEnum}}
156
+ {{#isEnumRef}}
157
+ localVarQueryParameter['{{baseName}}'] = {{paramName}};
158
+ {{/isEnumRef}}
159
+ {{/isPrimitiveType}}
160
+ {{/isExplode}}
161
+ {{^isExplode}}
162
+ localVarQueryParameter['{{baseName}}'] = {{paramName}};
163
+ {{/isExplode}}
164
+ {{/isDate}}
165
+ {{/isDateTime}}
166
+ }
167
+ {{/isArray}}
168
+
169
+ {{/queryParams}}
170
+ {{#vendorExtensions}}
171
+ {{#formParams}}
172
+ {{#isArray}}
173
+ if ({{paramName}}) {
174
+ {{#isCollectionFormatMulti}}
175
+ {{#contentType}}
176
+ localVarFormParams.append('{{baseName}}', new Blob([JSON.stringify({{paramName}})], { type: "{{contentType}}", }));
177
+ {{/contentType}}
178
+ {{^contentType}}
179
+ {{paramName}}.forEach((element) => {
180
+ localVarFormParams.{{#multipartFormData}}append{{/multipartFormData}}{{^multipartFormData}}set{{/multipartFormData}}('{{baseName}}{{#useSquareBracketsInArrayNames}}[]{{/useSquareBracketsInArrayNames}}', element as any);
181
+ })
182
+ {{/contentType}}
183
+ {{/isCollectionFormatMulti}}
184
+ {{^isCollectionFormatMulti}}
185
+ localVarFormParams.{{#multipartFormData}}append{{/multipartFormData}}{{^multipartFormData}}set{{/multipartFormData}}('{{baseName}}{{#useSquareBracketsInArrayNames}}[]{{/useSquareBracketsInArrayNames}}', {{paramName}}.join(COLLECTION_FORMATS.{{collectionFormat}}));
186
+ {{/isCollectionFormatMulti}}
187
+ }{{/isArray}}
188
+ {{^isArray}}
189
+ if ({{paramName}} !== undefined) { {{^multipartFormData}}
190
+ localVarFormParams.set('{{baseName}}', {{paramName}} as any);{{/multipartFormData}}{{#multipartFormData}}{{#isPrimitiveType}}{{^isBoolean}}
191
+ localVarFormParams.append('{{baseName}}', {{paramName}} as any);{{/isBoolean}}{{/isPrimitiveType}}{{#isPrimitiveType}}{{#isBoolean}}
192
+ localVarFormParams.append('{{baseName}}', String({{paramName}}) as any);{{/isBoolean}}{{/isPrimitiveType}}{{^isPrimitiveType}}{{#isEnumRef}}
193
+ localVarFormParams.append('{{baseName}}', {{paramName}} as any);{{/isEnumRef}}{{^isEnumRef}}
194
+ localVarFormParams.append('{{baseName}}', new Blob([JSON.stringify({{paramName}})], { type: "application/json", }));{{/isEnumRef}}{{/isPrimitiveType}}{{/multipartFormData}}
195
+ }{{/isArray}}
196
+ {{/formParams}}{{/vendorExtensions}}
197
+ {{#vendorExtensions}}{{#hasFormParams}}{{^multipartFormData}}
198
+ localVarHeaderParameter['Content-Type'] = 'application/x-www-form-urlencoded';{{/multipartFormData}}{{#multipartFormData}}
199
+ localVarHeaderParameter['Content-Type'] = 'multipart/form-data';{{/multipartFormData}}
200
+ {{/hasFormParams}}{{/vendorExtensions}}
201
+ {{#bodyParam}}
202
+ {{^consumes}}
203
+ localVarHeaderParameter['Content-Type'] = 'application/json';
204
+ {{/consumes}}
205
+ {{#consumes.0}}
206
+ localVarHeaderParameter['Content-Type'] = '{{{mediaType}}}';
207
+ {{/consumes.0}}
208
+
209
+ {{/bodyParam}}
210
+ {{#headerParams}}
211
+ {{#isArray}}
212
+ if ({{paramName}}) {
213
+ {{#uniqueItems}}
214
+ let mapped = Array.from({{paramName}}).map(value => (<any>"{{{dataType}}}" !== "Set<string>") ? JSON.stringify(value) : (value || ""));
215
+ {{/uniqueItems}}
216
+ {{^uniqueItems}}
217
+ let mapped = {{paramName}}.map(value => (<any>"{{{dataType}}}" !== "Array<string>") ? JSON.stringify(value) : (value || ""));
218
+ {{/uniqueItems}}
219
+ localVarHeaderParameter['{{baseName}}'] = mapped.join(COLLECTION_FORMATS["{{collectionFormat}}"]);
220
+ }
221
+ {{/isArray}}
222
+ {{^isArray}}
223
+ {{! `val == null` covers for both `null` and `undefined`}}
224
+ if ({{paramName}} != null) {
225
+ {{#isString}}
226
+ localVarHeaderParameter['{{baseName}}'] = String({{paramName}});
227
+ {{/isString}}
228
+ {{^isString}}
229
+ {{! isString is falsy also for $ref that defines a string or enum type}}
230
+ localVarHeaderParameter['{{baseName}}'] = typeof {{paramName}} === 'string'
231
+ ? {{paramName}}
232
+ : JSON.stringify({{paramName}});
233
+ {{/isString}}
234
+ }
235
+ {{/isArray}}
236
+ {{/headerParams}}
237
+ setSearchParams(localVarUrlObj, localVarQueryParameter);
238
+ let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
239
+ localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions,{{#hasFormParams}}{{#multipartFormData}} ...(localVarFormParams as any).getHeaders?.(),{{/multipartFormData}}{{/hasFormParams}} ...options.headers};
240
+ {{#hasFormParams}}
241
+ localVarRequestOptions.data = localVarFormParams{{#vendorExtensions}}{{^multipartFormData}}.toString(){{/multipartFormData}}{{/vendorExtensions}};
242
+ {{/hasFormParams}}
243
+ {{#bodyParam}}
244
+ localVarRequestOptions.data = serializeDataIfNeeded({{paramName}}, localVarRequestOptions, configuration)
245
+ {{/bodyParam}}
246
+
247
+ return {
248
+ url: toPathString(localVarUrlObj),
249
+ options: localVarRequestOptions,
250
+ };
251
+ },
252
+ {{/operation}}
253
+ }
254
+ };
255
+
256
+ /**
257
+ * {{classname}} - functional programming interface{{#description}}
258
+ * {{{.}}}{{/description}}
259
+ * @export
260
+ */
261
+ export const {{classname}}Fp = function(configuration?: Configuration) {
262
+ const localVarAxiosParamCreator = {{classname}}AxiosParamCreator(configuration)
263
+ return {
264
+ {{#operation}}
265
+ /**
266
+ * {{nickname}}{{#summary}} - {{&summary}}{{/summary}}
267
+ *
268
+ {{#notes}}
269
+ * {{&notes}}
270
+ *
271
+ {{/notes}}
272
+ * @method {{httpMethod}}{{#summary}}
273
+ * @summary {{&summary}}{{/summary}}
274
+ {{#allParams}}
275
+ * @param {{=<% %>=}}{<%#isEnum%><%&datatypeWithEnum%><%/isEnum%><%^isEnum%><%&dataType%><%#isNullable%> | null<%/isNullable%><%/isEnum%>}<%={{ }}=%> {{^required}}[{{/required}}{{paramName}}{{^required}}]{{/required}}{{#description}} - {{&description}}{{/description}}{{#required}} (required){{/required}}
276
+ {{/allParams}}
277
+ * @param {RawAxiosRequestConfig} [options] Override http request option.{{#isDeprecated}}
278
+ * @deprecated This endpoint is deprecated{{/isDeprecated}}
279
+ * @throws {RequiredError} When required parameters are missing
280
+ * @returns {Promise<RequestArgs>} Request configuration
281
+ */
282
+ async {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}, {{/allParams}}options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<{{{returnType}}}{{^returnType}}void{{/returnType}}>> {
283
+ const localVarAxiosArgs = await localVarAxiosParamCreator.{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}options);
284
+ const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
285
+ const localVarOperationServerBasePath = operationServerMap['{{classname}}.{{nickname}}']?.[localVarOperationServerIndex]?.url;
286
+ {{#returnType}}
287
+ {{^returnTypeIsPrimitive}}
288
+ return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath).then(response => {
289
+ // Check if response transformation is enabled (default: true)
290
+ if (configuration?.enableResponseTransformation !== false) {
291
+ try {
292
+ {{#isArray}}
293
+ response.data = plainToInstance({{returnBaseType}}, response.data as any[]);
294
+ {{/isArray}}
295
+ {{^isArray}}
296
+ response.data = plainToInstance({{returnBaseType}}, response.data);
297
+ {{/isArray}}
298
+ } catch (error) {
299
+ // Handle transformation errors
300
+ if (configuration?.onTransformationError) {
301
+ configuration.onTransformationError(error as Error, {{returnBaseType}}, response.data);
302
+ } else {
303
+ console.error('class-transformer failed to transform response:', error);
304
+ console.error('Returning original response data. To handle this error, provide onTransformationError in Configuration.');
305
+ }
306
+ // Return original data on error (cast for type safety)
307
+ {{#isArray}}
308
+ response.data = response.data as any as {{returnBaseType}}[];
309
+ {{/isArray}}
310
+ {{^isArray}}
311
+ response.data = response.data as any as {{returnBaseType}};
312
+ {{/isArray}}
313
+ }
314
+ }
315
+ return response as AxiosResponse<{{#isArray}}{{returnBaseType}}[]{{/isArray}}{{^isArray}}{{returnBaseType}}{{/isArray}}>;
316
+ });
317
+ {{/returnTypeIsPrimitive}}
318
+ {{#returnTypeIsPrimitive}}
319
+ return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
320
+ {{/returnTypeIsPrimitive}}
321
+ {{/returnType}}
322
+ {{^returnType}}
323
+ return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
324
+ {{/returnType}}
325
+ },
326
+ {{/operation}}
327
+ }
328
+ };
329
+
330
+ /**
331
+ * {{classname}} - factory interface{{#description}}
332
+ * {{&description}}{{/description}}
333
+ * @export
334
+ */
335
+ export const {{classname}}Factory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
336
+ const localVarFp = {{classname}}Fp(configuration)
337
+ return {
338
+ {{#operation}}
339
+ /**
340
+ * {{&notes}}
341
+ {{#summary}}
342
+ * @summary {{&summary}}
343
+ {{/summary}}
344
+ {{#useSingleRequestParameter}}
345
+ {{#allParams.0}}
346
+ * @param {{=<% %>=}}{<%& classname %><%& operationIdCamelCase %>Request}<%={{ }}=%> requestParameters Request parameters.
347
+ {{/allParams.0}}
348
+ {{/useSingleRequestParameter}}
349
+ {{^useSingleRequestParameter}}
350
+ {{#allParams}}
351
+ * @param {{=<% %>=}}{<%#isEnum%><%&datatypeWithEnum%><%/isEnum%><%^isEnum%><%&dataType%><%#isNullable%> | null<%/isNullable%><%/isEnum%>}<%={{ }}=%> {{^required}}[{{/required}}{{paramName}}{{^required}}]{{/required}} {{description}}
352
+ {{/allParams}}
353
+ {{/useSingleRequestParameter}}
354
+ * @param {*} [options] Override http request option.{{#isDeprecated}}
355
+ * @deprecated{{/isDeprecated}}
356
+ * @throws {RequiredError}
357
+ */
358
+ {{#useSingleRequestParameter}}
359
+ {{nickname}}({{#allParams.0}}requestParameters: {{classname}}{{operationIdCamelCase}}Request{{^hasRequiredParams}} = {}{{/hasRequiredParams}}, {{/allParams.0}}options?: RawAxiosRequestConfig): AxiosPromise<{{{returnType}}}{{^returnType}}void{{/returnType}}> {
360
+ return localVarFp.{{nickname}}({{#allParams.0}}{{#allParams}}requestParameters.{{paramName}}, {{/allParams}}{{/allParams.0}}options).then((request) => request(axios, basePath));
361
+ },
362
+ {{/useSingleRequestParameter}}
363
+ {{^useSingleRequestParameter}}
364
+ {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}, {{/allParams}}options?: RawAxiosRequestConfig): AxiosPromise<{{{returnType}}}{{^returnType}}void{{/returnType}}> {
365
+ return localVarFp.{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}options).then((request) => request(axios, basePath));
366
+ },
367
+ {{/useSingleRequestParameter}}
368
+ {{/operation}}
369
+ };
370
+ };
371
+
372
+ {{#withInterfaces}}
373
+ /**
374
+ * {{classname}} - interface{{#description}}
375
+ * {{&description}}{{/description}}
376
+ * @export
377
+ * @interface {{classname}}
378
+ */
379
+ export interface {{classname}}Interface {
380
+ {{#operation}}
381
+ /**
382
+ * {{nickname}}{{#summary}} - {{&summary}}{{/summary}}
383
+ *
384
+ {{#notes}}
385
+ * {{&notes}}
386
+ *
387
+ {{/notes}}
388
+ * @method {{httpMethod}}{{#summary}}
389
+ * @summary {{&summary}}{{/summary}}
390
+ {{#useSingleRequestParameter}}
391
+ {{#allParams.0}}
392
+ * @param {{=<% %>=}}{<%& classname %><%& operationIdCamelCase %>Request}<%={{ }}=%> requestParameters Request parameters.
393
+ {{/allParams.0}}
394
+ {{/useSingleRequestParameter}}
395
+ {{^useSingleRequestParameter}}
396
+ {{#allParams}}
397
+ * @param {{=<% %>=}}{<%#isEnum%><%&datatypeWithEnum%><%/isEnum%><%^isEnum%><%&dataType%><%#isNullable%> | null<%/isNullable%><%/isEnum%>}<%={{ }}=%> {{^required}}[{{/required}}{{paramName}}{{^required}}]{{/required}}{{#description}} - {{&description}}{{/description}}{{#required}} (required){{/required}}
398
+ {{/allParams}}
399
+ {{/useSingleRequestParameter}}
400
+ * @param {RawAxiosRequestConfig} [options] Override http request option.{{#isDeprecated}}
401
+ * @deprecated This endpoint is deprecated{{/isDeprecated}}
402
+ * @throws {RequiredError} When required parameters are missing
403
+ * @memberof {{classname}}Interface
404
+ * @returns {{=<% %>=}}{Promise<AxiosResponse<<%returnType%><%^returnType%>void<%/returnType%>>>}<%={{ }}=%>
405
+ */
406
+ {{#useSingleRequestParameter}}
407
+ {{nickname}}({{#allParams.0}}requestParameters{{^hasRequiredParams}}?{{/hasRequiredParams}}: {{classname}}{{operationIdCamelCase}}Request, {{/allParams.0}}options?: RawAxiosRequestConfig): AxiosPromise<{{{returnType}}}{{^returnType}}void{{/returnType}}>;
408
+ {{/useSingleRequestParameter}}
409
+ {{^useSingleRequestParameter}}
410
+ {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}, {{/allParams}}options?: RawAxiosRequestConfig): AxiosPromise<{{{returnType}}}{{^returnType}}void{{/returnType}}>;
411
+ {{/useSingleRequestParameter}}
412
+
413
+ {{/operation}}
414
+ }
415
+
416
+ {{/withInterfaces}}
417
+ {{#useSingleRequestParameter}}
418
+ {{#operation}}
419
+ {{#allParams.0}}
420
+ /**
421
+ * Request parameters for {{nickname}} operation in {{classname}}.
422
+ * @export
423
+ * @interface {{classname}}{{operationIdCamelCase}}Request
424
+ */
425
+ export interface {{classname}}{{operationIdCamelCase}}Request {
426
+ {{#allParams}}
427
+ /**
428
+ * {{description}}
429
+ * @type {{=<% %>=}}{<%&dataType%>}<%={{ }}=%>
430
+ * @memberof {{classname}}{{operationIdCamelCase}}
431
+ */
432
+ readonly {{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}
433
+ {{^-last}}
434
+
435
+ {{/-last}}
436
+ {{/allParams}}
437
+ }
438
+
439
+ {{/allParams.0}}
440
+ {{/operation}}
441
+ {{/useSingleRequestParameter}}
442
+ /**
443
+ * {{classname}} - object-oriented interface{{#description}}
444
+ * {{{.}}}{{/description}}
445
+ * @export
446
+ * @class {{classname}}
447
+ * @extends {BaseAPI}
448
+ */
449
+ {{#withInterfaces}}
450
+ export class {{classname}} extends BaseAPI implements {{classname}}Interface {
451
+ {{/withInterfaces}}
452
+ {{^withInterfaces}}
453
+ export class {{classname}} extends BaseAPI {
454
+ {{/withInterfaces}}
455
+ {{#operation}}
456
+ /**
457
+ * {{&notes}}
458
+ {{#summary}}
459
+ * @summary {{&summary}}
460
+ {{/summary}}
461
+ {{#useSingleRequestParameter}}
462
+ {{#allParams.0}}
463
+ * @param {{=<% %>=}}{<%& classname %><%& operationIdCamelCase %>Request}<%={{ }}=%> requestParameters Request parameters.
464
+ {{/allParams.0}}
465
+ {{/useSingleRequestParameter}}
466
+ {{^useSingleRequestParameter}}
467
+ {{#allParams}}
468
+ * @param {{=<% %>=}}{<%#isEnum%><%&datatypeWithEnum%><%/isEnum%><%^isEnum%><%&dataType%><%#isNullable%> | null<%/isNullable%><%/isEnum%>}<%={{ }}=%> {{^required}}[{{/required}}{{paramName}}{{^required}}]{{/required}} {{description}}
469
+ {{/allParams}}
470
+ {{/useSingleRequestParameter}}
471
+ * @param {*} [options] Override http request option.{{#isDeprecated}}
472
+ * @deprecated{{/isDeprecated}}
473
+ * @throws {RequiredError}
474
+ * @memberof {{classname}}
475
+ */
476
+ {{#useSingleRequestParameter}}
477
+ public {{nickname}}({{#allParams.0}}requestParameters: {{classname}}{{operationIdCamelCase}}Request{{^hasRequiredParams}} = {}{{/hasRequiredParams}}, {{/allParams.0}}options?: RawAxiosRequestConfig) {
478
+ return {{classname}}Fp(this.configuration).{{nickname}}({{#allParams.0}}{{#allParams}}requestParameters.{{paramName}}, {{/allParams}}{{/allParams.0}}options).then((request) => request(this.axios, this.basePath));
479
+ }
480
+ {{/useSingleRequestParameter}}
481
+ {{^useSingleRequestParameter}}
482
+ public {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}, {{/allParams}}options?: RawAxiosRequestConfig) {
483
+ return {{classname}}Fp(this.configuration).{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}options).then((request) => request(this.axios, this.basePath));
484
+ }
485
+ {{/useSingleRequestParameter}}
486
+ {{^-last}}
487
+
488
+ {{/-last}}
489
+ {{/operation}}
490
+ }
491
+ {{/operations}}
492
+
493
+ {{#operations}}
494
+ {{#operation}}
495
+ {{#allParams}}
496
+ {{#isEnum}}
497
+ {{#stringEnums}}
498
+ /**
499
+ * @export
500
+ * @enum {string}
501
+ */
502
+ export enum {{operationIdCamelCase}}{{enumName}} {
503
+ {{#allowableValues}}
504
+ {{#enumVars}}
505
+ {{{name}}} = {{{value}}}{{^-last}},{{/-last}}
506
+ {{/enumVars}}
507
+ {{/allowableValues}}
508
+ }
509
+ {{/stringEnums}}
510
+ {{^stringEnums}}
511
+ /**
512
+ * @export
513
+ */
514
+ export const {{operationIdCamelCase}}{{enumName}} = {
515
+ {{#allowableValues}}
516
+ {{#enumVars}}
517
+ {{{name}}}: {{{value}}}{{^-last}},{{/-last}}
518
+ {{/enumVars}}
519
+ {{/allowableValues}}
520
+ } as const;
521
+ export type {{operationIdCamelCase}}{{enumName}} = typeof {{operationIdCamelCase}}{{enumName}}[keyof typeof {{operationIdCamelCase}}{{enumName}}];
522
+ {{/stringEnums}}
523
+ {{/isEnum}}
524
+ {{/allParams}}
525
+ {{/operation}}
526
+ {{/operations}}
@@ -0,0 +1,137 @@
1
+
2
+ import { Expose, Type } from 'class-transformer';{{#nestJsSwagger}}
3
+ import { ApiProperty } from '@nestjs/swagger';{{/nestJsSwagger}}
4
+
5
+ {{#description}}
6
+ /**
7
+ * {{classname}}
8
+ *
9
+ * {{{description}}}
10
+ *
11
+ * @export
12
+ * @class {{classname}}{{#parent}}
13
+ * @extends {{=<% %>=}}{<%parent%>}<%={{ }}=%>{{/parent}}
14
+ */
15
+ {{/description}}
16
+ {{^description}}
17
+ /**
18
+ * {{classname}}
19
+ *
20
+ * @export
21
+ * @class {{classname}}{{#parent}}
22
+ * @extends {{=<% %>=}}{<%parent%>}<%={{ }}=%>{{/parent}}
23
+ */
24
+ {{/description}}
25
+ export class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{
26
+ {{#additionalPropertiesType}}
27
+ [key: string]: {{{additionalPropertiesType}}}{{#additionalPropertiesIsAnyType}}{{#hasVars}} | any{{/hasVars}}{{/additionalPropertiesIsAnyType}};
28
+
29
+ {{/additionalPropertiesType}}
30
+ {{#vars}}
31
+ /**
32
+ * {{baseName}}{{#description}} - {{{description}}}{{/description}}
33
+ *
34
+ * @type {{=<% %>=}}{<%&dataType%><%#isNullable%> | null<%/isNullable%>}<%={{ }}=%>
35
+ * @memberof {{classname}}{{#required}}
36
+ * @required{{/required}}{{#deprecated}}
37
+ * @deprecated{{/deprecated}}{{#dataFormat}}
38
+ * @format {{dataFormat}}{{/dataFormat}}{{#minimum}}
39
+ * @minimum {{minimum}}{{/minimum}}{{#maximum}}
40
+ * @maximum {{maximum}}{{/maximum}}{{#minLength}}
41
+ * @minLength {{minLength}}{{/minLength}}{{#maxLength}}
42
+ * @maxLength {{maxLength}}{{/maxLength}}{{#pattern}}
43
+ * @pattern {{pattern}}{{/pattern}}{{#example}}
44
+ * @example {{=<% %>=}}<%&example%><%={{ }}=%>{{/example}}
45
+ */{{#nestJsSwagger}}
46
+ @ApiProperty({
47
+ description: {{#description}}`{{{description}}}`{{/description}}{{^description}}undefined{{/description}},{{#required}}
48
+ required: true,{{/required}}{{^required}}
49
+ required: false,{{/required}}{{#isNullable}}
50
+ nullable: true,{{/isNullable}}{{#deprecated}}
51
+ deprecated: true,{{/deprecated}}{{#isEnum}}
52
+ enum: {{enumName}},{{/isEnum}}{{^isEnum}}{{#isContainer}}
53
+ type: () => [{{#items}}{{^isPrimitiveType}}{{{complexType}}}{{/isPrimitiveType}}{{#isPrimitiveType}}{{{datatype}}}{{/isPrimitiveType}}{{/items}}],{{/isContainer}}{{^isContainer}}{{^isPrimitiveType}}
54
+ type: () => {{{dataType}}},{{/isPrimitiveType}}{{#isPrimitiveType}}
55
+ type: '{{{datatype}}}',{{/isPrimitiveType}}{{/isContainer}}{{/isEnum}}{{#dataFormat}}
56
+ format: '{{dataFormat}}',{{/dataFormat}}{{#example}}
57
+ example: {{=<% %>=}}<%&example%><%={{ }}=%>,{{/example}}{{#minimum}}
58
+ minimum: {{minimum}},{{/minimum}}{{#maximum}}
59
+ maximum: {{maximum}},{{/maximum}}{{#minLength}}
60
+ minLength: {{minLength}},{{/minLength}}{{#maxLength}}
61
+ maxLength: {{maxLength}},{{/maxLength}}{{#pattern}}
62
+ pattern: '{{pattern}}',{{/pattern}}
63
+ }){{/nestJsSwagger}}
64
+ @Expose()
65
+ {{^isPrimitiveType}}{{^isEnum}}{{#isContainer}}{{#items}}{{^isPrimitiveType}}@Type(() => {{{complexType}}}){{/isPrimitiveType}}{{/items}}{{/isContainer}}{{^isContainer}}@Type(() => {{{dataType}}}){{/isContainer}}
66
+ {{/isEnum}}{{/isPrimitiveType}}'{{baseName}}'{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}} | null{{/isNullable}};
67
+ {{/vars}}
68
+
69
+ static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string, description?: string, vendorExtensions?: any, modelClass?: any}> = [
70
+ {{#vars}}
71
+ {
72
+ "name": "{{name}}",
73
+ "baseName": "{{baseName}}",
74
+ "type": "{{#isContainer}}Array<{{#items}}{{datatype}}{{/items}}>{{/isContainer}}{{^isContainer}}{{datatype}}{{/isContainer}}",
75
+ "format": "{{dataFormat}}",
76
+ "description": {{#description}}`{{description}}`{{/description}}{{^description}}undefined{{/description}},
77
+ "vendorExtensions": {}{{^isPrimitiveType}}{{^isEnum}},
78
+ "modelClass": {{#isContainer}}{{#items}}{{^isPrimitiveType}}{{{complexType}}}{{/isPrimitiveType}}{{#isPrimitiveType}}undefined{{/isPrimitiveType}}{{/items}}{{/isContainer}}{{^isContainer}}{{{dataType}}}{{/isContainer}}{{/isEnum}}{{/isPrimitiveType}}
79
+ }{{^-last}},{{/-last}}
80
+ {{/vars}}
81
+ ];
82
+ }{{#hasEnums}}
83
+
84
+ {{#vars}}
85
+ {{#isEnum}}
86
+ {{#stringEnums}}
87
+ {{#allowableValues}}
88
+ /**
89
+ * Enum for {{enumName}}{{#description}}
90
+ *
91
+ * {{{description}}}{{/description}}
92
+ *
93
+ * @export
94
+ * @enum {string}
95
+ */
96
+ {{/allowableValues}}
97
+ export enum {{enumName}} {
98
+ {{#allowableValues}}
99
+ {{#enumVars}}
100
+ {{#enumDescription}}
101
+ /**
102
+ * {{.}}
103
+ */
104
+ {{/enumDescription}}
105
+ {{{name}}} = {{{value}}}{{^-last}},{{/-last}}
106
+ {{/enumVars}}
107
+ {{/allowableValues}}
108
+ }
109
+ {{/stringEnums}}
110
+ {{^stringEnums}}
111
+ {{#allowableValues}}
112
+ /**
113
+ * Constant for {{enumName}}{{#description}}
114
+ *
115
+ * {{{description}}}{{/description}}
116
+ *
117
+ * @export
118
+ */
119
+ {{/allowableValues}}
120
+ export const {{enumName}} = {
121
+ {{#allowableValues}}
122
+ {{#enumVars}}
123
+ {{#enumDescription}}
124
+ /**
125
+ * {{.}}
126
+ */
127
+ {{/enumDescription}}
128
+ {{{name}}}: {{{value}}}{{^-last}},{{/-last}}
129
+ {{/enumVars}}
130
+ {{/allowableValues}}
131
+ } as const;
132
+
133
+ export type {{enumName}} = typeof {{enumName}}[keyof typeof {{enumName}}];
134
+ {{/stringEnums}}
135
+ {{/isEnum}}
136
+ {{/vars}}
137
+ {{/hasEnums}}