ng-openapi 0.0.3 → 0.0.4
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 +52 -32
- package/cli.cjs +216 -12
- package/index.js +212 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Angular OpenAPI client generator
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/ng-openapi)
|
|
4
|
+
## 💪 Made with ❤️ by Angular Devs for Angular Devs
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## Quick Start Guide
|
|
3
8
|
## Installation
|
|
4
9
|
|
|
5
10
|
```bash
|
|
@@ -84,13 +89,13 @@ ng-openapi -i ./swagger.json -o ./src/api --date-type string
|
|
|
84
89
|
|
|
85
90
|
### Optional Fields
|
|
86
91
|
|
|
87
|
-
- `
|
|
88
|
-
- `
|
|
89
|
-
- `
|
|
90
|
-
- `
|
|
91
|
-
- `
|
|
92
|
-
- `
|
|
93
|
-
- `
|
|
92
|
+
- `dateType` - How to handle date types: `'string'` or `'Date'` (default: `'Date'`)
|
|
93
|
+
- `enumStyle` - Enum generation style: `'enum'` or `'union'` (default: `'enum'`)
|
|
94
|
+
- `generateEnumBasedOnDescription` - Parse enum values from description field (default: `true`)
|
|
95
|
+
- `generateServices` - Generate Angular services (default: `true`)
|
|
96
|
+
- `customHeaders` - Headers to add to all HTTP requests
|
|
97
|
+
- `responseTypeMapping` - Map content types to Angular HttpClient response types
|
|
98
|
+
- `customizeMethodName` - Function to customize generated method names
|
|
94
99
|
- `compilerOptions` - TypeScript compiler options for code generation
|
|
95
100
|
|
|
96
101
|
## Generated Files Structure
|
|
@@ -104,44 +109,60 @@ output/
|
|
|
104
109
|
│ └── *.service.ts # Angular services
|
|
105
110
|
├── tokens/
|
|
106
111
|
│ └── index.ts # Injection tokens
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
├── utils/
|
|
113
|
+
│ ├── date-transformer.ts # Date transformation interceptor
|
|
114
|
+
│ └── file-download.ts # File download helpers
|
|
115
|
+
├── providers.ts # Provider functions for easy setup
|
|
116
|
+
└── index.ts # Main exports
|
|
110
117
|
```
|
|
111
118
|
|
|
112
119
|
## Angular Integration
|
|
113
120
|
|
|
114
|
-
###
|
|
121
|
+
### 🚀 Easy Setup (Recommended)
|
|
122
|
+
|
|
123
|
+
The simplest way to integrate ng-openapi is using the provider function:
|
|
115
124
|
|
|
116
125
|
```typescript
|
|
117
|
-
|
|
126
|
+
// In your app.config.ts
|
|
127
|
+
import { ApplicationConfig } from '@angular/core';
|
|
128
|
+
import { provideNgOpenapi } from './api/providers';
|
|
118
129
|
|
|
119
|
-
// In your app.config.ts or module
|
|
120
130
|
export const appConfig: ApplicationConfig = {
|
|
121
131
|
providers: [
|
|
122
|
-
|
|
132
|
+
// One-line setup with automatic interceptor configuration
|
|
133
|
+
provideNgOpenapi({
|
|
134
|
+
basePath: 'https://api.example.com'
|
|
135
|
+
}),
|
|
123
136
|
// other providers...
|
|
124
137
|
]
|
|
125
138
|
};
|
|
126
139
|
```
|
|
127
140
|
|
|
128
|
-
|
|
141
|
+
That's it! This automatically configures:
|
|
142
|
+
- ✅ BASE_PATH token
|
|
143
|
+
- ✅ Date transformation interceptor (if using Date type)
|
|
129
144
|
|
|
130
|
-
```typescript
|
|
131
|
-
import { DateInterceptor } from './api/utils/date-transformer';
|
|
132
|
-
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
133
145
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
146
|
+
### Advanced Provider Options
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// Disable date transformation
|
|
150
|
+
provideNgOpenapi({
|
|
151
|
+
basePath: 'https://api.example.com',
|
|
152
|
+
enableDateTransform: false
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Async configuration
|
|
156
|
+
provideNgOpenapiAsync({
|
|
157
|
+
basePath: () => import('./config').then(c => c.apiConfig.baseUrl)
|
|
158
|
+
});
|
|
140
159
|
```
|
|
141
160
|
|
|
142
|
-
|
|
161
|
+
## Using Generated Services
|
|
143
162
|
|
|
144
163
|
```typescript
|
|
164
|
+
import { Component, inject } from '@angular/core';
|
|
165
|
+
import { toSignal } from '@angular/core/rxjs-interop';
|
|
145
166
|
import { UserService } from './api/services';
|
|
146
167
|
import { User } from './api/models';
|
|
147
168
|
|
|
@@ -150,19 +171,19 @@ import { User } from './api/models';
|
|
|
150
171
|
template: `...`
|
|
151
172
|
})
|
|
152
173
|
export class UsersComponent {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
constructor(private userService: UserService) {}
|
|
174
|
+
private readonly userService = inject(UserService);
|
|
175
|
+
readonly users = toSignal(this.userService.getUsers());
|
|
156
176
|
}
|
|
157
177
|
```
|
|
158
178
|
|
|
159
179
|
## File Download Example
|
|
160
180
|
|
|
161
181
|
```typescript
|
|
182
|
+
import { Component, inject } from '@angular/core';
|
|
162
183
|
import { downloadFileOperator } from './api/utils/file-download';
|
|
163
184
|
|
|
164
185
|
export class ReportComponent {
|
|
165
|
-
|
|
186
|
+
private readonly reportService = inject(ReportService);
|
|
166
187
|
|
|
167
188
|
downloadReport() {
|
|
168
189
|
this.reportService.getReport('pdf', { reportId: 123 })
|
|
@@ -181,8 +202,7 @@ Add these scripts to your `package.json`:
|
|
|
181
202
|
```json
|
|
182
203
|
{
|
|
183
204
|
"scripts": {
|
|
184
|
-
"generate:api": "ng-openapi -c openapi.config.ts"
|
|
185
|
-
"generate:api:watch": "nodemon --watch swagger.json --exec npm run generate:api"
|
|
205
|
+
"generate:api": "ng-openapi -c openapi.config.ts"
|
|
186
206
|
}
|
|
187
207
|
}
|
|
188
208
|
```
|
package/cli.cjs
CHANGED
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
|
|
27
27
|
// src/lib/cli.ts
|
|
28
28
|
var import_commander = require("commander");
|
|
29
|
-
var
|
|
29
|
+
var path8 = __toESM(require("path"));
|
|
30
30
|
var fs4 = __toESM(require("fs"));
|
|
31
31
|
|
|
32
32
|
// src/lib/core/swagger-parser.ts
|
|
@@ -89,6 +89,10 @@ var MAIN_INDEX_GENERATOR_HEADER_COMMENT = defaultHeaderComment + `* Entrypoint f
|
|
|
89
89
|
* Do not edit this file manually
|
|
90
90
|
*/
|
|
91
91
|
`;
|
|
92
|
+
var PROVIDER_GENERATOR_HEADER_COMMENT = defaultHeaderComment + `* Generated provider functions for easy setup
|
|
93
|
+
* Do not edit this file manually
|
|
94
|
+
*/
|
|
95
|
+
`;
|
|
92
96
|
|
|
93
97
|
// src/lib/generators/type/type.generator.ts
|
|
94
98
|
var TypeGenerator = class {
|
|
@@ -731,11 +735,16 @@ var MainIndexGenerator = class {
|
|
|
731
735
|
moduleSpecifier: "./models"
|
|
732
736
|
});
|
|
733
737
|
sourceFile.addExportDeclaration({
|
|
734
|
-
moduleSpecifier: "./
|
|
738
|
+
moduleSpecifier: "./tokens"
|
|
735
739
|
});
|
|
736
740
|
sourceFile.addExportDeclaration({
|
|
737
|
-
moduleSpecifier: "./
|
|
741
|
+
moduleSpecifier: "./providers"
|
|
738
742
|
});
|
|
743
|
+
if (this.config.options.generateServices !== false) {
|
|
744
|
+
sourceFile.addExportDeclaration({
|
|
745
|
+
moduleSpecifier: "./services"
|
|
746
|
+
});
|
|
747
|
+
}
|
|
739
748
|
if (this.config.options.dateType === "Date") {
|
|
740
749
|
sourceFile.addExportDeclaration({
|
|
741
750
|
moduleSpecifier: "./utils/date-transformer"
|
|
@@ -1487,7 +1496,7 @@ var ServiceGenerator = class {
|
|
|
1487
1496
|
extractPaths() {
|
|
1488
1497
|
const paths = [];
|
|
1489
1498
|
const swaggerPaths = this.spec.paths || {};
|
|
1490
|
-
Object.entries(swaggerPaths).forEach(([
|
|
1499
|
+
Object.entries(swaggerPaths).forEach(([path9, pathItem]) => {
|
|
1491
1500
|
const methods = [
|
|
1492
1501
|
"get",
|
|
1493
1502
|
"post",
|
|
@@ -1501,7 +1510,7 @@ var ServiceGenerator = class {
|
|
|
1501
1510
|
if (pathItem[method]) {
|
|
1502
1511
|
const operation = pathItem[method];
|
|
1503
1512
|
paths.push({
|
|
1504
|
-
path:
|
|
1513
|
+
path: path9,
|
|
1505
1514
|
method: method.toUpperCase(),
|
|
1506
1515
|
operationId: operation.operationId,
|
|
1507
1516
|
summary: operation.summary,
|
|
@@ -1533,12 +1542,12 @@ var ServiceGenerator = class {
|
|
|
1533
1542
|
}
|
|
1534
1543
|
groupPathsByController(paths) {
|
|
1535
1544
|
const groups = {};
|
|
1536
|
-
paths.forEach((
|
|
1545
|
+
paths.forEach((path9) => {
|
|
1537
1546
|
let controllerName = "Default";
|
|
1538
|
-
if (
|
|
1539
|
-
controllerName =
|
|
1547
|
+
if (path9.tags && path9.tags.length > 0) {
|
|
1548
|
+
controllerName = path9.tags[0];
|
|
1540
1549
|
} else {
|
|
1541
|
-
const pathParts =
|
|
1550
|
+
const pathParts = path9.path.split("/").filter((p) => p && !p.startsWith("{"));
|
|
1542
1551
|
if (pathParts.length > 1) {
|
|
1543
1552
|
controllerName = pascalCase(pathParts[1]);
|
|
1544
1553
|
}
|
|
@@ -1547,7 +1556,7 @@ var ServiceGenerator = class {
|
|
|
1547
1556
|
if (!groups[controllerName]) {
|
|
1548
1557
|
groups[controllerName] = [];
|
|
1549
1558
|
}
|
|
1550
|
-
groups[controllerName].push(
|
|
1559
|
+
groups[controllerName].push(path9);
|
|
1551
1560
|
});
|
|
1552
1561
|
return groups;
|
|
1553
1562
|
}
|
|
@@ -1740,6 +1749,198 @@ var ServiceIndexGenerator = class {
|
|
|
1740
1749
|
}
|
|
1741
1750
|
};
|
|
1742
1751
|
|
|
1752
|
+
// src/lib/generators/utility/provider.generator.ts
|
|
1753
|
+
var path7 = __toESM(require("path"));
|
|
1754
|
+
var ProviderGenerator = class {
|
|
1755
|
+
static {
|
|
1756
|
+
__name(this, "ProviderGenerator");
|
|
1757
|
+
}
|
|
1758
|
+
project;
|
|
1759
|
+
config;
|
|
1760
|
+
constructor(project, config) {
|
|
1761
|
+
this.project = project;
|
|
1762
|
+
this.config = config;
|
|
1763
|
+
}
|
|
1764
|
+
generate(outputDir) {
|
|
1765
|
+
const filePath = path7.join(outputDir, "providers.ts");
|
|
1766
|
+
const sourceFile = this.project.createSourceFile(filePath, "", {
|
|
1767
|
+
overwrite: true
|
|
1768
|
+
});
|
|
1769
|
+
sourceFile.insertText(0, PROVIDER_GENERATOR_HEADER_COMMENT);
|
|
1770
|
+
sourceFile.addImportDeclarations([
|
|
1771
|
+
{
|
|
1772
|
+
namedImports: [
|
|
1773
|
+
"EnvironmentProviders",
|
|
1774
|
+
"Provider",
|
|
1775
|
+
"makeEnvironmentProviders"
|
|
1776
|
+
],
|
|
1777
|
+
moduleSpecifier: "@angular/core"
|
|
1778
|
+
},
|
|
1779
|
+
{
|
|
1780
|
+
namedImports: [
|
|
1781
|
+
"HTTP_INTERCEPTORS"
|
|
1782
|
+
],
|
|
1783
|
+
moduleSpecifier: "@angular/common/http"
|
|
1784
|
+
},
|
|
1785
|
+
{
|
|
1786
|
+
namedImports: [
|
|
1787
|
+
"BASE_PATH"
|
|
1788
|
+
],
|
|
1789
|
+
moduleSpecifier: "./tokens"
|
|
1790
|
+
}
|
|
1791
|
+
]);
|
|
1792
|
+
if (this.config.options.dateType === "Date") {
|
|
1793
|
+
sourceFile.addImportDeclaration({
|
|
1794
|
+
namedImports: [
|
|
1795
|
+
"DateInterceptor"
|
|
1796
|
+
],
|
|
1797
|
+
moduleSpecifier: "./utils/date-transformer"
|
|
1798
|
+
});
|
|
1799
|
+
}
|
|
1800
|
+
sourceFile.addInterface({
|
|
1801
|
+
name: "NgOpenapiConfig",
|
|
1802
|
+
isExported: true,
|
|
1803
|
+
docs: [
|
|
1804
|
+
"Configuration options for ng-openapi providers"
|
|
1805
|
+
],
|
|
1806
|
+
properties: [
|
|
1807
|
+
{
|
|
1808
|
+
name: "basePath",
|
|
1809
|
+
type: "string",
|
|
1810
|
+
docs: [
|
|
1811
|
+
"Base API URL"
|
|
1812
|
+
]
|
|
1813
|
+
},
|
|
1814
|
+
{
|
|
1815
|
+
name: "enableDateTransform",
|
|
1816
|
+
type: "boolean",
|
|
1817
|
+
hasQuestionToken: true,
|
|
1818
|
+
docs: [
|
|
1819
|
+
"Enable automatic date transformation (default: true)"
|
|
1820
|
+
]
|
|
1821
|
+
}
|
|
1822
|
+
]
|
|
1823
|
+
});
|
|
1824
|
+
this.addMainProviderFunction(sourceFile);
|
|
1825
|
+
this.addAsyncProviderFunction(sourceFile);
|
|
1826
|
+
sourceFile.saveSync();
|
|
1827
|
+
}
|
|
1828
|
+
addMainProviderFunction(sourceFile) {
|
|
1829
|
+
const hasDateInterceptor = this.config.options.dateType === "Date";
|
|
1830
|
+
const functionBody = `
|
|
1831
|
+
const providers: Provider[] = [
|
|
1832
|
+
// Base path token
|
|
1833
|
+
{
|
|
1834
|
+
provide: BASE_PATH,
|
|
1835
|
+
useValue: config.basePath
|
|
1836
|
+
}
|
|
1837
|
+
];
|
|
1838
|
+
|
|
1839
|
+
${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
|
|
1840
|
+
if (config.enableDateTransform !== false) {
|
|
1841
|
+
providers.push({
|
|
1842
|
+
provide: HTTP_INTERCEPTORS,
|
|
1843
|
+
useClass: DateInterceptor,
|
|
1844
|
+
multi: true
|
|
1845
|
+
});
|
|
1846
|
+
}` : `// Date transformation not available (dateType: 'string' was used in generation)`}
|
|
1847
|
+
|
|
1848
|
+
return makeEnvironmentProviders(providers);`;
|
|
1849
|
+
sourceFile.addFunction({
|
|
1850
|
+
name: "provideNgOpenapi",
|
|
1851
|
+
isExported: true,
|
|
1852
|
+
docs: [
|
|
1853
|
+
"Provides all necessary configuration for ng-openapi generated services",
|
|
1854
|
+
"",
|
|
1855
|
+
"@example",
|
|
1856
|
+
"```typescript",
|
|
1857
|
+
"// In your app.config.ts",
|
|
1858
|
+
"import { provideNgOpenapi } from './api/providers';",
|
|
1859
|
+
"",
|
|
1860
|
+
"export const appConfig: ApplicationConfig = {",
|
|
1861
|
+
" providers: [",
|
|
1862
|
+
" provideNgOpenapi({",
|
|
1863
|
+
" basePath: 'https://api.example.com'",
|
|
1864
|
+
" }),",
|
|
1865
|
+
" // other providers...",
|
|
1866
|
+
" ]",
|
|
1867
|
+
"};",
|
|
1868
|
+
"```"
|
|
1869
|
+
],
|
|
1870
|
+
parameters: [
|
|
1871
|
+
{
|
|
1872
|
+
name: "config",
|
|
1873
|
+
type: "NgOpenapiConfig"
|
|
1874
|
+
}
|
|
1875
|
+
],
|
|
1876
|
+
returnType: "EnvironmentProviders",
|
|
1877
|
+
statements: functionBody
|
|
1878
|
+
});
|
|
1879
|
+
}
|
|
1880
|
+
addAsyncProviderFunction(sourceFile) {
|
|
1881
|
+
const hasDateInterceptor = this.config.options.dateType === "Date";
|
|
1882
|
+
const functionBody = `
|
|
1883
|
+
const providers: Provider[] = [];
|
|
1884
|
+
|
|
1885
|
+
// Handle async base path
|
|
1886
|
+
if (typeof config.basePath === 'string') {
|
|
1887
|
+
providers.push({
|
|
1888
|
+
provide: BASE_PATH,
|
|
1889
|
+
useValue: config.basePath
|
|
1890
|
+
});
|
|
1891
|
+
} else {
|
|
1892
|
+
providers.push({
|
|
1893
|
+
provide: BASE_PATH,
|
|
1894
|
+
useFactory: config.basePath
|
|
1895
|
+
});
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
|
|
1899
|
+
if (config.enableDateTransform !== false) {
|
|
1900
|
+
providers.push({
|
|
1901
|
+
provide: HTTP_INTERCEPTORS,
|
|
1902
|
+
useClass: DateInterceptor,
|
|
1903
|
+
multi: true
|
|
1904
|
+
});
|
|
1905
|
+
}` : `// Date transformation not available (dateType: 'string' was used in generation)`}
|
|
1906
|
+
|
|
1907
|
+
return makeEnvironmentProviders(providers);`;
|
|
1908
|
+
sourceFile.addFunction({
|
|
1909
|
+
name: "provideNgOpenapiAsync",
|
|
1910
|
+
isExported: true,
|
|
1911
|
+
docs: [
|
|
1912
|
+
"Alternative function for cases where you need to handle async configuration",
|
|
1913
|
+
"",
|
|
1914
|
+
"@example",
|
|
1915
|
+
"```typescript",
|
|
1916
|
+
"// In your app.config.ts",
|
|
1917
|
+
"import { provideNgOpenapiAsync } from './api/providers';",
|
|
1918
|
+
"",
|
|
1919
|
+
"export const appConfig: ApplicationConfig = {",
|
|
1920
|
+
" providers: [",
|
|
1921
|
+
" provideNgOpenapiAsync({",
|
|
1922
|
+
" basePath: () => import('./config').then(c => c.apiConfig.baseUrl)",
|
|
1923
|
+
" }),",
|
|
1924
|
+
" // other providers...",
|
|
1925
|
+
" ]",
|
|
1926
|
+
"};",
|
|
1927
|
+
"```"
|
|
1928
|
+
],
|
|
1929
|
+
parameters: [
|
|
1930
|
+
{
|
|
1931
|
+
name: "config",
|
|
1932
|
+
type: `{
|
|
1933
|
+
basePath: string | (() => Promise<string>);
|
|
1934
|
+
enableDateTransform?: boolean;
|
|
1935
|
+
}`
|
|
1936
|
+
}
|
|
1937
|
+
],
|
|
1938
|
+
returnType: "EnvironmentProviders",
|
|
1939
|
+
statements: functionBody
|
|
1940
|
+
});
|
|
1941
|
+
}
|
|
1942
|
+
};
|
|
1943
|
+
|
|
1743
1944
|
// src/lib/core/generator.ts
|
|
1744
1945
|
var fs3 = __toESM(require("fs"));
|
|
1745
1946
|
async function generateFromConfig(config) {
|
|
@@ -1783,6 +1984,9 @@ async function generateFromConfig(config) {
|
|
|
1783
1984
|
indexGenerator.generateIndex(outputPath);
|
|
1784
1985
|
console.log(`\u2705 Angular services generated`);
|
|
1785
1986
|
}
|
|
1987
|
+
const providerGenerator = new ProviderGenerator(project, config);
|
|
1988
|
+
providerGenerator.generate(outputPath);
|
|
1989
|
+
console.log(`\u2705 Provider functions generated`);
|
|
1786
1990
|
const mainIndexGenerator = new MainIndexGenerator(project, config);
|
|
1787
1991
|
mainIndexGenerator.generateMainIndex(outputPath);
|
|
1788
1992
|
console.log("\u{1F389} Generation completed successfully at:", outputPath);
|
|
@@ -1800,7 +2004,7 @@ __name(generateFromConfig, "generateFromConfig");
|
|
|
1800
2004
|
// src/lib/cli.ts
|
|
1801
2005
|
var program = new import_commander.Command();
|
|
1802
2006
|
async function loadConfigFile(configPath) {
|
|
1803
|
-
const resolvedPath =
|
|
2007
|
+
const resolvedPath = path8.resolve(configPath);
|
|
1804
2008
|
if (!fs4.existsSync(resolvedPath)) {
|
|
1805
2009
|
throw new Error(`Configuration file not found: ${resolvedPath}`);
|
|
1806
2010
|
}
|
|
@@ -1826,7 +2030,7 @@ async function generateFromOptions(options) {
|
|
|
1826
2030
|
const config = await loadConfigFile(options.config);
|
|
1827
2031
|
await generateFromConfig(config);
|
|
1828
2032
|
} else if (options.input) {
|
|
1829
|
-
const inputPath =
|
|
2033
|
+
const inputPath = path8.resolve(options.input);
|
|
1830
2034
|
if (!fs4.existsSync(inputPath)) {
|
|
1831
2035
|
console.error(`Error: Input file not found: ${inputPath}`);
|
|
1832
2036
|
process.exit(1);
|
package/index.js
CHANGED
|
@@ -131,6 +131,10 @@ var MAIN_INDEX_GENERATOR_HEADER_COMMENT = defaultHeaderComment + `* Entrypoint f
|
|
|
131
131
|
* Do not edit this file manually
|
|
132
132
|
*/
|
|
133
133
|
`;
|
|
134
|
+
var PROVIDER_GENERATOR_HEADER_COMMENT = defaultHeaderComment + `* Generated provider functions for easy setup
|
|
135
|
+
* Do not edit this file manually
|
|
136
|
+
*/
|
|
137
|
+
`;
|
|
134
138
|
|
|
135
139
|
// src/lib/generators/type/type.generator.ts
|
|
136
140
|
var _TypeGenerator = class _TypeGenerator {
|
|
@@ -768,11 +772,16 @@ var _MainIndexGenerator = class _MainIndexGenerator {
|
|
|
768
772
|
moduleSpecifier: "./models"
|
|
769
773
|
});
|
|
770
774
|
sourceFile.addExportDeclaration({
|
|
771
|
-
moduleSpecifier: "./
|
|
775
|
+
moduleSpecifier: "./tokens"
|
|
772
776
|
});
|
|
773
777
|
sourceFile.addExportDeclaration({
|
|
774
|
-
moduleSpecifier: "./
|
|
778
|
+
moduleSpecifier: "./providers"
|
|
775
779
|
});
|
|
780
|
+
if (this.config.options.generateServices !== false) {
|
|
781
|
+
sourceFile.addExportDeclaration({
|
|
782
|
+
moduleSpecifier: "./services"
|
|
783
|
+
});
|
|
784
|
+
}
|
|
776
785
|
if (this.config.options.dateType === "Date") {
|
|
777
786
|
sourceFile.addExportDeclaration({
|
|
778
787
|
moduleSpecifier: "./utils/date-transformer"
|
|
@@ -1530,7 +1539,7 @@ var _ServiceGenerator = class _ServiceGenerator {
|
|
|
1530
1539
|
extractPaths() {
|
|
1531
1540
|
const paths = [];
|
|
1532
1541
|
const swaggerPaths = this.spec.paths || {};
|
|
1533
|
-
Object.entries(swaggerPaths).forEach(([
|
|
1542
|
+
Object.entries(swaggerPaths).forEach(([path8, pathItem]) => {
|
|
1534
1543
|
const methods = [
|
|
1535
1544
|
"get",
|
|
1536
1545
|
"post",
|
|
@@ -1544,7 +1553,7 @@ var _ServiceGenerator = class _ServiceGenerator {
|
|
|
1544
1553
|
if (pathItem[method]) {
|
|
1545
1554
|
const operation = pathItem[method];
|
|
1546
1555
|
paths.push({
|
|
1547
|
-
path:
|
|
1556
|
+
path: path8,
|
|
1548
1557
|
method: method.toUpperCase(),
|
|
1549
1558
|
operationId: operation.operationId,
|
|
1550
1559
|
summary: operation.summary,
|
|
@@ -1576,12 +1585,12 @@ var _ServiceGenerator = class _ServiceGenerator {
|
|
|
1576
1585
|
}
|
|
1577
1586
|
groupPathsByController(paths) {
|
|
1578
1587
|
const groups = {};
|
|
1579
|
-
paths.forEach((
|
|
1588
|
+
paths.forEach((path8) => {
|
|
1580
1589
|
let controllerName = "Default";
|
|
1581
|
-
if (
|
|
1582
|
-
controllerName =
|
|
1590
|
+
if (path8.tags && path8.tags.length > 0) {
|
|
1591
|
+
controllerName = path8.tags[0];
|
|
1583
1592
|
} else {
|
|
1584
|
-
const pathParts =
|
|
1593
|
+
const pathParts = path8.path.split("/").filter((p) => p && !p.startsWith("{"));
|
|
1585
1594
|
if (pathParts.length > 1) {
|
|
1586
1595
|
controllerName = pascalCase(pathParts[1]);
|
|
1587
1596
|
}
|
|
@@ -1590,7 +1599,7 @@ var _ServiceGenerator = class _ServiceGenerator {
|
|
|
1590
1599
|
if (!groups[controllerName]) {
|
|
1591
1600
|
groups[controllerName] = [];
|
|
1592
1601
|
}
|
|
1593
|
-
groups[controllerName].push(
|
|
1602
|
+
groups[controllerName].push(path8);
|
|
1594
1603
|
});
|
|
1595
1604
|
return groups;
|
|
1596
1605
|
}
|
|
@@ -1785,6 +1794,197 @@ var _ServiceIndexGenerator = class _ServiceIndexGenerator {
|
|
|
1785
1794
|
__name(_ServiceIndexGenerator, "ServiceIndexGenerator");
|
|
1786
1795
|
var ServiceIndexGenerator = _ServiceIndexGenerator;
|
|
1787
1796
|
|
|
1797
|
+
// src/lib/generators/utility/provider.generator.ts
|
|
1798
|
+
var path7 = __toESM(require("path"));
|
|
1799
|
+
var _ProviderGenerator = class _ProviderGenerator {
|
|
1800
|
+
constructor(project, config) {
|
|
1801
|
+
__publicField(this, "project");
|
|
1802
|
+
__publicField(this, "config");
|
|
1803
|
+
this.project = project;
|
|
1804
|
+
this.config = config;
|
|
1805
|
+
}
|
|
1806
|
+
generate(outputDir) {
|
|
1807
|
+
const filePath = path7.join(outputDir, "providers.ts");
|
|
1808
|
+
const sourceFile = this.project.createSourceFile(filePath, "", {
|
|
1809
|
+
overwrite: true
|
|
1810
|
+
});
|
|
1811
|
+
sourceFile.insertText(0, PROVIDER_GENERATOR_HEADER_COMMENT);
|
|
1812
|
+
sourceFile.addImportDeclarations([
|
|
1813
|
+
{
|
|
1814
|
+
namedImports: [
|
|
1815
|
+
"EnvironmentProviders",
|
|
1816
|
+
"Provider",
|
|
1817
|
+
"makeEnvironmentProviders"
|
|
1818
|
+
],
|
|
1819
|
+
moduleSpecifier: "@angular/core"
|
|
1820
|
+
},
|
|
1821
|
+
{
|
|
1822
|
+
namedImports: [
|
|
1823
|
+
"HTTP_INTERCEPTORS"
|
|
1824
|
+
],
|
|
1825
|
+
moduleSpecifier: "@angular/common/http"
|
|
1826
|
+
},
|
|
1827
|
+
{
|
|
1828
|
+
namedImports: [
|
|
1829
|
+
"BASE_PATH"
|
|
1830
|
+
],
|
|
1831
|
+
moduleSpecifier: "./tokens"
|
|
1832
|
+
}
|
|
1833
|
+
]);
|
|
1834
|
+
if (this.config.options.dateType === "Date") {
|
|
1835
|
+
sourceFile.addImportDeclaration({
|
|
1836
|
+
namedImports: [
|
|
1837
|
+
"DateInterceptor"
|
|
1838
|
+
],
|
|
1839
|
+
moduleSpecifier: "./utils/date-transformer"
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
sourceFile.addInterface({
|
|
1843
|
+
name: "NgOpenapiConfig",
|
|
1844
|
+
isExported: true,
|
|
1845
|
+
docs: [
|
|
1846
|
+
"Configuration options for ng-openapi providers"
|
|
1847
|
+
],
|
|
1848
|
+
properties: [
|
|
1849
|
+
{
|
|
1850
|
+
name: "basePath",
|
|
1851
|
+
type: "string",
|
|
1852
|
+
docs: [
|
|
1853
|
+
"Base API URL"
|
|
1854
|
+
]
|
|
1855
|
+
},
|
|
1856
|
+
{
|
|
1857
|
+
name: "enableDateTransform",
|
|
1858
|
+
type: "boolean",
|
|
1859
|
+
hasQuestionToken: true,
|
|
1860
|
+
docs: [
|
|
1861
|
+
"Enable automatic date transformation (default: true)"
|
|
1862
|
+
]
|
|
1863
|
+
}
|
|
1864
|
+
]
|
|
1865
|
+
});
|
|
1866
|
+
this.addMainProviderFunction(sourceFile);
|
|
1867
|
+
this.addAsyncProviderFunction(sourceFile);
|
|
1868
|
+
sourceFile.saveSync();
|
|
1869
|
+
}
|
|
1870
|
+
addMainProviderFunction(sourceFile) {
|
|
1871
|
+
const hasDateInterceptor = this.config.options.dateType === "Date";
|
|
1872
|
+
const functionBody = `
|
|
1873
|
+
const providers: Provider[] = [
|
|
1874
|
+
// Base path token
|
|
1875
|
+
{
|
|
1876
|
+
provide: BASE_PATH,
|
|
1877
|
+
useValue: config.basePath
|
|
1878
|
+
}
|
|
1879
|
+
];
|
|
1880
|
+
|
|
1881
|
+
${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
|
|
1882
|
+
if (config.enableDateTransform !== false) {
|
|
1883
|
+
providers.push({
|
|
1884
|
+
provide: HTTP_INTERCEPTORS,
|
|
1885
|
+
useClass: DateInterceptor,
|
|
1886
|
+
multi: true
|
|
1887
|
+
});
|
|
1888
|
+
}` : `// Date transformation not available (dateType: 'string' was used in generation)`}
|
|
1889
|
+
|
|
1890
|
+
return makeEnvironmentProviders(providers);`;
|
|
1891
|
+
sourceFile.addFunction({
|
|
1892
|
+
name: "provideNgOpenapi",
|
|
1893
|
+
isExported: true,
|
|
1894
|
+
docs: [
|
|
1895
|
+
"Provides all necessary configuration for ng-openapi generated services",
|
|
1896
|
+
"",
|
|
1897
|
+
"@example",
|
|
1898
|
+
"```typescript",
|
|
1899
|
+
"// In your app.config.ts",
|
|
1900
|
+
"import { provideNgOpenapi } from './api/providers';",
|
|
1901
|
+
"",
|
|
1902
|
+
"export const appConfig: ApplicationConfig = {",
|
|
1903
|
+
" providers: [",
|
|
1904
|
+
" provideNgOpenapi({",
|
|
1905
|
+
" basePath: 'https://api.example.com'",
|
|
1906
|
+
" }),",
|
|
1907
|
+
" // other providers...",
|
|
1908
|
+
" ]",
|
|
1909
|
+
"};",
|
|
1910
|
+
"```"
|
|
1911
|
+
],
|
|
1912
|
+
parameters: [
|
|
1913
|
+
{
|
|
1914
|
+
name: "config",
|
|
1915
|
+
type: "NgOpenapiConfig"
|
|
1916
|
+
}
|
|
1917
|
+
],
|
|
1918
|
+
returnType: "EnvironmentProviders",
|
|
1919
|
+
statements: functionBody
|
|
1920
|
+
});
|
|
1921
|
+
}
|
|
1922
|
+
addAsyncProviderFunction(sourceFile) {
|
|
1923
|
+
const hasDateInterceptor = this.config.options.dateType === "Date";
|
|
1924
|
+
const functionBody = `
|
|
1925
|
+
const providers: Provider[] = [];
|
|
1926
|
+
|
|
1927
|
+
// Handle async base path
|
|
1928
|
+
if (typeof config.basePath === 'string') {
|
|
1929
|
+
providers.push({
|
|
1930
|
+
provide: BASE_PATH,
|
|
1931
|
+
useValue: config.basePath
|
|
1932
|
+
});
|
|
1933
|
+
} else {
|
|
1934
|
+
providers.push({
|
|
1935
|
+
provide: BASE_PATH,
|
|
1936
|
+
useFactory: config.basePath
|
|
1937
|
+
});
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
|
|
1941
|
+
if (config.enableDateTransform !== false) {
|
|
1942
|
+
providers.push({
|
|
1943
|
+
provide: HTTP_INTERCEPTORS,
|
|
1944
|
+
useClass: DateInterceptor,
|
|
1945
|
+
multi: true
|
|
1946
|
+
});
|
|
1947
|
+
}` : `// Date transformation not available (dateType: 'string' was used in generation)`}
|
|
1948
|
+
|
|
1949
|
+
return makeEnvironmentProviders(providers);`;
|
|
1950
|
+
sourceFile.addFunction({
|
|
1951
|
+
name: "provideNgOpenapiAsync",
|
|
1952
|
+
isExported: true,
|
|
1953
|
+
docs: [
|
|
1954
|
+
"Alternative function for cases where you need to handle async configuration",
|
|
1955
|
+
"",
|
|
1956
|
+
"@example",
|
|
1957
|
+
"```typescript",
|
|
1958
|
+
"// In your app.config.ts",
|
|
1959
|
+
"import { provideNgOpenapiAsync } from './api/providers';",
|
|
1960
|
+
"",
|
|
1961
|
+
"export const appConfig: ApplicationConfig = {",
|
|
1962
|
+
" providers: [",
|
|
1963
|
+
" provideNgOpenapiAsync({",
|
|
1964
|
+
" basePath: () => import('./config').then(c => c.apiConfig.baseUrl)",
|
|
1965
|
+
" }),",
|
|
1966
|
+
" // other providers...",
|
|
1967
|
+
" ]",
|
|
1968
|
+
"};",
|
|
1969
|
+
"```"
|
|
1970
|
+
],
|
|
1971
|
+
parameters: [
|
|
1972
|
+
{
|
|
1973
|
+
name: "config",
|
|
1974
|
+
type: `{
|
|
1975
|
+
basePath: string | (() => Promise<string>);
|
|
1976
|
+
enableDateTransform?: boolean;
|
|
1977
|
+
}`
|
|
1978
|
+
}
|
|
1979
|
+
],
|
|
1980
|
+
returnType: "EnvironmentProviders",
|
|
1981
|
+
statements: functionBody
|
|
1982
|
+
});
|
|
1983
|
+
}
|
|
1984
|
+
};
|
|
1985
|
+
__name(_ProviderGenerator, "ProviderGenerator");
|
|
1986
|
+
var ProviderGenerator = _ProviderGenerator;
|
|
1987
|
+
|
|
1788
1988
|
// src/lib/core/generator.ts
|
|
1789
1989
|
var fs3 = __toESM(require("fs"));
|
|
1790
1990
|
function generateFromConfig(config) {
|
|
@@ -1829,6 +2029,9 @@ function generateFromConfig(config) {
|
|
|
1829
2029
|
indexGenerator.generateIndex(outputPath);
|
|
1830
2030
|
console.log(`\u2705 Angular services generated`);
|
|
1831
2031
|
}
|
|
2032
|
+
const providerGenerator = new ProviderGenerator(project, config);
|
|
2033
|
+
providerGenerator.generate(outputPath);
|
|
2034
|
+
console.log(`\u2705 Provider functions generated`);
|
|
1832
2035
|
const mainIndexGenerator = new MainIndexGenerator(project, config);
|
|
1833
2036
|
mainIndexGenerator.generateMainIndex(outputPath);
|
|
1834
2037
|
console.log("\u{1F389} Generation completed successfully at:", outputPath);
|