ng-openapi 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +61 -32
  2. package/cli.cjs +216 -12
  3. package/index.js +212 -9
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -1,4 +1,18 @@
1
- # ng-openapi Usage Guide
1
+ <div align="center">
2
+ <h1 align="center"><b>Angular OpenAPI client generator</b></h1>
3
+ <p align="center">💪 Made with ❤️ by Angular Devs for Angular Devs</p>
4
+ </div>
5
+
6
+ <br/>
7
+
8
+ <p align="center">
9
+ <a href="https://opensource.org/license/mit" rel="nofollow"><img src="https://img.shields.io/github/license/ng-openapi/ng-openapi" alt="MIT License"></a>
10
+ <a href="https://github.com/ng-openapi/ng-openapi/actions?query=branch%3Amain"><img src="https://img.shields.io/github/last-commit/ng-openapi/ng-openapi" alt="Last commit" /></a>
11
+ <a href="https://github.com/ng-openapi/ng-openapi/actions?query=branch%3Amain"><img src="https://github.com/ng-openapi/ng-openapi/actions/workflows/release.yml/badge.svg?event=push&branch=main" alt="CI status" /></a>
12
+ <a href="https://github.com/ng-openapi/ng-openapi/issues" rel="nofollow"><img src="https://img.shields.io/github/issues/ng-openapi/ng-openapi" alt="Number of open issues"></a>
13
+ </p>
14
+ <br/>
15
+
2
16
 
3
17
  ## Installation
4
18
 
@@ -84,13 +98,13 @@ ng-openapi -i ./swagger.json -o ./src/api --date-type string
84
98
 
85
99
  ### Optional Fields
86
100
 
87
- - `options.dateType` - How to handle date types: `'string'` or `'Date'` (default: `'Date'`)
88
- - `options.enumStyle` - Enum generation style: `'enum'` or `'union'` (default: `'enum'`)
89
- - `options.generateEnumBasedOnDescription` - Parse enum values from description field (default: `true`)
90
- - `options.generateServices` - Generate Angular services (default: `true`)
91
- - `options.customHeaders` - Headers to add to all HTTP requests
92
- - `options.responseTypeMapping` - Map content types to Angular HttpClient response types
93
- - `options.customizeMethodName` - Function to customize generated method names
101
+ - `dateType` - How to handle date types: `'string'` or `'Date'` (default: `'Date'`)
102
+ - `enumStyle` - Enum generation style: `'enum'` or `'union'` (default: `'enum'`)
103
+ - `generateEnumBasedOnDescription` - Parse enum values from description field (default: `true`)
104
+ - `generateServices` - Generate Angular services (default: `true`)
105
+ - `customHeaders` - Headers to add to all HTTP requests
106
+ - `responseTypeMapping` - Map content types to Angular HttpClient response types
107
+ - `customizeMethodName` - Function to customize generated method names
94
108
  - `compilerOptions` - TypeScript compiler options for code generation
95
109
 
96
110
  ## Generated Files Structure
@@ -104,44 +118,60 @@ output/
104
118
  │ └── *.service.ts # Angular services
105
119
  ├── tokens/
106
120
  │ └── index.ts # Injection tokens
107
- └── utils/
108
- ├── date-transformer.ts # Date transformation interceptor
109
- └── file-download.ts # File download helpers
121
+ ├── utils/
122
+ ├── date-transformer.ts # Date transformation interceptor
123
+ └── file-download.ts # File download helpers
124
+ ├── providers.ts # Provider functions for easy setup
125
+ └── index.ts # Main exports
110
126
  ```
111
127
 
112
128
  ## Angular Integration
113
129
 
114
- ### 1. Configure Base Path
130
+ ### 🚀 Easy Setup (Recommended)
131
+
132
+ The simplest way to integrate ng-openapi is using the provider function:
115
133
 
116
134
  ```typescript
117
- import { BASE_PATH } from './api/tokens';
135
+ // In your app.config.ts
136
+ import { ApplicationConfig } from '@angular/core';
137
+ import { provideNgOpenapi } from './api/providers';
118
138
 
119
- // In your app.config.ts or module
120
139
  export const appConfig: ApplicationConfig = {
121
140
  providers: [
122
- { provide: BASE_PATH, useValue: 'https://api.example.com' },
141
+ // One-line setup with automatic interceptor configuration
142
+ provideNgOpenapi({
143
+ basePath: 'https://api.example.com'
144
+ }),
123
145
  // other providers...
124
146
  ]
125
147
  };
