ng-openapi 0.0.23 → 0.0.24

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/cli.cjs +102 -263
  2. package/index.d.ts +0 -1
  3. package/index.js +92 -150
  4. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -7,10 +7,6 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
9
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
10
- var __export = (target, all) => {
11
- for (var name in all)
12
- __defProp(target, name, { get: all[name], enumerable: true });
13
- };
14
10
  var __copyProps = (to, from, except, desc) => {
15
11
  if (from && typeof from === "object" || typeof from === "function") {
16
12
  for (let key of __getOwnPropNames(from))
@@ -27,14 +23,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
23
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
24
  mod
29
25
  ));
30
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
26
 
32
27
  // src/lib/cli.ts
33
- var cli_exports = {};
34
- __export(cli_exports, {
35
- generateFromOptions: () => generateFromOptions
36
- });
37
- module.exports = __toCommonJS(cli_exports);
38
28
  var import_commander = require("commander");
39
29
  var path8 = __toESM(require("path"));
40
30
  var fs4 = __toESM(require("fs"));
@@ -412,10 +402,8 @@ var TokenGenerator = class {
412
402
  __name(this, "TokenGenerator");
413
403
  }
414
404
  project;
415
- config;
416
- constructor(project, config) {
405
+ constructor(project) {
417
406
  this.project = project;
418
- this.config = config;
419
407
  }
420
408
  generate(outputDir) {
421
409
  const tokensDir = path.join(outputDir, "tokens");
@@ -429,55 +417,23 @@ var TokenGenerator = class {
429
417
  ],
430
418
  moduleSpecifier: "@angular/core"
431
419
  });
