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