126
148
  ```
127
149
 
128
- ### 2. Add Date Interceptor (if using Date type)
150
+ That's it! This automatically configures:
151
+ - ✅ BASE_PATH token
152
+ - ✅ Date transformation interceptor (if using Date type)
129
153
 
130
- ```typescript
131
- import { DateInterceptor } from './api/utils/date-transformer';
132
- import { HTTP_INTERCEPTORS } from '@angular/common/http';
133
154
 
134
- export const appConfig: ApplicationConfig = {
135
- providers: [
136
- { provide: HTTP_INTERCEPTORS, useClass: DateInterceptor, multi: true },
137
- // other providers...
138
- ]
139
- };
155
+ ### Advanced Provider Options
156
+
157
+ ```typescript
158
+ // Disable date transformation
159
+ provideNgOpenapi({
160
+ basePath: 'https://api.example.com',
161
+ enableDateTransform: false
162
+ });
163
+
164
+ // Async configuration
165
+ provideNgOpenapiAsync({
166
+ basePath: () => import('./config').then(c => c.apiConfig.baseUrl)
167
+ });
140
168
  ```
141
169
 
142
- ### 3. Use Generated Services
170
+ ## Using Generated Services
143
171
 
144
172
  ```typescript
173
+ import { Component, inject } from '@angular/core';
174
+ import { toSignal } from '@angular/core/rxjs-interop';
145
175
  import { UserService } from './api/services';
146
176
  import { User } from './api/models';
147
177
 
@@ -150,19 +180,19 @@ import { User } from './api/models';
150
180
  template: `...`
151
181
  })
152
182
  export class UsersComponent {
153
- users$ = this.userService.getUsers();
154
-
155
- constructor(private userService: UserService) {}
183
+ private readonly userService = inject(UserService);
184
+ readonly users = toSignal(this.userService.getUsers());
156
185
  }
157
186
  ```
158
187
 
159
188
  ## File Download Example
160
189
 
161
190
  ```typescript
191
+ import { Component, inject } from '@angular/core';
162
192
  import { downloadFileOperator } from './api/utils/file-download';
163
193
 
164
194
  export class ReportComponent {
165
- constructor(private reportService: ReportService) {}
195
+ private readonly reportService = inject(ReportService);
166
196
 
167
197
  downloadReport() {
168
198
  this.reportService.getReport('pdf', { reportId: 123 })
@@ -181,8 +211,7 @@ Add these scripts to your `package.json`:
181
211
  ```json
182
212
  {
183
213
  "scripts": {
184
- "generate:api": "ng-openapi -c openapi.config.ts",
185
- "generate:api:watch": "nodemon --watch swagger.json --exec npm run generate:api"
214
+ "generate:api": "ng-openapi -c openapi.config.ts"
186
215
  }
187
216
  }
188
217
  ```
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 path7 = __toESM(require("path"));
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: "./services"
738
+ moduleSpecifier: "./tokens"
735
739
  });
736
740
  sourceFile.addExportDeclaration({
737
- moduleSpecifier: "./tokens"
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(([path8, pathItem]) => {
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: path8,
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((path8) => {
1545
+ paths.forEach((path9) => {
1537
1546
  let controllerName = "Default";
1538
- if (path8.tags && path8.tags.length > 0) {
1539
- controllerName = path8.tags[0];
1547
+ if (path9.tags && path9.tags.length > 0) {
1548
+ controllerName = path9.tags[0];
1540
1549
  } else {
1541
- const pathParts = path8.path.split("/").filter((p) => p && !p.startsWith("{"));
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(path8);
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 = path7.resolve(configPath);
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 = path7.resolve(options.input);
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: "./services"
775
+ moduleSpecifier: "./tokens"
772
776
  });
773
777
  sourceFile.addExportDeclaration({
774
- moduleSpecifier: "./tokens"
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(([path7, pathItem]) => {
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: path7,
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((path7) => {
1588
+ paths.forEach((path8) => {
1580
1589
  let controllerName = "Default";
1581
- if (path7.tags && path7.tags.length > 0) {
1582
- controllerName = path7.tags[0];
1590
+ if (path8.tags && path8.tags.length > 0) {
1591
+ controllerName = path8.tags[0];
1583
1592
  } else {
1584
- const pathParts = path7.path.split("/").filter((p) => p && !p.startsWith("{"));
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(path7);
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ng-openapi",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Generate Angular services and TypeScript types from OpenAPI/Swagger specifications",
5
5
  "keywords": [
6
6
  "angular",