openapi-sync 2.1.17 → 3.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 +246 -22
- package/dist/index.d.mts +44 -1
- package/dist/index.d.ts +44 -1
- package/dist/index.js +52 -43
- package/dist/index.mjs +52 -43
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
- [Configuration](#configuration)
|
|
13
13
|
- [Usage](#usage)
|
|
14
14
|
- [Generated Output](#generated-output)
|
|
15
|
+
- [Custom Code Injection](#custom-code-injection)
|
|
15
16
|
- [API Reference](#api-reference)
|
|
16
17
|
- [Advanced Examples](#advanced-examples)
|
|
17
18
|
- [Troubleshooting](#troubleshooting)
|
|
@@ -44,6 +45,7 @@
|
|
|
44
45
|
- URL transformation and text replacement rules
|
|
45
46
|
- Configurable documentation generation
|
|
46
47
|
- Support for multiple API specifications
|
|
48
|
+
- Custom code injection, preserve your custom code between regenerations
|
|
47
49
|
|
|
48
50
|
### 🛡️ **Enterprise Ready**
|
|
49
51
|
|
|
@@ -606,6 +608,250 @@ export type IPet = {
|
|
|
606
608
|
};
|
|
607
609
|
```
|
|
608
610
|
|
|
611
|
+
## Custom Code Injection
|
|
612
|
+
|
|
613
|
+
OpenAPI Sync supports preserving custom code between regenerations using special comment markers. This allows you to add your own custom endpoints, types, or utility functions that will survive when the generated code is updated.
|
|
614
|
+
|
|
615
|
+
### How It Works
|
|
616
|
+
|
|
617
|
+
Custom code is preserved using special comment markers in the generated files. Any code you add between these markers will be preserved when the files are regenerated.
|
|
618
|
+
|
|
619
|
+
### Configuration
|
|
620
|
+
|
|
621
|
+
Add the `customCode` configuration to your `openapi.sync.ts` file:
|
|
622
|
+
|
|
623
|
+
```typescript
|
|
624
|
+
import { IConfig } from "openapi-sync/types";
|
|
625
|
+
|
|
626
|
+
export default {
|
|
627
|
+
refetchInterval: 5000,
|
|
628
|
+
folder: "./src/api",
|
|
629
|
+
api: {
|
|
630
|
+
petstore: "https://petstore3.swagger.io/api/v3/openapi.json",
|
|
631
|
+
},
|
|
632
|
+
customCode: {
|
|
633
|
+
enabled: true, // Enable custom code preservation (default: true)
|
|
634
|
+
position: "bottom", // Position of custom code: "top", "bottom", or "both"
|
|
635
|
+
markerText: "CUSTOM CODE", // Custom marker text (default: "CUSTOM CODE")
|
|
636
|
+
includeInstructions: true, // Include helpful instructions (default: true)
|
|
637
|
+
},
|
|
638
|
+
} as IConfig;
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
### Configuration Options
|
|
642
|
+
|
|
643
|
+
| Option | Type | Default | Description |
|
|
644
|
+
| --------------------- | ----------------------------- | --------------- | ------------------------------------------ |
|
|
645
|
+
| `enabled` | `boolean` | `true` | Enable or disable custom code preservation |
|
|
646
|
+
| `position` | `"top" \| "bottom" \| "both"` | `"bottom"` | Where to place custom code markers |
|
|
647
|
+
| `markerText` | `string` | `"CUSTOM CODE"` | Custom text for markers |
|
|
648
|
+
| `includeInstructions` | `boolean` | `true` | Include helpful instructions in markers |
|
|
649
|
+
|
|
650
|
+
### Usage Example
|
|
651
|
+
|
|
652
|
+
After running OpenAPI Sync for the first time, your generated files will include custom code markers:
|
|
653
|
+
|
|
654
|
+
**endpoints.ts**
|
|
655
|
+
|
|
656
|
+
```typescript
|
|
657
|
+
// AUTO-GENERATED FILE - DO NOT EDIT OUTSIDE CUSTOM CODE MARKERS
|
|
658
|
+
export const getPet = (petId: string) => `/pet/${petId}`;
|
|
659
|
+
export const createPet = "/pet";
|
|
660
|
+
export const updatePet = (petId: string) => `/pet/${petId}`;
|
|
661
|
+
|
|
662
|
+
// ============================================================
|
|
663
|
+
// 🔒 CUSTOM CODE START
|
|
664
|
+
// Add your custom code above this line
|
|
665
|
+
// This section will be preserved during regeneration
|
|
666
|
+
// ============================================================
|
|
667
|
+
|
|
668
|
+
// ============================================================
|
|
669
|
+
// 🔒 CUSTOM CODE END
|
|
670
|
+
// ============================================================
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### Adding Custom Code
|
|
674
|
+
|
|
675
|
+
Simply add your custom code between the markers:
|
|
676
|
+
|
|
677
|
+
**endpoints.ts**
|
|
678
|
+
|
|
679
|
+
```typescript
|
|
680
|
+
export const getPet = (petId: string) => `/pet/${petId}`;
|
|
681
|
+
export const createPet = "/pet";
|
|
682
|
+
|
|
683
|
+
// ============================================================
|
|
684
|
+
// 🔒 CUSTOM CODE START
|
|
685
|
+
// ============================================================
|
|
686
|
+
|
|
687
|
+
// Custom endpoints for legacy API
|
|
688
|
+
export const legacyGetPet = (petId: string) => `/api/v1/pet/${petId}`;
|
|
689
|
+
export const customSearch = "/api/search";
|
|
690
|
+
|
|
691
|
+
// Custom utility function
|
|
692
|
+
export const buildPetUrl = (petId: string, includePhotos: boolean) => {
|
|
693
|
+
const base = getPet(petId);
|
|
694
|
+
return includePhotos ? `${base}?include=photos` : base;
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
// ============================================================
|
|
698
|
+
// 🔒 CUSTOM CODE END
|
|
699
|
+
// ============================================================
|
|
700
|
+
|
|
701
|
+
export const updatePet = (petId: string) => `/pet/${petId}`;
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### Custom Types
|
|
705
|
+
|
|
706
|
+
You can also add custom types in the `types.ts` and `shared.ts` files:
|
|
707
|
+
|
|
708
|
+
**types.ts**
|
|
709
|
+
|
|
710
|
+
```typescript
|
|
711
|
+
import * as Shared from "./shared";
|
|
712
|
+
|
|
713
|
+
export type IGetPetByIdResponse = Shared.IPet;
|
|
714
|
+
export type ICreatePetDTO = {
|
|
715
|
+
name: string;
|
|
716
|
+
status?: "available" | "pending" | "sold";
|
|
717
|
+
};
|
|
718
|
+
|
|
719
|
+
// ============================================================
|
|
720
|
+
// 🔒 CUSTOM CODE START
|
|
721
|
+
// ============================================================
|
|
722
|
+
|
|
723
|
+
// Custom type extending generated types
|
|
724
|
+
export interface IPetWithMetadata extends Shared.IPet {
|
|
725
|
+
fetchedAt: Date;
|
|
726
|
+
cached: boolean;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// Custom utility type
|
|
730
|
+
export type PartialPet = Partial<Shared.IPet>;
|
|
731
|
+
|
|
732
|
+
// Custom enum
|
|
733
|
+
export enum PetStatus {
|
|
734
|
+
Available = "available",
|
|
735
|
+
Pending = "pending",
|
|
736
|
+
Sold = "sold",
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// ============================================================
|
|
740
|
+
// 🔒 CUSTOM CODE END
|
|
741
|
+
// ============================================================
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
### Position Options
|
|
745
|
+
|
|
746
|
+
#### Bottom Position (Default)
|
|
747
|
+
|
|
748
|
+
Custom code markers appear at the bottom of the file:
|
|
749
|
+
|
|
750
|
+
```typescript
|
|
751
|
+
// Generated code...
|
|
752
|
+
export const endpoint1 = "/api/v1";
|
|
753
|
+
|
|
754
|
+
// 🔒 CUSTOM CODE START
|
|
755
|
+
// Your custom code here
|
|
756
|
+
// 🔒 CUSTOM CODE END
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
#### Top Position
|
|
760
|
+
|
|
761
|
+
Custom code markers appear at the top of the file:
|
|
762
|
+
|
|
763
|
+
```typescript
|
|
764
|
+
// 🔒 CUSTOM CODE START
|
|
765
|
+
// Your custom code here
|
|
766
|
+
// 🔒 CUSTOM CODE END
|
|
767
|
+
|
|
768
|
+
// Generated code...
|
|
769
|
+
export const endpoint1 = "/api/v1";
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
#### Both Positions
|
|
773
|
+
|
|
774
|
+
Custom code markers appear at both top and bottom:
|
|
775
|
+
|
|
776
|
+
```typescript
|
|
777
|
+
// 🔒 CUSTOM CODE START (TOP)
|
|
778
|
+
// Top custom code
|
|
779
|
+
// 🔒 CUSTOM CODE END
|
|
780
|
+
|
|
781
|
+
// Generated code...
|
|
782
|
+
|
|
783
|
+
// 🔒 CUSTOM CODE START (BOTTOM)
|
|
784
|
+
// Bottom custom code
|
|
785
|
+
// 🔒 CUSTOM CODE END
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
### Best Practices
|
|
789
|
+
|
|
790
|
+
1. **Don't Edit Outside Markers**: Only add code between the custom code markers. Code outside these markers will be overwritten.
|
|
791
|
+
|
|
792
|
+
2. **Use Descriptive Names**: Use clear, descriptive names for your custom code to avoid conflicts with generated code.
|
|
793
|
+
|
|
794
|
+
3. **Keep It Organized**: Group related custom code together and add comments explaining its purpose.
|
|
795
|
+
|
|
796
|
+
4. **Test After Regeneration**: After regenerating, verify your custom code is still present and working correctly.
|
|
797
|
+
|
|
798
|
+
5. **Version Control**: Commit your custom code changes separately from regeneration to track what's custom vs generated.
|
|
799
|
+
|
|
800
|
+
### Use Cases
|
|
801
|
+
|
|
802
|
+
#### Legacy API Support
|
|
803
|
+
|
|
804
|
+
```typescript
|
|
805
|
+
// 🔒 CUSTOM CODE START
|
|
806
|
+
// Support for legacy v1 API that's not in OpenAPI spec
|
|
807
|
+
export const legacyLogin = "/api/v1/auth/login";
|
|
808
|
+
export const legacyLogout = "/api/v1/auth/logout";
|
|
809
|
+
// 🔒 CUSTOM CODE END
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
#### Custom Utilities
|
|
813
|
+
|
|
814
|
+
```typescript
|
|
815
|
+
// 🔒 CUSTOM CODE START
|
|
816
|
+
// Utility functions for working with generated endpoints
|
|
817
|
+
export const isPublicEndpoint = (endpoint: string): boolean => {
|
|
818
|
+
return endpoint.startsWith("/public/");
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
export const requiresAuth = (endpoint: string): boolean => {
|
|
822
|
+
return !isPublicEndpoint(endpoint);
|
|
823
|
+
};
|
|
824
|
+
// 🔒 CUSTOM CODE END
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
#### Type Extensions
|
|
828
|
+
|
|
829
|
+
```typescript
|
|
830
|
+
// 🔒 CUSTOM CODE START
|
|
831
|
+
// Extended types with additional client-side fields
|
|
832
|
+
export interface IUserWithUI extends Shared.IUser {
|
|
833
|
+
isLoading?: boolean;
|
|
834
|
+
hasError?: boolean;
|
|
835
|
+
lastFetched?: Date;
|
|
836
|
+
}
|
|
837
|
+
// 🔒 CUSTOM CODE END
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
### Disabling Custom Code Preservation
|
|
841
|
+
|
|
842
|
+
If you want to disable custom code preservation (not recommended for most use cases):
|
|
843
|
+
|
|
844
|
+
```typescript
|
|
845
|
+
export default {
|
|
846
|
+
// ... other config
|
|
847
|
+
customCode: {
|
|
848
|
+
enabled: false, // Disables custom code preservation
|
|
849
|
+
},
|
|
850
|
+
} as IConfig;
|
|
851
|
+
```
|
|
852
|
+
|
|
853
|
+
⚠️ **Warning**: When disabled, all files will be completely overwritten on each regeneration.
|
|
854
|
+
|
|
609
855
|
## API Reference
|
|
610
856
|
|
|
611
857
|
### Exported Functions
|
|
@@ -1157,28 +1403,6 @@ The tool maintains state in `db.json` to track changes:
|
|
|
1157
1403
|
|
|
1158
1404
|
## Changelog
|
|
1159
1405
|
|
|
1160
|
-
### v2.1.11 (Latest)
|
|
1161
|
-
|
|
1162
|
-
- **NEW**: Folder splitting configuration for organized code generation
|
|
1163
|
-
- `folderSplit.byTags` - Create folders based on endpoint tags
|
|
1164
|
-
- `folderSplit.customFolder` - Custom function for folder structure logic
|
|
1165
|
-
- Enhanced folder organization with priority-based assignment
|
|
1166
|
-
- Improved code organization for large APIs
|
|
1167
|
-
|
|
1168
|
-
### v2.1.10
|
|
1169
|
-
|
|
1170
|
-
- OperationId-based naming for types and endpoints
|
|
1171
|
-
- `types.name.useOperationId` - Use OpenAPI operationId for type naming
|
|
1172
|
-
- `endpoints.name.useOperationId` - Use operationId for endpoint naming
|
|
1173
|
-
- Enhanced endpoint filtering capabilities
|
|
1174
|
-
- Improved tag-based filtering
|
|
1175
|
-
- Better regex pattern matching
|
|
1176
|
-
- More flexible include/exclude rules
|
|
1177
|
-
- Enhanced JSONStringify function with array serialization support
|
|
1178
|
-
- Improved endpoint tags support in generated documentation
|
|
1179
|
-
|
|
1180
|
-
### Previous Versions
|
|
1181
|
-
|
|
1182
1406
|
- v2.1.13: Fix dts type fixes and Clean up tsup build config and introduction of unit testing
|
|
1183
1407
|
- v2.1.12: Add automatic sync support for function-based config, improved handling of missing OpenAPI urls
|
|
1184
1408
|
- v2.1.11: Folder splitting configuration for organized code generation
|
package/dist/index.d.mts
CHANGED
|
@@ -84,6 +84,16 @@ type IConfigFolderSplit = {
|
|
|
84
84
|
responses?: IOpenApiResponseSpec;
|
|
85
85
|
}) => string | null;
|
|
86
86
|
};
|
|
87
|
+
type IConfigCustomCode = {
|
|
88
|
+
/** Enable custom code preservation (default: true) */
|
|
89
|
+
enabled?: boolean;
|
|
90
|
+
/** Position of custom code block in generated files (default: "bottom") */
|
|
91
|
+
position?: "top" | "bottom" | "both";
|
|
92
|
+
/** Custom marker text to use for identifying custom code sections (default: "CUSTOM CODE") */
|
|
93
|
+
markerText?: string;
|
|
94
|
+
/** Add helpful instructions in markers (default: true) */
|
|
95
|
+
includeInstructions?: boolean;
|
|
96
|
+
};
|
|
87
97
|
type IConfig = {
|
|
88
98
|
refetchInterval?: number;
|
|
89
99
|
folder?: string;
|
|
@@ -91,6 +101,8 @@ type IConfig = {
|
|
|
91
101
|
server?: number | string;
|
|
92
102
|
/** Configuration for splitting generated code into folders */
|
|
93
103
|
folderSplit?: IConfigFolderSplit;
|
|
104
|
+
/** Configuration for preserving custom code between regenerations */
|
|
105
|
+
customCode?: IConfigCustomCode;
|
|
94
106
|
/** Configuration for excluding endpoints from code generation */
|
|
95
107
|
types?: {
|
|
96
108
|
name?: {
|
|
@@ -161,6 +173,37 @@ declare const getEndpointDetails: (path: string, method: string) => {
|
|
|
161
173
|
declare const JSONStringify: (obj: Record<string, any>, indent?: number) => string;
|
|
162
174
|
declare const renderTypeRefMD: (typeRef: string, indent?: number) => string;
|
|
163
175
|
declare function getNestedValue<T>(obj: object, path: string): T | undefined;
|
|
176
|
+
interface ExtractedCustomCode {
|
|
177
|
+
beforeGenerated: string;
|
|
178
|
+
afterGenerated: string;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Extract custom code from existing file using comment markers
|
|
182
|
+
* @param fileContent - The content of the existing file
|
|
183
|
+
* @param markerText - The marker text to look for (default: "CUSTOM CODE")
|
|
184
|
+
* @returns Object containing custom code sections before and after generated code
|
|
185
|
+
*/
|
|
186
|
+
declare const extractCustomCode: (fileContent: string, markerText?: string) => ExtractedCustomCode;
|
|
187
|
+
/**
|
|
188
|
+
* Create an empty custom code marker section
|
|
189
|
+
* @param position - Position of the marker ("top" or "bottom")
|
|
190
|
+
* @param markerText - The marker text (default: "CUSTOM CODE")
|
|
191
|
+
* @param includeInstructions - Whether to include helpful instructions
|
|
192
|
+
* @returns The marker section as a string
|
|
193
|
+
*/
|
|
194
|
+
declare const createCustomCodeMarker: (position: "top" | "bottom", markerText?: string, includeInstructions?: boolean) => string;
|
|
195
|
+
/**
|
|
196
|
+
* Merge generated content with preserved custom code
|
|
197
|
+
* @param generatedContent - The newly generated content
|
|
198
|
+
* @param existingFileContent - The existing file content (null if file doesn't exist)
|
|
199
|
+
* @param config - Configuration options
|
|
200
|
+
* @returns The merged content with custom code preserved
|
|
201
|
+
*/
|
|
202
|
+
declare const mergeCustomCode: (generatedContent: string, existingFileContent: string | null, config?: {
|
|
203
|
+
position?: "top" | "bottom" | "both";
|
|
204
|
+
markerText?: string;
|
|
205
|
+
includeInstructions?: boolean;
|
|
206
|
+
}) => string;
|
|
164
207
|
|
|
165
208
|
declare const variableName: RegExp;
|
|
166
209
|
declare const variableNameChar: RegExp;
|
|
@@ -169,4 +212,4 @@ declare const Init: (options?: {
|
|
|
169
212
|
refetchInterval?: number;
|
|
170
213
|
}) => Promise<void>;
|
|
171
214
|
|
|
172
|
-
export { type IConfig, type IConfigDoc, type IConfigExclude, type IConfigFolderSplit, type IConfigInclude, type IConfigReplaceWord, type IOpenApSchemaSpec, type IOpenApiMediaTypeSpec, type IOpenApiParameterSpec, type IOpenApiRequestBodySpec, type IOpenApiResponseSpec, type IOpenApiSecuritySchemes, type IOpenApiSpec, Init, JSONStringify, capitalize, getEndpointDetails, getNestedValue, isJson, isYamlString, renderTypeRefMD, variableName, variableNameChar, yamlStringToJson };
|
|
215
|
+
export { type ExtractedCustomCode, type IConfig, type IConfigCustomCode, type IConfigDoc, type IConfigExclude, type IConfigFolderSplit, type IConfigInclude, type IConfigReplaceWord, type IOpenApSchemaSpec, type IOpenApiMediaTypeSpec, type IOpenApiParameterSpec, type IOpenApiRequestBodySpec, type IOpenApiResponseSpec, type IOpenApiSecuritySchemes, type IOpenApiSpec, Init, JSONStringify, capitalize, createCustomCodeMarker, extractCustomCode, getEndpointDetails, getNestedValue, isJson, isYamlString, mergeCustomCode, renderTypeRefMD, variableName, variableNameChar, yamlStringToJson };
|
package/dist/index.d.ts
CHANGED
|
@@ -84,6 +84,16 @@ type IConfigFolderSplit = {
|
|
|
84
84
|
responses?: IOpenApiResponseSpec;
|
|
85
85
|
}) => string | null;
|
|
86
86
|
};
|
|
87
|
+
type IConfigCustomCode = {
|
|
88
|
+
/** Enable custom code preservation (default: true) */
|
|
89
|
+
enabled?: boolean;
|
|
90
|
+
/** Position of custom code block in generated files (default: "bottom") */
|
|
91
|
+
position?: "top" | "bottom" | "both";
|
|
92
|
+
/** Custom marker text to use for identifying custom code sections (default: "CUSTOM CODE") */
|
|
93
|
+
markerText?: string;
|
|
94
|
+
/** Add helpful instructions in markers (default: true) */
|
|
95
|
+
includeInstructions?: boolean;
|
|
96
|
+
};
|
|
87
97
|
type IConfig = {
|
|
88
98
|
refetchInterval?: number;
|
|
89
99
|
folder?: string;
|
|
@@ -91,6 +101,8 @@ type IConfig = {
|
|
|
91
101
|
server?: number | string;
|
|
92
102
|
/** Configuration for splitting generated code into folders */
|
|
93
103
|
folderSplit?: IConfigFolderSplit;
|
|
104
|
+
/** Configuration for preserving custom code between regenerations */
|
|
105
|
+
customCode?: IConfigCustomCode;
|
|
94
106
|
/** Configuration for excluding endpoints from code generation */
|
|
95
107
|
types?: {
|
|
96
108
|
name?: {
|
|
@@ -161,6 +173,37 @@ declare const getEndpointDetails: (path: string, method: string) => {
|
|
|
161
173
|
declare const JSONStringify: (obj: Record<string, any>, indent?: number) => string;
|
|
162
174
|
declare const renderTypeRefMD: (typeRef: string, indent?: number) => string;
|
|
163
175
|
declare function getNestedValue<T>(obj: object, path: string): T | undefined;
|
|
176
|
+
interface ExtractedCustomCode {
|
|
177
|
+
beforeGenerated: string;
|
|
178
|
+
afterGenerated: string;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Extract custom code from existing file using comment markers
|
|
182
|
+
* @param fileContent - The content of the existing file
|
|
183
|
+
* @param markerText - The marker text to look for (default: "CUSTOM CODE")
|
|
184
|
+
* @returns Object containing custom code sections before and after generated code
|
|
185
|
+
*/
|
|
186
|
+
declare const extractCustomCode: (fileContent: string, markerText?: string) => ExtractedCustomCode;
|
|
187
|
+
/**
|
|
188
|
+
* Create an empty custom code marker section
|
|
189
|
+
* @param position - Position of the marker ("top" or "bottom")
|
|
190
|
+
* @param markerText - The marker text (default: "CUSTOM CODE")
|
|
191
|
+
* @param includeInstructions - Whether to include helpful instructions
|
|
192
|
+
* @returns The marker section as a string
|
|
193
|
+
*/
|
|
194
|
+
declare const createCustomCodeMarker: (position: "top" | "bottom", markerText?: string, includeInstructions?: boolean) => string;
|
|
195
|
+
/**
|
|
196
|
+
* Merge generated content with preserved custom code
|
|
197
|
+
* @param generatedContent - The newly generated content
|
|
198
|
+
* @param existingFileContent - The existing file content (null if file doesn't exist)
|
|
199
|
+
* @param config - Configuration options
|
|
200
|
+
* @returns The merged content with custom code preserved
|
|
201
|
+
*/
|
|
202
|
+
declare const mergeCustomCode: (generatedContent: string, existingFileContent: string | null, config?: {
|
|
203
|
+
position?: "top" | "bottom" | "both";
|
|
204
|
+
markerText?: string;
|
|
205
|
+
includeInstructions?: boolean;
|
|
206
|
+
}) => string;
|
|
164
207
|
|
|
165
208
|
declare const variableName: RegExp;
|
|
166
209
|
declare const variableNameChar: RegExp;
|
|
@@ -169,4 +212,4 @@ declare const Init: (options?: {
|
|
|
169
212
|
refetchInterval?: number;
|
|
170
213
|
}) => Promise<void>;
|
|
171
214
|
|
|
172
|
-
export { type IConfig, type IConfigDoc, type IConfigExclude, type IConfigFolderSplit, type IConfigInclude, type IConfigReplaceWord, type IOpenApSchemaSpec, type IOpenApiMediaTypeSpec, type IOpenApiParameterSpec, type IOpenApiRequestBodySpec, type IOpenApiResponseSpec, type IOpenApiSecuritySchemes, type IOpenApiSpec, Init, JSONStringify, capitalize, getEndpointDetails, getNestedValue, isJson, isYamlString, renderTypeRefMD, variableName, variableNameChar, yamlStringToJson };
|
|
215
|
+
export { type ExtractedCustomCode, type IConfig, type IConfigCustomCode, type IConfigDoc, type IConfigExclude, type IConfigFolderSplit, type IConfigInclude, type IConfigReplaceWord, type IOpenApSchemaSpec, type IOpenApiMediaTypeSpec, type IOpenApiParameterSpec, type IOpenApiRequestBodySpec, type IOpenApiResponseSpec, type IOpenApiSecuritySchemes, type IOpenApiSpec, Init, JSONStringify, capitalize, createCustomCodeMarker, extractCustomCode, getEndpointDetails, getNestedValue, isJson, isYamlString, mergeCustomCode, renderTypeRefMD, variableName, variableNameChar, yamlStringToJson };
|
package/dist/index.js
CHANGED
|
@@ -1,56 +1,65 @@
|
|
|
1
|
-
'use strict';var
|
|
2
|
-
`+" ".repeat(
|
|
3
|
-
`).filter(
|
|
4
|
-
${" ".repeat(
|
|
5
|
-
${" ".repeat(
|
|
1
|
+
'use strict';var L=require('fs'),B=require('path'),ee=require('js-yaml'),ut=require('lodash.isequal'),rt=require('lodash.get'),yt=require('axios'),ct=require('axios-retry'),ht=require('@apidevtools/swagger-parser'),curlGenerator=require('curl-generator');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var L__default=/*#__PURE__*/_interopDefault(L);var B__default=/*#__PURE__*/_interopDefault(B);var ee__namespace=/*#__PURE__*/_interopNamespace(ee);var ut__default=/*#__PURE__*/_interopDefault(ut);var rt__default=/*#__PURE__*/_interopDefault(rt);var yt__default=/*#__PURE__*/_interopDefault(yt);var ct__default=/*#__PURE__*/_interopDefault(ct);var ht__default=/*#__PURE__*/_interopDefault(ht);var X=(n=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(n,{get:(i,e)=>(typeof require!="undefined"?require:i)[e]}):n)(function(n){if(typeof require!="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var g=(n,i,e)=>new Promise((O,$)=>{var C=f=>{try{p(e.next(f));}catch(E){$(E);}},o=f=>{try{p(e.throw(f));}catch(E){$(E);}},p=f=>f.done?O(f.value):Promise.resolve(f.value).then(C,o);p((e=e.apply(n,i)).next());});var Ot=/^[A-Za-z_$][A-Za-z0-9_$]*$/,Ye=/[A-Za-z0-9_$]/;var Ze=n=>["object"].includes(typeof n)&&!(n instanceof Blob),pt=n=>{try{return ee__namespace.load(n),!0}catch(i){let e=i;if(e instanceof ee__namespace.YAMLException)return false;throw e}},De=n=>{if(pt(n)){let i=ee__namespace.load(n),e=JSON.stringify(i,null,2);return JSON.parse(e)}},W=n=>n.substring(0,1).toUpperCase()+n.substring(1),He=(n,i)=>{let e=n.split("/"),O=`${W(i)}`,$=[];return e.forEach(C=>{if(C[0]==="{"&&C[C.length-1]==="}"){let p=C.replace(/{/,"").replace(/}/,"");$.push(p),C=`$${p}`;}else if(C[0]==="<"&&C[C.length-1]===">"){let p=C.replace(/</,"").replace(/>/,"");$.push(p),C=`$${p}`;}else if(C[0]===":"){let p=C.replace(/:/,"");$.push(p),C=`$${p}`;}let o="";C.split("").forEach(p=>{let f=p;Ye.test(p)||(f="/"),o+=f;}),o.split("/").forEach(p=>{O+=W(p);});}),{name:O,variables:$,pathParts:e}},_=(n,i=1)=>{let e="{",O=Object.keys(n);for(let $=0;$<O.length;$++){let C=O[$],o=n[C];if(e+=`
|
|
2
|
+
`+" ".repeat(i)+C+": ",Array.isArray(o)){e+="[";for(let p=0;p<o.length;p++){let f=o[p];typeof f=="object"&&f!==null?e+=_(f,i+1):e+=typeof f=="string"?`"${f}"`:f,p<o.length-1&&(e+=", ");}e+="]";}else typeof o=="object"&&o!==null?e+=""+_(o,i+1):e+=o.split(`
|
|
3
|
+
`).filter(p=>p.trim()!=="").join(`
|
|
4
|
+
${" ".repeat(i)}`);$<O.length-1&&(e+=", ");}return e+=`
|
|
5
|
+
${" ".repeat(i-1)}}`,e},le=(n,i=1)=>`
|
|
6
6
|
\`\`\`typescript
|
|
7
|
-
${" ".repeat(
|
|
7
|
+
${" ".repeat(i)} ${n.split(`
|
|
8
8
|
`).filter(e=>e.trim()!=="").join(`
|
|
9
|
-
${" ".repeat(
|
|
10
|
-
\`\`\``;function
|
|
11
|
-
`).filter(
|
|
12
|
-
|
|
13
|
-
${
|
|
9
|
+
${" ".repeat(i)} `)}
|
|
10
|
+
\`\`\``;function xt(n,i){return i.split(".").reduce((O,$)=>O&&O[$]!==void 0?O[$]:void 0,n)}var dt=(n,i="CUSTOM CODE")=>{let e=`// \u{1F512} ${i} START`,O=`// \u{1F512} ${i} END`,$={beforeGenerated:"",afterGenerated:""},C=0,o=[];for(;C<n.length;){let p=n.indexOf(e,C);if(p===-1)break;let f=n.indexOf(O,p);if(f===-1)break;let E=f+O.length,k=p,ne=n.substring(Math.max(0,p-200),p).lastIndexOf("// ==========");ne!==-1&&(k=Math.max(0,p-200)+ne);let oe=n.substring(k,E);o.push({start:k,end:E,content:oe}),C=E;}return o.length>0&&(n.substring(0,o[0].start).split(`
|
|
11
|
+
`).filter(E=>{let k=E.trim();return k.length>0&&!k.startsWith("//")}).join("").length===0?($.beforeGenerated=o[0].content,o.length>1&&($.afterGenerated=o[1].content)):($.afterGenerated=o[0].content,o.length>1&&!$.beforeGenerated&&($.beforeGenerated=o[1].content))),$},Qe=(n,i="CUSTOM CODE",e=true)=>{let O=e?`// ${n==="top"?"Add your custom code below this line":"Add your custom code above this line"}
|
|
12
|
+
// This section will be preserved during regeneration
|
|
13
|
+
`:"";return `// ${"=".repeat(60)}
|
|
14
|
+
// \u{1F512} ${i} START
|
|
15
|
+
${O}// ${"=".repeat(60)}
|
|
16
|
+
|
|
17
|
+
// \u{1F512} ${i} END
|
|
18
|
+
// ${"=".repeat(60)}`},Xe=(n,i,e={})=>{let{position:O="bottom",markerText:$="CUSTOM CODE",includeInstructions:C=true}=e,o={beforeGenerated:"",afterGenerated:""};i&&(o=dt(i,$)),!o.beforeGenerated&&!o.afterGenerated&&((O==="top"||O==="both")&&(o.beforeGenerated=Qe("top",$,C)),(O==="bottom"||O==="both")&&(o.afterGenerated=Qe("bottom",$,C)));let p=[];return o.beforeGenerated&&(p.push(o.beforeGenerated),p.push("")),p.push(n),o.afterGenerated&&(p.push(""),p.push(o.afterGenerated)),p.join(`
|
|
19
|
+
`)};var pe=B__default.default.join(__dirname,"../","../db.json");L__default.default.existsSync(pe)||L__default.default.writeFileSync(pe,"{}");var ue={};try{ue=X(pe);}catch(n){ue={};}var te=ue||{},ge=n=>{L__default.default.writeFileSync(pe,JSON.stringify(n));},_e=(n,i)=>{te[n]=i,ge(te);},et=n=>te[n],tt=()=>{te={},ge(te);};var re=process.cwd(),ye={},st=yt__default.default.create({timeout:6e4});ct__default.default(st,{retries:20,retryCondition:n=>n.code==="ECONNABORTED"||n.message.includes("Network Error"),retryDelay:n=>n*1e3});var se=(n,i,e)=>g(null,null,function*(){var o,p,f,E;if(!(((o=e==null?void 0:e.customCode)==null?void 0:o.enabled)!==false)){yield L__default.default.promises.writeFile(n,i);return}let $=null;try{$=yield L__default.default.promises.readFile(n,"utf-8");}catch(k){}let C=Xe(i,$,{position:((p=e==null?void 0:e.customCode)==null?void 0:p.position)||"bottom",markerText:(f=e==null?void 0:e.customCode)==null?void 0:f.markerText,includeInstructions:(E=e==null?void 0:e.customCode)==null?void 0:E.includeInstructions});yield L__default.default.promises.writeFile(n,C);}),nt=(n,i,e,O)=>g(null,null,function*(){var fe,be,Oe,Ce,Ie,xe;let $=yield st.get(n),C=Ze($.data)?$.data:De($.data),o;try{o=yield ht__default.default.parse(C);}catch(s){let r=s instanceof Error?s.message:String(s);throw new Error(`Failed to parse OpenAPI spec for ${i}: ${r}`)}let p=B__default.default.join((e==null?void 0:e.folder)||"",i),f={},E=s=>{var r,x;if((r=e==null?void 0:e.folderSplit)!=null&&r.customFolder){let b=e.folderSplit.customFolder(s);if(console.log("customFolder",b),b)return b}return (x=e==null?void 0:e.folderSplit)!=null&&x.byTags&&s.tags&&s.tags.length>0?s.tags[0].toLowerCase().replace(/\s+/g,"-"):"default"},k=typeof(e==null?void 0:e.server)=="string"?e==null?void 0:e.server:((be=(fe=o==null?void 0:o.servers)==null?void 0:fe[(e==null?void 0:e.server)||0])==null?void 0:be.url)||"",M=typeof((Ce=(Oe=e==null?void 0:e.types)==null?void 0:Oe.name)==null?void 0:Ce.prefix)=="string"?e==null?void 0:e.types.name.prefix:"I",ne=typeof((xe=(Ie=e==null?void 0:e.endpoints)==null?void 0:Ie.name)==null?void 0:xe.prefix)=="string"?e==null?void 0:e.endpoints.name.prefix:"",oe=(s,r)=>{var b,a;let x=W(s);if((a=(b=e==null?void 0:e.types)==null?void 0:b.name)!=null&&a.format){let m=e==null?void 0:e.types.name.format("shared",{name:s},x);if(m)return `${M}${m}`}return `${M}${x}`},q=(s,r,x,b,a,m=0)=>{let I="",l="",d="";if(r){if(r.$ref)if(r.$ref[0]==="#"){let u=(r.$ref||"").split("/");u.shift(),[...u].pop();let w=rt__default.default(s,u,null);if(w){w!=null&&w.name&&(I=w.name),l=u[u.length-1];let N=oe(l);N.includes(".")&&(N=N.split(".").map((U,K)=>K===0?U:`["${U}"]`).join("")),d+=`${a!=null&&a.noSharedImport?"":"Shared."}${N}`;}}else d+="";else if(r.anyOf)d+=`(${r.anyOf.map(u=>q(s,u,"",b,a)).filter(u=>!!u).join("|")})`;else if(r.oneOf)d+=`(${r.oneOf.map(u=>q(s,u,"",b,a)).filter(u=>!!u).join("|")})`;else if(r.allOf)d+=`(${r.allOf.map(u=>q(s,u,"",b,a)).filter(u=>!!u).join("&")})`;else if(r.items)d+=`${q(s,r.items,"",false,a)}[]`;else if(r.properties){let u=Object.keys(r.properties),j=r.required||[],S="";u.forEach(w=>{var Z,U,K,Y,ae,D;let N="";!((U=(Z=e==null?void 0:e.types)==null?void 0:Z.doc)!=null&&U.disable)&&((Y=(K=r.properties)==null?void 0:K[w])!=null&&Y.description)&&(N=" * "+((ae=r.properties)==null?void 0:ae[w].description.split(`
|
|
20
|
+
`).filter(ie=>ie.trim()!=="").join(`
|
|
21
|
+
*${" ".repeat(1)}`))),S+=(N?`/**
|
|
22
|
+
${N}
|
|
14
23
|
*/
|
|
15
|
-
`:"")+`${
|
|
16
|
-
${" ".repeat(
|
|
17
|
-
`:""}`:""},z=(s,r)=>{let
|
|
18
|
-
`);
|
|
19
|
-
${
|
|
20
|
-
}`:
|
|
24
|
+
`:"")+`${q(s,(D=r.properties)==null?void 0:D[w],w,j.includes(w),a,m+1)}`;}),S.length>0?d+=`{
|
|
25
|
+
${" ".repeat(m)}${S}${" ".repeat(m)}}`:d+="{[k: string]: any}";}else if(r.enum&&r.enum.length>0)r.enum.length>1&&(d+="("),r.enum.map(u=>JSON.stringify(u)).filter(u=>!!u).forEach((u,j)=>{d+=`${j===0?"":"|"}${u}`;}),r.enum.length>1&&(d+=")");else if(r.type){let u=j=>{let S="";if(typeof j=="string")["string","integer","number","array","boolean","null"].includes(j)?["integer","number"].includes(j)?S+="number":j==="array"?S+="any[]":S+=j:j==="object"&&(r.additionalProperties?S+=`{[k: string]: ${q(s,r.additionalProperties,"",true,a)||"any"}}`:S+="{[k: string]: any}");else if(Array.isArray(j)){let w=j.map(N=>u(N));w.filter(N=>N!==""),w.length>1&&(S+="("+w.join("|")+")");}else S+="any";return S};d=u(r.type);}}else d="string";let c=I||x;a!=null&&a.useComponentName&&!c&&(c=l);let T=c?` "${c}"${b?"":"?"}: `:"",t=r!=null&&r.nullable?" | null":"";return d.length>0?`${T}${d}${t}${c?`;
|
|
26
|
+
`:""}`:""},z=(s,r)=>{let a="";if(r){if(r.$ref)if(r.$ref[0]==="#"){let m=(r.$ref||"").split("/");m.shift();let l=rt__default.default(s,m,null);l&&(l!=null&&l.name&&(l.name),m[m.length-1],a+=z(s,l));}else a+="";else if(r.anyOf)a+=z(s,r.anyOf[0]);else if(r.oneOf)a+=z(s,r.oneOf[0]);else if(r.allOf)a+=`{${r.allOf.map(m=>`...(${z(s,m)})`).join(",")}}`;else if(r.items)a+=`[${z(s,r.items)}]`;else if(r.properties){let l=Object.keys(r.properties).map(d=>{var c;return ` "${d}": ${z(s,(c=r.properties)==null?void 0:c[d])}`}).join(`,
|
|
27
|
+
`);l.length>0?a+=`{
|
|
28
|
+
${l}
|
|
29
|
+
}`:a+="{}";}else if(r.enum&&r.enum.length>0)r.enum.length>1&&(a+=r.enum[0]);else if(r.type)if(r.example)a+=JSON.stringify(r.example);else {let m=I=>{let l="";if(typeof I=="string")["string","integer","number","array","boolean","null"].includes(I)?["integer","number"].includes(I)?l+="123":I==="array"?l+="[]":I==="boolean"?l+="true":I==="null"?l+="null":l+=`"${I}"`:I==="object"&&(l+="{}");else if(Array.isArray(I)){let d=I.map(c=>m(c));d.filter(c=>c!==""),d.length>1&&(l+=d.join("|"));}else l+="any";return l};a=m(r.type);}}else a="string";return a};O&&!isNaN(O)&&O>0&&(process.env.NODE_ENV&&["production","prod","test","staging"].includes(process.env.NODE_ENV)||(ye[i]&&clearTimeout(ye[i]),ye[i]=setTimeout(()=>nt(n,i,e,O),O)));let at=et(i);if(ut__default.default(at,o))return;_e(i,o);let de="",Q="",V={};o.components&&Object.keys(o.components).forEach(s=>{if(["schemas","responses","parameters","examples","requestBodies","headers","links","callbacks"].includes(s)){let r=o.components[s],x={},b={};Object.keys(r).forEach(m=>{var d;let I=(d=r[m])!=null&&d.schema?r[m].schema:r[m],l=`${q(o,I,"",true,{noSharedImport:true,useComponentName:["parameters"].includes(s)})}`;if(l){let c=m.split("."),T=x,t=b;for(let u=0;u<c.length;u++){let j=c[u];u<c.length-1?(j in T||(T[j]={},t[j]={}),T=T[j],t=t[j]):(T[j]=l,t[j]=I);}}}),Object.keys(x).forEach(m=>{var c,T,t,u;let I=oe(m),l=x[m],d="";!((T=(c=e==null?void 0:e.types)==null?void 0:c.doc)!=null&&T.disable)&&m in r&&((t=r[m])!=null&&t.description)&&(d=" * "+r[m].description.split(`
|
|
21
30
|
`).filter(j=>j.trim()!=="").join(`
|
|
22
|
-
*${" ".repeat(1)}`)),
|
|
23
|
-
${
|
|
31
|
+
*${" ".repeat(1)}`)),V[m]=((u=V[m])!=null?u:"")+(d?`/**
|
|
32
|
+
${d}
|
|
24
33
|
*/
|
|
25
|
-
`:"")+"export type "+
|
|
26
|
-
`;});}});let $e=s=>{let r="";if(s.content){let
|
|
27
|
-
${
|
|
28
|
-
`;e!=null&&e.folderSplit?
|
|
29
|
-
`;e!=null&&e.folderSplit?
|
|
30
|
-
`;e!=null&&e.folderSplit?
|
|
31
|
-
- Scopes: [\`${
|
|
32
|
-
- ${
|
|
33
|
-
`),U=t!=null&&t.security?Z(t.security):"",K="";if(!((
|
|
34
|
-
--cert client-certificate.crt --key client-private-key.key --cacert ca-certificate.crt`:
|
|
34
|
+
`:"")+"export type "+I+" = "+(typeof l=="string"?l:_(l))+`;
|
|
35
|
+
`;});}});let $e=s=>{let r="";if(s.content){let x=Object.keys(s.content);x[0]&&s.content[x[0]].schema&&(r+=`${q(o,s.content[x[0]].schema,"")}`);}return r},it=s=>{var r,x,b,a,m;if((x=(r=e==null?void 0:e.endpoints)==null?void 0:r.value)!=null&&x.replaceWords&&Array.isArray(e==null?void 0:e.endpoints.value.replaceWords)){let I=s;return (m=(a=(b=e==null?void 0:e.endpoints)==null?void 0:b.value)==null?void 0:a.replaceWords)==null||m.forEach((l,d)=>{let c=new RegExp(l.replace,"g");I=I.replace(c,l.with||"");}),I}else return s},lt=(s,r,x=[])=>{var m,I;let b=(m=e==null?void 0:e.endpoints)==null?void 0:m.exclude,a=(I=e==null?void 0:e.endpoints)==null?void 0:I.include;if(a){let l=a.tags&&a.tags.length>0?x.some(c=>a.tags.includes(c)):true,d=a.endpoints&&a.endpoints.length>0?a.endpoints.some(c=>{let T=!c.method||c.method.toLowerCase()===r.toLowerCase();return c.path?s===c.path&&T:c.regex?new RegExp(c.regex).test(s)&&T:false}):true;if(!l||!d)return true}return !!(b&&(b.tags&&b.tags.length>0&&x.some(d=>b.tags.includes(d))||b.endpoints&&b.endpoints.length>0&&b.endpoints.some(d=>{let c=!d.method||d.method.toLowerCase()===r.toLowerCase();return d.path?s===d.path&&c:d.regex?new RegExp(d.regex).test(s)&&c:false})))};if(Object.keys(o.paths||{}).forEach(s=>{let r=o.paths[s];Object.keys(r).forEach(b=>{var ie,je,Ee,Ae,Te,Se,we,Ne,ve,Re,ke,Be,Me,Fe,Ge,Pe,qe,Ue,Je,Le,ze,Ke,We,Ve;let a=b,m=He(s,a),I=((ie=r[a])==null?void 0:ie.tags)||[];if(lt(s,a,I))return;let l=r[a],d=E({method:a,path:s,summary:l==null?void 0:l.summary,operationId:l==null?void 0:l.operationId,tags:I,parameters:l==null?void 0:l.parameters,requestBody:l==null?void 0:l.requestBody,responses:l==null?void 0:l.responses});f[d]||(f[d]={endpoints:"",types:""});let c=((Ee=(je=e==null?void 0:e.endpoints)==null?void 0:je.value)!=null&&Ee.includeServer?k:"")+m.pathParts.map(h=>(h[0]==="{"&&h[h.length-1]==="}"?h=`\${${h.replace(/{/,"").replace(/}/,"")}}`:h[0]==="<"&&h[h.length-1]===">"?h=`\${${h.replace(/</,"").replace(/>/,"")}}`:h[0]===":"&&(h=`\${${h.replace(/:/,"")}}`),h)).join("/"),T=`"${c}"`;m.variables.length>0&&(T=`(${m.variables.map(y=>`${y}:string`).join(",")})=> \`${c}\``),T=it(T);let t=r[a],u="";if(t!=null&&t.parameters&&((t==null?void 0:t.parameters).forEach((y,v)=>{(y.$ref||y.in==="query"&&y.name)&&(u+=`${q(o,y.$ref?y:y.schema,y.name||"",y.required)}`);}),u)){u=`{
|
|
36
|
+
${u}}`;let y=`${m.name}Query`;if((Te=(Ae=e==null?void 0:e.types)==null?void 0:Ae.name)!=null&&Te.useOperationId&&(t!=null&&t.operationId)&&(y=`${t.operationId}Query`),y=W(`${M}${y}`),(we=(Se=e==null?void 0:e.types)==null?void 0:Se.name)!=null&&we.format){let G=e==null?void 0:e.types.name.format("endpoint",{code:"",type:"query",method:a,path:s,summary:t==null?void 0:t.summary,operationId:t==null?void 0:t.operationId},y);G&&(y=`${M}${G}`);}let v=`export type ${y} = ${u};
|
|
37
|
+
`;e!=null&&e.folderSplit?f[d].types+=v:Q+=v;}let j=t==null?void 0:t.requestBody,S="";if(j&&(S=$e(j),S)){let h=`${m.name}DTO`;if((ve=(Ne=e==null?void 0:e.types)==null?void 0:Ne.name)!=null&&ve.useOperationId&&(t!=null&&t.operationId)&&(h=`${t.operationId}DTO`),h=W(`${M}${h}`),(ke=(Re=e==null?void 0:e.types)==null?void 0:Re.name)!=null&&ke.format){let v=e==null?void 0:e.types.name.format("endpoint",{code:"",type:"dto",method:a,path:s,summary:t==null?void 0:t.summary,operationId:t==null?void 0:t.operationId},h);v&&(h=`${M}${v}`);}let y=`export type ${h} = ${S};
|
|
38
|
+
`;e!=null&&e.folderSplit?f[d].types+=y:Q+=y;}let w={},N="";if(t!=null&&t.responses){let h=t==null?void 0:t.responses;Object.keys(h).forEach(v=>{var G,P,R,F;if(N=$e(h[v]),w[v]=N,N){let A=`${m.name}${v}Response`;if((P=(G=e==null?void 0:e.types)==null?void 0:G.name)!=null&&P.useOperationId&&(t!=null&&t.operationId)&&(A=`${t.operationId}${v}Response`),A=W(`${M}${A}`),(F=(R=e==null?void 0:e.types)==null?void 0:R.name)!=null&&F.format){let H=e==null?void 0:e.types.name.format("endpoint",{code:v,type:"response",method:a,path:s,summary:t==null?void 0:t.summary,operationId:t==null?void 0:t.operationId},A);H&&(A=`${M}${H}`);}let J=`export type ${A} = ${N};
|
|
39
|
+
`;e!=null&&e.folderSplit?f[d].types+=J:Q+=J;}});}let Z=h=>!h||!h.length?"":h.map(y=>Object.entries(y).map(([G,P])=>{let R=G,F="";return Array.isArray(P)&&P.length&&(F=`
|
|
40
|
+
- Scopes: [\`${P.join("`, `")}\`]`,R=`**${R}**`),`
|
|
41
|
+
- ${R}${F}`}).join("")).join(`
|
|
42
|
+
`),U=t!=null&&t.security?Z(t.security):"",K="";if(!((Me=(Be=e==null?void 0:e.endpoints)==null?void 0:Be.doc)!=null&&Me.disable)){let h="";if((Ge=(Fe=e==null?void 0:e.endpoints)==null?void 0:Fe.doc)!=null&&Ge.showCurl){let y={},v="",G="";(Pe=t.requestBody)!=null&&Pe.content&&Object.keys(t.requestBody.content).forEach(F=>{let A=t.requestBody.content[F].schema;if(A){Array.isArray(y["Content-type"])?y["Content-type"].push(F):y["Content-type"]=[F];let J=z(o,A);J&&(v=J);}}),t!=null&&t.security&&t.security.forEach(R=>{Object.keys(R).forEach(F=>{var J,H;let A=(H=(J=o.components)==null?void 0:J.securitySchemes)==null?void 0:H[F];A&&(A.type==="mutualTLS"?G+=`
|
|
43
|
+
--cert client-certificate.crt --key client-private-key.key --cacert ca-certificate.crt`:A.type==="apiKey"?y[(A==null?void 0:A.name)||"X-API-KEY"]="{API_KEY_VALUE}":y.Authorization=`${(A==null?void 0:A.scheme)==="basic"?"Basic":"Bearer"} {${(A==null?void 0:A.scheme)==="basic"?"VALUE":"TOKEN"}}`);});});let P={};Object.keys(y).forEach(R=>{Array.isArray(y[R])?P[R]=y[R].join("; "):P[R]=y[R];}),h=`
|
|
35
44
|
\`\`\`bash
|
|
36
|
-
${curlGenerator.CurlGenerator({url:
|
|
45
|
+
${curlGenerator.CurlGenerator({url:k+s,method:a.toUpperCase(),headers:P,body:v})}${G}
|
|
37
46
|
\`\`\``;}K=`/**${t!=null&&t.description?`
|
|
38
47
|
* ${t==null?void 0:t.description} `:""}
|
|
39
|
-
* **Method**: \`${
|
|
48
|
+
* **Method**: \`${a.toUpperCase()}\`
|
|
40
49
|
* **Summary**: ${(t==null?void 0:t.summary)||""}
|
|
41
|
-
* **Tags**: [${((
|
|
42
|
-
* **OperationId**: ${(t==null?void 0:t.operationId)||""} ${
|
|
43
|
-
* **Query**: ${
|
|
44
|
-
* **DTO**: ${
|
|
45
|
-
* **Response**: ${Object.entries(w).map(([
|
|
46
|
-
- **${
|
|
50
|
+
* **Tags**: [${((qe=t==null?void 0:t.tags)==null?void 0:qe.join(", "))||""}]
|
|
51
|
+
* **OperationId**: ${(t==null?void 0:t.operationId)||""} ${u?`
|
|
52
|
+
* **Query**: ${le(u)} `:""}${S?`
|
|
53
|
+
* **DTO**: ${le(S)} `:""}${N?`
|
|
54
|
+
* **Response**: ${Object.entries(w).map(([y,v])=>`
|
|
55
|
+
- **${y}**: ${le(v,2)} `).join("")}`:""}${U?`
|
|
47
56
|
* **Security**: ${U}
|
|
48
|
-
`:""}${
|
|
57
|
+
`:""}${h}
|
|
49
58
|
*/
|
|
50
|
-
`;}let Y=(Je=(
|
|
51
|
-
`;e!=null&&e.folderSplit?
|
|
59
|
+
`;}let Y=(Je=(Ue=e==null?void 0:e.endpoints)==null?void 0:Ue.name)!=null&&Je.useOperationId&&((Le=t==null?void 0:t.operationId)==null?void 0:Le.length)>0?t.operationId:`${m.name}`;if((Ke=(ze=e==null?void 0:e.endpoints)==null?void 0:ze.name)!=null&&Ke.format){let h=e==null?void 0:e.endpoints.name.format({method:a,path:s,summary:t==null?void 0:t.summary,operationId:t==null?void 0:t.operationId},Y);h&&(Y=h);}let ae={method:`"${a}"`,operationId:`"${t==null?void 0:t.operationId}"`,url:T,tags:(t==null?void 0:t.tags)||[]},D=`${K}export const ${ne}${Y} = ${((Ve=(We=e==null?void 0:e.endpoints)==null?void 0:We.value)==null?void 0:Ve.type)==="object"?_(ae):T};
|
|
60
|
+
`;e!=null&&e.folderSplit?f[d].endpoints+=D:de+=D;});}),e!=null&&e.folderSplit){for(let[s,r]of Object.entries(f))if(r.endpoints||r.types){let x=B__default.default.join(p,s);if(r.endpoints){let b=B__default.default.join(re,x,"endpoints.ts");yield L__default.default.promises.mkdir(B__default.default.dirname(b),{recursive:true}),yield se(b,r.endpoints,e);}if(r.types){let b=B__default.default.join(re,x,"types.ts");yield L__default.default.promises.mkdir(B__default.default.dirname(b),{recursive:true});let a=Object.values(V).length>0?`import * as Shared from "../shared";
|
|
52
61
|
|
|
53
|
-
${r.types}`:r.types;yield
|
|
54
|
-
`));}if(Q.length>0){let s=
|
|
62
|
+
${r.types}`:r.types;yield se(b,a,e);}}}if(de.length>0){let s=B__default.default.join(re,p,"endpoints.ts");yield L__default.default.promises.mkdir(B__default.default.dirname(s),{recursive:true}),yield se(s,de,e);}if(Object.values(V).length>0){let s=B__default.default.join(re,p,e!=null&&e.folderSplit?"":"types","shared.ts");yield L__default.default.promises.mkdir(B__default.default.dirname(s),{recursive:true}),yield se(s,Object.values(V).join(`
|
|
63
|
+
`),e);}if(Q.length>0){let s=B__default.default.join(re,p,"types","index.ts");yield L__default.default.promises.mkdir(B__default.default.dirname(s),{recursive:true}),yield se(s,`${Object.values(V).length>0?`import * as Shared from "./shared";
|
|
55
64
|
|
|
56
|
-
`:""}${Q}
|
|
65
|
+
`:""}${Q}`,e);}}),ot=nt;var he=process.cwd(),Vt=n=>g(null,null,function*(){let i;try{X("esbuild-register");}catch(E){throw E}let e=B__default.default.join(he,"openapi.sync.js"),O=B__default.default.join(he,"openapi.sync.ts"),$=B__default.default.join(he,"openapi.sync.json"),C=[e,O,$];try{for(let E of C)L__default.default.existsSync(E)&&(i=X(E),Object.keys(i).length===1&&i.default&&(i=i.default));}catch(E){console.log(E);}typeof i=="function"&&(i=i());let o=i;if(!o)throw new Error("No config found");let p=Object.keys(o.api),f=n&&"refetchInterval"in n&&!isNaN(n==null?void 0:n.refetchInterval)?n.refetchInterval:o.refetchInterval;tt();for(let E=0;E<p.length;E+=1){let k=p[E],M=o.api[k];ot(M,k,o,f);}});exports.Init=Vt;exports.JSONStringify=_;exports.capitalize=W;exports.createCustomCodeMarker=Qe;exports.extractCustomCode=dt;exports.getEndpointDetails=He;exports.getNestedValue=xt;exports.isJson=Ze;exports.isYamlString=pt;exports.mergeCustomCode=Xe;exports.renderTypeRefMD=le;exports.variableName=Ot;exports.variableNameChar=Ye;exports.yamlStringToJson=De;
|
package/dist/index.mjs
CHANGED
|
@@ -1,56 +1,65 @@
|
|
|
1
|
-
import
|
|
2
|
-
`+" ".repeat(
|
|
3
|
-
`).filter(
|
|
4
|
-
${" ".repeat(
|
|
5
|
-
${" ".repeat(
|
|
1
|
+
import L from'fs';import B from'path';import*as ee from'js-yaml';import ut from'lodash.isequal';import rt from'lodash.get';import yt from'axios';import ct from'axios-retry';import ht from'@apidevtools/swagger-parser';import {CurlGenerator}from'curl-generator';var X=(n=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(n,{get:(i,e)=>(typeof require!="undefined"?require:i)[e]}):n)(function(n){if(typeof require!="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var g=(n,i,e)=>new Promise((O,$)=>{var C=f=>{try{p(e.next(f));}catch(E){$(E);}},o=f=>{try{p(e.throw(f));}catch(E){$(E);}},p=f=>f.done?O(f.value):Promise.resolve(f.value).then(C,o);p((e=e.apply(n,i)).next());});var Ot=/^[A-Za-z_$][A-Za-z0-9_$]*$/,Ye=/[A-Za-z0-9_$]/;var Ze=n=>["object"].includes(typeof n)&&!(n instanceof Blob),pt=n=>{try{return ee.load(n),!0}catch(i){let e=i;if(e instanceof ee.YAMLException)return false;throw e}},De=n=>{if(pt(n)){let i=ee.load(n),e=JSON.stringify(i,null,2);return JSON.parse(e)}},W=n=>n.substring(0,1).toUpperCase()+n.substring(1),He=(n,i)=>{let e=n.split("/"),O=`${W(i)}`,$=[];return e.forEach(C=>{if(C[0]==="{"&&C[C.length-1]==="}"){let p=C.replace(/{/,"").replace(/}/,"");$.push(p),C=`$${p}`;}else if(C[0]==="<"&&C[C.length-1]===">"){let p=C.replace(/</,"").replace(/>/,"");$.push(p),C=`$${p}`;}else if(C[0]===":"){let p=C.replace(/:/,"");$.push(p),C=`$${p}`;}let o="";C.split("").forEach(p=>{let f=p;Ye.test(p)||(f="/"),o+=f;}),o.split("/").forEach(p=>{O+=W(p);});}),{name:O,variables:$,pathParts:e}},_=(n,i=1)=>{let e="{",O=Object.keys(n);for(let $=0;$<O.length;$++){let C=O[$],o=n[C];if(e+=`
|
|
2
|
+
`+" ".repeat(i)+C+": ",Array.isArray(o)){e+="[";for(let p=0;p<o.length;p++){let f=o[p];typeof f=="object"&&f!==null?e+=_(f,i+1):e+=typeof f=="string"?`"${f}"`:f,p<o.length-1&&(e+=", ");}e+="]";}else typeof o=="object"&&o!==null?e+=""+_(o,i+1):e+=o.split(`
|
|
3
|
+
`).filter(p=>p.trim()!=="").join(`
|
|
4
|
+
${" ".repeat(i)}`);$<O.length-1&&(e+=", ");}return e+=`
|
|
5
|
+
${" ".repeat(i-1)}}`,e},le=(n,i=1)=>`
|
|
6
6
|
\`\`\`typescript
|
|
7
|
-
${" ".repeat(
|
|
7
|
+
${" ".repeat(i)} ${n.split(`
|
|
8
8
|
`).filter(e=>e.trim()!=="").join(`
|
|
9
|
-
${" ".repeat(
|
|
10
|
-
\`\`\``;function
|
|
11
|
-
`).filter(
|
|
12
|
-
|
|
13
|
-
${
|
|
9
|
+
${" ".repeat(i)} `)}
|
|
10
|
+
\`\`\``;function xt(n,i){return i.split(".").reduce((O,$)=>O&&O[$]!==void 0?O[$]:void 0,n)}var dt=(n,i="CUSTOM CODE")=>{let e=`// \u{1F512} ${i} START`,O=`// \u{1F512} ${i} END`,$={beforeGenerated:"",afterGenerated:""},C=0,o=[];for(;C<n.length;){let p=n.indexOf(e,C);if(p===-1)break;let f=n.indexOf(O,p);if(f===-1)break;let E=f+O.length,k=p,ne=n.substring(Math.max(0,p-200),p).lastIndexOf("// ==========");ne!==-1&&(k=Math.max(0,p-200)+ne);let oe=n.substring(k,E);o.push({start:k,end:E,content:oe}),C=E;}return o.length>0&&(n.substring(0,o[0].start).split(`
|
|
11
|
+
`).filter(E=>{let k=E.trim();return k.length>0&&!k.startsWith("//")}).join("").length===0?($.beforeGenerated=o[0].content,o.length>1&&($.afterGenerated=o[1].content)):($.afterGenerated=o[0].content,o.length>1&&!$.beforeGenerated&&($.beforeGenerated=o[1].content))),$},Qe=(n,i="CUSTOM CODE",e=true)=>{let O=e?`// ${n==="top"?"Add your custom code below this line":"Add your custom code above this line"}
|
|
12
|
+
// This section will be preserved during regeneration
|
|
13
|
+
`:"";return `// ${"=".repeat(60)}
|
|
14
|
+
// \u{1F512} ${i} START
|
|
15
|
+
${O}// ${"=".repeat(60)}
|
|
16
|
+
|
|
17
|
+
// \u{1F512} ${i} END
|
|
18
|
+
// ${"=".repeat(60)}`},Xe=(n,i,e={})=>{let{position:O="bottom",markerText:$="CUSTOM CODE",includeInstructions:C=true}=e,o={beforeGenerated:"",afterGenerated:""};i&&(o=dt(i,$)),!o.beforeGenerated&&!o.afterGenerated&&((O==="top"||O==="both")&&(o.beforeGenerated=Qe("top",$,C)),(O==="bottom"||O==="both")&&(o.afterGenerated=Qe("bottom",$,C)));let p=[];return o.beforeGenerated&&(p.push(o.beforeGenerated),p.push("")),p.push(n),o.afterGenerated&&(p.push(""),p.push(o.afterGenerated)),p.join(`
|
|
19
|
+
`)};var pe=B.join(__dirname,"../","../db.json");L.existsSync(pe)||L.writeFileSync(pe,"{}");var ue={};try{ue=X(pe);}catch(n){ue={};}var te=ue||{},ge=n=>{L.writeFileSync(pe,JSON.stringify(n));},_e=(n,i)=>{te[n]=i,ge(te);},et=n=>te[n],tt=()=>{te={},ge(te);};var re=process.cwd(),ye={},st=yt.create({timeout:6e4});ct(st,{retries:20,retryCondition:n=>n.code==="ECONNABORTED"||n.message.includes("Network Error"),retryDelay:n=>n*1e3});var se=(n,i,e)=>g(null,null,function*(){var o,p,f,E;if(!(((o=e==null?void 0:e.customCode)==null?void 0:o.enabled)!==false)){yield L.promises.writeFile(n,i);return}let $=null;try{$=yield L.promises.readFile(n,"utf-8");}catch(k){}let C=Xe(i,$,{position:((p=e==null?void 0:e.customCode)==null?void 0:p.position)||"bottom",markerText:(f=e==null?void 0:e.customCode)==null?void 0:f.markerText,includeInstructions:(E=e==null?void 0:e.customCode)==null?void 0:E.includeInstructions});yield L.promises.writeFile(n,C);}),nt=(n,i,e,O)=>g(null,null,function*(){var fe,be,Oe,Ce,Ie,xe;let $=yield st.get(n),C=Ze($.data)?$.data:De($.data),o;try{o=yield ht.parse(C);}catch(s){let r=s instanceof Error?s.message:String(s);throw new Error(`Failed to parse OpenAPI spec for ${i}: ${r}`)}let p=B.join((e==null?void 0:e.folder)||"",i),f={},E=s=>{var r,x;if((r=e==null?void 0:e.folderSplit)!=null&&r.customFolder){let b=e.folderSplit.customFolder(s);if(console.log("customFolder",b),b)return b}return (x=e==null?void 0:e.folderSplit)!=null&&x.byTags&&s.tags&&s.tags.length>0?s.tags[0].toLowerCase().replace(/\s+/g,"-"):"default"},k=typeof(e==null?void 0:e.server)=="string"?e==null?void 0:e.server:((be=(fe=o==null?void 0:o.servers)==null?void 0:fe[(e==null?void 0:e.server)||0])==null?void 0:be.url)||"",M=typeof((Ce=(Oe=e==null?void 0:e.types)==null?void 0:Oe.name)==null?void 0:Ce.prefix)=="string"?e==null?void 0:e.types.name.prefix:"I",ne=typeof((xe=(Ie=e==null?void 0:e.endpoints)==null?void 0:Ie.name)==null?void 0:xe.prefix)=="string"?e==null?void 0:e.endpoints.name.prefix:"",oe=(s,r)=>{var b,a;let x=W(s);if((a=(b=e==null?void 0:e.types)==null?void 0:b.name)!=null&&a.format){let m=e==null?void 0:e.types.name.format("shared",{name:s},x);if(m)return `${M}${m}`}return `${M}${x}`},q=(s,r,x,b,a,m=0)=>{let I="",l="",d="";if(r){if(r.$ref)if(r.$ref[0]==="#"){let u=(r.$ref||"").split("/");u.shift(),[...u].pop();let w=rt(s,u,null);if(w){w!=null&&w.name&&(I=w.name),l=u[u.length-1];let N=oe(l);N.includes(".")&&(N=N.split(".").map((U,K)=>K===0?U:`["${U}"]`).join("")),d+=`${a!=null&&a.noSharedImport?"":"Shared."}${N}`;}}else d+="";else if(r.anyOf)d+=`(${r.anyOf.map(u=>q(s,u,"",b,a)).filter(u=>!!u).join("|")})`;else if(r.oneOf)d+=`(${r.oneOf.map(u=>q(s,u,"",b,a)).filter(u=>!!u).join("|")})`;else if(r.allOf)d+=`(${r.allOf.map(u=>q(s,u,"",b,a)).filter(u=>!!u).join("&")})`;else if(r.items)d+=`${q(s,r.items,"",false,a)}[]`;else if(r.properties){let u=Object.keys(r.properties),j=r.required||[],S="";u.forEach(w=>{var Z,U,K,Y,ae,D;let N="";!((U=(Z=e==null?void 0:e.types)==null?void 0:Z.doc)!=null&&U.disable)&&((Y=(K=r.properties)==null?void 0:K[w])!=null&&Y.description)&&(N=" * "+((ae=r.properties)==null?void 0:ae[w].description.split(`
|
|
20
|
+
`).filter(ie=>ie.trim()!=="").join(`
|
|
21
|
+
*${" ".repeat(1)}`))),S+=(N?`/**
|
|
22
|
+
${N}
|
|
14
23
|
*/
|
|
15
|
-
`:"")+`${
|
|
16
|
-
${" ".repeat(
|
|
17
|
-
`:""}`:""},z=(s,r)=>{let
|
|
18
|
-
`);
|
|
19
|
-
${
|
|
20
|
-
}`:
|
|
24
|
+
`:"")+`${q(s,(D=r.properties)==null?void 0:D[w],w,j.includes(w),a,m+1)}`;}),S.length>0?d+=`{
|
|
25
|
+
${" ".repeat(m)}${S}${" ".repeat(m)}}`:d+="{[k: string]: any}";}else if(r.enum&&r.enum.length>0)r.enum.length>1&&(d+="("),r.enum.map(u=>JSON.stringify(u)).filter(u=>!!u).forEach((u,j)=>{d+=`${j===0?"":"|"}${u}`;}),r.enum.length>1&&(d+=")");else if(r.type){let u=j=>{let S="";if(typeof j=="string")["string","integer","number","array","boolean","null"].includes(j)?["integer","number"].includes(j)?S+="number":j==="array"?S+="any[]":S+=j:j==="object"&&(r.additionalProperties?S+=`{[k: string]: ${q(s,r.additionalProperties,"",true,a)||"any"}}`:S+="{[k: string]: any}");else if(Array.isArray(j)){let w=j.map(N=>u(N));w.filter(N=>N!==""),w.length>1&&(S+="("+w.join("|")+")");}else S+="any";return S};d=u(r.type);}}else d="string";let c=I||x;a!=null&&a.useComponentName&&!c&&(c=l);let T=c?` "${c}"${b?"":"?"}: `:"",t=r!=null&&r.nullable?" | null":"";return d.length>0?`${T}${d}${t}${c?`;
|
|
26
|
+
`:""}`:""},z=(s,r)=>{let a="";if(r){if(r.$ref)if(r.$ref[0]==="#"){let m=(r.$ref||"").split("/");m.shift();let l=rt(s,m,null);l&&(l!=null&&l.name&&(l.name),m[m.length-1],a+=z(s,l));}else a+="";else if(r.anyOf)a+=z(s,r.anyOf[0]);else if(r.oneOf)a+=z(s,r.oneOf[0]);else if(r.allOf)a+=`{${r.allOf.map(m=>`...(${z(s,m)})`).join(",")}}`;else if(r.items)a+=`[${z(s,r.items)}]`;else if(r.properties){let l=Object.keys(r.properties).map(d=>{var c;return ` "${d}": ${z(s,(c=r.properties)==null?void 0:c[d])}`}).join(`,
|
|
27
|
+
`);l.length>0?a+=`{
|
|
28
|
+
${l}
|
|
29
|
+
}`:a+="{}";}else if(r.enum&&r.enum.length>0)r.enum.length>1&&(a+=r.enum[0]);else if(r.type)if(r.example)a+=JSON.stringify(r.example);else {let m=I=>{let l="";if(typeof I=="string")["string","integer","number","array","boolean","null"].includes(I)?["integer","number"].includes(I)?l+="123":I==="array"?l+="[]":I==="boolean"?l+="true":I==="null"?l+="null":l+=`"${I}"`:I==="object"&&(l+="{}");else if(Array.isArray(I)){let d=I.map(c=>m(c));d.filter(c=>c!==""),d.length>1&&(l+=d.join("|"));}else l+="any";return l};a=m(r.type);}}else a="string";return a};O&&!isNaN(O)&&O>0&&(process.env.NODE_ENV&&["production","prod","test","staging"].includes(process.env.NODE_ENV)||(ye[i]&&clearTimeout(ye[i]),ye[i]=setTimeout(()=>nt(n,i,e,O),O)));let at=et(i);if(ut(at,o))return;_e(i,o);let de="",Q="",V={};o.components&&Object.keys(o.components).forEach(s=>{if(["schemas","responses","parameters","examples","requestBodies","headers","links","callbacks"].includes(s)){let r=o.components[s],x={},b={};Object.keys(r).forEach(m=>{var d;let I=(d=r[m])!=null&&d.schema?r[m].schema:r[m],l=`${q(o,I,"",true,{noSharedImport:true,useComponentName:["parameters"].includes(s)})}`;if(l){let c=m.split("."),T=x,t=b;for(let u=0;u<c.length;u++){let j=c[u];u<c.length-1?(j in T||(T[j]={},t[j]={}),T=T[j],t=t[j]):(T[j]=l,t[j]=I);}}}),Object.keys(x).forEach(m=>{var c,T,t,u;let I=oe(m),l=x[m],d="";!((T=(c=e==null?void 0:e.types)==null?void 0:c.doc)!=null&&T.disable)&&m in r&&((t=r[m])!=null&&t.description)&&(d=" * "+r[m].description.split(`
|
|
21
30
|
`).filter(j=>j.trim()!=="").join(`
|
|
22
|
-
*${" ".repeat(1)}`)),
|
|
23
|
-
${
|
|
31
|
+
*${" ".repeat(1)}`)),V[m]=((u=V[m])!=null?u:"")+(d?`/**
|
|
32
|
+
${d}
|
|
24
33
|
*/
|
|
25
|
-
`:"")+"export type "+
|
|
26
|
-
`;});}});let $e=s=>{let r="";if(s.content){let
|
|
27
|
-
${
|
|
28
|
-
`;e!=null&&e.folderSplit?
|
|
29
|
-
`;e!=null&&e.folderSplit?
|
|
30
|
-
`;e!=null&&e.folderSplit?
|
|
31
|
-
- Scopes: [\`${
|
|
32
|
-
- ${
|
|
33
|
-
`),U=t!=null&&t.security?Z(t.security):"",K="";if(!((
|
|
34
|
-
--cert client-certificate.crt --key client-private-key.key --cacert ca-certificate.crt`:
|
|
34
|
+
`:"")+"export type "+I+" = "+(typeof l=="string"?l:_(l))+`;
|
|
35
|
+
`;});}});let $e=s=>{let r="";if(s.content){let x=Object.keys(s.content);x[0]&&s.content[x[0]].schema&&(r+=`${q(o,s.content[x[0]].schema,"")}`);}return r},it=s=>{var r,x,b,a,m;if((x=(r=e==null?void 0:e.endpoints)==null?void 0:r.value)!=null&&x.replaceWords&&Array.isArray(e==null?void 0:e.endpoints.value.replaceWords)){let I=s;return (m=(a=(b=e==null?void 0:e.endpoints)==null?void 0:b.value)==null?void 0:a.replaceWords)==null||m.forEach((l,d)=>{let c=new RegExp(l.replace,"g");I=I.replace(c,l.with||"");}),I}else return s},lt=(s,r,x=[])=>{var m,I;let b=(m=e==null?void 0:e.endpoints)==null?void 0:m.exclude,a=(I=e==null?void 0:e.endpoints)==null?void 0:I.include;if(a){let l=a.tags&&a.tags.length>0?x.some(c=>a.tags.includes(c)):true,d=a.endpoints&&a.endpoints.length>0?a.endpoints.some(c=>{let T=!c.method||c.method.toLowerCase()===r.toLowerCase();return c.path?s===c.path&&T:c.regex?new RegExp(c.regex).test(s)&&T:false}):true;if(!l||!d)return true}return !!(b&&(b.tags&&b.tags.length>0&&x.some(d=>b.tags.includes(d))||b.endpoints&&b.endpoints.length>0&&b.endpoints.some(d=>{let c=!d.method||d.method.toLowerCase()===r.toLowerCase();return d.path?s===d.path&&c:d.regex?new RegExp(d.regex).test(s)&&c:false})))};if(Object.keys(o.paths||{}).forEach(s=>{let r=o.paths[s];Object.keys(r).forEach(b=>{var ie,je,Ee,Ae,Te,Se,we,Ne,ve,Re,ke,Be,Me,Fe,Ge,Pe,qe,Ue,Je,Le,ze,Ke,We,Ve;let a=b,m=He(s,a),I=((ie=r[a])==null?void 0:ie.tags)||[];if(lt(s,a,I))return;let l=r[a],d=E({method:a,path:s,summary:l==null?void 0:l.summary,operationId:l==null?void 0:l.operationId,tags:I,parameters:l==null?void 0:l.parameters,requestBody:l==null?void 0:l.requestBody,responses:l==null?void 0:l.responses});f[d]||(f[d]={endpoints:"",types:""});let c=((Ee=(je=e==null?void 0:e.endpoints)==null?void 0:je.value)!=null&&Ee.includeServer?k:"")+m.pathParts.map(h=>(h[0]==="{"&&h[h.length-1]==="}"?h=`\${${h.replace(/{/,"").replace(/}/,"")}}`:h[0]==="<"&&h[h.length-1]===">"?h=`\${${h.replace(/</,"").replace(/>/,"")}}`:h[0]===":"&&(h=`\${${h.replace(/:/,"")}}`),h)).join("/"),T=`"${c}"`;m.variables.length>0&&(T=`(${m.variables.map(y=>`${y}:string`).join(",")})=> \`${c}\``),T=it(T);let t=r[a],u="";if(t!=null&&t.parameters&&((t==null?void 0:t.parameters).forEach((y,v)=>{(y.$ref||y.in==="query"&&y.name)&&(u+=`${q(o,y.$ref?y:y.schema,y.name||"",y.required)}`);}),u)){u=`{
|
|
36
|
+
${u}}`;let y=`${m.name}Query`;if((Te=(Ae=e==null?void 0:e.types)==null?void 0:Ae.name)!=null&&Te.useOperationId&&(t!=null&&t.operationId)&&(y=`${t.operationId}Query`),y=W(`${M}${y}`),(we=(Se=e==null?void 0:e.types)==null?void 0:Se.name)!=null&&we.format){let G=e==null?void 0:e.types.name.format("endpoint",{code:"",type:"query",method:a,path:s,summary:t==null?void 0:t.summary,operationId:t==null?void 0:t.operationId},y);G&&(y=`${M}${G}`);}let v=`export type ${y} = ${u};
|
|
37
|
+
`;e!=null&&e.folderSplit?f[d].types+=v:Q+=v;}let j=t==null?void 0:t.requestBody,S="";if(j&&(S=$e(j),S)){let h=`${m.name}DTO`;if((ve=(Ne=e==null?void 0:e.types)==null?void 0:Ne.name)!=null&&ve.useOperationId&&(t!=null&&t.operationId)&&(h=`${t.operationId}DTO`),h=W(`${M}${h}`),(ke=(Re=e==null?void 0:e.types)==null?void 0:Re.name)!=null&&ke.format){let v=e==null?void 0:e.types.name.format("endpoint",{code:"",type:"dto",method:a,path:s,summary:t==null?void 0:t.summary,operationId:t==null?void 0:t.operationId},h);v&&(h=`${M}${v}`);}let y=`export type ${h} = ${S};
|
|
38
|
+
`;e!=null&&e.folderSplit?f[d].types+=y:Q+=y;}let w={},N="";if(t!=null&&t.responses){let h=t==null?void 0:t.responses;Object.keys(h).forEach(v=>{var G,P,R,F;if(N=$e(h[v]),w[v]=N,N){let A=`${m.name}${v}Response`;if((P=(G=e==null?void 0:e.types)==null?void 0:G.name)!=null&&P.useOperationId&&(t!=null&&t.operationId)&&(A=`${t.operationId}${v}Response`),A=W(`${M}${A}`),(F=(R=e==null?void 0:e.types)==null?void 0:R.name)!=null&&F.format){let H=e==null?void 0:e.types.name.format("endpoint",{code:v,type:"response",method:a,path:s,summary:t==null?void 0:t.summary,operationId:t==null?void 0:t.operationId},A);H&&(A=`${M}${H}`);}let J=`export type ${A} = ${N};
|
|
39
|
+
`;e!=null&&e.folderSplit?f[d].types+=J:Q+=J;}});}let Z=h=>!h||!h.length?"":h.map(y=>Object.entries(y).map(([G,P])=>{let R=G,F="";return Array.isArray(P)&&P.length&&(F=`
|
|
40
|
+
- Scopes: [\`${P.join("`, `")}\`]`,R=`**${R}**`),`
|
|
41
|
+
- ${R}${F}`}).join("")).join(`
|
|
42
|
+
`),U=t!=null&&t.security?Z(t.security):"",K="";if(!((Me=(Be=e==null?void 0:e.endpoints)==null?void 0:Be.doc)!=null&&Me.disable)){let h="";if((Ge=(Fe=e==null?void 0:e.endpoints)==null?void 0:Fe.doc)!=null&&Ge.showCurl){let y={},v="",G="";(Pe=t.requestBody)!=null&&Pe.content&&Object.keys(t.requestBody.content).forEach(F=>{let A=t.requestBody.content[F].schema;if(A){Array.isArray(y["Content-type"])?y["Content-type"].push(F):y["Content-type"]=[F];let J=z(o,A);J&&(v=J);}}),t!=null&&t.security&&t.security.forEach(R=>{Object.keys(R).forEach(F=>{var J,H;let A=(H=(J=o.components)==null?void 0:J.securitySchemes)==null?void 0:H[F];A&&(A.type==="mutualTLS"?G+=`
|
|
43
|
+
--cert client-certificate.crt --key client-private-key.key --cacert ca-certificate.crt`:A.type==="apiKey"?y[(A==null?void 0:A.name)||"X-API-KEY"]="{API_KEY_VALUE}":y.Authorization=`${(A==null?void 0:A.scheme)==="basic"?"Basic":"Bearer"} {${(A==null?void 0:A.scheme)==="basic"?"VALUE":"TOKEN"}}`);});});let P={};Object.keys(y).forEach(R=>{Array.isArray(y[R])?P[R]=y[R].join("; "):P[R]=y[R];}),h=`
|
|
35
44
|
\`\`\`bash
|
|
36
|
-
${CurlGenerator({url:
|
|
45
|
+
${CurlGenerator({url:k+s,method:a.toUpperCase(),headers:P,body:v})}${G}
|
|
37
46
|
\`\`\``;}K=`/**${t!=null&&t.description?`
|
|
38
47
|
* ${t==null?void 0:t.description} `:""}
|
|
39
|
-
* **Method**: \`${
|
|
48
|
+
* **Method**: \`${a.toUpperCase()}\`
|
|
40
49
|
* **Summary**: ${(t==null?void 0:t.summary)||""}
|
|
41
|
-
* **Tags**: [${((
|
|
42
|
-
* **OperationId**: ${(t==null?void 0:t.operationId)||""} ${
|
|
43
|
-
* **Query**: ${
|
|
44
|
-
* **DTO**: ${
|
|
45
|
-
* **Response**: ${Object.entries(w).map(([
|
|
46
|
-
- **${
|
|
50
|
+
* **Tags**: [${((qe=t==null?void 0:t.tags)==null?void 0:qe.join(", "))||""}]
|
|
51
|
+
* **OperationId**: ${(t==null?void 0:t.operationId)||""} ${u?`
|
|
52
|
+
* **Query**: ${le(u)} `:""}${S?`
|
|
53
|
+
* **DTO**: ${le(S)} `:""}${N?`
|
|
54
|
+
* **Response**: ${Object.entries(w).map(([y,v])=>`
|
|
55
|
+
- **${y}**: ${le(v,2)} `).join("")}`:""}${U?`
|
|
47
56
|
* **Security**: ${U}
|
|
48
|
-
`:""}${
|
|
57
|
+
`:""}${h}
|
|
49
58
|
*/
|
|
50
|
-
`;}let Y=(Je=(
|
|
51
|
-
`;e!=null&&e.folderSplit?
|
|
59
|
+
`;}let Y=(Je=(Ue=e==null?void 0:e.endpoints)==null?void 0:Ue.name)!=null&&Je.useOperationId&&((Le=t==null?void 0:t.operationId)==null?void 0:Le.length)>0?t.operationId:`${m.name}`;if((Ke=(ze=e==null?void 0:e.endpoints)==null?void 0:ze.name)!=null&&Ke.format){let h=e==null?void 0:e.endpoints.name.format({method:a,path:s,summary:t==null?void 0:t.summary,operationId:t==null?void 0:t.operationId},Y);h&&(Y=h);}let ae={method:`"${a}"`,operationId:`"${t==null?void 0:t.operationId}"`,url:T,tags:(t==null?void 0:t.tags)||[]},D=`${K}export const ${ne}${Y} = ${((Ve=(We=e==null?void 0:e.endpoints)==null?void 0:We.value)==null?void 0:Ve.type)==="object"?_(ae):T};
|
|
60
|
+
`;e!=null&&e.folderSplit?f[d].endpoints+=D:de+=D;});}),e!=null&&e.folderSplit){for(let[s,r]of Object.entries(f))if(r.endpoints||r.types){let x=B.join(p,s);if(r.endpoints){let b=B.join(re,x,"endpoints.ts");yield L.promises.mkdir(B.dirname(b),{recursive:true}),yield se(b,r.endpoints,e);}if(r.types){let b=B.join(re,x,"types.ts");yield L.promises.mkdir(B.dirname(b),{recursive:true});let a=Object.values(V).length>0?`import * as Shared from "../shared";
|
|
52
61
|
|
|
53
|
-
${r.types}`:r.types;yield
|
|
54
|
-
`));}if(Q.length>0){let s=
|
|
62
|
+
${r.types}`:r.types;yield se(b,a,e);}}}if(de.length>0){let s=B.join(re,p,"endpoints.ts");yield L.promises.mkdir(B.dirname(s),{recursive:true}),yield se(s,de,e);}if(Object.values(V).length>0){let s=B.join(re,p,e!=null&&e.folderSplit?"":"types","shared.ts");yield L.promises.mkdir(B.dirname(s),{recursive:true}),yield se(s,Object.values(V).join(`
|
|
63
|
+
`),e);}if(Q.length>0){let s=B.join(re,p,"types","index.ts");yield L.promises.mkdir(B.dirname(s),{recursive:true}),yield se(s,`${Object.values(V).length>0?`import * as Shared from "./shared";
|
|
55
64
|
|
|
56
|
-
`:""}${Q}
|
|
65
|
+
`:""}${Q}`,e);}}),ot=nt;var he=process.cwd(),Vt=n=>g(null,null,function*(){let i;try{X("esbuild-register");}catch(E){throw E}let e=B.join(he,"openapi.sync.js"),O=B.join(he,"openapi.sync.ts"),$=B.join(he,"openapi.sync.json"),C=[e,O,$];try{for(let E of C)L.existsSync(E)&&(i=X(E),Object.keys(i).length===1&&i.default&&(i=i.default));}catch(E){console.log(E);}typeof i=="function"&&(i=i());let o=i;if(!o)throw new Error("No config found");let p=Object.keys(o.api),f=n&&"refetchInterval"in n&&!isNaN(n==null?void 0:n.refetchInterval)?n.refetchInterval:o.refetchInterval;tt();for(let E=0;E<p.length;E+=1){let k=p[E],M=o.api[k];ot(M,k,o,f);}});export{Vt as Init,_ as JSONStringify,W as capitalize,Qe as createCustomCodeMarker,dt as extractCustomCode,He as getEndpointDetails,xt as getNestedValue,Ze as isJson,pt as isYamlString,Xe as mergeCustomCode,le as renderTypeRefMD,Ot as variableName,Ye as variableNameChar,De as yamlStringToJson};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-sync",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "A developer-friendly tool designed to keep your API up-to-date by leveraging OpenAPI schemas. It automates the generation of endpoint URIs and type definitions, including shared types, directly from your OpenAPI specification.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"jest": "^30.2.0",
|
|
67
67
|
"source-map-explorer": "^2.5.3",
|
|
68
68
|
"ts-jest": "^29.4.4",
|
|
69
|
+
"tsup": "^8.5.0",
|
|
69
70
|
"typescript": "^5.5.4"
|
|
70
71
|
},
|
|
71
72
|
"dependencies": {
|
|
@@ -77,7 +78,6 @@
|
|
|
77
78
|
"js-yaml": "^4.1.0",
|
|
78
79
|
"lodash.get": "^4.4.2",
|
|
79
80
|
"lodash.isequal": "^4.5.0",
|
|
80
|
-
"tsup": "^8.5.0",
|
|
81
81
|
"yargs": "^17.7.2"
|
|
82
82
|
}
|
|
83
83
|
}
|