@paulpugovkin/api-docs-axios-ts-generator 1.0.17 → 1.2.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,310 +1,237 @@
1
- # API Docs Axios TS Generator
2
-
3
- Generate TypeScript interfaces and axios classes from OpenAPI (Swagger) specifications.
4
-
5
- ## Features
6
-
7
- - 🚀 Generate TypeScript interfaces from OpenAPI schemas
8
- - 📦 Generate axios classes with API methods
9
- - 🔧 Flexible configuration via TypeScript file
10
- - 🏷️ Tag filtering (include/exclude)
11
- - 📁 Generation modes: single class or multiple by tags
12
- - ⚙️ Automatic axios configuration generation
13
- - 🎯 Support for spreading user axios configurations
14
- - 📝 JSDoc comments for methods
15
- - 🔄 Backward compatibility with CLI arguments
16
-
17
- ## Installation
18
-
19
- ```bash
20
- npm install -g @paulpugovkin/api-docs-axios-ts-generator
21
- ```
22
-
23
- ## Usage
24
-
25
- ### 1. Install as project dependency
26
-
27
- ```bash
28
- npm install --save-dev @paulpugovkin/api-docs-axios-ts-generator
29
- ```
30
-
31
- Add script to your `package.json`:
32
-
33
- ```json
34
- {
35
- "scripts": {
36
- "generate-services": "npx @paulpugovkin/api-docs-axios-ts-generator --config api-docs-generator.config.js"
37
- }
38
- }
39
- ```
40
-
41
- Now you can run generation:
42
-
43
- ```bash
44
- npm run generate-services
45
- ```
46
-
47
-
48
- ### 2. Use as global tool
49
-
50
- ```bash
51
- # Install as global tool
52
- npm install -g @paulpugovkin/api-docs-axios-ts-generator
53
-
54
- # Run generation
55
- api-docs-generator --config api-docs-generator.config.js
56
-
57
- # Or via npx
58
- npx @paulpugovkin/api-docs-axios-ts-generator --config api-docs-generator.config.js
59
- ```
60
-
61
- ### 3. Create configuration file
62
-
63
- A default configuration file `api-docs-generator.config.js` is automatically created in your project root during installation. You can modify this file to suit your needs.
64
-
65
- If you need to create it manually, create `api-docs-generator.config.js` file in the root of your project:
66
-
67
- ```javascript
68
- module.exports = {
69
- // URL to fetch OpenAPI specification from
70
- apiDocsUrl: 'https://api.example.com/v3/api-docs.json',
71
-
72
- // Output directory for generated files
73
- outputDir: './src/api',
74
-
75
- // Tag filtering options
76
- tags: {
77
- include: ['api_tag_users', 'api_tag_products'],
78
- },
79
-
80
- // Grouping mode for API methods
81
- groupBy: 'tag',
82
-
83
- // Class generation mode
84
- classMode: 'multiple',
85
-
86
- // Generation options
87
- options: {
88
- generateAxiosConfig: true,
89
- allowAxiosConfigSpread: true,
90
- },
91
-
92
- // Axios configuration settings
93
- axios: {
94
- baseURL: 'https://api.example.com',
95
- timeout: 30000,
96
- },
97
- };
98
- ```
99
-
100
- ### 4. Use generated API
101
-
102
- ```typescript
103
- import { UsersApi, ProductsApi } from './src/api';
104
-
105
- // Use API
106
- const usersApi = new UsersApi();
107
- const productsApi = new ProductsApi();
108
-
109
- // Get user
110
- const user = await usersApi.getUserById(123);
111
-
112
- // With custom axios configuration
113
- const user = await usersApi.getUserById(123, {
114
- headers: {
115
- 'X-Custom-Header': 'value',
116
- },
117
- timeout: 5000,
118
- });
119
- ```
120
-
121
- ## Configuration
122
-
123
- ### Main parameters
124
-
125
- | Parameter | Type | Required | Description |
126
- |-----------|------|--------------|------------|
127
- | `apiDocsUrl` | `string` | No* | URL to fetch OpenAPI specification |
128
- | `apiDocsPath` | `string` | No* | Local path to OpenAPI specification file |
129
- | `outputDir` | `string` | Yes | Output directory for generated files |
130
-
131
- *One of `apiDocsUrl` or `apiDocsPath` is required.
132
-
133
- ### Tag filtering
134
-
135
- ```typescript
136
- tags: {
137
- include?: string[]; // Tags to include
138
- exclude?: string[]; // Tags to exclude
139
- prefix?: string; // Tag prefix (default "api_tag_")
140
- }
141
- ```
142
-
143
- ### Grouping modes
144
-
145
- ```typescript
146
- groupBy: 'tag' | 'all' | 'path';
147
- ```
148
-
149
- - `'tag'` - grouping by tags (multiple classes)
150
- - `'all'` - all methods in one class
151
- - `'path'` - grouping by API paths
152
-
153
- ### Class generation modes
154
-
155
- ```typescript
156
- classMode: 'single' | 'multiple';
157
- ```
158
-
159
- - `'single'` - one class for all methods
160
- - `'multiple'` - multiple classes by grouping
161
-
162
- ### Naming options
163
-
164
- ```typescript
165
- naming: {
166
- className?: (tag: string) => string;
167
- interfaceName?: (name: string) => string;
168
- methodName?: (operationId: string) => string;
169
- }
170
- ```
171
-
172
- ### Import options
173
-
174
- ```typescript
175
- imports: {
176
- axiosPath?: string; // Path to import axios (default 'axios')
177
- baseUrlPath?: string; // Path to import BASE_URL
178
- }
179
- ```
180
-
181
- ### Generation options
182
-
183
- ```typescript
184
- options: {
185
- generateJSDoc?: boolean; // Generate JSDoc (default true)
186
- generateIndexFiles?: boolean; // Generate index files (default true)
187
- cleanOutputDir?: boolean; // Clean output directory (default true)
188
- generateAxiosConfig?: boolean; // Generate axios configuration (default true)
189
- allowAxiosConfigSpread?: boolean; // Allow spreading axios configs (default true)
190
- }
191
- ```
192
-
193
- ### Axios settings
194
-
195
- ```typescript
196
- axios: {
197
- baseURL?: string;
198
- timeout?: number;
199
- headers?: Record<string, string>;
200
- withCredentials?: boolean;
201
- }
202
- ```
203
-
204
- ## Spreading user axios configurations
205
-
206
- When `allowAxiosConfigSpread: true` is enabled, API methods support passing user configurations:
207
-
208
- ```typescript
209
- // Generated method
210
- async getUserById(id: number, config?: AxiosRequestConfig): Promise<AxiosResponse<User>>
211
-
212
- // Usage
213
- const response = await usersApi.getUserById(123, {
214
- headers: {
215
- 'X-Custom-Header': 'value',
216
- },
217
- timeout: 5000,
218
- params: {
219
- fields: 'id,name,email',
220
- },
221
- });
222
- ```
223
-
224
- ## Generated files structure
225
-
226
- ```
227
- outputDir/
228
- ├── config/
229
- │ └── axios/
230
- │ └── axios.ts # Axios configuration with interceptors
231
- ├── interfaces/
232
- │ ├── User.ts
233
- │ ├── Product.ts
234
- │ └── index.ts
235
- ├── classes/
236
- │ ├── UsersApi.ts
237
- │ ├── ProductsApi.ts
238
- │ └── index.ts
239
- └── index.ts
240
- ```
241
-
242
- ## CLI options
243
-
244
- ```
245
- Usage: api-docs-generator [options]
246
-
247
- Options:
248
- -V, --version output the version number
249
- -c, --config <path> Path to configuration file
250
- --api-docs-url <url> URL to fetch OpenAPI documentation
251
- --api-docs-path <path> Local path to OpenAPI documentation file
252
- --output-dir <dir> Output directory for generated files
253
- --clean Clean output directory before generation
254
- -h, --help display help for command
255
- ```
256
-
257
- ## Configuration examples
258
-
259
- ### Generate by tags (multiple classes)
260
-
261
- ```typescript
262
- {
263
- tags: {
264
- include: ['api_tag_users', 'api_tag_products'],
265
- },
266
- groupBy: 'tag',
267
- classMode: 'multiple',
268
- }
269
- ```
270
-
271
- ### Generate single class
272
-
273
- ```typescript
274
- {
275
- groupBy: 'all',
276
- classMode: 'single',
277
- }
278
- ```
279
-
280
- ### Exclude tags
281
-
282
- ```typescript
283
- {
284
- tags: {
285
- exclude: ['api_tag_internal', 'api_tag_admin'],
286
- },
287
- }
288
- ```
289
-
290
- ### Generate with axios configuration
291
-
292
- ```typescript
293
- {
294
- options: {
295
- generateAxiosConfig: true,
296
- },
297
- axios: {
298
- baseURL: 'https://api.example.com',
299
- timeout: 30000,
300
- headers: {
301
- 'Content-Type': 'application/json',
302
- 'X-API-Key': 'your-api-key',
303
- },
304
- },
305
- }
306
- ```
307
-
308
- ## License
309
-
310
- MIT
1
+ # API Docs Axios TS Generator
2
+
3
+ Generate TypeScript interfaces and axios classes from OpenAPI (Swagger) specifications.
4
+
5
+ ## Features
6
+
7
+ - Generate TypeScript interfaces from OpenAPI schemas
8
+ - Generate axios classes with API methods
9
+ - Flexible configuration via TypeScript file
10
+ - Tag filtering (include/exclude)
11
+ - Generation modes: single class or multiple by tags
12
+ - Automatic axios configuration generation
13
+ - Support for spreading user axios configurations
14
+ - JSDoc comments for methods
15
+ - Backward compatibility with CLI arguments
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install --save-dev @paulpugovkin/api-docs-axios-ts-generator
21
+ ```
22
+
23
+ Add script to your `package.json`:
24
+
25
+ ```json
26
+ {
27
+ "scripts": {
28
+ "generate-services": "api-docs-generator --config api-docs-generator.config.js"
29
+ }
30
+ }
31
+ ```
32
+
33
+ Now generate your API client:
34
+
35
+ ```bash
36
+ npm run generate-services
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ### Create configuration file
42
+
43
+ A default configuration file `api-docs-generator.config.js` is automatically created in your project root during installation. You can modify this file to suit your needs.
44
+
45
+ If you need to create it manually, see the template at `src/templates/default.config.template.js` or the [Configuration](#configuration) reference below.
46
+
47
+ ## Generated API usage
48
+
49
+ ```typescript
50
+ import { UsersApi, ProductsApi } from './generated';
51
+
52
+ // Use API
53
+ const usersApi = new UsersApi();
54
+ const productsApi = new ProductsApi();
55
+
56
+ // Get user
57
+ const user = await usersApi.getUserById(123);
58
+
59
+ // With custom axios configuration
60
+ const user = await usersApi.getUserById(123, {
61
+ headers: {
62
+ 'X-Custom-Header': 'value',
63
+ },
64
+ timeout: 5000,
65
+ });
66
+ ```
67
+
68
+ ## Configuration
69
+
70
+ ### Main parameters
71
+
72
+ | Parameter | Type | Required | Description |
73
+ |-----------|------|--------------|------------|
74
+ | `apiDocsUrl` | `string` | No* | URL to fetch OpenAPI specification |
75
+ | `apiDocsPath` | `string` | No* | Local path to OpenAPI specification file |
76
+ | `outputDir` | `string` | Yes | Output directory for generated files |
77
+
78
+ *One of `apiDocsUrl` or `apiDocsPath` is required.
79
+
80
+ ### Tag filtering
81
+
82
+ ```typescript
83
+ tags: {
84
+ include?: string[]; // Tags to include
85
+ exclude?: string[]; // Tags to exclude
86
+ prefix?: string; // Tag prefix (default "api_tag_")
87
+ }
88
+ ```
89
+
90
+ ### Grouping modes
91
+
92
+ ```typescript
93
+ groupBy: 'tag' | 'all' | 'path';
94
+ ```
95
+
96
+ - `'tag'` - grouping by tags (multiple classes)
97
+ - `'all'` - all methods in one class
98
+ - `'path'` - grouping by API paths
99
+
100
+ ### Class generation modes
101
+
102
+ ```typescript
103
+ classMode: 'single' | 'multiple';
104
+ ```
105
+
106
+ - `'single'` - one class for all methods
107
+ - `'multiple'` - multiple classes by grouping
108
+
109
+ ### Naming options
110
+
111
+ ```typescript
112
+ naming: {
113
+ className?: (tag: string) => string;
114
+ interfaceName?: (name: string) => string;
115
+ methodName?: (operationId: string) => string;
116
+ }
117
+ ```
118
+
119
+ ### Import options
120
+
121
+ ```typescript
122
+ imports: {
123
+ axiosPath?: string; // Path to import axios (default 'axios')
124
+ baseUrlPath?: string; // Path to import BASE_URL
125
+ }
126
+ ```
127
+
128
+ ### Generation options
129
+
130
+ ```typescript
131
+ options: {
132
+ generateJSDoc?: boolean; // Generate JSDoc (default true)
133
+ generateIndexFiles?: boolean; // Generate index files (default true)
134
+ cleanOutputDir?: boolean; // Clean output directory (default true)
135
+ generateAxiosConfig?: boolean; // Generate axios configuration (default true)
136
+ allowAxiosConfigSpread?: boolean; // Allow spreading axios configs (default true)
137
+ }
138
+ ```
139
+
140
+ ### Axios settings
141
+
142
+ ```typescript
143
+ axios: {
144
+ baseURL?: string;
145
+ timeout?: number;
146
+ headers?: Record<string, string>;
147
+ withCredentials?: boolean;
148
+ }
149
+ ```
150
+
151
+ ## Generated files structure
152
+
153
+ ```
154
+ outputDir/
155
+ ├── config/
156
+ │ └── axios/
157
+ │ └── axios.ts # Axios configuration with interceptors
158
+ ├── interfaces/
159
+ │ ├── User.ts
160
+ │ ├── Product.ts
161
+ │ └── index.ts
162
+ ├── classes/
163
+ │ ├── UsersApi.ts
164
+ │ ├── ProductsApi.ts
165
+ │ └── index.ts
166
+ └── index.ts
167
+ ```
168
+
169
+ ## CLI options
170
+
171
+ ```
172
+ Usage: api-docs-generator [options]
173
+
174
+ Options:
175
+ -V, --version output the version number
176
+ -c, --config <path> Path to configuration file
177
+ --api-docs-url <url> URL to fetch OpenAPI documentation
178
+ --api-docs-path <path> Local path to OpenAPI documentation file
179
+ --output-dir <dir> Output directory for generated files
180
+ --clean Clean output directory before generation
181
+ -h, --help display help for command
182
+ ```
183
+
184
+ ## Configuration examples
185
+
186
+ ### Generate by tags (multiple classes)
187
+
188
+ ```typescript
189
+ {
190
+ tags: {
191
+ include: ['api_tag_users', 'api_tag_products'],
192
+ },
193
+ groupBy: 'tag',
194
+ classMode: 'multiple',
195
+ }
196
+ ```
197
+
198
+ ### Generate single class
199
+
200
+ ```typescript
201
+ {
202
+ groupBy: 'all',
203
+ classMode: 'single',
204
+ }
205
+ ```
206
+
207
+ ### Exclude tags
208
+
209
+ ```typescript
210
+ {
211
+ tags: {
212
+ exclude: ['api_tag_internal', 'api_tag_admin'],
213
+ },
214
+ }
215
+ ```
216
+
217
+ ### Generate with axios configuration
218
+
219
+ ```typescript
220
+ {
221
+ options: {
222
+ generateAxiosConfig: true,
223
+ },
224
+ axios: {
225
+ baseURL: 'https://api.example.com',
226
+ timeout: 30000,
227
+ headers: {
228
+ 'Content-Type': 'application/json',
229
+ 'X-API-Key': 'your-api-key',
230
+ },
231
+ },
232
+ }
233
+ ```
234
+
235
+ ## License
236
+
237
+ MIT
package/dist/index.js ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ var h=(t,o)=>()=>(o||t((o={exports:{}}).exports,o),o.exports);var M=h((at,E)=>{var N=require("fs"),B=require("path");function Ce(t){N.existsSync(t)&&(N.rmSync(t,{recursive:!0}),console.log(`Deleted: ${t}`)),N.mkdirSync(t,{recursive:!0}),N.mkdirSync(B.join(t,"interfaces"),{recursive:!0}),N.mkdirSync(B.join(t,"classes"),{recursive:!0}),console.log("Recreated necessary directories.")}E.exports={cleanGeneratedFolder:Ce}});var _=h((ct,G)=>{var k=require("fs"),Ue=require("path");async function ve(t,o){try{console.log(`Fetching API docs from: ${t}`);let e=await fetch(t);if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);let s=await e.json();k.mkdirSync(Ue.dirname(o),{recursive:!0}),k.writeFileSync(o,JSON.stringify(s,null,2),{encoding:"utf-8"}),console.log(`Updated and saved API docs to: ${o}`)}catch(e){console.error(`Failed to fetch or save the OpenAPI docs: ${e.message}`)}}G.exports={updateApiDocsJson:ve}});var W=h((pt,J)=>{function Ne(t){return{string:"string",integer:"number",boolean:"boolean",array:"any[]",object:"Record<string, any>",binary:"File"}[t]||"any"}J.exports={mapType:Ne}});var I=h((lt,Q)=>{var{mapType:Te}=W();function R(t,o,e){if(t.$ref){let i=t.$ref.split("/").pop();return e.add(i),i}return t.type==="array"?`Array<${R(t.items||{},o,e)}>`:t.type==="object"?t.properties?"{"+Object.entries(t.properties).map(([s,i])=>`${s}: ${R(i,o,e)}`).join("; ")+"}":"Record<string, any>":t.enum?t.enum.map(s=>`"${s}"`).join(" | "):t.oneOf?t.oneOf.map(i=>R(i,o,e)).join(" | "):t.type?Te(t.type):"any"}Q.exports={resolveType:R}});var H=h((ut,K)=>{var{resolveType:Re}=I(),z=require("path");function Ie(t){return t&&t.charAt(0).toUpperCase()+t.slice(1)}function Fe(t,o,e){let s={},i=[];for(let n of t)if(n.$ref){let a=n.$ref.split("/").pop();e.add(a),i.push(a)}else n.properties&&(s={...s,...n.properties});return{mergedProperties:s,extendsInterfaces:i}}function Le(t,o,e){let s=[];for(let i of t)if(i.$ref){let n=i.$ref.split("/").pop();e.add(n),s.push(n)}return s}function Be(t,o,e,s){let i=new Set,n=o.properties||{},a=[];if(o.allOf){let c=Fe(o.allOf,e,i);n={...n,...c.mergedProperties},a=c.extendsInterfaces}if(o.oneOf){let c=Le(o.oneOf,e,i);a.push(...c)}let m=[];for(let[c,f]of Object.entries(n)){let u=Re(f,e,i);m.push(` ${c}: ${u};`)}let g=s?.outputDir?z.relative(z.join(s.outputDir,"interfaces"),s.outputDir):"./",r=Array.from(i).sort().map(c=>`import type { ${c} } from '${g}';`).join(`
3
+ `),p=a.length?` extends ${a.join(", ")}`:"";return`${r}
4
+
5
+ export interface ${Ie(t)}${p} {
6
+ ${m.join(`
7
+ `)}
8
+ }
9
+ `}K.exports={generateInterface:Be}});var X=h((dt,V)=>{var{resolveType:ft}=I();function Ee(t){let o="",e="",s=t.parameters||[],i=t.summary||"",n=["/**"];if(t.requestBody){let r=t.requestBody.content||{};if(r["application/json"]){let p=r["application/json"].schema||{};if(p.oneOf)o=p.oneOf.map(c=>c.$ref.split("/").pop()).join(" | ");else if(p.$ref){let c=p.$ref.split("/").pop();c&&(o=c)}}r["multipart/form-data"]&&(e="FormData")}i&&n.push(` * @description ${i}`),e&&n.push(` * @param {${e}} data - \u0442\u0435\u043B\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0430`),o&&n.push(` * @param {${o}} values - \u0442\u0435\u043B\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0430`);let a={},m=[];return s.forEach(r=>{if(r.in==="query")if(r.name.includes(".")){let[p,c]=r.name.split(".");a[p]||(a[p]=[]),a[p].push({propertyName:c,description:r.description||"",type:r.schema.type||"string",required:r.required||!1})}else a[r.name]||(a[r.name]=[]),a[r.name].push({description:r.description||"",type:r.schema.type||"string",required:r.required||!1});else m.push({name:r.name,description:r.description||"",type:r.schema.type||"string",required:r.required||!1})}),Object.keys(a).length>0&&(n.push(" * @param {object} queryParams"),Object.keys(a).forEach(r=>{let c=a[r].sort((f,u)=>(u.required?1:0)-(f.required?1:0));if(c.length===1&&c[0].propertyName===void 0){let f=c[0],u=f.type==="integer"?"number":f.type;n.push(` * @param {${u}} queryParams.${r} - ${f.description}`)}else n.push(` * @param {object} queryParams.${r} - Query parameter`),c.forEach(f=>{let{propertyName:u,description:P,type:A}=f,b=A==="integer"?"number":A;n.push(` * @param {${b}} queryParams.${r}.${u} - ${P}`)})})),m.sort((r,p)=>(p.required?1:0)-(r.required?1:0)).forEach(r=>{let p=r.type==="integer"?"number":r.type;n.push(` * @param {${p}} ${r.name} - ${r.description}`)}),n.push(" * @param {AxiosRequestConfig} config - \u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F axios"),n.push(" */"),n.join(`
10
+ `)}V.exports={generateJSDoc:Ee}});var Z=h((gt,Y)=>{var mt=require("path"),{resolveType:S}=I(),{generateJSDoc:Me}=X();function ke(t,o,e,s,i,n,a={}){let m=a?.options?.allowAxiosConfigSpread!==!1;[...e.matchAll(/\{(\w+)\}/g)].map(l=>l[1]).forEach(l=>{e=e.replace(`{${l}}`,`\${${l}}`)});let r=[],p=[],c=[],f={},u=null,P="",A=!1;for(let l of o.parameters||[]){let d=l.name,$=l.in,q=l.required||!1,O=l.schema||{},Se=O.$ref||O.properties;if($==="path"){let x=S(O,i,n);r.push(`${d}: ${x}`)}else if($==="query")if(Se){let x=S(O,i,n);q?(r.push(`${d}: ${x}`),p.push(`...${d}`)):(c.push(`${d}?: ${x}`),p.push(`...(${d} || {})`))}else if(d.includes(".")){let[x,we]=d.split(".");f[x]=f[x]||[];let De=S(O,i,n);f[x].push(`${we}?: ${De}`)}else{let x=S(O,i,n);q?(p.push(d),r.push(`${d}: ${x}`)):c.push(`${d}?: ${x}`)}}for(let[l,d]of Object.entries(f))c.push(`${l}?: { ${d.join(", ")} }`);let F=["post","put","patch","delete"].includes(s.toLowerCase())&&o.requestBody&&o.requestBody.content&&Object.keys(o.requestBody.content).length>0;if(F){let l=o.requestBody.content||{};if(l["application/json"]){let d=l["application/json"].schema||{};if(d.oneOf)u=`values: ${S(d,i,n)}`;else if(d.$ref){let $=d.$ref.split("/").pop();n.add($),u=`values: ${$}`}else d.properties?u=`values: { ${Object.entries(d.properties).map(([q,O])=>`${q}: ${S(O,i,n)}`).join(", ")} }`:u="values: any";P="values"}else if(l["multipart/form-data"]){A=!0;let d=l["multipart/form-data"].schema||{};if(d.properties)for(let[$,q]of Object.entries(d.properties)){let O=S(q,i,n);q.format==="binary"&&(O="File")}u="data: FormData",P="data"}}let L="void";if(o.responses){for(let[l,d]of Object.entries(o.responses))if(d.content){let $=Object.values(d.content)[0].schema||{};if($.$ref){let q=$.$ref.split("/").pop();L=q,n.add(q)}}}let je=`Promise<AxiosResponse<${L}>>`,C=c.length?"queryParams":null,qe=C?`${C}: { ${c.join(", ")} }`:"",U=p.length>0||c.length>0,Oe=Me(o),Pe=`(${[...r,u,qe,"config?: AxiosRequestConfig"].filter(Boolean).join(", ")}): ${je}`,Ae=`${t}${Pe}`,be=`const fullURL = \`\${BASE_URL}${e}\`;`,y="",v=()=>{let l=[];return p.length>0&&l.push(...p),C&&(l.length>0?l.push(`...${C}`):l.push(`...${C}`)),l.length>0?`{ ${l.join(", ")} }`:"{}"};if(s.toLowerCase()==="delete")u?U?y=`return axios.delete(fullURL, { data: values, ...config, params: ${v()} });`:y="return axios.delete(fullURL, { data: values, ...config });":U?y=`return axios.delete(fullURL, { ...config, params: ${v()} });`:y="return axios.delete(fullURL, config);";else if(s.toLowerCase()==="get")U?y=`return axios.get(fullURL, { ...config, params: ${v()} });`:y="return axios.get(fullURL, config);";else if(F)if(U){let l=v();y=`return axios.${s}(fullURL, ${A?"data":P}, { ...config, params: ${l} });`}else y=`return axios.${s}(fullURL, ${A?"data":P}, config);`;else if(U){let l=v();y=`return axios.${s}(fullURL, null, { ...config, params: ${l} });`}else y=`return axios.${s}(fullURL, null, config);`;return`
11
+ ${Oe}
12
+ ${Ae} {
13
+ ${be}
14
+ ${y}
15
+ }
16
+ `}Y.exports={generateMethod:ke}});var oe=h((ht,te)=>{var ee=require("path");function Ge(t,o,e,s){let i=`import type { AxiosResponse, AxiosRequestConfig } from "axios";
17
+ `,n=s?.imports?.axiosPath||"axios",a=s?.imports?.baseUrlPath||"./config/axios/axios",m=s?.outputDir?ee.relative(ee.join(s.outputDir,"classes"),s.outputDir):"../../",g="";e&&e.size>0&&(g=Array.from(e).sort().map(u=>`import { ${u} } from '${m}';`).join(`
18
+ `));let r=`
19
+ import axios from '${n}'`,p=`
20
+ import { BASE_URL } from '${a}'`,c=`${i}${g}${r}${p}`,f=o.join(`
21
+ `);return`${c}
22
+
23
+ export class ${t} {
24
+ ${f}
25
+ }
26
+ `}te.exports={generateClass:Ge}});var ae=h((yt,ie)=>{var D=require("fs"),w=require("path"),{generateInterface:_e}=H(),{generateMethod:se}=Z(),{generateClass:re}=oe();function ne(t){D.existsSync(t)||D.mkdirSync(t,{recursive:!0})}function Je(t,o){let e=o?.tags?.prefix||"api_tag_";for(let s of t)if(s.includes(e))return s;return""}function We(t,o){let{include:e,exclude:s,prefix:i}=o?.tags||{};if(e&&e.length>0)return e.includes(t);if(s&&s.length>0)return!s.includes(t);let n=i||"api_tag_";return t.includes(n)}function Qe(t,o){let e={},s=o?.tags?.prefix||"api_tag_";for(let i of t){if(!i.tag)continue;let n=o?.naming?.className?o.naming.className(i.tag):i.tag.replace(s,"");e[n]||(e[n]=[]),e[n].push(i)}return e}async function ze(t,o){let e=JSON.parse(D.readFileSync(t,{encoding:"utf-8"})),s=o.outputDir||w.resolve(process.cwd(),"generated"),i=o.interfacesDir||w.join(s,"interfaces"),n=o.classesDir||w.join(s,"classes");ne(i),ne(n);let a=e?.components?.schemas||{};if(e?.components?.schemas)for(let[r,p]of Object.entries(a)){let c=_e(r,p,a,o);D.writeFileSync(w.join(i,`${r}.ts`),c,{encoding:"utf-8"})}let m=[];if(e?.paths){for(let[r,p]of Object.entries(e.paths))for(let[c,f]of Object.entries(p))if(f?.tags){let u=Je(f.tags,o);if(!u||!We(u,o))continue;m.push({operationId:f.operationId,methodDetails:f,pathKey:r,methodType:c,tag:u})}}if((o.groupBy||"tag")==="all"||o.classMode==="single"){let r=o?.naming?.className?o.naming.className("all"):"ApiClient",p=new Set,c=m.map(u=>se(u.operationId,u.methodDetails,u.pathKey,u.methodType,a,p,o)),f=re(r,c,p,o);D.writeFileSync(w.join(n,`${r}.ts`),f,{encoding:"utf-8"})}else{let r=Qe(m,o);for(let[p,c]of Object.entries(r)){let f=new Set,u=c.map(b=>se(b.operationId,b.methodDetails,b.pathKey,b.methodType,a,f,o)),P=o?.naming?.className?o.naming.className(c[0].tag):p+"Api",A=re(P,u,f,o);D.writeFileSync(w.join(n,`${P}.ts`),A,{encoding:"utf-8"})}}console.log(`Generated ${m.length} API methods.`),console.log(`Generated ${Object.keys(a).length} interfaces.`)}ie.exports={parseAndGenerate:ze}});var ue=h(($t,le)=>{var ce=require("fs"),pe=require("path");function Ke(t,o){let e=[];function s(i){let n=ce.readdirSync(i,{withFileTypes:!0});for(let a of n){let m=pe.join(i,a.name);if(a.isDirectory())s(m);else if(a.isFile()&&a.name.endsWith(".ts")&&a.name!=="index.ts"){let r=pe.relative(t,m).replace(/\\/g,"/").replace(/\.ts$/,"");e.push(`export * from './${r}';`)}}}s(t),ce.writeFileSync(o,e.join(`
27
+ `),{encoding:"utf-8"}),console.log(`Generated ${o} with ${e.length} exports.`)}le.exports={generateIndexFileWithOpenApi:Ke}});var de=h((xt,fe)=>{var He=require("fs"),Ve=require("path");function Xe(t){let o=Ve.join(t,"index.ts"),e=["export * from './interfaces/';","export * from './classes/';"];He.writeFileSync(o,e.join(`
28
+ `),{encoding:"utf-8"}),console.log(`Generated main index.ts at ${o}.`)}fe.exports={generateMainIndexFile:Xe}});var ye=h((jt,he)=>{var me=require("fs"),ge=require("path");function Ye(t,o){let e=ge.join(o,"config","axios");me.mkdirSync(e,{recursive:!0});let s=t.axios||{},i=s.baseURL||"",n=s.timeout||3e4,a=s.headers||{"Content-Type":"application/json"},m=s.withCredentials||!1,g=`import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
29
+
30
+ export const BASE_URL = '${i}';
31
+
32
+ const axiosConfig: AxiosRequestConfig = {
33
+ baseURL: BASE_URL,
34
+ timeout: ${n},
35
+ headers: ${JSON.stringify(a,null,2)},
36
+ withCredentials: ${m},
37
+ };
38
+
39
+ const axiosInstance: AxiosInstance = axios.create(axiosConfig);
40
+
41
+ // \u041F\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043A \u0437\u0430\u043F\u0440\u043E\u0441\u043E\u0432
42
+ axiosInstance.interceptors.request.use(
43
+ (config) => {
44
+ // \u041C\u043E\u0436\u043D\u043E \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0442\u043E\u043A\u0435\u043D \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u0430\u0446\u0438\u0438
45
+ // const token = localStorage.getItem('token');
46
+ // if (token) {
47
+ // config.headers.Authorization = \`Bearer \${token}\`;
48
+ // }
49
+ return config;
50
+ },
51
+ (error) => {
52
+ return Promise.reject(error);
53
+ }
54
+ );
55
+
56
+ // \u041F\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043A \u043E\u0442\u0432\u0435\u0442\u043E\u0432
57
+ axiosInstance.interceptors.response.use(
58
+ (response) => {
59
+ return response;
60
+ },
61
+ (error) => {
62
+ // \u041E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u043E\u0448\u0438\u0431\u043E\u043A
63
+ if (error.response) {
64
+ // \u0421\u0435\u0440\u0432\u0435\u0440 \u043E\u0442\u0432\u0435\u0442\u0438\u043B \u0441\u043E \u0441\u0442\u0430\u0442\u0443\u0441\u043E\u043C, \u043E\u0442\u043B\u0438\u0447\u043D\u044B\u043C \u043E\u0442 2xx
65
+ console.error('Response error:', error.response.status, error.response.data);
66
+ } else if (error.request) {
67
+ // \u0417\u0430\u043F\u0440\u043E\u0441 \u0431\u044B\u043B \u0441\u0434\u0435\u043B\u0430\u043D, \u043D\u043E \u043E\u0442\u0432\u0435\u0442 \u043D\u0435 \u043F\u043E\u043B\u0443\u0447\u0435\u043D
68
+ console.error('Request error:', error.request);
69
+ } else {
70
+ // \u041F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430 \u043F\u0440\u0438 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0435 \u0437\u0430\u043F\u0440\u043E\u0441\u0430
71
+ console.error('Error:', error.message);
72
+ }
73
+ return Promise.reject(error);
74
+ }
75
+ );
76
+
77
+ export default axiosInstance;
78
+ `;me.writeFileSync(ge.join(e,"axios.ts"),g,{encoding:"utf-8"}),console.log(`Generated axios config at: ${e}/axios.ts`)}he.exports={generateAxiosConfig:Ye}});var{program:xe}=require("commander"),{cleanGeneratedFolder:Ze}=M(),{updateApiDocsJson:et}=_(),{parseAndGenerate:tt}=ae(),{generateIndexFileWithOpenApi:$e}=ue(),{generateMainIndexFile:ot}=de(),{generateAxiosConfig:st}=ye(),T=require("fs"),j=require("path");async function rt(t,o={}){let e=j.resolve(t);if(!T.existsSync(e))throw new Error(`Configuration file not found: ${e}`);let s=j.extname(e),i;try{if(s===".js"){let a=e;i=require(a)}else if(s===".json"){let a=T.readFileSync(e,"utf8");i=JSON.parse(a)}else if(s===".ts"){let a=require("typescript"),m=T.readFileSync(e,"utf8"),g=a.transpileModule(m,{compilerOptions:{module:1,target:99,esModuleInterop:!0}}),r=e.replace(".ts",".js");T.writeFileSync(r,g.outputText),i=require(r)}else throw new Error("Unsupported configuration file format. Use .js, .json, or .ts")}catch(a){throw new Error(`Failed to load configuration: ${a.message}`)}let n={...i};return Object.keys(o).forEach(a=>{o[a]!==void 0&&(n[a]=o[a])}),n}xe.version("1.0.0").description("Generate TypeScript API client from OpenAPI documentation").option("-c, --config <path>","Path to configuration file").option("--api-docs-url <url>","URL to fetch the OpenAPI documentation").option("--api-docs-path <path>","Local path to OpenAPI documentation file").option("--output-dir <dir>","Output directory for generated files").option("--clean","Clean output directory before generation").parse(process.argv);async function nt(){let t=xe.opts(),o=t.config;if(!o){let r=["api-docs-generator.config.js","api-docs-generator.config.json","api-docs-generator.config.ts"];for(let p of r){let c=j.join(process.cwd(),p);if(T.existsSync(c)){o=c,console.log(`Auto-detected configuration file: ${p}`);break}}}let e=null;if(o)try{e=await rt(o,{apiDocsUrl:t.apiDocsUrl,apiDocsPath:t.apiDocsPath,outputDir:t.outputDir})}catch(r){console.error(`Failed to load configuration: ${r.message}`),process.exit(1)}else{let r=t.apiDocsUrl,p=t.outputDir||j.resolve(process.cwd(),"generated");r||(console.error("Error: API documentation URL is required."),console.error("Please specify --api-docs-url or --api-docs-path, or create a configuration file."),console.error('Run "api-docs-generator --help" for more information.'),process.exit(1)),e={apiDocsUrl:r,outputDir:p,interfacesDir:j.join(p,"interfaces"),classesDir:j.join(p,"classes"),groupBy:"tag",classMode:"multiple",options:{cleanOutputDir:t.clean!==void 0?t.clean:!0,generateAxiosConfig:!1,generateIndexFiles:!0}}}console.log(`Using API Docs URL: ${e.apiDocsUrl}`),console.log(`Output directory: ${e.outputDir||"Not specified - using default"}`);let s=e.outputDir||j.resolve(process.cwd(),"generated"),i=e.interfacesDir||j.join(s,"interfaces"),n=e.classesDir||j.join(s,"classes"),a=j.join(i,"index.ts"),m=j.join(n,"index.ts");e.options?.cleanOutputDir!==!1&&Ze(s),e.apiDocsUrl&&await et(e.apiDocsUrl,"api-docs.json");let g=e.apiDocsPath||"api-docs.json";await tt(g,e),e.options?.generateAxiosConfig&&st(e,s),e.options?.generateIndexFiles!==!1&&(await $e(i,a),await $e(n,m),await ot(s)),console.log("Generation completed successfully.")}nt().catch(t=>console.error("Error during generation:",t));