432
- const clientName = this.config.clientName || "DEFAULT";
433
- const upperCaseClientName = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
434
420
  sourceFile.addVariableStatement({
435
421
  isExported: true,
436
422
  declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
437
423
  declarations: [
438
424
  {
439
- name: `${upperCaseClientName}_BASE_PATH`,
440
- initializer: `new InjectionToken<string>('${upperCaseClientName}_BASE_PATH', {
425
+ name: "BASE_PATH",
426
+ initializer: `new InjectionToken<string>('BASE_PATH', {
441
427
  providedIn: 'root',
442
- factory: () => '/api',
428
+ factory: () => '/api', // Default fallback
443
429
  })`
444
430
  }
445
431
  ],
446
432
  leadingTrivia: `/**
447
- * Base path token for ${clientName} client
448
- */
449
- `
450
- });
451
- sourceFile.addVariableStatement({
452
- isExported: true,
453
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
454
- declarations: [
455
- {
456
- name: `${upperCaseClientName}_HTTP_CLIENT`,
457
- initializer: `new InjectionToken<HttpClient>('${upperCaseClientName}_HTTP_CLIENT')`
458
- }
459
- ],
460
- leadingTrivia: `/**
461
- * HTTP client token for ${clientName} client
433
+ * Injection token for the base API path
462
434
  */
463
435
  `
464
436
  });
465
- if (!this.config.clientName) {
466
- sourceFile.addVariableStatement({
467
- isExported: true,
468
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
469
- declarations: [
470
- {
471
- name: "BASE_PATH",
472
- initializer: `${upperCaseClientName}_BASE_PATH`
473
- }
474
- ],
475
- leadingTrivia: `/**
476
- * @deprecated Use ${upperCaseClientName}_BASE_PATH instead
477
- */
478
- `
479
- });
480
- }
481
437
  sourceFile.saveSync();
482
438
  }
483
439
  };
@@ -1746,8 +1702,6 @@ var ServiceGenerator = class {
1746
1702
  });
1747
1703
  }
1748
1704
  addImports(sourceFile, usedTypes) {
1749
- const clientName = this.config.clientName || "DEFAULT";
1750
- const upperCaseClientName = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
1751
1705
  sourceFile.addImportDeclarations([
1752
1706
  {
1753
1707
  namedImports: [
@@ -1775,15 +1729,11 @@ var ServiceGenerator = class {
1775
1729
  },
1776
1730
  {
1777
1731
  namedImports: [
1778
- `${upperCaseClientName}_BASE_PATH`,
1779
- `${upperCaseClientName}_HTTP_CLIENT`
1732
+ "BASE_PATH"
1780
1733
  ],
1781
1734
  moduleSpecifier: "../tokens"
1782
1735
  }
1783
1736
  ]);
1784
- if (!this.config.clientName) {
1785
- sourceFile.getImportDeclaration("../tokens")?.addNamedImport("BASE_PATH");
1786
- }
1787
1737
  if (usedTypes.size > 0) {
1788
1738
  sourceFile.addImportDeclaration({
1789
1739
  namedImports: Array.from(usedTypes).sort(),
@@ -1793,8 +1743,6 @@ var ServiceGenerator = class {
1793
1743
  }
1794
1744
  addServiceClass(sourceFile, controllerName, operations) {
1795
1745
  const className = `${controllerName}Service`;
1796
- const clientName = this.config.clientName || "DEFAULT";
1797
- const upperCaseClientName = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
1798
1746
  sourceFile.insertText(0, SERVICE_GENERATOR_HEADER_COMMENT(controllerName));
1799
1747
  const serviceClass = sourceFile.addClass({
1800
1748
  name: className,
@@ -1813,14 +1761,14 @@ var ServiceGenerator = class {
1813
1761
  type: "HttpClient",
1814
1762
  scope: import_ts_morph3.Scope.Private,
1815
1763
  isReadonly: true,
1816
- initializer: `inject(${upperCaseClientName}_HTTP_CLIENT, { optional: true }) ?? inject(HttpClient)`
1764
+ initializer: "inject(HttpClient)"
1817
1765
  });
1818
1766
  serviceClass.addProperty({
1819
1767
  name: "basePath",
1820
1768
  type: "string",
1821
1769
  scope: import_ts_morph3.Scope.Private,
1822
1770
  isReadonly: true,
1823
- initializer: `inject(${upperCaseClientName}_BASE_PATH)`
1771
+ initializer: "inject(BASE_PATH)"
1824
1772
  });
1825
1773
  operations.forEach((operation) => {
1826
1774
  this.methodGenerator.addServiceMethod(serviceClass, operation);
@@ -1884,34 +1832,24 @@ var ProviderGenerator = class {
1884
1832
  overwrite: true
1885
1833
  });
1886
1834
  sourceFile.insertText(0, PROVIDER_GENERATOR_HEADER_COMMENT);
1887
- const clientName = this.config.clientName || "Default";
1888
- const pascalClientName = this.pascalCase(clientName);
1889
- const upperCaseClientName = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
1890
1835
  sourceFile.addImportDeclarations([
1891
1836
  {
1892
1837
  namedImports: [
1893
1838
  "EnvironmentProviders",
1894
1839
  "Provider",
1895
- "makeEnvironmentProviders",
1896
- "Type",
1897
- "Injector",
1898
- "inject"
1840
+ "makeEnvironmentProviders"
1899
1841
  ],
1900
1842
  moduleSpecifier: "@angular/core"
1901
1843
  },
1902
1844
  {
1903
1845
  namedImports: [
1904
- "HttpClient",
1905
- "HttpInterceptor",
1906
- "HttpHandler",
1907
- "HttpRequest"
1846
+ "HTTP_INTERCEPTORS"
1908
1847
  ],
1909
1848
  moduleSpecifier: "@angular/common/http"
1910
1849
  },
1911
1850
  {
1912
1851
  namedImports: [
1913
- `${upperCaseClientName}_BASE_PATH`,
1914
- `${upperCaseClientName}_HTTP_CLIENT`
1852
+ "BASE_PATH"
1915
1853
  ],
1916
1854
  moduleSpecifier: "./tokens"
1917
1855
  }
@@ -1925,10 +1863,10 @@ var ProviderGenerator = class {
1925
1863
  });
1926
1864
  }
1927
1865
  sourceFile.addInterface({
1928
- name: `${pascalClientName}Config`,
1866
+ name: "NgOpenapiConfig",
1929
1867
  isExported: true,
1930
1868
  docs: [
1931
- `Configuration options for ${clientName} API client`
1869
+ "Configuration options for ng-openapi providers"
1932
1870
  ],
1933
1871
  properties: [
1934
1872
  {
@@ -1938,14 +1876,6 @@ var ProviderGenerator = class {
1938
1876
  "Base API URL"
1939
1877
  ]
1940
1878
  },
1941
- {
1942
- name: "interceptors",
1943
- type: "Type<HttpInterceptor>[]",
1944
- hasQuestionToken: true,
1945
- docs: [
1946
- "HTTP interceptors to apply to this client's requests"
1947
- ]
1948
- },
1949
1879
  {
1950
1880
  name: "enableDateTransform",
1951
1881
  type: "boolean",
@@ -1956,102 +1886,105 @@ var ProviderGenerator = class {
1956
1886
  }
1957
1887
  ]
1958
1888
  });
1959
- this.addInterceptorChainHelper(sourceFile);
1960
- this.addClientProviderFunction(sourceFile, pascalClientName, upperCaseClientName);
1889
+ this.addMainProviderFunction(sourceFile);
1890
+ this.addAsyncProviderFunction(sourceFile);
1961
1891
  sourceFile.saveSync();
1962
1892
  }
1963
- addInterceptorChainHelper(sourceFile) {
1893
+ addMainProviderFunction(sourceFile) {
1894
+ const hasDateInterceptor = this.config.options.dateType === "Date";
1895
+ const functionBody = `
1896
+ const providers: Provider[] = [
1897
+ // Base path token
1898
+ {
1899
+ provide: BASE_PATH,
1900
+ useValue: config.basePath
1901
+ }
1902
+ ];
1903
+
1904
+ ${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
1905
+ if (config.enableDateTransform !== false) {
1906
+ providers.push({
1907
+ provide: HTTP_INTERCEPTORS,
1908
+ useClass: DateInterceptor,
1909
+ multi: true
1910
+ });
1911
+ }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
1912
+
1913
+ return makeEnvironmentProviders(providers);`;
1964
1914
  sourceFile.addFunction({
1965
- name: "createHttpClientWithInterceptors",
1915
+ name: "provideNgOpenapi",
1916
+ isExported: true,
1966
1917
  docs: [
1967
- "Creates an HttpClient with a custom interceptor chain"
1918
+ "Provides all necessary configuration for ng-openapi generated services",
1919
+ "",
1920
+ "@example",
1921
+ "```typescript",
1922
+ "// In your app.config.ts",
1923
+ "import { provideNgOpenapi } from './api/providers';",
1924
+ "",
1925
+ "export const appConfig: ApplicationConfig = {",
1926
+ " providers: [",
1927
+ " provideNgOpenapi({",
1928
+ " basePath: 'https://api.example.com'",
1929
+ " }),",
1930
+ " // other providers...",
1931
+ " ]",
1932
+ "};",
1933
+ "```"
1968
1934
  ],
1969
1935
  parameters: [
1970
1936
  {
1971
- name: "baseClient",
1972
- type: "HttpClient"
1973
- },
1974
- {
1975
- name: "interceptors",
1976
- type: "HttpInterceptor[]"
1937
+ name: "config",
1938
+ type: "NgOpenapiConfig"
1977
1939
  }
1978
1940
  ],
1979
- returnType: "HttpClient",
1980
- statements: `
1981
- if (!interceptors.length) {
1982
- return baseClient;
1983
- }
1984
-
1985
- // Create a custom handler that applies interceptors in sequence
1986
- let handler = baseClient.handler;
1987
-
1988
- // Apply interceptors in reverse order (last interceptor wraps the original handler)
1989
- for (let i = interceptors.length - 1; i >= 0; i--) {
1990
- const currentHandler = handler;
1991
- const interceptor = interceptors[i];
1992
-
1993
- handler = {
1994
- handle: (req: HttpRequest<any>) => interceptor.intercept(req, currentHandler)
1995
- };
1996
- }
1997
-
1998
- // Return a new HttpClient with the custom handler
1999
- return new (baseClient.constructor as any)(handler);`
1941
+ returnType: "EnvironmentProviders",
1942
+ statements: functionBody
2000
1943
  });
2001
1944
  }
2002
- addClientProviderFunction(sourceFile, pascalClientName, upperCaseClientName) {
1945
+ addAsyncProviderFunction(sourceFile) {
2003
1946
  const hasDateInterceptor = this.config.options.dateType === "Date";
2004
1947
  const functionBody = `
2005
- const providers: Provider[] = [
2006
- // Base path token
2007
- {
2008
- provide: ${upperCaseClientName}_BASE_PATH,
1948
+ const providers: Provider[] = [];
1949
+
1950
+ // Handle async base path
1951
+ if (typeof config.basePath === 'string') {
1952
+ providers.push({
1953
+ provide: BASE_PATH,
2009
1954
  useValue: config.basePath
2010
- },
2011
-
2012
- // HTTP client with custom interceptors
2013
- {
2014
- provide: ${upperCaseClientName}_HTTP_CLIENT,
2015
- useFactory: (baseClient: HttpClient, injector: Injector) => {
2016
- const interceptorInstances: HttpInterceptor[] = [];
2017
-
2018
- // Add custom interceptors
2019
- if (config.interceptors?.length) {
2020
- config.interceptors.forEach(interceptorClass => {
2021
- interceptorInstances.push(injector.get(interceptorClass));
2022
- });
2023
- }
2024
-
2025
- ${hasDateInterceptor ? `
2026
- // Add date interceptor if enabled (default: true)
2027
- if (config.enableDateTransform !== false) {
2028
- interceptorInstances.push(injector.get(DateInterceptor));
2029
- }` : ""}
2030
-
2031
- return createHttpClientWithInterceptors(baseClient, interceptorInstances);
2032
- },
2033
- deps: [HttpClient, Injector]
2034
- }
2035
- ];
1955
+ });
1956
+ } else {
1957
+ providers.push({
1958
+ provide: BASE_PATH,
1959
+ useFactory: config.basePath
1960
+ });
1961
+ }
1962
+
1963
+ ${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
1964
+ if (config.enableDateTransform !== false) {
1965
+ providers.push({
1966
+ provide: HTTP_INTERCEPTORS,
1967
+ useClass: DateInterceptor,
1968
+ multi: true
1969
+ });
1970
+ }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
2036
1971
 
2037
1972
  return makeEnvironmentProviders(providers);`;
2038
1973
  sourceFile.addFunction({
2039
- name: `provide${pascalClientName}`,
1974
+ name: "provideNgOpenapiAsync",
2040
1975
  isExported: true,
2041
1976
  docs: [
2042
- `Provides configuration for ${pascalClientName} API client`,
1977
+ "Alternative function for cases where you need to handle async configuration",
2043
1978
  "",
2044
1979
  "@example",
2045
1980
  "```typescript",
2046
- `// In your app.config.ts`,
2047
- `import { provide${pascalClientName} } from './api/providers';`,
2048
- `import { AuthInterceptor } from './interceptors/auth.interceptor';`,
1981
+ "// In your app.config.ts",
1982
+ "import { provideNgOpenapiAsync } from './api/providers';",
2049
1983
  "",
2050
1984
  "export const appConfig: ApplicationConfig = {",
2051
1985
  " providers: [",
2052
- ` provide${pascalClientName}({`,
2053
- " basePath: 'https://api.example.com',",
2054
- " interceptors: [AuthInterceptor]",
1986
+ " provideNgOpenapiAsync({",
1987
+ " basePath: () => import('./config').then(c => c.apiConfig.baseUrl)",
2055
1988
  " }),",
2056
1989
  " // other providers...",
2057
1990
  " ]",
@@ -2061,16 +1994,16 @@ return makeEnvironmentProviders(providers);`;
2061
1994
  parameters: [
2062
1995
  {
2063
1996
  name: "config",
2064
- type: `${pascalClientName}Config`
1997
+ type: `{
1998
+ basePath: string | (() => Promise<string>);
1999
+ enableDateTransform?: boolean;
2000
+ }`
2065
2001
  }
2066
2002
  ],
2067
2003
  returnType: "EnvironmentProviders",
2068
2004
  statements: functionBody
2069
2005
  });
2070
2006
  }
2071
- pascalCase(str) {
2072
- return str.replace(/(?:^|[-_])([a-z])/g, (_, char) => char.toUpperCase());
2073
- }
2074
2007
  };
2075
2008
 
2076
2009
  // src/lib/core/generator.ts
@@ -2100,7 +2033,7 @@ async function generateFromConfig(config) {
2100
2033
  typeGenerator.generate();
2101
2034
  console.log(`\u2705 TypeScript interfaces generated`);
2102
2035
  if (generateServices) {
2103
- const tokenGenerator = new TokenGenerator(project, config);
2036
+ const tokenGenerator = new TokenGenerator(project);
2104
2037
  tokenGenerator.generate(outputPath);
2105
2038
  if (config.options.dateType === "Date") {
2106
2039
  const dateTransformer = new DateTransformerGenerator(project);
@@ -2133,94 +2066,6 @@ async function generateFromConfig(config) {
2133
2066
  }
2134
2067
  __name(generateFromConfig, "generateFromConfig");
2135
2068
 
2136
- // package.json
2137
- var package_default = {
2138
- name: "ng-openapi",
2139
- version: "0.0.22",
2140
- description: "Generate Angular services and TypeScript types from OpenAPI/Swagger specifications",
2141
- keywords: [
2142
- "angular",
2143
- "openapi",
2144
- "swagger",
2145
- "codegen",
2146
- "typescript",
2147
- "generator",
2148
- "code-generator",
2149
- "api",
2150
- "rest",
2151
- "http",
2152
- "cli"
2153
- ],
2154
- author: {
2155
- name: "Tareq Jami",
2156
- email: "info@jami-it.de",
2157
- url: "http://tareqjami.de"
2158
- },
2159
- license: "MIT",
2160
- homepage: "https://ng-openapi.dev/",
2161
- bugs: {
2162
- url: "https://github.com/ng-openapi/ng-openapi/issues"
2163
- },
2164
- repository: {
2165
- type: "git",
2166
- url: "git+https://github.com/ng-openapi/ng-openapi.git",
2167
- directory: "packages/ng-openapi"
2168
- },
2169
- funding: {
2170
- type: "github",
2171
- url: "https://github.com/sponsors/ng-openapi"
2172
- },
2173
- main: "./index.cjs",
2174
- module: "./index.js",
2175
- types: "./index.d.ts",
2176
- bin: {
2177
- "ng-openapi": "./cli.cjs"
2178
- },
2179
- files: [
2180
- "index.js",
2181
- "index.cjs",
2182
- "index.d.ts",
2183
- "cli.cjs",
2184
- "lib/**/*.js",
2185
- "lib/**/*.cjs",
2186
- "lib/**/*.d.ts",
2187
- "README.md",
2188
- "LICENSE",
2189
- "CHANGELOG.md"
2190
- ],
2191
- scripts: {
2192
- prepublishOnly: "echo 'Build the package using: npm run build:ng-openapi from workspace root'",
2193
- build: "tsup"
2194
- },
2195
- dependencies: {
2196
- commander: "^14.0.0",
2197
- "ts-morph": "^26.0.0",
2198
- "ts-node": "^10.9.2",
2199
- typescript: "^5.8.3",
2200
- "@types/swagger-schema-official": "^2.0.25"
2201
- },
2202
- peerDependencies: {
2203
- "@angular/core": ">=15",
2204
- "@angular/common": ">=15"
2205
- },
2206
- peerDependenciesMeta: {
2207
- "@angular/core": {
2208
- optional: false
2209
- },
2210
- "@angular/common": {
2211
- optional: false
2212
- }
2213
- },
2214
- engines: {
2215
- node: ">=18.0.0",
2216
- npm: ">=8.0.0"
2217
- },
2218
- publishConfig: {
2219
- access: "public",
2220
- registry: "https://registry.npmjs.org/"
2221
- }
2222
- };
2223
-
2224
2069
  // src/lib/cli.ts
2225
2070
  var program = new import_commander.Command();
2226
2071
  async function loadConfigFile(configPath) {
@@ -2247,19 +2092,17 @@ __name(loadConfigFile, "loadConfigFile");
2247
2092
  async function generateFromOptions(options) {
2248
2093
  try {
2249
2094
  if (options.config) {
2250
- const configPaths = Array.isArray(options.config) ? options.config : [
2251
- options.config
2252
- ];
2253
- for (const configPath of configPaths) {
2254
- const config = await loadConfigFile(configPath);
2255
- await generateFromConfig(config);
2256
- console.log(`\u2728 Generated client: ${config.clientName || "default"}`);
2257
- }
2095
+ const config = await loadConfigFile(options.config);
2096
+ await generateFromConfig(config);
2258
2097
  } else if (options.input) {
2098
+ const inputPath = path8.resolve(options.input);
2099
+ if (!fs4.existsSync(inputPath)) {
2100
+ console.error(`Error: Input file not found: ${inputPath}`);
2101
+ process.exit(1);
2102
+ }
2259
2103
  const config = {
2260
- input: path8.resolve(options.input),
2104
+ input: inputPath,
2261
2105
  output: options.output || "./src/generated",
2262
- clientName: options.clientName,
2263
2106
  options: {
2264
2107
  dateType: options.dateType || "Date",
2265
2108
  enumStyle: "enum",
@@ -2273,14 +2116,14 @@ async function generateFromOptions(options) {
2273
2116
  program.help();
2274
2117
  process.exit(1);
2275
2118
  }
2276
- console.log("\u2728 All clients generated successfully!");
2119
+ console.log("\u2728 Generation completed successfully!");
2277
2120
  } catch (error) {
2278
2121
  console.error("\u274C Generation failed:", error instanceof Error ? error.message : error);
2279
2122
  process.exit(1);
2280
2123
  }
2281
2124
  }
2282
2125
  __name(generateFromOptions, "generateFromOptions");
2283
- program.name("ng-openapi").description("Generate Angular services and types from Swagger/OpenAPI spec").version(package_default.version).option("-c, --config <path>", "Path to configuration file").option("-i, --input <path>", "Path to Swagger/OpenAPI specification file").option("-o, --output <path>", "Output directory", "./src/generated").option("--types-only", "Generate only TypeScript interfaces").option("--date-type <type>", "Date type to use (string | Date)", "Date").action(async (options) => {
2126
+ program.name("ng-openapi").description("Generate Angular services and types from Swagger/OpenAPI spec").version("0.0.1").option("-c, --config <path>", "Path to configuration file").option("-i, --input <path>", "Path to Swagger/OpenAPI specification file").option("-o, --output <path>", "Output directory", "./src/generated").option("--types-only", "Generate only TypeScript interfaces").option("--date-type <type>", "Date type to use (string | Date)", "Date").action(async (options) => {
2284
2127
  await generateFromOptions(options);
2285
2128
  });
2286
2129
  program.command("generate").alias("gen").description("Generate code from Swagger specification").option("-c, --config <path>", "Path to configuration file").option("-i, --input <path>", "Path to Swagger/OpenAPI specification file").option("-o, --output <path>", "Output directory", "./src/generated").option("--types-only", "Generate only TypeScript interfaces").option("--date-type <type>", "Date type to use (string | Date)", "Date").action(async (options) => {
@@ -2295,8 +2138,4 @@ program.on("--help", () => {
2295
2138
  console.log(" $ ng-openapi generate -i ./api.yaml --types-only");
2296
2139
  });
2297
2140
  program.parse();
2298
- // Annotate the CommonJS export names for ESM import in node:
2299
- 0 && (module.exports = {
2300
- generateFromOptions
2301
- });
2302
2141
  //# sourceMappingURL=cli.cjs.map
package/index.d.ts CHANGED
@@ -28,7 +28,6 @@ interface TypeSchema {
28
28
  interface GeneratorConfig {
29
29
  input: string;
30
30
  output: string;
31
- clientName?: string;
32
31
  options: {
33
32
  dateType: "string" | "Date";
34
33
  enumStyle: "enum" | "union";
package/index.js CHANGED
@@ -441,11 +441,9 @@ var TypeGenerator = _TypeGenerator;
441
441
  var import_ts_morph2 = require("ts-morph");
442
442
  var path = __toESM(require("path"));
443
443
  var _TokenGenerator = class _TokenGenerator {
444
- constructor(project, config) {
444
+ constructor(project) {
445
445
  __publicField(this, "project");
446
- __publicField(this, "config");
447
446
  this.project = project;
448
- this.config = config;
449
447
  }
450
448
  generate(outputDir) {
451
449
  const tokensDir = path.join(outputDir, "tokens");
@@ -459,55 +457,23 @@ var _TokenGenerator = class _TokenGenerator {
459
457
  ],
460
458
  moduleSpecifier: "@angular/core"
461
459
  });
462
- const clientName = this.config.clientName || "DEFAULT";
463
- const upperCaseClientName = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
464
460
  sourceFile.addVariableStatement({
465
461
  isExported: true,
466
462
  declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
467
463
  declarations: [
468
464
  {
469
- name: `${upperCaseClientName}_BASE_PATH`,
470
- initializer: `new InjectionToken<string>('${upperCaseClientName}_BASE_PATH', {
465
+ name: "BASE_PATH",
466
+ initializer: `new InjectionToken<string>('BASE_PATH', {
471
467
  providedIn: 'root',
472
- factory: () => '/api',
468
+ factory: () => '/api', // Default fallback
473
469
  })`
474
470
  }
475
471
  ],
476
472
  leadingTrivia: `/**
477
- * Base path token for ${clientName} client
478
- */
479
- `
480
- });
481
- sourceFile.addVariableStatement({
482
- isExported: true,
483
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
484
- declarations: [
485
- {
486
- name: `${upperCaseClientName}_HTTP_CLIENT`,
487
- initializer: `new InjectionToken<HttpClient>('${upperCaseClientName}_HTTP_CLIENT')`
488
- }
489
- ],
490
- leadingTrivia: `/**
491
- * HTTP client token for ${clientName} client
473
+ * Injection token for the base API path
492
474
  */
493
475
  `
494
476
  });
495
- if (!this.config.clientName) {
496
- sourceFile.addVariableStatement({
497
- isExported: true,
498
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
499
- declarations: [
500
- {
501
- name: "BASE_PATH",
502
- initializer: `${upperCaseClientName}_BASE_PATH`
503
- }
504
- ],
505
- leadingTrivia: `/**
506
- * @deprecated Use ${upperCaseClientName}_BASE_PATH instead
507
- */
508
- `
509
- });
510
- }
511
477
  sourceFile.saveSync();
512
478
  }
513
479
  };
@@ -1780,9 +1746,6 @@ var _ServiceGenerator = class _ServiceGenerator {
1780
1746
  });
1781
1747
  }
