openapi-sync 2.1.6 → 2.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +797 -72
  2. package/db.json +1 -1
  3. package/package.json +9 -1
package/README.md CHANGED
@@ -1,138 +1,863 @@
1
- # Openapi-sync
1
+ # OpenAPI Sync - Comprehensive Documentation
2
2
 
3
3
  [![NPM Version](https://img.shields.io/npm/v/openapi-sync.svg)](https://www.npmjs.com/package/openapi-sync)
4
4
  [![License](https://img.shields.io/npm/l/openapi-sync.svg)](https://github.com/akintomiwa-fisayo/openapi-sync/blob/main/LICENSE)
5
5
 
6
- **Openapi-sync** is a powerful developer tool that automates the synchronization of your API documentation with your codebase using OpenAPI (formerly Swagger) specifications. It generates TypeScript types and endpoint definitions from your OpenAPI schema, ensuring your API documentation stays up-to-date with your code.
6
+ **OpenAPI Sync** is a powerful developer tool that automates the synchronization of your API documentation with your codebase using OpenAPI (formerly Swagger) specifications. It generates TypeScript types, endpoint definitions, and comprehensive documentation from your OpenAPI schema, ensuring your API documentation stays up-to-date with your code.
7
+
8
+ ## Table of Contents
9
+
10
+ - [Features](#features)
11
+ - [Installation](#installation)
12
+ - [Quick Start](#quick-start)
13
+ - [Configuration](#configuration)
14
+ - [Usage](#usage)
15
+ - [Generated Output](#generated-output)
16
+ - [API Reference](#api-reference)
17
+ - [Advanced Examples](#advanced-examples)
18
+ - [Troubleshooting](#troubleshooting)
7
19
 
8
20
  ## Features
9
21
 
10
- - 🔄 Real-time API Synchronization
11
- - 📝 Automatic Type Generation
12
- - 🔄 Periodic API Refetching
13
- - 📁 Configurable Output Directory
14
- - 🔄 Customizable Naming Conventions
15
- - 🔄 Endpoint URL Transformation
16
- - 🔄 Schema Validation
17
- - 🔄 CLI Integration
18
- - 🔄 TypeScript Support
19
- - 🔄 YAML and JSON Support
22
+ ### 🔄 **Real-time API Synchronization**
23
+
24
+ - Automatically fetches and syncs OpenAPI specifications from remote URLs
25
+ - Supports both JSON and YAML formats
26
+ - Configurable refetch intervals for development environments
27
+ - Smart caching to avoid unnecessary regeneration
28
+
29
+ ### 📝 **Automatic Type Generation**
30
+
31
+ - Generates TypeScript interfaces for all API endpoints
32
+ - Creates type definitions for request/response bodies
33
+ - Supports complex nested objects, arrays, and unions
34
+ - Handles nullable types and optional properties
35
+ - Generates shared component types from OpenAPI components
36
+
37
+ ### 🔧 **Highly Configurable**
38
+
39
+ - Customizable naming conventions for types and endpoints
40
+ - Flexible output directory structure
41
+ - URL transformation and text replacement rules
42
+ - Configurable documentation generation
43
+ - Support for multiple API specifications
44
+
45
+ ### 🛡️ **Enterprise Ready**
46
+
47
+ - Network error handling with exponential backoff retry
48
+ - Schema validation using Redocly OpenAPI Core
49
+ - State persistence to track changes
50
+ - Environment-aware (disables auto-sync in production)
51
+ - TypeScript support with full type safety
52
+
53
+ ### 📚 **Rich Documentation**
54
+
55
+ - Generates comprehensive JSDoc comments
56
+ - Includes cURL examples for each endpoint
57
+ - Security scheme documentation
58
+ - Request/response type documentation
59
+ - Markdown-formatted type references
20
60
 
21
61
  ## Installation
22
62
 
23
- Install the package using npm:
63
+ ### NPM Package
24
64
 
25
65
  ```bash
26
66
  npm install openapi-sync
27
67
  ```
28
68
 
29
- Or use it directly via npx:
69
+ ### Global Installation
70
+
71
+ ```bash
72
+ npm install -g openapi-sync
73
+ ```
74
+
75
+ ### Direct Usage (No Installation)
30
76
 
31
77
  ```bash
32
78
  npx openapi-sync
33
79
  ```
34
80
 
81
+ ## Quick Start
82
+
83
+ 1. **Create a configuration file** in your project root:
84
+
85
+ ```json
86
+ // openapi.sync.json
87
+ {
88
+ "refetchInterval": 5000,
89
+ "folder": "./src/api",
90
+ "api": {
91
+ "petstore": "https://petstore3.swagger.io/api/v3/openapi.json"
92
+ }
93
+ }
94
+ ```
95
+
96
+ 2. **Run the sync command**:
97
+
98
+ ```bash
99
+ npx openapi-sync
100
+ ```
101
+
102
+ 3. **Use the generated types and endpoints**:
103
+
104
+ ```typescript
105
+ import { getPetById } from "./src/api/petstore/endpoints";
106
+ import { IPet, IGetPetByIdResponse } from "./src/api/petstore/types";
107
+
108
+ // Use the endpoint URL
109
+ const petUrl = getPetById("123"); // Returns: "/pet/123"
110
+
111
+ // Use the generated types
112
+ const pet: IPet = {
113
+ id: 1,
114
+ name: "Fluffy",
115
+ status: "available",
116
+ };
117
+ ```
118
+
35
119
  ## Configuration
36
120
 
37
- Create a `openapi.sync.json` file in your project root with the following structure:
121
+ OpenAPI Sync supports multiple configuration file formats:
122
+
123
+ - `openapi.sync.json` (JSON format)
124
+ - `openapi.sync.ts` (TypeScript format)
125
+ - `openapi.sync.js` (JavaScript format)
126
+
127
+ ### Basic Configuration
38
128
 
39
129
  ```json
40
130
  {
41
- "refetchInterval": 5000, // milliseconds between API refetches
42
- "folder": "/path/to/output", // output directory for generated files
131
+ "refetchInterval": 5000,
132
+ "folder": "./src/api",
43
133
  "api": {
44
- "example1": "https://api.example.com/openapi.json",
45
- "example2": "https://api.example.com/openapi.yaml"
134
+ "petstore": "https://petstore3.swagger.io/api/v3/openapi.json",
135
+ "jsonplaceholder": "https://jsonplaceholder.typicode.com/openapi.yaml"
46
136
  },
47
- "naming": {
48
- "replaceWords": [
49
- {
50
- "replace": "Api",
51
- "with": "",
52
- "type": "endpoint"
53
- }
54
- ]
137
+ "server": 0
138
+ }
139
+ ```
140
+
141
+ ### Advanced Configuration
142
+
143
+ ```typescript
144
+ // openapi.sync.ts
145
+ import { IConfig } from "openapi-sync/types";
146
+
147
+ const config: IConfig = {
148
+ refetchInterval: 10000,
149
+ folder: "./src/generated/api",
150
+ api: {
151
+ "main-api": "https://api.example.com/openapi.json",
152
+ "auth-api": "https://auth.example.com/openapi.yaml",
55
153
  },
56
- "endpoints": {
57
- "value": {
58
- "replaceWords": [
59
- {
60
- "replace": "/api/v\\d/",
61
- "with": ""
154
+ server: "https://api.example.com", // Override server URL
155
+
156
+ // Type generation configuration
157
+ types: {
158
+ name: {
159
+ prefix: "I", // Prefix for interface names
160
+ format: (source, data, defaultName) => {
161
+ if (source === "shared") {
162
+ return `${data.name}Type`;
163
+ } else if (source === "endpoint") {
164
+ return `${data.method?.toUpperCase()}${data.path?.replace(
165
+ /\//g,
166
+ "_"
167
+ )}${data.type}`;
62
168
  }
63
- ]
64
- }
65
- }
66
- }
169
+ return defaultName;
170
+ },
171
+ },
172
+ doc: {
173
+ disable: false, // Enable/disable JSDoc generation
174
+ },
175
+ },
176
+
177
+ // Endpoint generation configuration
178
+ endpoints: {
179
+ value: {
180
+ replaceWords: [
181
+ {
182
+ replace: "/api/v\\d+/", // Remove version from URLs
183
+ with: "/",
184
+ },
185
+ {
186
+ replace: "/internal/",
187
+ with: "/",
188
+ type: "endpoint",
189
+ },
190
+ ],
191
+ includeServer: true, // Include server URL in endpoints
192
+ type: "object", // Generate as objects instead of strings
193
+ },
194
+ name: {
195
+ prefix: "API_",
196
+ useOperationId: true, // Use operationId from OpenAPI spec
197
+ format: ({ method, path, summary, operationId }, defaultName) => {
198
+ if (operationId) return operationId;
199
+ return path.replace(/\//g, "_").replace(/{|}/g, "");
200
+ },
201
+ },
202
+ doc: {
203
+ disable: false,
204
+ showCurl: true, // Include cURL examples in documentation
205
+ },
206
+ },
207
+ };
208
+
209
+ export default config;
67
210
  ```
68
211
 
212
+ ### Configuration Options Reference
213
+
214
+ #### Root Configuration
215
+
216
+ | Property | Type | Description | Default |
217
+ | ----------------- | ------------------------ | --------------------------------------------- | -------- |
218
+ | `refetchInterval` | `number` | Milliseconds between API refetches (dev only) | - |
219
+ | `folder` | `string` | Output directory for generated files | `""` |
220
+ | `api` | `Record<string, string>` | Map of API names to OpenAPI spec URLs | Required |
221
+ | `server` | `number \| string` | Server index or custom server URL | `0` |
222
+
223
+ #### Type Configuration (`types`)
224
+
225
+ | Property | Type | Description |
226
+ | ------------- | ---------- | ---------------------------------- |
227
+ | `name.prefix` | `string` | Prefix for generated type names |
228
+ | `name.format` | `function` | Custom naming function for types |
229
+ | `doc.disable` | `boolean` | Disable JSDoc generation for types |
230
+
231
+ #### Endpoint Configuration (`endpoints`)
232
+
233
+ | Property | Type | Description |
234
+ | --------------------- | ---------------------- | -------------------------------------- |
235
+ | `value.replaceWords` | `IConfigReplaceWord[]` | URL transformation rules |
236
+ | `value.includeServer` | `boolean` | Include server URL in endpoints |
237
+ | `value.type` | `"string" \| "object"` | Output format for endpoints |
238
+ | `name.prefix` | `string` | Prefix for endpoint names |
239
+ | `name.useOperationId` | `boolean` | Use OpenAPI operationId for naming |
240
+ | `name.format` | `function` | Custom naming function for endpoints |
241
+ | `doc.disable` | `boolean` | Disable JSDoc generation for endpoints |
242
+ | `doc.showCurl` | `boolean` | Include cURL examples in documentation |
243
+
69
244
  ## Usage
70
245
 
71
- ### CLI Commands
246
+ ### CLI Usage
247
+
248
+ #### Basic Commands
72
249
 
73
250
  ```bash
74
- # Basic usage
251
+ # Run with default configuration
75
252
  npx openapi-sync
76
253
 
77
- # With custom refetch interval
254
+ # Run with custom refetch interval
78
255
  npx openapi-sync --refreshinterval 30000
256
+ npx openapi-sync -ri 30000
257
+
258
+ # Get help
259
+ npx openapi-sync --help
79
260
  ```
80
261
 
262
+ #### CLI Options
263
+
264
+ | Option | Alias | Type | Description |
265
+ | ------------------- | ----- | -------- | ------------------------------------- |
266
+ | `--refreshinterval` | `-ri` | `number` | Override refetch interval from config |
267
+
81
268
  ### Programmatic Usage
82
269
 
270
+ #### Basic Usage
271
+
83
272
  ```typescript
84
273
  import { Init } from "openapi-sync";
85
274
 
275
+ // Initialize with default config
276
+ await Init();
277
+
86
278
  // Initialize with custom options
87
279
  await Init({
88
- refetchInterval: 30000, // optional, defaults to config value
280
+ refetchInterval: 30000,
89
281
  });
90
282
  ```
91
283
 
92
- ## Output Generation
284
+ #### Advanced Integration
285
+
286
+ ```typescript
287
+ import { Init } from "openapi-sync";
288
+
289
+ // In your application startup
290
+ export const initializeAPI = async () => {
291
+ try {
292
+ await Init({
293
+ refetchInterval: process.env.NODE_ENV === "development" ? 5000 : 0,
294
+ });
295
+ console.log("API types synchronized successfully");
296
+ } catch (error) {
297
+ console.error("Failed to sync API types:", error);
298
+ throw error;
299
+ }
300
+ };
301
+
302
+ // Call during app initialization
303
+ initializeAPI();
304
+ ```
305
+
306
+ #### Function-based Configuration
93
307
 
94
- The tool generates:
308
+ ```typescript
309
+ // openapi.sync.ts
310
+ import { IConfig } from "openapi-sync/types";
311
+
312
+ export default (): IConfig => {
313
+ const baseConfig = {
314
+ refetchInterval: 5000,
315
+ folder: "./src/api",
316
+ api: {},
317
+ };
318
+
319
+ // Dynamic configuration based on environment
320
+ if (process.env.NODE_ENV === "development") {
321
+ baseConfig.api = {
322
+ "local-api": "http://localhost:3000/openapi.json",
323
+ };
324
+ } else {
325
+ baseConfig.api = {
326
+ "prod-api": "https://api.production.com/openapi.json",
327
+ };
328
+ }
95
329
 
96
- 1. TypeScript interfaces for API endpoints
97
- 2. Type definitions for request/response bodies
98
- 3. Shared component types
99
- 4. Endpoint URL constants
330
+ return baseConfig;
331
+ };
332
+ ```
100
333
 
101
- ## Type Generation
334
+ ## Generated Output
102
335
 
103
- The tool supports:
336
+ OpenAPI Sync generates a structured output in your specified folder:
104
337
 
105
- - Primitive types (string, number, boolean, etc.)
106
- - Complex types (objects, arrays)
107
- - Enums
108
- - Nullable types
109
- - Any types
110
- - Shared components
111
- - Request/response bodies
338
+ ```
339
+ src/api/
340
+ ├── petstore/
341
+ │ ├── endpoints.ts # Endpoint URLs and metadata
342
+ │ └── types/
343
+ │ ├── index.ts # Endpoint-specific types
344
+ │ └── shared.ts # Shared component types
345
+ └── auth-api/
346
+ ├── endpoints.ts
347
+ └── types/
348
+ ├── index.ts
349
+ └── shared.ts
350
+ ```
112
351
 
113
- ## Error Handling
352
+ ### Generated Endpoints
353
+
354
+ #### String Format (Default)
355
+
356
+ ````typescript
357
+ // endpoints.ts
358
+ /**
359
+ * **Method**: `GET`
360
+ * **Summary**: Find pet by ID
361
+ * **Tags**: [pet]
362
+ * **OperationId**: getPetById
363
+ * **Response**:
364
+ * - **200**:
365
+ * ```typescript
366
+ * {
367
+ * "id": number;
368
+ * "name": string;
369
+ * "status": ("available"|"pending"|"sold");
370
+ * }
371
+ * ```
372
+ *
373
+ * ```bash
374
+ * curl -X GET "https://petstore3.swagger.io/api/v3/pet/123" \
375
+ * -H "accept: application/json"
376
+ * ```
377
+ */
378
+ export const getPetById = (petId: string) => `/pet/${petId}`;
379
+
380
+ /**
381
+ * **Method**: `POST`
382
+ * **Summary**: Add a new pet to the store
383
+ */
384
+ export const addPet = "/pet";
385
+ ````
386
+
387
+ #### Object Format
388
+
389
+ ````typescript
390
+ // endpoints.ts (with type: "object")
391
+ /**
392
+ * **Method**: `POST`
393
+ * **Summary**: Add a new pet to the store
394
+ * **DTO**:
395
+ * ```typescript
396
+ * {
397
+ * "name": string;
398
+ * "photoUrls": string[];
399
+ * "status": ("available"|"pending"|"sold");
400
+ * }
401
+ * ```
402
+ */
403
+ export const addPet = {
404
+ method: "POST",
405
+ operationId: "addPet",
406
+ url: "/pet",
407
+ };
408
+
409
+ export const getPetById = {
410
+ method: "GET",
411
+ operationId: "getPetById",
412
+ url: (petId: string) => `/pet/${petId}`,
413
+ };
414
+ ````
415
+
416
+ ### Generated Types
417
+
418
+ #### Endpoint Types
114
419
 
115
- The tool includes:
420
+ ```typescript
421
+ // types/index.ts
422
+ import * as Shared from "./shared";
423
+
424
+ // Query parameter types
425
+ export type IFindPetsByStatusQuery = {
426
+ status?: "available" | "pending" | "sold";
427
+ };
428
+
429
+ // Request body types (DTO)
430
+ export type IAddPetDTO = {
431
+ id?: number;
432
+ name: string;
433
+ category?: Shared.ICategory;
434
+ photoUrls: string[];
435
+ tags?: Shared.ITag[];
436
+ status?: "available" | "pending" | "sold";
437
+ };
438
+
439
+ // Response types
440
+ export type IGetPetById200Response = {
441
+ id?: number;
442
+ name: string;
443
+ category?: Shared.ICategory;
444
+ photoUrls: string[];
445
+ tags?: Shared.ITag[];
446
+ status?: "available" | "pending" | "sold";
447
+ };
448
+ ```
116
449
 
117
- - Network error retries
118
- - Schema validation
119
- - Type generation error handling
120
- - State persistence
450
+ #### Shared Component Types
121
451
 
122
- ## API Documentation
452
+ ```typescript
453
+ // types/shared.ts
454
+ /**
455
+ * A category for a pet
456
+ */
457
+ export type ICategory = {
458
+ id?: number;
459
+ name?: string;
460
+ };
461
+
462
+ /**
463
+ * A tag for a pet
464
+ */
465
+ export type ITag = {
466
+ id?: number;
467
+ name?: string;
468
+ };
469
+
470
+ export type IPet = {
471
+ id?: number;
472
+ name: string;
473
+ category?: ICategory;
474
+ photoUrls: string[];
475
+ tags?: ITag[];
476
+ status?: "available" | "pending" | "sold";
477
+ };
478
+ ```
123
479
 
124
- For detailed API documentation, please refer to the [OpenAPI specification](https://spec.openapis.org/oas/v3.0.3).
480
+ ## API Reference
125
481
 
126
- ## License
482
+ ### Exported Functions
127
483
 
128
- This project is licensed under the ISC License - see the [LICENSE](LICENSE) file for details.
484
+ #### `Init(options?: { refetchInterval?: number }): Promise<void>`
485
+
486
+ Initializes OpenAPI sync with the specified configuration.
487
+
488
+ **Parameters:**
489
+
490
+ - `options.refetchInterval` - Override the refetch interval from config file
491
+
492
+ **Example:**
493
+
494
+ ```typescript
495
+ import { Init } from "openapi-sync";
496
+
497
+ await Init({ refetchInterval: 10000 });
498
+ ```
499
+
500
+ ### Exported Types
501
+
502
+ All types from the `types.ts` file are available for import:
503
+
504
+ ```typescript
505
+ import {
506
+ IConfig,
507
+ IOpenApiSpec,
508
+ IOpenApSchemaSpec,
509
+ IConfigReplaceWord,
510
+ } from "openapi-sync/types";
511
+ ```
512
+
513
+ ## Advanced Examples
514
+
515
+ ### Multi-Environment Configuration
516
+
517
+ ```typescript
518
+ // openapi.sync.ts
519
+ import { IConfig } from "openapi-sync/types";
520
+
521
+ const getConfig = (): IConfig => {
522
+ const env = process.env.NODE_ENV || "development";
523
+
524
+ const baseConfig: IConfig = {
525
+ refetchInterval: env === "development" ? 5000 : 0,
526
+ folder: "./src/api",
527
+ api: {},
528
+ types: {
529
+ name: {
530
+ prefix: "I",
531
+ format: (source, data, defaultName) => {
532
+ if (source === "endpoint" && data.type === "response") {
533
+ return `${defaultName.replace(/Response$/, "")}Data`;
534
+ }
535
+ return defaultName;
536
+ },
537
+ },
538
+ },
539
+ };
540
+
541
+ switch (env) {
542
+ case "development":
543
+ baseConfig.api = {
544
+ "local-api": "http://localhost:3000/api/openapi.json",
545
+ };
546
+ break;
547
+ case "staging":
548
+ baseConfig.api = {
549
+ "staging-api": "https://staging-api.example.com/openapi.json",
550
+ };
551
+ break;
552
+ case "production":
553
+ baseConfig.api = {
554
+ "prod-api": "https://api.example.com/openapi.json",
555
+ };
556
+ break;
557
+ }
558
+
559
+ return baseConfig;
560
+ };
561
+
562
+ export default getConfig;
563
+ ```
564
+
565
+ ### Custom Type Formatting
566
+
567
+ ```typescript
568
+ // Advanced type name formatting
569
+ const config: IConfig = {
570
+ // ... other config
571
+ types: {
572
+ name: {
573
+ prefix: "",
574
+ format: (source, data, defaultName) => {
575
+ if (source === "shared") {
576
+ // Shared types: UserProfile, OrderStatus, etc.
577
+ return `${data.name}`;
578
+ } else if (source === "endpoint") {
579
+ const method = data.method?.toUpperCase();
580
+ const cleanPath = data.path
581
+ ?.replace(/[{}\/]/g, "_")
582
+ .replace(/_+/g, "_");
583
+
584
+ switch (data.type) {
585
+ case "query":
586
+ return `${method}${cleanPath}Query`;
587
+ case "dto":
588
+ return `${method}${cleanPath}Request`;
589
+ case "response":
590
+ return `${method}${cleanPath}${data.code}Response`;
591
+ default:
592
+ return defaultName;
593
+ }
594
+ }
595
+ return defaultName;
596
+ },
597
+ },
598
+ },
599
+ };
600
+ ```
601
+
602
+ ### URL Transformation Rules
603
+
604
+ ```typescript
605
+ const config: IConfig = {
606
+ // ... other config
607
+ endpoints: {
608
+ value: {
609
+ replaceWords: [
610
+ // Remove API versioning from URLs
611
+ {
612
+ replace: "/api/v[0-9]+/",
613
+ with: "/",
614
+ },
615
+ // Remove internal prefixes
616
+ {
617
+ replace: "/internal/",
618
+ with: "/",
619
+ },
620
+ // Transform specific paths
621
+ {
622
+ replace: "/users/profile",
623
+ with: "/profile",
624
+ },
625
+ ],
626
+ includeServer: true,
627
+ type: "object",
628
+ },
629
+ name: {
630
+ format: ({ method, path, operationId }, defaultName) => {
631
+ // Use operationId if available, otherwise generate from path
632
+ if (operationId) {
633
+ return operationId.replace(/[^a-zA-Z0-9]/g, "");
634
+ }
635
+
636
+ // Generate meaningful names from path and method
637
+ const cleanPath = path
638
+ .replace(/^\//, "")
639
+ .replace(/\//g, "_")
640
+ .replace(/{([^}]+)}/g, "By$1")
641
+ .replace(/[^a-zA-Z0-9_]/g, "");
642
+
643
+ return `${method.toLowerCase()}${cleanPath}`;
644
+ },
645
+ },
646
+ },
647
+ };
648
+ ```
649
+
650
+ ### Integration with Build Process
651
+
652
+ #### Package.json Scripts
653
+
654
+ ```json
655
+ {
656
+ "scripts": {
657
+ "api:sync": "openapi-sync",
658
+ "api:sync:watch": "openapi-sync --refreshinterval 3000",
659
+ "prebuild": "npm run api:sync",
660
+ "build": "tsc",
661
+ "dev": "concurrently \"npm run api:sync:watch\" \"npm run dev:server\""
662
+ }
663
+ }
664
+ ```
665
+
666
+ #### Pre-commit Hook
667
+
668
+ ```bash
669
+ #!/bin/sh
670
+ # .husky/pre-commit
671
+
672
+ # Sync API types before commit
673
+ npm run api:sync
674
+
675
+ # Add generated files to commit
676
+ git add src/api/
677
+ ```
678
+
679
+ #### CI/CD Integration
680
+
681
+ ```yaml
682
+ # .github/workflows/build.yml
683
+ name: Build
684
+ on: [push, pull_request]
685
+
686
+ jobs:
687
+ build:
688
+ runs-on: ubuntu-latest
689
+ steps:
690
+ - uses: actions/checkout@v2
691
+ - uses: actions/setup-node@v2
692
+ with:
693
+ node-version: "16"
694
+
695
+ - name: Install dependencies
696
+ run: npm ci
697
+
698
+ - name: Sync API types
699
+ run: npm run api:sync
700
+ env:
701
+ NODE_ENV: production
702
+
703
+ - name: Build
704
+ run: npm run build
705
+ ```
706
+
707
+ ### Error Handling and Monitoring
708
+
709
+ ```typescript
710
+ import { Init } from "openapi-sync";
711
+
712
+ const initializeAPIWithRetry = async (maxRetries = 3) => {
713
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
714
+ try {
715
+ await Init({
716
+ refetchInterval: process.env.NODE_ENV === "development" ? 5000 : 0,
717
+ });
718
+
719
+ console.log("✅ API types synchronized successfully");
720
+ return;
721
+ } catch (error) {
722
+ console.error(`❌ Attempt ${attempt} failed:`, error.message);
723
+
724
+ if (attempt === maxRetries) {
725
+ console.error("🚨 Failed to sync API types after all retries");
726
+ throw error;
727
+ }
728
+
729
+ // Wait before retry
730
+ await new Promise((resolve) => setTimeout(resolve, 2000 * attempt));
731
+ }
732
+ }
733
+ };
734
+
735
+ // Usage in your app
736
+ initializeAPIWithRetry().catch((error) => {
737
+ // Handle critical error - maybe use cached types or exit
738
+ console.error("Critical: Could not sync API types", error);
739
+ process.exit(1);
740
+ });
741
+ ```
742
+
743
+ ## Troubleshooting
744
+
745
+ ### Common Issues
746
+
747
+ #### 1. Configuration File Not Found
748
+
749
+ ```
750
+ Error: No config found
751
+ ```
752
+
753
+ **Solution:** Ensure you have one of these files in your project root:
754
+
755
+ - `openapi.sync.json`
756
+ - `openapi.sync.ts`
757
+ - `openapi.sync.js`
758
+
759
+ #### 2. Network Timeout Errors
760
+
761
+ ```
762
+ Error: timeout of 60000ms exceeded
763
+ ```
764
+
765
+ **Solution:** The tool includes automatic retry with exponential backoff. If issues persist:
766
+
767
+ - Check your internet connection
768
+ - Verify the OpenAPI spec URL is accessible
769
+ - Consider increasing timeout in your configuration
770
+
771
+ #### 3. TypeScript Compilation Errors
772
+
773
+ ```
774
+ Error: Cannot find module './src/api/petstore/types'
775
+ ```
776
+
777
+ **Solution:**
778
+
779
+ - Ensure the sync process completed successfully
780
+ - Check that the `folder` path in config is correct
781
+ - Verify TypeScript can resolve the generated paths
782
+
783
+ #### 4. Invalid OpenAPI Specification
784
+
785
+ ```
786
+ Error: Schema validation failed
787
+ ```
129
788
 
130
- ## Support
789
+ **Solution:**
790
+
791
+ - Validate your OpenAPI spec using online validators
792
+ - Check for syntax errors in YAML/JSON
793
+ - Ensure the spec follows OpenAPI 3.0+ standards
794
+
795
+ ### Performance Optimization
796
+
797
+ #### 1. Reduce Refetch Frequency
798
+
799
+ ```json
800
+ {
801
+ "refetchInterval": 30000 // Increase to 30 seconds
802
+ }
803
+ ```
804
+
805
+ #### 2. Disable Documentation Generation
806
+
807
+ ```json
808
+ {
809
+ "types": { "doc": { "disable": true } },
810
+ "endpoints": { "doc": { "disable": true } }
811
+ }
812
+ ```
131
813
 
132
- For support, please open an issue in the GitHub repository.
814
+ #### 3. Use Specific Output Folders
815
+
816
+ ```json
817
+ {
818
+ "folder": "./src/api" // Specific path instead of root
819
+ }
820
+ ```
821
+
822
+ ### Debugging
823
+
824
+ #### Enable Verbose Logging
825
+
826
+ ```typescript
827
+ // Set environment variable for debugging
828
+ process.env.DEBUG = "openapi-sync:*";
829
+
830
+ import { Init } from "openapi-sync";
831
+ await Init();
832
+ ```
833
+
834
+ #### Check Generated State
835
+
836
+ The tool maintains state in `db.json` to track changes:
837
+
838
+ ```json
839
+ // db.json
840
+ {
841
+ "petstore": {
842
+ "openapi": "3.0.0",
843
+ "info": { "title": "Petstore API" }
844
+ // ... full OpenAPI spec
845
+ }
846
+ }
847
+ ```
848
+
849
+ ### Getting Help
850
+
851
+ 1. **Check the Issues**: [GitHub Issues](https://github.com/akintomiwa-fisayo/openapi-sync/issues)
852
+ 2. **Create a Bug Report**: Include your configuration and error logs
853
+ 3. **Feature Requests**: Describe your use case and expected behavior
854
+
855
+ ---
856
+
857
+ ## License
858
+
859
+ This project is licensed under the ISC License - see the [LICENSE](LICENSE) file for details.
133
860
 
134
- ## Acknowledgments
861
+ ## Contributing
135
862
 
136
- - Thanks to the OpenAPI Initiative for the OpenAPI specification
137
- - Thanks to all contributors and users of this package
138
- - Flexible CLI Commands: Sync your API at any point in the development process on app start, pre-commit, or via manual triggers.
863
+ Contributions are welcome! Please read our contributing guidelines and submit pull requests to our GitHub repository.