ng-openapi 0.0.24-rc.0 → 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 +104 -263
  2. package/index.d.ts +0 -1
  3. package/index.js +94 -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,35 +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
- "InjectionToken"
1840
+ "makeEnvironmentProviders"
1899
1841
  ],
1900
1842
  moduleSpecifier: "@angular/core"
1901
1843
  },
1902
1844
  {
1903
1845
  namedImports: [
1904
- "HttpClient",
1905
- "HttpInterceptor",
1906
- "HttpHandler",
1907
- "HttpBackend",
1908
1846
  "HTTP_INTERCEPTORS"
1909
1847
  ],
1910
1848
  moduleSpecifier: "@angular/common/http"
1911
1849
  },
1912
1850
  {
1913
1851
  namedImports: [
1914
- `${upperCaseClientName}_BASE_PATH`,
1915
- `${upperCaseClientName}_HTTP_CLIENT`
1852
+ "BASE_PATH"
1916
1853
  ],
1917
1854
  moduleSpecifier: "./tokens"
1918
1855
  }
@@ -1926,10 +1863,10 @@ var ProviderGenerator = class {
1926
1863
  });
1927
1864
  }
1928
1865
  sourceFile.addInterface({
1929
- name: `${pascalClientName}Config`,
1866
+ name: "NgOpenapiConfig",
1930
1867
  isExported: true,
1931
1868
  docs: [
1932
- `Configuration options for ${clientName} API client`
1869
+ "Configuration options for ng-openapi providers"
1933
1870
  ],
1934
1871
  properties: [
1935
1872
  {
@@ -1939,14 +1876,6 @@ var ProviderGenerator = class {
1939
1876
  "Base API URL"
1940
1877
  ]
1941
1878
  },
1942
- {
1943
- name: "interceptors",
1944
- type: "Type<HttpInterceptor>[]",
1945
- hasQuestionToken: true,
1946
- docs: [
1947
- "HTTP interceptors to apply to this client's requests"
1948
- ]
1949
- },
1950
1879
  {
1951
1880
  name: "enableDateTransform",
1952
1881
  type: "boolean",
@@ -1957,99 +1886,46 @@ var ProviderGenerator = class {
1957
1886
  }
1958
1887
  ]
1959
1888
  });
1960
- sourceFile.addVariableStatement({
1961
- isExported: true,
1962
- declarationKind: "const",
1963
- declarations: [
1964
- {
1965
- name: `${upperCaseClientName}_INTERCEPTORS`,
1966
- initializer: `new InjectionToken<HttpInterceptor[]>('${upperCaseClientName}_INTERCEPTORS')`
1967
- }
1968
- ],
1969
- leadingTrivia: `/**
1970
- * Interceptor token for ${clientName} client
1971
- */
1972
- `
1973
- });
1974
- this.addSimpleProviderFunction(sourceFile, pascalClientName, upperCaseClientName);
1889
+ this.addMainProviderFunction(sourceFile);
1890
+ this.addAsyncProviderFunction(sourceFile);
1975
1891
  sourceFile.saveSync();
1976
1892
  }