1782
1748
  addImports(sourceFile, usedTypes) {
1783
- var _a;
1784
- const clientName = this.config.clientName || "DEFAULT";
1785
- const upperCaseClientName = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
1786
1749
  sourceFile.addImportDeclarations([
1787
1750
  {
1788
1751
  namedImports: [
@@ -1810,15 +1773,11 @@ var _ServiceGenerator = class _ServiceGenerator {
1810
1773
  },
1811
1774
  {
1812
1775
  namedImports: [
1813
- `${upperCaseClientName}_BASE_PATH`,
1814
- `${upperCaseClientName}_HTTP_CLIENT`
1776
+ "BASE_PATH"
1815
1777
  ],
1816
1778
  moduleSpecifier: "../tokens"
1817
1779
  }
1818
1780
  ]);
1819
- if (!this.config.clientName) {
1820
- (_a = sourceFile.getImportDeclaration("../tokens")) == null ? void 0 : _a.addNamedImport("BASE_PATH");
1821
- }
1822
1781
  if (usedTypes.size > 0) {
1823
1782
  sourceFile.addImportDeclaration({
1824
1783
  namedImports: Array.from(usedTypes).sort(),
@@ -1828,8 +1787,6 @@ var _ServiceGenerator = class _ServiceGenerator {
1828
1787
  }
1829
1788
  addServiceClass(sourceFile, controllerName, operations) {
1830
1789
  const className = `${controllerName}Service`;
1831
- const clientName = this.config.clientName || "DEFAULT";
1832
- const upperCaseClientName = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
1833
1790
  sourceFile.insertText(0, SERVICE_GENERATOR_HEADER_COMMENT(controllerName));
1834
1791
  const serviceClass = sourceFile.addClass({
1835
1792
  name: className,
@@ -1848,14 +1805,14 @@ var _ServiceGenerator = class _ServiceGenerator {
1848
1805
  type: "HttpClient",
1849
1806
  scope: import_ts_morph3.Scope.Private,
1850
1807
  isReadonly: true,
1851
- initializer: `inject(${upperCaseClientName}_HTTP_CLIENT, { optional: true }) ?? inject(HttpClient)`
1808
+ initializer: "inject(HttpClient)"
1852
1809
  });
1853
1810
  serviceClass.addProperty({
1854
1811
  name: "basePath",
1855
1812
  type: "string",
1856
1813
  scope: import_ts_morph3.Scope.Private,
1857
1814
  isReadonly: true,
1858
- initializer: `inject(${upperCaseClientName}_BASE_PATH)`
1815
+ initializer: "inject(BASE_PATH)"
1859
1816
  });
1860
1817
  operations.forEach((operation) => {
1861
1818
  this.methodGenerator.addServiceMethod(serviceClass, operation);
@@ -1917,34 +1874,24 @@ var _ProviderGenerator = class _ProviderGenerator {
1917
1874
  overwrite: true
1918
1875
  });
1919
1876
  sourceFile.insertText(0, PROVIDER_GENERATOR_HEADER_COMMENT);
1920
- const clientName = this.config.clientName || "Default";
1921
- const pascalClientName = this.pascalCase(clientName);
1922
- const upperCaseClientName = clientName.toUpperCase().replace(/[^A-Z0-9]/g, "_");
1923
1877
  sourceFile.addImportDeclarations([
1924
1878
  {
1925
1879
  namedImports: [
1926
1880
  "EnvironmentProviders",
1927
1881
  "Provider",
1928
- "makeEnvironmentProviders",
1929
- "Type",
1930
- "Injector",
1931
- "inject"
1882
+ "makeEnvironmentProviders"
1932
1883
  ],
1933
1884
  moduleSpecifier: "@angular/core"
1934
1885
  },
1935
1886
  {
1936
1887
  namedImports: [
1937
- "HttpClient",
1938
- "HttpInterceptor",
1939
- "HttpHandler",
1940
- "HttpRequest"
1888
+ "HTTP_INTERCEPTORS"
1941
1889
  ],
1942
1890
  moduleSpecifier: "@angular/common/http"
1943
1891
  },
1944
1892
  {
1945
1893
  namedImports: [
1946
- `${upperCaseClientName}_BASE_PATH`,
1947
- `${upperCaseClientName}_HTTP_CLIENT`
1894
+ "BASE_PATH"
1948
1895
  ],
1949
1896
  moduleSpecifier: "./tokens"
1950
1897
  }
@@ -1958,10 +1905,10 @@ var _ProviderGenerator = class _ProviderGenerator {
1958
1905
  });
1959
1906
  }
1960
1907
  sourceFile.addInterface({
1961
- name: `${pascalClientName}Config`,
1908
+ name: "NgOpenapiConfig",
1962
1909
  isExported: true,
1963
1910
  docs: [
1964
- `Configuration options for ${clientName} API client`
1911
+ "Configuration options for ng-openapi providers"
1965
1912
  ],
1966
1913
  properties: [
1967
1914
  {
@@ -1971,14 +1918,6 @@ var _ProviderGenerator = class _ProviderGenerator {
1971
1918
  "Base API URL"
1972
1919
  ]
1973
1920
  },
1974
- {
1975
- name: "interceptors",
1976
- type: "Type<HttpInterceptor>[]",
1977
- hasQuestionToken: true,
1978
- docs: [
1979
- "HTTP interceptors to apply to this client's requests"
1980
- ]
1981
- },
1982
1921
  {
1983
1922
  name: "enableDateTransform",
1984
1923
  type: "boolean",
@@ -1989,102 +1928,105 @@ var _ProviderGenerator = class _ProviderGenerator {
1989
1928
  }
1990
1929
  ]
1991
1930
  });
1992
- this.addInterceptorChainHelper(sourceFile);
1993
- this.addClientProviderFunction(sourceFile, pascalClientName, upperCaseClientName);
1931
+ this.addMainProviderFunction(sourceFile);
1932
+ this.addAsyncProviderFunction(sourceFile);
1994
1933
  sourceFile.saveSync();
1995
1934
  }
1996
- addInterceptorChainHelper(sourceFile) {
1935
+ addMainProviderFunction(sourceFile) {
1936
+ const hasDateInterceptor = this.config.options.dateType === "Date";
1937
+ const functionBody = `
1938
+ const providers: Provider[] = [
1939
+ // Base path token
1940
+ {
1941
+ provide: BASE_PATH,
1942
+ useValue: config.basePath
1943
+ }
1944
+ ];
1945
+
1946
+ ${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
1947
+ if (config.enableDateTransform !== false) {
1948
+ providers.push({
1949
+ provide: HTTP_INTERCEPTORS,
1950
+ useClass: DateInterceptor,
1951
+ multi: true
1952
+ });
1953
+ }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
1954
+
1955
+ return makeEnvironmentProviders(providers);`;
1997
1956
  sourceFile.addFunction({
1998
- name: "createHttpClientWithInterceptors",
1957
+ name: "provideNgOpenapi",
1958
+ isExported: true,
1999
1959
  docs: [
2000
- "Creates an HttpClient with a custom interceptor chain"
1960
+ "Provides all necessary configuration for ng-openapi generated services",
1961
+ "",
1962
+ "@example",
1963
+ "```typescript",
1964
+ "// In your app.config.ts",
1965
+ "import { provideNgOpenapi } from './api/providers';",
1966
+ "",
1967
+ "export const appConfig: ApplicationConfig = {",
1968
+ " providers: [",
1969
+ " provideNgOpenapi({",
1970
+ " basePath: 'https://api.example.com'",
1971
+ " }),",
1972
+ " // other providers...",
1973
+ " ]",
1974
+ "};",
1975
+ "```"
2001
1976
  ],
2002
1977
  parameters: [
2003
1978
  {
2004
- name: "baseClient",
2005
- type: "HttpClient"
2006
- },
2007
- {
2008
- name: "interceptors",
2009
- type: "HttpInterceptor[]"
1979
+ name: "config",
1980
+ type: "NgOpenapiConfig"
2010
1981
  }
2011
1982
  ],
2012
- returnType: "HttpClient",
2013
- statements: `
2014
- if (!interceptors.length) {
2015
- return baseClient;
2016
- }
2017
-
2018
- // Create a custom handler that applies interceptors in sequence
2019
- let handler = baseClient.handler;
2020
-
2021
- // Apply interceptors in reverse order (last interceptor wraps the original handler)
2022
- for (let i = interceptors.length - 1; i >= 0; i--) {
2023
- const currentHandler = handler;
2024
- const interceptor = interceptors[i];
2025
-
2026
- handler = {
2027
- handle: (req: HttpRequest<any>) => interceptor.intercept(req, currentHandler)
2028
- };
2029
- }
2030
-
2031
- // Return a new HttpClient with the custom handler
2032
- return new (baseClient.constructor as any)(handler);`
1983
+ returnType: "EnvironmentProviders",
1984
+ statements: functionBody
2033
1985
  });
2034
1986
  }
2035
- addClientProviderFunction(sourceFile, pascalClientName, upperCaseClientName) {
1987
+ addAsyncProviderFunction(sourceFile) {
2036
1988
  const hasDateInterceptor = this.config.options.dateType === "Date";
2037
1989
  const functionBody = `
2038
- const providers: Provider[] = [
2039
- // Base path token
2040
- {
2041
- provide: ${upperCaseClientName}_BASE_PATH,
1990
+ const providers: Provider[] = [];
1991
+
1992
+ // Handle async base path
1993
+ if (typeof config.basePath === 'string') {
1994
+ providers.push({
1995
+ provide: BASE_PATH,
2042
1996
  useValue: config.basePath
2043
- },
2044
-
2045
- // HTTP client with custom interceptors
2046
- {
2047
- provide: ${upperCaseClientName}_HTTP_CLIENT,
2048
- useFactory: (baseClient: HttpClient, injector: Injector) => {
2049
- const interceptorInstances: HttpInterceptor[] = [];
2050
-
2051
- // Add custom interceptors
2052
- if (config.interceptors?.length) {
2053
- config.interceptors.forEach(interceptorClass => {
2054
- interceptorInstances.push(injector.get(interceptorClass));
2055
- });
2056
- }
2057
-
2058
- ${hasDateInterceptor ? `
2059
- // Add date interceptor if enabled (default: true)
2060
- if (config.enableDateTransform !== false) {
2061
- interceptorInstances.push(injector.get(DateInterceptor));
2062
- }` : ""}
2063
-
2064
- return createHttpClientWithInterceptors(baseClient, interceptorInstances);
2065
- },
2066
- deps: [HttpClient, Injector]
2067
- }
2068
- ];
1997
+ });
1998
+ } else {
1999
+ providers.push({
2000
+ provide: BASE_PATH,
2001
+ useFactory: config.basePath
2002
+ });
2003
+ }
2004
+
2005
+ ${hasDateInterceptor ? `// Add date interceptor if enabled (default: true)
2006
+ if (config.enableDateTransform !== false) {
2007
+ providers.push({
2008
+ provide: HTTP_INTERCEPTORS,
2009
+ useClass: DateInterceptor,
2010
+ multi: true
2011
+ });
2012
+ }` : `// Date transformation not available (dateType: 'string' was used in generation)`}
2069
2013
 
2070
2014
  return makeEnvironmentProviders(providers);`;
2071
2015
  sourceFile.addFunction({
2072
- name: `provide${pascalClientName}`,
2016
+ name: "provideNgOpenapiAsync",
2073
2017
  isExported: true,
2074
2018
  docs: [
2075
- `Provides configuration for ${pascalClientName} API client`,
2019
+ "Alternative function for cases where you need to handle async configuration",
2076
2020
  "",
2077
2021
  "@example",
2078
2022
  "```typescript",
2079
- `// In your app.config.ts`,
2080
- `import { provide${pascalClientName} } from './api/providers';`,
2081
- `import { AuthInterceptor } from './interceptors/auth.interceptor';`,
2023
+ "// In your app.config.ts",
2024
+ "import { provideNgOpenapiAsync } from './api/providers';",
2082
2025
  "",
2083
2026
  "export const appConfig: ApplicationConfig = {",
2084
2027
  " providers: [",
2085
- ` provide${pascalClientName}({`,
2086
- " basePath: 'https://api.example.com',",
2087
- " interceptors: [AuthInterceptor]",
2028
+ " provideNgOpenapiAsync({",
2029
+ " basePath: () => import('./config').then(c => c.apiConfig.baseUrl)",
2088
2030
  " }),",
2089
2031
  " // other providers...",
2090
2032
  " ]",
@@ -2094,16 +2036,16 @@ return makeEnvironmentProviders(providers);`;
2094
2036
  parameters: [
2095
2037
  {
2096
2038
  name: "config",
2097
- type: `${pascalClientName}Config`
2039
+ type: `{
2040
+ basePath: string | (() => Promise<string>);
2041
+ enableDateTransform?: boolean;
2042
+ }`
2098
2043
  }
2099
2044
  ],
2100
2045
  returnType: "EnvironmentProviders",
2101
2046
  statements: functionBody
2102
2047
  });
2103
2048
  }
2104
- pascalCase(str) {
2105
- return str.replace(/(?:^|[-_])([a-z])/g, (_, char) => char.toUpperCase());
2106
- }
2107
2049
  };
2108
2050
  __name(_ProviderGenerator, "ProviderGenerator");
2109
2051
  var ProviderGenerator = _ProviderGenerator;
@@ -2136,7 +2078,7 @@ function generateFromConfig(config) {
2136
2078
  typeGenerator.generate();
2137
2079
  console.log(`\u2705 TypeScript interfaces generated`);
2138
2080
  if (generateServices) {
2139
- const tokenGenerator = new TokenGenerator(project, config);
2081
+ const tokenGenerator = new TokenGenerator(project);
2140
2082
  tokenGenerator.generate(outputPath);
2141
2083
  if (config.options.dateType === "Date") {
2142
2084
  const dateTransformer = new DateTransformerGenerator(project);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ng-openapi",
3
- "version": "0.0.23",
3
+ "version": "0.0.24",
4
4
  "description": "Generate Angular services and TypeScript types from OpenAPI/Swagger specifications",
5
5
  "keywords": [
6
6
  "angular",