ng-openapi 0.1.12 → 0.1.13-pr-22-http-params-builder-e72d48f.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/cli.cjs +252 -34
  2. package/index.js +243 -26
  3. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -41,13 +41,13 @@ __name(isUrl, "isUrl");
41
41
  // src/lib/cli.ts
42
42
  var import_commander = require("commander");
43
43
  var fs4 = __toESM(require("fs"));
44
- var path11 = __toESM(require("path"));
44
+ var path12 = __toESM(require("path"));
45
45
 
46
46
  // package.json
47
- var version = "0.1.11";
47
+ var version = "0.1.12";
48
48
 
49
49
  // src/lib/core/generator.ts
50
- var import_ts_morph6 = require("ts-morph");
50
+ var import_ts_morph7 = require("ts-morph");
51
51
 
52
52
  // src/lib/generators/type/type.generator.ts
53
53
  var import_ts_morph = require("ts-morph");
@@ -229,12 +229,12 @@ function extractPaths(swaggerPaths = {}, methods = [
229
229
  "head"
230
230
  ]) {
231
231
  const paths = [];
232
- Object.entries(swaggerPaths).forEach(([path12, pathItem]) => {
232
+ Object.entries(swaggerPaths).forEach(([path13, pathItem]) => {
233
233
  methods.forEach((method) => {
234
234
  if (pathItem[method]) {
235
235
  const operation = pathItem[method];
236
236
  paths.push({
237
- path: path12,
237
+ path: path13,
238
238
  method: method.toUpperCase(),
239
239
  operationId: operation.operationId,
240
240
  summary: operation.summary,
@@ -1796,9 +1796,219 @@ var BaseInterceptorGenerator = class {
1796
1796
  }
1797
1797
  };
1798
1798
 
1799
- // src/lib/generators/service/service.generator.ts
1800
- var import_ts_morph5 = require("ts-morph");
1799
+ // src/lib/generators/utility/http-params-builder.generator.ts
1801
1800
  var path8 = __toESM(require("path"));
1801
+ var import_ts_morph5 = require("ts-morph");
1802
+ var HttpParamsBuilderGenerator = class {
1803
+ static {
1804
+ __name(this, "HttpParamsBuilderGenerator");
1805
+ }
1806
+ project;
1807
+ constructor(project) {
1808
+ this.project = project;
1809
+ }
1810
+ generate(outputDir) {
1811
+ const utilsDir = path8.join(outputDir, "utils");
1812
+ const filePath = path8.join(utilsDir, "http-params-builder.ts");
1813
+ const sourceFile = this.project.createSourceFile(filePath, "", {
1814
+ overwrite: true
1815
+ });
1816
+ sourceFile.addImportDeclaration({
1817
+ namedImports: [
1818
+ "HttpParams"
1819
+ ],
1820
+ moduleSpecifier: "@angular/common/http"
1821
+ });
1822
+ const classDeclaration = sourceFile.addClass({
1823
+ name: "HttpParamsBuilder",
1824
+ isExported: true
1825
+ });
1826
+ this.addMethods(classDeclaration);
1827
+ sourceFile.formatText();
1828
+ sourceFile.saveSync();
1829
+ }
1830
+ addMethods(classDeclaration) {
1831
+ const methods = [
1832
+ {
1833
+ name: "addToHttpParams",
1834
+ isStatic: true,
1835
+ scope: import_ts_morph5.Scope.Public,
1836
+ parameters: [
1837
+ {
1838
+ name: "httpParams",
1839
+ type: "HttpParams"
1840
+ },
1841
+ {
1842
+ name: "value",
1843
+ type: "any"
1844
+ },
1845
+ {
1846
+ name: "key",
1847
+ type: "string",
1848
+ hasQuestionToken: true
1849
+ }
1850
+ ],
1851
+ returnType: "HttpParams",
1852
+ docs: [
1853
+ "Adds a value to HttpParams. Delegates to recursive handler for objects/arrays."
1854
+ ],
1855
+ statements: `const isDate = value instanceof Date;
1856
+ const isObject = typeof value === "object" && !isDate;
1857
+
1858
+ if (isObject) {
1859
+ return this.addToHttpParamsRecursive(httpParams, value);
1860
+ }
1861
+
1862
+ return this.addToHttpParamsRecursive(httpParams, value, key);`
1863
+ },
1864
+ {
1865
+ name: "addToHttpParamsRecursive",
1866
+ isStatic: true,
1867
+ scope: import_ts_morph5.Scope.Private,
1868
+ parameters: [
1869
+ {
1870
+ name: "httpParams",
1871
+ type: "HttpParams"
1872
+ },
1873
+ {
1874
+ name: "value",
1875
+ type: "any",
1876
+ hasQuestionToken: true
1877
+ },
1878
+ {
1879
+ name: "key",
1880
+ type: "string",
1881
+ hasQuestionToken: true
1882
+ }
1883
+ ],
1884
+ returnType: "HttpParams",
1885
+ statements: `if (value == null) {
1886
+ return httpParams;
1887
+ }
1888
+
1889
+ if (Array.isArray(value)) {
1890
+ return this.handleArray(httpParams, value, key);
1891
+ }
1892
+
1893
+ if (value instanceof Date) {
1894
+ return this.handleDate(httpParams, value, key);
1895
+ }
1896
+
1897
+ if (typeof value === "object") {
1898
+ return this.handleObject(httpParams, value, key);
1899
+ }
1900
+
1901
+ return this.handlePrimitive(httpParams, value, key);`
1902
+ },
1903
+ {
1904
+ name: "handleArray",
1905
+ isStatic: true,
1906
+ scope: import_ts_morph5.Scope.Private,
1907
+ parameters: [
1908
+ {
1909
+ name: "httpParams",
1910
+ type: "HttpParams"
1911
+ },
1912
+ {
1913
+ name: "arr",
1914
+ type: "unknown[]"
1915
+ },
1916
+ {
1917
+ name: "key",
1918
+ type: "string",
1919
+ hasQuestionToken: true
1920
+ }
1921
+ ],
1922
+ returnType: "HttpParams",
1923
+ statements: `arr.forEach((element) => {
1924
+ httpParams = this.addToHttpParamsRecursive(httpParams, element, key);
1925
+ });
1926
+ return httpParams;`
1927
+ },
1928
+ {
1929
+ name: "handleDate",
1930
+ isStatic: true,
1931
+ scope: import_ts_morph5.Scope.Private,
1932
+ parameters: [
1933
+ {
1934
+ name: "httpParams",
1935
+ type: "HttpParams"
1936
+ },
1937
+ {
1938
+ name: "date",
1939
+ type: "Date"
1940
+ },
1941
+ {
1942
+ name: "key",
1943
+ type: "string",
1944
+ hasQuestionToken: true
1945
+ }
1946
+ ],
1947
+ returnType: "HttpParams",
1948
+ statements: `if (!key) {
1949
+ throw new Error("key may not be null if value is Date");
1950
+ }
1951
+ return httpParams.append(key, date.toISOString().substring(0, 10));`
1952
+ },
1953
+ {
1954
+ name: "handleObject",
1955
+ isStatic: true,
1956
+ scope: import_ts_morph5.Scope.Private,
1957
+ parameters: [
1958
+ {
1959
+ name: "httpParams",
1960
+ type: "HttpParams"
1961
+ },
1962
+ {
1963
+ name: "obj",
1964
+ type: "Record<string, any>"
1965
+ },
1966
+ {
1967
+ name: "key",
1968
+ type: "string",
1969
+ hasQuestionToken: true
1970
+ }
1971
+ ],
1972
+ returnType: "HttpParams",
1973
+ statements: `Object.keys(obj).forEach((prop) => {
1974
+ const nestedKey = key ? \`\${key}.\${prop}\` : prop;
1975
+ httpParams = this.addToHttpParamsRecursive(httpParams, obj[prop], nestedKey);
1976
+ });
1977
+ return httpParams;`
1978
+ },
1979
+ {
1980
+ name: "handlePrimitive",
1981
+ isStatic: true,
1982
+ scope: import_ts_morph5.Scope.Private,
1983
+ parameters: [
1984
+ {
1985
+ name: "httpParams",
1986
+ type: "HttpParams"
1987
+ },
1988
+ {
1989
+ name: "value",
1990
+ type: "string | number | boolean"
1991
+ },
1992
+ {
1993
+ name: "key",
1994
+ type: "string",
1995
+ hasQuestionToken: true
1996
+ }
1997
+ ],
1998
+ returnType: "HttpParams",
1999
+ statements: `if (!key) {
2000
+ throw new Error("key may not be null if value is primitive");
2001
+ }
2002
+ return httpParams.append(key, value);`
2003
+ }
2004
+ ];
2005
+ classDeclaration.addMethods(methods);
2006
+ }
2007
+ };
2008
+
2009
+ // src/lib/generators/service/service.generator.ts
2010
+ var import_ts_morph6 = require("ts-morph");
2011
+ var path9 = __toESM(require("path"));
1802
2012
 
1803
2013
  // src/lib/generators/service/service-method/service-method-body.generator.ts
1804
2014
  var ServiceMethodBodyGenerator = class {
@@ -1854,8 +2064,8 @@ var ServiceMethodBodyGenerator = class {
1854
2064
  if (context.queryParams.length === 0) {
1855
2065
  return "";
1856
2066
  }
1857
- const paramMappings = context.queryParams.map((param) => `if (${param.name} !== undefined) {
1858
- params = params.set('${param.name}', String(${param.name}));
2067
+ const paramMappings = context.queryParams.map((param) => `if (${param.name} != null) {
2068
+ params = HttpParamsBuilder.addToHttpParams(params, ${param.name}, '${param.name}');
1859
2069
  }`).join("\n");
1860
2070
  return `
1861
2071
  let params = new HttpParams();
@@ -2268,7 +2478,7 @@ var ServiceGenerator = class {
2268
2478
  this.methodGenerator = new ServiceMethodGenerator(config);
2269
2479
  }
2270
2480
  async generate(outputRoot) {
2271
- const outputDir = path8.join(outputRoot, "services");
2481
+ const outputDir = path9.join(outputRoot, "services");
2272
2482
  const paths = extractPaths(this.spec.paths);
2273
2483
  if (paths.length === 0) {
2274
2484
  console.warn("No API paths found in the specification");
@@ -2279,12 +2489,12 @@ var ServiceGenerator = class {
2279
2489
  }
2280
2490
  groupPathsByController(paths) {
2281
2491
  const groups = {};
2282
- paths.forEach((path12) => {
2492
+ paths.forEach((path13) => {
2283
2493
  let controllerName = "Default";
2284
- if (path12.tags && path12.tags.length > 0) {
2285
- controllerName = path12.tags[0];
2494
+ if (path13.tags && path13.tags.length > 0) {
2495
+ controllerName = path13.tags[0];
2286
2496
  } else {
2287
- const pathParts = path12.path.split("/").filter((p) => p && !p.startsWith("{"));
2497
+ const pathParts = path13.path.split("/").filter((p) => p && !p.startsWith("{"));
2288
2498
  if (pathParts.length > 1) {
2289
2499
  controllerName = pascalCase(pathParts[1]);
2290
2500
  }
@@ -2293,13 +2503,13 @@ var ServiceGenerator = class {
2293
2503
  if (!groups[controllerName]) {
2294
2504
  groups[controllerName] = [];
2295
2505
  }
2296
- groups[controllerName].push(path12);
2506
+ groups[controllerName].push(path13);
2297
2507
  });
2298
2508
  return groups;
2299
2509
  }
2300
2510
  async generateServiceFile(controllerName, operations, outputDir) {
2301
2511
  const fileName = `${camelCase(controllerName)}.service.ts`;
2302
- const filePath = path8.join(outputDir, fileName);
2512
+ const filePath = path9.join(outputDir, fileName);
2303
2513
  const sourceFile = this.project.createSourceFile(filePath, "", {
2304
2514
  overwrite: true
2305
2515
  });
@@ -2345,6 +2555,12 @@ var ServiceGenerator = class {
2345
2555
  clientContextTokenName
2346
2556
  ],
2347
2557
  moduleSpecifier: "../tokens"
2558
+ },
2559
+ {
2560
+ namedImports: [
2561
+ "HttpParamsBuilder"
2562
+ ],
2563
+ moduleSpecifier: "../utils"
2348
2564
  }
2349
2565
  ]);
2350
2566
  if (usedTypes.size > 0) {
@@ -2374,27 +2590,27 @@ var ServiceGenerator = class {
2374
2590
  serviceClass.addProperty({
2375
2591
  name: "httpClient",
2376
2592
  type: "HttpClient",
2377
- scope: import_ts_morph5.Scope.Private,
2593
+ scope: import_ts_morph6.Scope.Private,
2378
2594
  isReadonly: true,
2379
2595
  initializer: "inject(HttpClient)"
2380
2596
  });
2381
2597
  serviceClass.addProperty({
2382
2598
  name: "basePath",
2383
2599
  type: "string",
2384
- scope: import_ts_morph5.Scope.Private,
2600
+ scope: import_ts_morph6.Scope.Private,
2385
2601
  isReadonly: true,
2386
2602
  initializer: `inject(${basePathTokenName})`
2387
2603
  });
2388
2604
  serviceClass.addProperty({
2389
2605
  name: "clientContextToken",
2390
2606
  type: "HttpContextToken<string>",
2391
- scope: import_ts_morph5.Scope.Private,
2607
+ scope: import_ts_morph6.Scope.Private,
2392
2608
  isReadonly: true,
2393
2609
  initializer: clientContextTokenName
2394
2610
  });
2395
2611
  serviceClass.addMethod({
2396
2612
  name: "createContextWithClientId",
2397
- scope: import_ts_morph5.Scope.Private,
2613
+ scope: import_ts_morph6.Scope.Private,
2398
2614
  parameters: [
2399
2615
  {
2400
2616
  name: "existingContext",
@@ -2417,7 +2633,7 @@ return context.set(this.clientContextToken, '${this.config.clientName || "defaul
2417
2633
 
2418
2634
  // src/lib/generators/service/service-index.generator.ts
2419
2635
  var fs2 = __toESM(require("fs"));
2420
- var path9 = __toESM(require("path"));
2636
+ var path10 = __toESM(require("path"));
2421
2637
  var ServiceIndexGenerator = class {
2422
2638
  static {
2423
2639
  __name(this, "ServiceIndexGenerator");
@@ -2427,8 +2643,8 @@ var ServiceIndexGenerator = class {
2427
2643
  this.project = project;
2428
2644
  }
2429
2645
  generateIndex(outputRoot) {
2430
- const servicesDir = path9.join(outputRoot, "services");
2431
- const indexPath = path9.join(servicesDir, "index.ts");
2646
+ const servicesDir = path10.join(outputRoot, "services");
2647
+ const indexPath = path10.join(servicesDir, "index.ts");
2432
2648
  const sourceFile = this.project.createSourceFile(indexPath, "", {
2433
2649
  overwrite: true
2434
2650
  });
@@ -2449,7 +2665,7 @@ var ServiceIndexGenerator = class {
2449
2665
 
2450
2666
  // src/lib/core/generator.ts
2451
2667
  var fs3 = __toESM(require("fs"));
2452
- var path10 = __toESM(require("path"));
2668
+ var path11 = __toESM(require("path"));
2453
2669
  function validateInput(inputPath) {
2454
2670
  if (isUrl(inputPath)) {
2455
2671
  return;
@@ -2457,7 +2673,7 @@ function validateInput(inputPath) {
2457
2673
  if (!fs3.existsSync(inputPath)) {
2458
2674
  throw new Error(`Input file not found: ${inputPath}`);
2459
2675
  }
2460
- const extension = path10.extname(inputPath).toLowerCase();
2676
+ const extension = path11.extname(inputPath).toLowerCase();
2461
2677
  const supportedExtensions = [
2462
2678
  ".json",
2463
2679
  ".yaml",
@@ -2479,11 +2695,11 @@ async function generateFromConfig(config) {
2479
2695
  });
2480
2696
  }
2481
2697
  try {
2482
- const project = new import_ts_morph6.Project({
2698
+ const project = new import_ts_morph7.Project({
2483
2699
  compilerOptions: {
2484
2700
  declaration: true,
2485
- target: import_ts_morph6.ScriptTarget.ES2022,
2486
- module: import_ts_morph6.ModuleKind.Preserve,
2701
+ target: import_ts_morph7.ScriptTarget.ES2022,
2702
+ module: import_ts_morph7.ModuleKind.Preserve,
2487
2703
  strict: true,
2488
2704
  ...config.compilerOptions
2489
2705
  }
@@ -2502,6 +2718,8 @@ async function generateFromConfig(config) {
2502
2718
  }
2503
2719
  const fileDownloadHelper = new FileDownloadGenerator(project);
2504
2720
  fileDownloadHelper.generate(outputPath);
2721
+ const httpParamsBuilderGenerator = new HttpParamsBuilderGenerator(project);
2722
+ httpParamsBuilderGenerator.generate(outputPath);
2505
2723
  const serviceGenerator = new ServiceGenerator(swaggerParser, project, config);
2506
2724
  await serviceGenerator.generate(outputPath);
2507
2725
  const indexGenerator = new ServiceIndexGenerator(project);
@@ -2546,7 +2764,7 @@ __name(generateFromConfig, "generateFromConfig");
2546
2764
  // src/lib/cli.ts
2547
2765
  var program = new import_commander.Command();
2548
2766
  async function loadConfigFile(configPath) {
2549
- const resolvedPath = path11.resolve(configPath);
2767
+ const resolvedPath = path12.resolve(configPath);
2550
2768
  if (!fs4.existsSync(resolvedPath)) {
2551
2769
  throw new Error(`Configuration file not found: ${resolvedPath}`);
2552
2770
  }
@@ -2560,12 +2778,12 @@ async function loadConfigFile(configPath) {
2560
2778
  if (!config.input || !config.output) {
2561
2779
  throw new Error('Configuration must include "input" and "output" properties');
2562
2780
  }
2563
- const configDir = path11.dirname(resolvedPath);
2564
- if (!isUrl(config.input) && !path11.isAbsolute(config.input)) {
2565
- config.input = path11.resolve(configDir, config.input);
2781
+ const configDir = path12.dirname(resolvedPath);
2782
+ if (!isUrl(config.input) && !path12.isAbsolute(config.input)) {
2783
+ config.input = path12.resolve(configDir, config.input);
2566
2784
  }
2567
- if (!path11.isAbsolute(config.output)) {
2568
- config.output = path11.resolve(configDir, config.output);
2785
+ if (!path12.isAbsolute(config.output)) {
2786
+ config.output = path12.resolve(configDir, config.output);
2569
2787
  }
2570
2788
  return config;
2571
2789
  } catch (error) {
package/index.js CHANGED
@@ -105,7 +105,7 @@ __export(index_exports, {
105
105
  module.exports = __toCommonJS(index_exports);
106
106
 
107
107
  // src/lib/core/generator.ts
108
- var import_ts_morph6 = require("ts-morph");
108
+ var import_ts_morph7 = require("ts-morph");
109
109
 
110
110
  // src/lib/generators/type/type.generator.ts
111
111
  var import_ts_morph = require("ts-morph");
@@ -292,12 +292,12 @@ function extractPaths(swaggerPaths = {}, methods = [
292
292
  "head"
293
293
  ]) {
294
294
  const paths = [];
295
- Object.entries(swaggerPaths).forEach(([path11, pathItem]) => {
295
+ Object.entries(swaggerPaths).forEach(([path12, pathItem]) => {
296
296
  methods.forEach((method) => {
297
297
  if (pathItem[method]) {
298
298
  const operation = pathItem[method];
299
299
  paths.push({
300
- path: path11,
300
+ path: path12,
301
301
  method: method.toUpperCase(),
302
302
  operationId: operation.operationId,
303
303
  summary: operation.summary,
@@ -1907,9 +1907,218 @@ _clientName = new WeakMap();
1907
1907
  __name(_BaseInterceptorGenerator, "BaseInterceptorGenerator");
1908
1908
  var BaseInterceptorGenerator = _BaseInterceptorGenerator;
1909
1909
 
1910
- // src/lib/generators/service/service.generator.ts
1911
- var import_ts_morph5 = require("ts-morph");
1910
+ // src/lib/generators/utility/http-params-builder.generator.ts
1912
1911
  var path8 = __toESM(require("path"));
1912
+ var import_ts_morph5 = require("ts-morph");
1913
+ var _HttpParamsBuilderGenerator = class _HttpParamsBuilderGenerator {
1914
+ constructor(project) {
1915
+ __publicField(this, "project");
1916
+ this.project = project;
1917
+ }
1918
+ generate(outputDir) {
1919
+ const utilsDir = path8.join(outputDir, "utils");
1920
+ const filePath = path8.join(utilsDir, "http-params-builder.ts");
1921
+ const sourceFile = this.project.createSourceFile(filePath, "", {
1922
+ overwrite: true
1923
+ });
1924
+ sourceFile.addImportDeclaration({
1925
+ namedImports: [
1926
+ "HttpParams"
1927
+ ],
1928
+ moduleSpecifier: "@angular/common/http"
1929
+ });
1930
+ const classDeclaration = sourceFile.addClass({
1931
+ name: "HttpParamsBuilder",
1932
+ isExported: true
1933
+ });
1934
+ this.addMethods(classDeclaration);
1935
+ sourceFile.formatText();
1936
+ sourceFile.saveSync();
1937
+ }
1938
+ addMethods(classDeclaration) {
1939
+ const methods = [
1940
+ {
1941
+ name: "addToHttpParams",
1942
+ isStatic: true,
1943
+ scope: import_ts_morph5.Scope.Public,
1944
+ parameters: [
1945
+ {
1946
+ name: "httpParams",
1947
+ type: "HttpParams"
1948
+ },
1949
+ {
1950
+ name: "value",
1951
+ type: "any"
1952
+ },
1953
+ {
1954
+ name: "key",
1955
+ type: "string",
1956
+ hasQuestionToken: true
1957
+ }
1958
+ ],
1959
+ returnType: "HttpParams",
1960
+ docs: [
1961
+ "Adds a value to HttpParams. Delegates to recursive handler for objects/arrays."
1962
+ ],
1963
+ statements: `const isDate = value instanceof Date;
1964
+ const isObject = typeof value === "object" && !isDate;
1965
+
1966
+ if (isObject) {
1967
+ return this.addToHttpParamsRecursive(httpParams, value);
1968
+ }
1969
+
1970
+ return this.addToHttpParamsRecursive(httpParams, value, key);`
1971
+ },
1972
+ {
1973
+ name: "addToHttpParamsRecursive",
1974
+ isStatic: true,
1975
+ scope: import_ts_morph5.Scope.Private,
1976
+ parameters: [
1977
+ {
1978
+ name: "httpParams",
1979
+ type: "HttpParams"
1980
+ },
1981
+ {
1982
+ name: "value",
1983
+ type: "any",
1984
+ hasQuestionToken: true
1985
+ },
1986
+ {
1987
+ name: "key",
1988
+ type: "string",
1989
+ hasQuestionToken: true
1990
+ }
1991
+ ],
1992
+ returnType: "HttpParams",
1993
+ statements: `if (value == null) {
1994
+ return httpParams;
1995
+ }
1996
+
1997
+ if (Array.isArray(value)) {
1998
+ return this.handleArray(httpParams, value, key);
1999
+ }
2000
+
2001
+ if (value instanceof Date) {
2002
+ return this.handleDate(httpParams, value, key);
2003
+ }
2004
+
2005
+ if (typeof value === "object") {
2006
+ return this.handleObject(httpParams, value, key);
2007
+ }
2008
+
2009
+ return this.handlePrimitive(httpParams, value, key);`
2010
+ },
2011
+ {
2012
+ name: "handleArray",
2013
+ isStatic: true,
2014
+ scope: import_ts_morph5.Scope.Private,
2015
+ parameters: [
2016
+ {
2017
+ name: "httpParams",
2018
+ type: "HttpParams"
2019
+ },
2020
+ {
2021
+ name: "arr",
2022
+ type: "unknown[]"
2023
+ },
2024
+ {
2025
+ name: "key",
2026
+ type: "string",
2027
+ hasQuestionToken: true
2028
+ }
2029
+ ],
2030
+ returnType: "HttpParams",
2031
+ statements: `arr.forEach((element) => {
2032
+ httpParams = this.addToHttpParamsRecursive(httpParams, element, key);
2033
+ });
2034
+ return httpParams;`
2035
+ },
2036
+ {
2037
+ name: "handleDate",
2038
+ isStatic: true,
2039
+ scope: import_ts_morph5.Scope.Private,
2040
+ parameters: [
2041
+ {
2042
+ name: "httpParams",
2043
+ type: "HttpParams"
2044
+ },
2045
+ {
2046
+ name: "date",
2047
+ type: "Date"
2048
+ },
2049
+ {
2050
+ name: "key",
2051
+ type: "string",
2052
+ hasQuestionToken: true
2053
+ }
2054
+ ],
2055
+ returnType: "HttpParams",
2056
+ statements: `if (!key) {
2057
+ throw new Error("key may not be null if value is Date");
2058
+ }
2059
+ return httpParams.append(key, date.toISOString().substring(0, 10));`
2060
+ },
2061
+ {
2062
+ name: "handleObject",
2063
+ isStatic: true,
2064
+ scope: import_ts_morph5.Scope.Private,
2065
+ parameters: [
2066
+ {
2067
+ name: "httpParams",
2068
+ type: "HttpParams"
2069
+ },
2070
+ {
2071
+ name: "obj",
2072
+ type: "Record<string, any>"
2073
+ },
2074
+ {
2075
+ name: "key",
2076
+ type: "string",
2077
+ hasQuestionToken: true
2078
+ }
2079
+ ],
2080
+ returnType: "HttpParams",
2081
+ statements: `Object.keys(obj).forEach((prop) => {
2082
+ const nestedKey = key ? \`\${key}.\${prop}\` : prop;
2083
+ httpParams = this.addToHttpParamsRecursive(httpParams, obj[prop], nestedKey);
2084
+ });
2085
+ return httpParams;`
2086
+ },
2087
+ {
2088
+ name: "handlePrimitive",
2089
+ isStatic: true,
2090
+ scope: import_ts_morph5.Scope.Private,
2091
+ parameters: [
2092
+ {
2093
+ name: "httpParams",
2094
+ type: "HttpParams"
2095
+ },
2096
+ {
2097
+ name: "value",
2098
+ type: "string | number | boolean"
2099
+ },
2100
+ {
2101
+ name: "key",
2102
+ type: "string",
2103
+ hasQuestionToken: true
2104
+ }
2105
+ ],
2106
+ returnType: "HttpParams",
2107
+ statements: `if (!key) {
2108
+ throw new Error("key may not be null if value is primitive");
2109
+ }
2110
+ return httpParams.append(key, value);`
2111
+ }
2112
+ ];
2113
+ classDeclaration.addMethods(methods);
2114
+ }
2115
+ };
2116
+ __name(_HttpParamsBuilderGenerator, "HttpParamsBuilderGenerator");
2117
+ var HttpParamsBuilderGenerator = _HttpParamsBuilderGenerator;
2118
+
2119
+ // src/lib/generators/service/service.generator.ts
2120
+ var import_ts_morph6 = require("ts-morph");
2121
+ var path9 = __toESM(require("path"));
1913
2122
 
1914
2123
  // src/lib/generators/service/service-method/service-method-body.generator.ts
1915
2124
  var _ServiceMethodBodyGenerator = class _ServiceMethodBodyGenerator {
@@ -1965,8 +2174,8 @@ var _ServiceMethodBodyGenerator = class _ServiceMethodBodyGenerator {
1965
2174
  if (context.queryParams.length === 0) {
1966
2175
  return "";
1967
2176
  }
1968
- const paramMappings = context.queryParams.map((param) => `if (${param.name} !== undefined) {
1969
- params = params.set('${param.name}', String(${param.name}));
2177
+ const paramMappings = context.queryParams.map((param) => `if (${param.name} != null) {
2178
+ params = HttpParamsBuilder.addToHttpParams(params, ${param.name}, '${param.name}');
1970
2179
  }`).join("\n");
1971
2180
  return `
1972
2181
  let params = new HttpParams();
@@ -2384,7 +2593,7 @@ var _ServiceGenerator = class _ServiceGenerator {
2384
2593
  }
2385
2594
  generate(outputRoot) {
2386
2595
  return __async(this, null, function* () {
2387
- const outputDir = path8.join(outputRoot, "services");
2596
+ const outputDir = path9.join(outputRoot, "services");
2388
2597
  const paths = extractPaths(this.spec.paths);
2389
2598
  if (paths.length === 0) {
2390
2599
  console.warn("No API paths found in the specification");
@@ -2396,12 +2605,12 @@ var _ServiceGenerator = class _ServiceGenerator {
2396
2605
  }
2397
2606
  groupPathsByController(paths) {
2398
2607
  const groups = {};
2399
- paths.forEach((path11) => {
2608
+ paths.forEach((path12) => {
2400
2609
  let controllerName = "Default";
2401
- if (path11.tags && path11.tags.length > 0) {
2402
- controllerName = path11.tags[0];
2610
+ if (path12.tags && path12.tags.length > 0) {
2611
+ controllerName = path12.tags[0];
2403
2612
  } else {
2404
- const pathParts = path11.path.split("/").filter((p) => p && !p.startsWith("{"));
2613
+ const pathParts = path12.path.split("/").filter((p) => p && !p.startsWith("{"));
2405
2614
  if (pathParts.length > 1) {
2406
2615
  controllerName = pascalCase(pathParts[1]);
2407
2616
  }
@@ -2410,14 +2619,14 @@ var _ServiceGenerator = class _ServiceGenerator {
2410
2619
  if (!groups[controllerName]) {
2411
2620
  groups[controllerName] = [];
2412
2621
  }
2413
- groups[controllerName].push(path11);
2622
+ groups[controllerName].push(path12);
2414
2623
  });
2415
2624
  return groups;
2416
2625
  }
2417
2626
  generateServiceFile(controllerName, operations, outputDir) {
2418
2627
  return __async(this, null, function* () {
2419
2628
  const fileName = `${camelCase(controllerName)}.service.ts`;
2420
- const filePath = path8.join(outputDir, fileName);
2629
+ const filePath = path9.join(outputDir, fileName);
2421
2630
  const sourceFile = this.project.createSourceFile(filePath, "", {
2422
2631
  overwrite: true
2423
2632
  });
@@ -2464,6 +2673,12 @@ var _ServiceGenerator = class _ServiceGenerator {
2464
2673
  clientContextTokenName
2465
2674
  ],
2466
2675
  moduleSpecifier: "../tokens"
2676
+ },
2677
+ {
2678
+ namedImports: [
2679
+ "HttpParamsBuilder"
2680
+ ],
2681
+ moduleSpecifier: "../utils"
2467
2682
  }
2468
2683
  ]);
2469
2684
  if (usedTypes.size > 0) {
@@ -2493,27 +2708,27 @@ var _ServiceGenerator = class _ServiceGenerator {
2493
2708
  serviceClass.addProperty({
2494
2709
  name: "httpClient",
2495
2710
  type: "HttpClient",
2496
- scope: import_ts_morph5.Scope.Private,
2711
+ scope: import_ts_morph6.Scope.Private,
2497
2712
  isReadonly: true,
2498
2713
  initializer: "inject(HttpClient)"
2499
2714
  });
2500
2715
  serviceClass.addProperty({
2501
2716
  name: "basePath",
2502
2717
  type: "string",
2503
- scope: import_ts_morph5.Scope.Private,
2718
+ scope: import_ts_morph6.Scope.Private,
2504
2719
  isReadonly: true,
2505
2720
  initializer: `inject(${basePathTokenName})`
2506
2721
  });
2507
2722
  serviceClass.addProperty({
2508
2723
  name: "clientContextToken",
2509
2724
  type: "HttpContextToken<string>",
2510
- scope: import_ts_morph5.Scope.Private,
2725
+ scope: import_ts_morph6.Scope.Private,
2511
2726
  isReadonly: true,
2512
2727
  initializer: clientContextTokenName
2513
2728
  });
2514
2729
  serviceClass.addMethod({
2515
2730
  name: "createContextWithClientId",
2516
- scope: import_ts_morph5.Scope.Private,
2731
+ scope: import_ts_morph6.Scope.Private,
2517
2732
  parameters: [
2518
2733
  {
2519
2734
  name: "existingContext",
@@ -2538,15 +2753,15 @@ var ServiceGenerator = _ServiceGenerator;
2538
2753
 
2539
2754
  // src/lib/generators/service/service-index.generator.ts
2540
2755
  var fs2 = __toESM(require("fs"));
2541
- var path9 = __toESM(require("path"));
2756
+ var path10 = __toESM(require("path"));
2542
2757
  var _ServiceIndexGenerator = class _ServiceIndexGenerator {
2543
2758
  constructor(project) {
2544
2759
  __publicField(this, "project");
2545
2760
  this.project = project;
2546
2761
  }
2547
2762
  generateIndex(outputRoot) {
2548
- const servicesDir = path9.join(outputRoot, "services");
2549
- const indexPath = path9.join(servicesDir, "index.ts");
2763
+ const servicesDir = path10.join(outputRoot, "services");
2764
+ const indexPath = path10.join(servicesDir, "index.ts");
2550
2765
  const sourceFile = this.project.createSourceFile(indexPath, "", {
2551
2766
  overwrite: true
2552
2767
  });
@@ -2569,7 +2784,7 @@ var ServiceIndexGenerator = _ServiceIndexGenerator;
2569
2784
 
2570
2785
  // src/lib/core/generator.ts
2571
2786
  var fs3 = __toESM(require("fs"));
2572
- var path10 = __toESM(require("path"));
2787
+ var path11 = __toESM(require("path"));
2573
2788
  function validateInput(inputPath) {
2574
2789
  if (isUrl(inputPath)) {
2575
2790
  return;
@@ -2577,7 +2792,7 @@ function validateInput(inputPath) {
2577
2792
  if (!fs3.existsSync(inputPath)) {
2578
2793
  throw new Error(`Input file not found: ${inputPath}`);
2579
2794
  }
2580
- const extension = path10.extname(inputPath).toLowerCase();
2795
+ const extension = path11.extname(inputPath).toLowerCase();
2581
2796
  const supportedExtensions = [
2582
2797
  ".json",
2583
2798
  ".yaml",
@@ -2601,11 +2816,11 @@ function generateFromConfig(config) {
2601
2816
  });
2602
2817
  }
2603
2818
  try {
2604
- const project = new import_ts_morph6.Project({
2819
+ const project = new import_ts_morph7.Project({
2605
2820
  compilerOptions: __spreadValues({
2606
2821
  declaration: true,
2607
- target: import_ts_morph6.ScriptTarget.ES2022,
2608
- module: import_ts_morph6.ModuleKind.Preserve,
2822
+ target: import_ts_morph7.ScriptTarget.ES2022,
2823
+ module: import_ts_morph7.ModuleKind.Preserve,
2609
2824
  strict: true
2610
2825
  }, config.compilerOptions)
2611
2826
  });
@@ -2623,6 +2838,8 @@ function generateFromConfig(config) {
2623
2838
  }
2624
2839
  const fileDownloadHelper = new FileDownloadGenerator(project);
2625
2840
  fileDownloadHelper.generate(outputPath);
2841
+ const httpParamsBuilderGenerator = new HttpParamsBuilderGenerator(project);
2842
+ httpParamsBuilderGenerator.generate(outputPath);
2626
2843
  const serviceGenerator = new ServiceGenerator(swaggerParser, project, config);
2627
2844
  yield serviceGenerator.generate(outputPath);
2628
2845
  const indexGenerator = new ServiceIndexGenerator(project);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ng-openapi",
3
- "version": "0.1.12",
3
+ "version": "0.1.13-pr-22-http-params-builder-e72d48f.0",
4
4
  "description": "Generate Angular services and TypeScript types from OpenAPI/Swagger specifications",
5
5
  "keywords": [
6
6
  "ng-openapi",