1977
- addSimpleProviderFunction(sourceFile, pascalClientName, upperCaseClientName) {
1893
+ addMainProviderFunction(sourceFile) {
1978
1894
  const hasDateInterceptor = this.config.options.dateType === "Date";
1979
1895
  const functionBody = `
1980
1896
  const providers: Provider[] = [
1981
1897
  // Base path token
1982
1898
  {
1983
- provide: ${upperCaseClientName}_BASE_PATH,
1899
+ provide: BASE_PATH,
1984
1900
  useValue: config.basePath
1985
- },
1986
-
1987
- // Collect interceptors for this client
1988
- {
1989
- provide: ${upperCaseClientName}_INTERCEPTORS,
1990
- useFactory: (injector: Injector) => {
1991
- const interceptorInstances: HttpInterceptor[] = [];
1992
-
1993
- // Add custom interceptors
1994
- if (config.interceptors?.length) {
1995
- config.interceptors.forEach(interceptorClass => {
1996
- interceptorInstances.push(injector.get(interceptorClass));
1997
- });
1998
- }
1999
-
2000
- ${hasDateInterceptor ? `
2001
- // Add date interceptor if enabled (default: true)
2002
- if (config.enableDateTransform !== false) {
2003
- interceptorInstances.push(injector.get(DateInterceptor));
2004
- }` : ""}
2005
-
2006
- return interceptorInstances;
2007
- },
2008
- deps: [Injector]
2009
- },
2010
-
2011
- // Create HTTP client with interceptors
2012
- {
2013
- provide: ${upperCaseClientName}_HTTP_CLIENT,
2014
- useFactory: (backend: HttpBackend, interceptors: HttpInterceptor[]) => {
2015
- if (!interceptors.length) {
2016
- return new HttpClient(backend);
2017
- }
2018
-
2019
- // Create handler chain
2020
- let handler = backend;
2021
- for (let i = interceptors.length - 1; i >= 0; i--) {
2022
- const interceptor = interceptors[i];
2023
- const currentHandler = handler;
2024
- handler = {
2025
- handle: req => interceptor.intercept(req, currentHandler)
2026
- };
2027
- }
2028
-
2029
- return new HttpClient(handler);
2030
- },
2031
- deps: [HttpBackend, ${upperCaseClientName}_INTERCEPTORS]
2032
1901
  }
2033
1902
  ];
2034
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
+
2035
1913
  return makeEnvironmentProviders(providers);`;
2036
1914
  sourceFile.addFunction({
2037
- name: `provide${pascalClientName}`,
1915
+ name: "provideNgOpenapi",
2038
1916
  isExported: true,
2039
1917
  docs: [
2040
- `Provides configuration for ${pascalClientName} API client`,
1918
+ "Provides all necessary configuration for ng-openapi generated services",
2041
1919
  "",
2042
1920
  "@example",
2043
1921
  "```typescript",
2044
- `// In your app.config.ts`,
2045
- `import { provide${pascalClientName} } from './api/providers';`,
2046
- `import { AuthInterceptor } from './interceptors/auth.interceptor';`,
1922
+ "// In your app.config.ts",
1923
+ "import { provideNgOpenapi } from './api/providers';",
2047
1924
  "",
2048
1925
  "export const appConfig: ApplicationConfig = {",
2049
1926
  " providers: [",
2050
- ` provide${pascalClientName}({`,
2051
- " basePath: 'https://api.example.com',",
2052
- " interceptors: [AuthInterceptor]",
1927
+ " provideNgOpenapi({",
1928
+ " basePath: 'https://api.example.com'",
2053
1929
  " }),",
2054
1930
  " // other providers...",
2055
1931
  " ]",
@@ -2059,15 +1935,74 @@ return makeEnvironmentProviders(providers);`;
2059
1935
  parameters: [
2060
1936
  {
2061
1937
  name: "config",
2062
- type: `${pascalClientName}Config`
1938
+ type: "NgOpenapiConfig"
2063
1939
  }
2064
1940
  ],
2065
1941
  returnType: "EnvironmentProviders",
2066
1942
  statements: functionBody
2067
1943
  });
2068
1944
  }
2069
- pascalCase(str) {
2070
- return str.replace(/(?:^|[-_])([a-z])/g, (_, char) => char.toUpperCase());
1945
+ addAsyncProviderFunction(sourceFile) {
1946
+ const hasDateInterceptor = this.config.options.dateType === "Date";
1947
+ const functionBody = `
1948
+ const providers: Provider[] = [];
1949
+
1950
+ // Handle async base path
1951
+ if (typeof config.basePath === 'string') {
1952
+ providers.push({
1953
+ provide: BASE_PATH,
1954
+ useValue: config.basePath
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)`}
1971
+
1972
+ return makeEnvironmentProviders(providers);`;
1973
+ sourceFile.addFunction({
1974
+ name: "provideNgOpenapiAsync",
1975
+ isExported: true,
1976
+ docs: [
1977
+ "Alternative function for cases where you need to handle async configuration",
1978
+ "",
1979
+ "@example",
1980
+ "```typescript",
1981
+ "// In your app.config.ts",
1982
+ "import { provideNgOpenapiAsync } from './api/providers';",
1983
+ "",
1984
+ "export const appConfig: ApplicationConfig = {",
1985
+ " providers: [",
1986
+ " provideNgOpenapiAsync({",
1987
+ " basePath: () => import('./config').then(c => c.apiConfig.baseUrl)",
1988
+ " }),",
1989
+ " // other providers...",
1990
+ " ]",
1991
+ "};",
1992
+ "```"
1993
+ ],
1994
+ parameters: [
1995
+ {
1996
+ name: "config",
1997
+ type: `{
1998
+ basePath: string | (() => Promise<string>);
1999
+ enableDateTransform?: boolean;
2000
+ }`
2001
+ }
2002
+ ],
2003
+ returnType: "EnvironmentProviders",
2004
+ statements: functionBody
2005
+ });
2071
2006
  }
2072
2007
  };
2073
2008
 
@@ -2098,7 +2033,7 @@ async function generateFromConfig(config) {
2098
2033
  typeGenerator.generate();
2099
2034
  console.log(`\u2705 TypeScript interfaces generated`);
2100
2035
  if (generateServices) {
2101
- const tokenGenerator = new TokenGenerator(project, config);
2036
+ const tokenGenerator = new TokenGenerator(project);
2102
2037
  tokenGenerator.generate(outputPath);
2103
2038
  if (config.options.dateType === "Date") {
2104
2039
  const dateTransformer = new DateTransformerGenerator(project);
@@ -2131,94 +2066,6 @@ async function generateFromConfig(config) {
2131
2066
  }
2132
2067
  __name(generateFromConfig, "generateFromConfig");
2133
2068
 
2134
- // package.json
2135
- var package_default = {
2136
- name: "ng-openapi",
2137
- version: "0.0.23",
2138
- description: "Generate Angular services and TypeScript types from OpenAPI/Swagger specifications",
2139
- keywords: [
2140
- "angular",
2141
- "openapi",
2142
- "swagger",
2143
- "codegen",
2144
- "typescript",
2145
- "generator",
2146
- "code-generator",
2147
- "api",
2148
- "rest",
2149
- "http",
2150
- "cli"
2151
- ],
2152
- author: {
2153
- name: "Tareq Jami",
2154
- email: "info@jami-it.de",
2155
- url: "http://tareqjami.de"
2156
- },
2157
- license: "MIT",
2158
- homepage: "https://ng-openapi.dev/",
2159
- bugs: {
2160
- url: "https://github.com/ng-openapi/ng-openapi/issues"
2161
- },
2162
- repository: {
2163
- type: "git",
2164
- url: "git+https://github.com/ng-openapi/ng-openapi.git",
2165
- directory: "packages/ng-openapi"
2166
- },
2167
- funding: {
2168
- type: "github",
2169
- url: "https://github.com/sponsors/ng-openapi"
2170
- },
2171
- main: "./index.cjs",
2172
- module: "./index.js",
2173
- types: "./index.d.ts",
2174
- bin: {
2175
- "ng-openapi": "./cli.cjs"
2176
- },
2177
- files: [
2178
- "index.js",
2179
- "index.cjs",
2180
- "index.d.ts",
2181
- "cli.cjs",
2182
- "lib/**/*.js",
2183
- "lib/**/*.cjs",
2184
- "lib/**/*.d.ts",
2185
- "README.md",
2186
- "LICENSE",
2187
- "CHANGELOG.md"
2188
- ],
2189
- scripts: {
2190
- prepublishOnly: "echo 'Build the package using: npm run build:ng-openapi from workspace root'",
2191
- build: "tsup"
2192
- },
2193
- dependencies: {
2194
- commander: "^14.0.0",
2195
- "ts-morph": "^26.0.0",
2196
- "ts-node": "^10.9.2",
2197
- typescript: "^5.8.3",
2198
- "@types/swagger-schema-official": "^2.0.25"
2199
- },
2200
- peerDependencies: {
2201
- "@angular/core": ">=15",
2202
- "@angular/common": ">=15"
2203
- },
2204
- peerDependenciesMeta: {
2205
- "@angular/core": {
2206
- optional: false
2207
- },
2208
- "@angular/common": {
2209
- optional: false
2210
- }
2211
- },
2212
- engines: {
2213
- node: ">=18.0.0",
2214
- npm: ">=8.0.0"
2215
- },
2216
- publishConfig: {
2217
- access: "public",
2218
- registry: "https://registry.npmjs.org/"
2219
- }
2220
- };
2221
-
2222
2069
  // src/lib/cli.ts
2223
2070
  var program = new import_commander.Command();
2224
2071
  async function loadConfigFile(configPath) {
@@ -2245,19 +2092,17 @@ __name(loadConfigFile, "loadConfigFile");
2245
2092
  async function generateFromOptions(options) {
2246
2093
  try {
2247
2094
  if (options.config) {
2248
- const configPaths = Array.isArray(options.config) ? options.config : [
2249
- options.config
2250
- ];
2251
- for (const configPath of configPaths) {
2252
- const config = await loadConfigFile(configPath);
2253
- await generateFromConfig(config);
2254
- console.log(`\u2728 Generated client: ${config.clientName || "default"}`);
2255
- }
2095
+ const config = await loadConfigFile(options.config);
2096
+ await generateFromConfig(config);
2256
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
+ }
2257
2103
  const config = {
2258
- input: path8.resolve(options.input),
2104
+ input: inputPath,
2259
2105
  output: options.output || "./src/generated",
2260
- clientName: options.clientName,
2261
2106
  options: {
2262
2107
  dateType: options.dateType || "Date",
2263
2108
  enumStyle: "enum",
@@ -2271,14 +2116,14 @@ async function generateFromOptions(options) {
2271
2116
  program.help();
2272
2117
  process.exit(1);
2273
2118
  }
2274
- console.log("\u2728 All clients generated successfully!");
2119
+ console.log("\u2728 Generation completed successfully!");
2275
2120
  } catch (error) {
2276
2121
  console.error("\u274C Generation failed:", error instanceof Error ? error.message : error);
2277
2122
  process.exit(1);
2278
2123
  }
2279
2124
  }
2280
2125
  __name(generateFromOptions, "generateFromOptions");
2281
- 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) => {
2282
2127
  await generateFromOptions(options);
2283
2128
  });
2284
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) => {
@@ -2293,8 +2138,4 @@ program.on("--help", () => {
2293
2138
  console.log(" $ ng-openapi generate -i ./api.yaml --types-only");
2294
2139
  });
2295
2140
  program.parse();
2296
- // Annotate the CommonJS export names for ESM import in node:
2297
- 0 && (module.exports = {
2298
- generateFromOptions
2299
- });
2300
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,35 +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
- "InjectionToken"
1882
+ "makeEnvironmentProviders"
1932
1883
  ],
1933
1884
  moduleSpecifier: "@angular/core"
1934
1885
  },
1935
1886
  {
1936
1887
  namedImports: [
1937
- "HttpClient",
1938
- "HttpInterceptor",
1939
- "HttpHandler",
1940
- "HttpBackend",
1941
1888
  "HTTP_INTERCEPTORS"
1942
1889
  ],
1943
1890
  moduleSpecifier: "@angular/common/http"
1944
1891
  },
1945
1892
  {
1946
1893
  namedImports: [
1947
- `${upperCaseClientName}_BASE_PATH`,
1948
- `${upperCaseClientName}_HTTP_CLIENT`
1894
+ "BASE_PATH"
1949
1895
  ],
1950
1896
  moduleSpecifier: "./tokens"
1951
1897
  }
@@ -1959,10 +1905,10 @@ var _ProviderGenerator = class _ProviderGenerator {
1959
1905
  });
1960
1906
  }
1961
1907
  sourceFile.addInterface({
1962
- name: `${pascalClientName}Config`,
1908
+ name: "NgOpenapiConfig",
1963
1909
  isExported: true,
1964
1910
  docs: [
1965
- `Configuration options for ${clientName} API client`
1911
+ "Configuration options for ng-openapi providers"
1966
1912
  ],
1967
1913
  properties: [
1968
1914
  {
@@ -1972,14 +1918,6 @@ var _ProviderGenerator = class _ProviderGenerator {
1972
1918
  "Base API URL"
1973
1919
  ]
1974
1920
  },
1975
- {
1976
- name: "interceptors",
1977
- type: "Type<HttpInterceptor>[]",
1978
- hasQuestionToken: true,
1979
- docs: [
1980
- "HTTP interceptors to apply to this client's requests"
1981
- ]
1982
- },
1983
1921
  {
1984
1922
  name: "enableDateTransform",
1985
1923
  type: "boolean",
@@ -1990,99 +1928,46 @@ var _ProviderGenerator = class _ProviderGenerator {
1990
1928
  }
1991
1929
  ]
1992
1930
  });
1993
- sourceFile.addVariableStatement({
1994
- isExported: true,
1995
- declarationKind: "const",
1996
- declarations: [
1997
- {
1998
- name: `${upperCaseClientName}_INTERCEPTORS`,
1999
- initializer: `new InjectionToken<HttpInterceptor[]>('${upperCaseClientName}_INTERCEPTORS')`
2000
- }
2001
- ],
2002
- leadingTrivia: `/**
2003
- * Interceptor token for ${clientName} client
2004
- */
2005
- `
2006
- });
2007
- this.addSimpleProviderFunction(sourceFile, pascalClientName, upperCaseClientName);
1931
+ this.addMainProviderFunction(sourceFile);
1932
+ this.addAsyncProviderFunction(sourceFile);
2008
1933
  sourceFile.saveSync();
2009
1934
  }
2010
- addSimpleProviderFunction(sourceFile, pascalClientName, upperCaseClientName) {
1935
+ addMainProviderFunction(sourceFile) {
2011
1936
  const hasDateInterceptor = this.config.options.dateType === "Date";
2012
1937
  const functionBody = `
2013
1938
  const providers: Provider[] = [
2014
1939
  // Base path token
2015
1940
  {
2016
- provide: ${upperCaseClientName}_BASE_PATH,
1941
+ provide: BASE_PATH,
2017
1942
  useValue: config.basePath
2018
- },
2019
-
2020
- // Collect interceptors for this client
2021
- {
2022
- provide: ${upperCaseClientName}_INTERCEPTORS,
2023
- useFactory: (injector: Injector) => {
2024
- const interceptorInstances: HttpInterceptor[] = [];
2025
-
2026
- // Add custom interceptors
2027
- if (config.interceptors?.length) {
2028
- config.interceptors.forEach(interceptorClass => {
2029
- interceptorInstances.push(injector.get(interceptorClass));
2030
- });
2031
- }
2032
-
2033
- ${hasDateInterceptor ? `
2034
- // Add date interceptor if enabled (default: true)
2035
- if (config.enableDateTransform !== false) {
2036
- interceptorInstances.push(injector.get(DateInterceptor));
2037
- }` : ""}
2038
-
2039
- return interceptorInstances;
2040
- },
2041
- deps: [Injector]
2042
- },
2043
-
2044
- // Create HTTP client with interceptors
2045
- {
2046
- provide: ${upperCaseClientName}_HTTP_CLIENT,
2047
- useFactory: (backend: HttpBackend, interceptors: HttpInterceptor[]) => {
2048
- if (!interceptors.length) {
2049
- return new HttpClient(backend);
2050
- }
2051
-
2052
- // Create handler chain
2053
- let handler = backend;
2054
- for (let i = interceptors.length - 1; i >= 0; i--) {
2055
- const interceptor = interceptors[i];
2056
- const currentHandler = handler;
2057
- handler = {
2058
- handle: req => interceptor.intercept(req, currentHandler)
2059
- };
2060
- }
2061
-
2062
- return new HttpClient(handler);
2063
- },
2064
- deps: [HttpBackend, ${upperCaseClientName}_INTERCEPTORS]
2065
1943
  }
2066
1944
  ];
2067
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
+
2068
1955
  return makeEnvironmentProviders(providers);`;
2069
1956
  sourceFile.addFunction({
2070
- name: `provide${pascalClientName}`,
1957
+ name: "provideNgOpenapi",
2071
1958
  isExported: true,
2072
1959
  docs: [
2073
- `Provides configuration for ${pascalClientName} API client`,
1960
+ "Provides all necessary configuration for ng-openapi generated services",
2074
1961
  "",
2075
1962
  "@example",
2076
1963
  "```typescript",
2077
- `// In your app.config.ts`,
2078
- `import { provide${pascalClientName} } from './api/providers';`,
2079
- `import { AuthInterceptor } from './interceptors/auth.interceptor';`,
1964
+ "// In your app.config.ts",
1965
+ "import { provideNgOpenapi } from './api/providers';",
2080
1966
  "",
2081
1967
  "export const appConfig: ApplicationConfig = {",
2082
1968
  " providers: [",
2083
- ` provide${pascalClientName}({`,
2084
- " basePath: 'https://api.example.com',",
2085
- " interceptors: [AuthInterceptor]",
1969
+ " provideNgOpenapi({",
1970
+ " basePath: 'https://api.example.com'",
2086
1971
  " }),",
2087
1972
  " // other providers...",
2088
1973
  " ]",
@@ -2092,15 +1977,74 @@ return makeEnvironmentProviders(providers);`;
2092
1977
  parameters: [
2093
1978
  {
2094
1979
  name: "config",
2095
- type: `${pascalClientName}Config`
1980
+ type: "NgOpenapiConfig"
2096
1981
  }
2097
1982
  ],
2098
1983
  returnType: "EnvironmentProviders",
2099
1984
  statements: functionBody
2100
1985
  });
2101
1986
  }
2102
- pascalCase(str) {
2103
- return str.replace(/(?:^|[-_])([a-z])/g, (_, char) => char.toUpperCase());
1987
+ addAsyncProviderFunction(sourceFile) {
1988
+ const hasDateInterceptor = this.config.options.dateType === "Date";
1989
+ const functionBody = `
1990
+ const providers: Provider[] = [];
1991
+
1992
+ // Handle async base path
1993
+ if (typeof config.basePath === 'string') {
1994
+ providers.push({
1995
+ provide: BASE_PATH,
1996
+ useValue: config.basePath
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)`}
2013
+
2014
+ return makeEnvironmentProviders(providers);`;
2015
+ sourceFile.addFunction({
2016
+ name: "provideNgOpenapiAsync",
2017
+ isExported: true,
2018
+ docs: [
2019
+ "Alternative function for cases where you need to handle async configuration",
2020
+ "",
2021
+ "@example",
2022
+ "```typescript",
2023
+ "// In your app.config.ts",
2024
+ "import { provideNgOpenapiAsync } from './api/providers';",
2025
+ "",
2026
+ "export const appConfig: ApplicationConfig = {",
2027
+ " providers: [",
2028
+ " provideNgOpenapiAsync({",
2029
+ " basePath: () => import('./config').then(c => c.apiConfig.baseUrl)",
2030
+ " }),",
2031
+ " // other providers...",
2032
+ " ]",
2033
+ "};",
2034
+ "```"
2035
+ ],
2036
+ parameters: [
2037
+ {
2038
+ name: "config",
2039
+ type: `{
2040
+ basePath: string | (() => Promise<string>);
2041
+ enableDateTransform?: boolean;
2042
+ }`
2043
+ }
2044
+ ],
2045
+ returnType: "EnvironmentProviders",
2046
+ statements: functionBody
2047
+ });
2104
2048
  }
2105
2049
  };
2106
2050
  __name(_ProviderGenerator, "ProviderGenerator");
@@ -2134,7 +2078,7 @@ function generateFromConfig(config) {
2134
2078
  typeGenerator.generate();
2135
2079
  console.log(`\u2705 TypeScript interfaces generated`);
2136
2080
  if (generateServices) {
2137
- const tokenGenerator = new TokenGenerator(project, config);
2081
+ const tokenGenerator = new TokenGenerator(project);
2138
2082
  tokenGenerator.generate(outputPath);
2139
2083
  if (config.options.dateType === "Date") {
2140
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.24-rc.0",
3
+ "version": "0.0.24",
4
4
  "description": "Generate Angular services and TypeScript types from OpenAPI/Swagger specifications",
5
5
  "keywords": [
6
6
  "angular",