klasik 1.0.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 ADDED
@@ -0,0 +1,314 @@
1
+ # klasik
2
+
3
+ Download OpenAPI specifications from remote URLs and generate TypeScript clients with class-transformer support for Kubernetes and other APIs.
4
+
5
+ ## Features
6
+
7
+ - ๐Ÿ“ฅ **Download OpenAPI specs** from remote URLs or local files
8
+ - ๐Ÿ“ **Multiple input formats** - HTTP/HTTPS URLs, file:// URLs, absolute/relative paths
9
+ - ๐Ÿ”„ **Automatic transformation** - Converts API responses to class instances using class-transformer
10
+ - ๐ŸŽฏ **Type-safe** - Full TypeScript support with decorators
11
+ - ๐Ÿ› ๏ธ **Configurable** - Custom headers, timeouts, and templates
12
+ - ๐Ÿงช **Well-tested** - Comprehensive test coverage (11 tests passing)
13
+ - ๐Ÿ“ฆ **Easy to use** - Simple CLI and programmatic API
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install klasik
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### CLI Usage
24
+
25
+ Generate a TypeScript client from a remote OpenAPI spec:
26
+
27
+ ```bash
28
+ npx klasik generate \
29
+ --url https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json \
30
+ --output ./k8s-client
31
+ ```
32
+
33
+ Generate from a local OpenAPI spec file:
34
+
35
+ ```bash
36
+ # Absolute path
37
+ npx klasik generate \
38
+ --url /path/to/openapi.json \
39
+ --output ./client
40
+
41
+ # Relative path
42
+ npx klasik generate \
43
+ --url ./specs/openapi.json \
44
+ --output ./client
45
+
46
+ # file:// URL
47
+ npx klasik generate \
48
+ --url file:///path/to/openapi.json \
49
+ --output ./client
50
+ ```
51
+
52
+ Download an OpenAPI spec without generating:
53
+
54
+ ```bash
55
+ npx klasik download \
56
+ --url https://api.example.com/openapi.json \
57
+ --output ./specs/api-spec.json
58
+ ```
59
+
60
+ ### Programmatic Usage
61
+
62
+ ```typescript
63
+ import { K8sClientGenerator } from 'klasik';
64
+
65
+ const generator = new K8sClientGenerator();
66
+
67
+ await generator.generate({
68
+ specUrl: 'https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json',
69
+ outputDir: './k8s-client',
70
+ });
71
+ ```
72
+
73
+ ## CLI Commands
74
+
75
+ ### `generate`
76
+
77
+ Generate a TypeScript client from an OpenAPI spec (remote URL or local file).
78
+
79
+ **Options:**
80
+ - `-u, --url <url>` - URL or file path to the OpenAPI spec (required)
81
+ - Supports: `https://...`, `http://...`, `file://...`, `/absolute/path`, `./relative/path`
82
+ - `-o, --output <dir>` - Output directory for generated client code (required)
83
+ - `-H, --header <header...>` - Custom headers for HTTP requests (format: "Key: Value")
84
+ - `-t, --template <dir>` - Custom template directory
85
+ - `-k, --keep-spec` - Keep the downloaded spec file after generation
86
+ - `--timeout <ms>` - Request timeout in milliseconds for HTTP requests (default: 30000)
87
+
88
+ **Examples:**
89
+
90
+ ```bash
91
+ # From remote URL
92
+ klasik generate \
93
+ --url https://api.example.com/openapi.json \
94
+ --output ./client \
95
+ --header "Authorization: Bearer token123" \
96
+ --timeout 60000
97
+
98
+ # From local file
99
+ klasik generate \
100
+ --url ./my-spec.json \
101
+ --output ./client
102
+
103
+ # From file:// URL
104
+ klasik generate \
105
+ --url file:///Users/me/specs/api.json \
106
+ --output ./client
107
+ ```
108
+
109
+ ### `download`
110
+
111
+ Download an OpenAPI spec from a remote URL without generating code.
112
+
113
+ **Options:**
114
+ - `-u, --url <url>` - Remote URL to download the OpenAPI spec from (required)
115
+ - `-o, --output <file>` - Output file path for the downloaded spec (required)
116
+ - `-H, --header <header...>` - Custom headers for the request
117
+ - `--timeout <ms>` - Request timeout in milliseconds (default: 30000)
118
+
119
+ **Example:**
120
+
121
+ ```bash
122
+ klasik download \
123
+ --url https://api.example.com/openapi.json \
124
+ --output ./specs/api-spec.json \
125
+ --header "Authorization: Bearer token123"
126
+ ```
127
+
128
+ ## Programmatic API
129
+
130
+ ### K8sClientGenerator
131
+
132
+ ```typescript
133
+ import { K8sClientGenerator } from 'klasik';
134
+
135
+ const generator = new K8sClientGenerator();
136
+
137
+ await generator.generate({
138
+ specUrl: 'https://api.example.com/openapi.json',
139
+ outputDir: './client',
140
+ headers: {
141
+ 'Authorization': 'Bearer token123',
142
+ 'X-Custom-Header': 'value'
143
+ },
144
+ templateDir: './custom-templates', // Optional
145
+ keepSpec: true, // Keep downloaded spec file
146
+ timeout: 60000 // Request timeout in ms
147
+ });
148
+ ```
149
+
150
+ ### SpecDownloader
151
+
152
+ ```typescript
153
+ import { SpecDownloader } from 'klasik';
154
+
155
+ const downloader = new SpecDownloader();
156
+
157
+ const specPath = await downloader.download({
158
+ url: 'https://api.example.com/openapi.json',
159
+ outputPath: './specs/api-spec.json',
160
+ headers: {
161
+ 'Authorization': 'Bearer token123'
162
+ },
163
+ timeout: 30000
164
+ });
165
+
166
+ console.log(`Spec downloaded to: ${specPath}`);
167
+
168
+ // Clean up temporary files
169
+ downloader.cleanupTemp();
170
+ ```
171
+
172
+ ## Generated Client Features
173
+
174
+ The generated TypeScript client includes:
175
+
176
+ - โœ… **Class-transformer decorators** - `@Expose()` and `@Type()` on all models
177
+ - โœ… **Automatic response transformation** - API responses converted to class instances
178
+ - โœ… **Runtime type metadata** - Static `attributeTypeMap` on all models
179
+ - โœ… **Union type support** - `anyOf` schemas become TypeScript unions
180
+ - โœ… **Vendor extensions** - Preserved in JSDoc comments and metadata
181
+ - โœ… **Error handling** - Configurable transformation error handlers
182
+ - โœ… **Configuration options** - Enable/disable transformation, custom error handlers
183
+
184
+ ### Example Generated Model
185
+
186
+ ```typescript
187
+ import { Expose, Type } from 'class-transformer';
188
+
189
+ export class User {
190
+ @Expose()
191
+ 'id': string;
192
+
193
+ @Expose()
194
+ 'name': string;
195
+
196
+ @Expose()
197
+ @Type(() => Profile)
198
+ 'profile'?: Profile;
199
+
200
+ static readonly attributeTypeMap = [
201
+ {
202
+ "name": "id",
203
+ "baseName": "id",
204
+ "type": "string",
205
+ "format": "",
206
+ "description": "User ID",
207
+ "vendorExtensions": {}
208
+ },
209
+ // ... more properties
210
+ ];
211
+ }
212
+ ```
213
+
214
+ ### Using the Generated Client
215
+
216
+ ```typescript
217
+ import { DefaultApi, Configuration } from './generated-client';
218
+ import { plainToInstance } from 'class-transformer';
219
+
220
+ // Create API client
221
+ const config = new Configuration({
222
+ basePath: 'https://api.example.com',
223
+ enableResponseTransformation: true, // Default
224
+ onTransformationError: (error, modelClass, data) => {
225
+ console.error('Transformation failed:', error);
226
+ }
227
+ });
228
+
229
+ const api = new DefaultApi(config);
230
+
231
+ // Get user - response is automatically transformed to User class instance
232
+ const response = await api.getUserById({ id: '123' });
233
+ const user = response.data; // user is instanceof User โœ…
234
+
235
+ console.log(user.name); // Fully typed!
236
+ ```
237
+
238
+ ## Advanced Configuration
239
+
240
+ ### Custom Error Handling
241
+
242
+ ```typescript
243
+ const config = new Configuration({
244
+ basePath: 'https://api.example.com',
245
+ onTransformationError: (error, modelClass, data) => {
246
+ // Log to custom logger
247
+ logger.error('Failed to transform response', {
248
+ error: error.message,
249
+ modelClass: modelClass.name,
250
+ rawData: data
251
+ });
252
+
253
+ // Send to error tracking
254
+ Sentry.captureException(error);
255
+ }
256
+ });
257
+ ```
258
+
259
+ ### Disable Transformation
260
+
261
+ ```typescript
262
+ const config = new Configuration({
263
+ basePath: 'https://api.example.com',
264
+ enableResponseTransformation: false // Get plain objects
265
+ });
266
+ ```
267
+
268
+ ## Requirements
269
+
270
+ - Node.js >= 16
271
+ - TypeScript >= 5.0 (for experimentalDecorators support)
272
+
273
+ ### TypeScript Configuration
274
+
275
+ Your `tsconfig.json` must include:
276
+
277
+ ```json
278
+ {
279
+ "compilerOptions": {
280
+ "experimentalDecorators": true,
281
+ "emitDecoratorMetadata": true
282
+ }
283
+ }
284
+ ```
285
+
286
+ ## Development
287
+
288
+ ```bash
289
+ # Install dependencies
290
+ npm install
291
+
292
+ # Build
293
+ npm run build
294
+
295
+ # Run tests
296
+ npm test
297
+
298
+ # Watch mode
299
+ npm run dev
300
+ ```
301
+
302
+ ## License
303
+
304
+ MIT
305
+
306
+ ## Related Projects
307
+
308
+ - [openapi-class-transformer](https://github.com/example/openapi-class-transformer) - The underlying generator used by this package
309
+ - [class-transformer](https://github.com/typestack/class-transformer) - Transformation library
310
+ - [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator) - OpenAPI code generator
311
+
312
+ ## Contributing
313
+
314
+ Contributions are welcome! Please open an issue or submit a pull request.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const commander_1 = require("commander");
38
+ const k8s_client_generator_1 = require("./k8s-client-generator");
39
+ const path = __importStar(require("path"));
40
+ const program = new commander_1.Command();
41
+ program
42
+ .name('klasik')
43
+ .description('Download OpenAPI specs from remote URLs and generate TypeScript clients with class-transformer support')
44
+ .version('1.0.0');
45
+ program
46
+ .command('generate')
47
+ .description('Generate TypeScript client from a remote OpenAPI spec')
48
+ .requiredOption('-u, --url <url>', 'Remote URL to download the OpenAPI spec from')
49
+ .requiredOption('-o, --output <dir>', 'Output directory for generated client code')
50
+ .option('-m, --mode <mode>', 'Generation mode: "full" (models + APIs + config) or "models-only"', 'full')
51
+ .option('-H, --header <header...>', 'Custom headers for the request (format: "Key: Value")')
52
+ .option('-t, --template <dir>', 'Custom template directory')
53
+ .option('-k, --keep-spec', 'Keep the downloaded spec file after generation', false)
54
+ .option('--timeout <ms>', 'Request timeout in milliseconds', '30000')
55
+ .action(async (options) => {
56
+ try {
57
+ // Validate mode
58
+ if (options.mode !== 'full' && options.mode !== 'models-only') {
59
+ console.error('Error: --mode must be either "full" or "models-only"');
60
+ process.exit(1);
61
+ }
62
+ // Parse headers if provided
63
+ const headers = {};
64
+ if (options.header) {
65
+ for (const header of options.header) {
66
+ const [key, ...valueParts] = header.split(':');
67
+ const value = valueParts.join(':').trim();
68
+ if (key && value) {
69
+ headers[key.trim()] = value;
70
+ }
71
+ }
72
+ }
73
+ // Resolve output directory to absolute path
74
+ const outputDir = path.resolve(options.output);
75
+ const generator = new k8s_client_generator_1.K8sClientGenerator();
76
+ await generator.generate({
77
+ specUrl: options.url,
78
+ outputDir,
79
+ mode: options.mode,
80
+ headers: Object.keys(headers).length > 0 ? headers : undefined,
81
+ templateDir: options.template,
82
+ keepSpec: options.keepSpec,
83
+ timeout: parseInt(options.timeout, 10),
84
+ });
85
+ process.exit(0);
86
+ }
87
+ catch (error) {
88
+ console.error('Error:', error instanceof Error ? error.message : error);
89
+ process.exit(1);
90
+ }
91
+ });
92
+ program
93
+ .command('download')
94
+ .description('Download an OpenAPI spec from a remote URL (without generating)')
95
+ .requiredOption('-u, --url <url>', 'Remote URL to download the OpenAPI spec from')
96
+ .requiredOption('-o, --output <file>', 'Output file path for the downloaded spec')
97
+ .option('-H, --header <header...>', 'Custom headers for the request (format: "Key: Value")')
98
+ .option('--timeout <ms>', 'Request timeout in milliseconds', '30000')
99
+ .action(async (options) => {
100
+ try {
101
+ const { SpecDownloader } = await Promise.resolve().then(() => __importStar(require('./spec-downloader')));
102
+ // Parse headers if provided
103
+ const headers = {};
104
+ if (options.header) {
105
+ for (const header of options.header) {
106
+ const [key, ...valueParts] = header.split(':');
107
+ const value = valueParts.join(':').trim();
108
+ if (key && value) {
109
+ headers[key.trim()] = value;
110
+ }
111
+ }
112
+ }
113
+ const downloader = new SpecDownloader();
114
+ await downloader.download({
115
+ url: options.url,
116
+ outputPath: path.resolve(options.output),
117
+ headers: Object.keys(headers).length > 0 ? headers : undefined,
118
+ timeout: parseInt(options.timeout, 10),
119
+ });
120
+ process.exit(0);
121
+ }
122
+ catch (error) {
123
+ console.error('Error:', error instanceof Error ? error.message : error);
124
+ process.exit(1);
125
+ }
126
+ });
127
+ program.parse();
@@ -0,0 +1,2 @@
1
+ export { K8sClientGenerator, K8sClientGeneratorOptions, GenerationMode } from './k8s-client-generator';
2
+ export { SpecDownloader, DownloadOptions } from './spec-downloader';
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpecDownloader = exports.K8sClientGenerator = void 0;
4
+ var k8s_client_generator_1 = require("./k8s-client-generator");
5
+ Object.defineProperty(exports, "K8sClientGenerator", { enumerable: true, get: function () { return k8s_client_generator_1.K8sClientGenerator; } });
6
+ var spec_downloader_1 = require("./spec-downloader");
7
+ Object.defineProperty(exports, "SpecDownloader", { enumerable: true, get: function () { return spec_downloader_1.SpecDownloader; } });
@@ -0,0 +1,52 @@
1
+ export type GenerationMode = 'full' | 'models-only';
2
+ export interface K8sClientGeneratorOptions {
3
+ /**
4
+ * Remote URL to download the OpenAPI spec from
5
+ */
6
+ specUrl: string;
7
+ /**
8
+ * Output directory for generated client code
9
+ */
10
+ outputDir: string;
11
+ /**
12
+ * Generation mode
13
+ * - 'full': Generate models, APIs, and configuration (default)
14
+ * - 'models-only': Generate only model classes
15
+ * @default 'full'
16
+ */
17
+ mode?: GenerationMode;
18
+ /**
19
+ * Optional headers to include in the spec download request
20
+ */
21
+ headers?: Record<string, string>;
22
+ /**
23
+ * Optional custom template directory
24
+ */
25
+ templateDir?: string;
26
+ /**
27
+ * Whether to keep the downloaded spec file after generation
28
+ * @default false
29
+ */
30
+ keepSpec?: boolean;
31
+ /**
32
+ * Request timeout for downloading spec in milliseconds
33
+ * @default 30000
34
+ */
35
+ timeout?: number;
36
+ }
37
+ export declare class K8sClientGenerator {
38
+ private downloader;
39
+ constructor();
40
+ /**
41
+ * Generate TypeScript client from a remote OpenAPI spec URL
42
+ */
43
+ generate(options: K8sClientGeneratorOptions): Promise<void>;
44
+ /**
45
+ * Prepare the output directory
46
+ */
47
+ private prepareOutputDirectory;
48
+ /**
49
+ * Clean up the downloaded spec file
50
+ */
51
+ private cleanupSpecFile;
52
+ }
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.K8sClientGenerator = void 0;
37
+ const openapi_class_transformer_1 = require("openapi-class-transformer");
38
+ const spec_downloader_1 = require("./spec-downloader");
39
+ const fs = __importStar(require("fs"));
40
+ class K8sClientGenerator {
41
+ constructor() {
42
+ this.downloader = new spec_downloader_1.SpecDownloader();
43
+ }
44
+ /**
45
+ * Generate TypeScript client from a remote OpenAPI spec URL
46
+ */
47
+ async generate(options) {
48
+ const { specUrl, outputDir, mode = 'full', headers, templateDir, keepSpec = false, timeout, } = options;
49
+ let specPath;
50
+ try {
51
+ // Step 1: Download the OpenAPI spec
52
+ console.log('Step 1: Downloading OpenAPI specification...');
53
+ const downloadOptions = {
54
+ url: specUrl,
55
+ headers,
56
+ timeout,
57
+ };
58
+ specPath = await this.downloader.download(downloadOptions);
59
+ // Step 2: Validate output directory
60
+ console.log('Step 2: Preparing output directory...');
61
+ this.prepareOutputDirectory(outputDir);
62
+ // Step 3: Generate client using openapi-class-transformer
63
+ const modeLabel = mode === 'models-only' ? 'models only' : 'full client';
64
+ console.log(`Step 3: Generating TypeScript ${modeLabel}...`);
65
+ const generatorOptions = {
66
+ inputSpec: specPath,
67
+ outputDir,
68
+ modelsOnly: mode === 'models-only',
69
+ };
70
+ // Only add templateDir if it's provided
71
+ if (templateDir) {
72
+ generatorOptions.templateDir = templateDir;
73
+ }
74
+ const generator = new openapi_class_transformer_1.Generator(generatorOptions);
75
+ await generator.generate();
76
+ console.log('โœ… Client generation completed successfully!');
77
+ console.log(`๐Ÿ“ Generated files location: ${outputDir}`);
78
+ }
79
+ catch (error) {
80
+ console.error('โŒ Client generation failed:', error);
81
+ throw error;
82
+ }
83
+ finally {
84
+ // Cleanup
85
+ if (!keepSpec && specPath) {
86
+ this.cleanupSpecFile(specPath);
87
+ }
88
+ }
89
+ }
90
+ /**
91
+ * Prepare the output directory
92
+ */
93
+ prepareOutputDirectory(outputDir) {
94
+ if (!fs.existsSync(outputDir)) {
95
+ fs.mkdirSync(outputDir, { recursive: true });
96
+ console.log(`Created output directory: ${outputDir}`);
97
+ }
98
+ else {
99
+ console.log(`Using existing output directory: ${outputDir}`);
100
+ }
101
+ }
102
+ /**
103
+ * Clean up the downloaded spec file
104
+ */
105
+ cleanupSpecFile(specPath) {
106
+ try {
107
+ if (fs.existsSync(specPath)) {
108
+ fs.unlinkSync(specPath);
109
+ console.log(`Cleaned up downloaded spec file: ${specPath}`);
110
+ }
111
+ // Also cleanup temp directory if empty
112
+ this.downloader.cleanupTemp();
113
+ }
114
+ catch (error) {
115
+ console.warn('Warning: Failed to cleanup spec file:', error);
116
+ }
117
+ }
118
+ }
119
+ exports.K8sClientGenerator = K8sClientGenerator;
@@ -0,0 +1,53 @@
1
+ export interface DownloadOptions {
2
+ /**
3
+ * URL or file path to the OpenAPI spec
4
+ * Supports:
5
+ * - HTTP/HTTPS URLs: https://example.com/spec.json
6
+ * - File URLs: file:///path/to/spec.json
7
+ * - Absolute paths: /path/to/spec.json
8
+ * - Relative paths: ./spec.json, ../specs/api.json
9
+ */
10
+ url: string;
11
+ /**
12
+ * Optional output path to save the downloaded spec
13
+ * If not provided, will save to a temp file (for HTTP) or use the source path (for files)
14
+ */
15
+ outputPath?: string;
16
+ /**
17
+ * Optional headers to include in the request (only used for HTTP/HTTPS)
18
+ */
19
+ headers?: Record<string, string>;
20
+ /**
21
+ * Request timeout in milliseconds (only used for HTTP/HTTPS)
22
+ * @default 30000
23
+ */
24
+ timeout?: number;
25
+ }
26
+ export declare class SpecDownloader {
27
+ /**
28
+ * Download an OpenAPI specification from a URL or load from a local file
29
+ * @param options Download options
30
+ * @returns Path to the spec file
31
+ */
32
+ download(options: DownloadOptions): Promise<string>;
33
+ /**
34
+ * Check if the URL is a local file path
35
+ */
36
+ private isLocalFile;
37
+ /**
38
+ * Load and validate an OpenAPI spec from a local file
39
+ */
40
+ private loadLocalFile;
41
+ /**
42
+ * Generate a temporary file path based on the URL
43
+ */
44
+ private generateTempPath;
45
+ /**
46
+ * Validate that the downloaded content is an OpenAPI spec
47
+ */
48
+ private validateSpec;
49
+ /**
50
+ * Clean up temporary files
51
+ */
52
+ cleanupTemp(): void;
53
+ }