ng-openapi 0.1.9-pr-18-feature-schema-validation-65d0501.0 → 0.1.10

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 +84 -99
  2. package/index.d.ts +9 -19
  3. package/index.js +111 -123
  4. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -24,25 +24,38 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  mod
25
25
  ));
26
26
 
27
+ // ../shared/src/utils/functions/is-url.ts
28
+ function isUrl(input) {
29
+ try {
30
+ const url = new URL(input);
31
+ return [
32
+ "http:",
33
+ "https:"
34
+ ].includes(url.protocol);
35
+ } catch {
36
+ return false;
37
+ }
38
+ }
39
+ __name(isUrl, "isUrl");
40
+
27
41
  // src/lib/cli.ts
28
42
  var import_commander = require("commander");
29
- var path11 = __toESM(require("path"));
30
43
  var fs4 = __toESM(require("fs"));
44
+ var path11 = __toESM(require("path"));
31
45
 
32
- // src/lib/core/generator.ts
33
- var import_ts_morph6 = require("ts-morph");
46
+ // package.json
47
+ var version = "0.1.9";
34
48
 
35
- // src/lib/generators/type/type.generator.ts
36
- var import_ts_morph = require("ts-morph");
49
+ // src/lib/core/generator.ts
50
+ var import_ts_morph5 = require("ts-morph");
37
51
 
38
52
  // ../shared/src/utils/string.utils.ts
39
53
  function camelCase(str) {
40
- const cleaned = str.replace(/[-_](\w)/g, (_, c) => c.toUpperCase());
41
- return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
54
+ return str.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^./, (char) => char.toLowerCase());
42
55
  }
43
56
  __name(camelCase, "camelCase");
44
57
  function pascalCase(str) {
45
- return str.replace(/(?:^|[-_])([a-z])/g, (_, char) => char.toUpperCase());
58
+ return str.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^./, (char) => char.toUpperCase());
46
59
  }
47
60
  __name(pascalCase, "pascalCase");
48
61
 
@@ -366,6 +379,12 @@ function inferResponseTypeFromContentType(contentType) {
366
379
  __name(inferResponseTypeFromContentType, "inferResponseTypeFromContentType");
367
380
  function getResponseType(response, config) {
368
381
  const responseType = getResponseTypeFromResponse(response);
382
+ const content = response.content || {};
383
+ for (const [contentType, mediaType] of Object.entries(content)) {
384
+ if (mediaType?.schema) {
385
+ return getTypeScriptType(mediaType.schema, config, mediaType.schema.nullable);
386
+ }
387
+ }
369
388
  switch (responseType) {
370
389
  case "blob":
371
390
  return "Blob";
@@ -373,15 +392,6 @@ function getResponseType(response, config) {
373
392
  return "ArrayBuffer";
374
393
  case "text":
375
394
  return "string";
376
- case "json": {
377
- const content = response.content || {};
378
- for (const [contentType, mediaType] of Object.entries(content)) {
379
- if (inferResponseTypeFromContentType(contentType) === "json" && mediaType?.schema) {
380
- return getTypeScriptType(mediaType.schema, config, mediaType.schema.nullable);
381
- }
382
- }
383
- return "any";
384
- }
385
395
  default:
386
396
  return "any";
387
397
  }
@@ -455,22 +465,6 @@ var BASE_INTERCEPTOR_HEADER_COMMENT = /* @__PURE__ */ __name((clientName) => def
455
465
  var fs = __toESM(require("fs"));
456
466
  var path = __toESM(require("path"));
457
467
  var yaml = __toESM(require("js-yaml"));
458
-
459
- // ../shared/src/utils/functions/is-url.ts
460
- function isUrl(input) {
461
- try {
462
- const url = new URL(input);
463
- return [
464
- "http:",
465
- "https:"
466
- ].includes(url.protocol);
467
- } catch {
468
- return false;
469
- }
470
- }
471
- __name(isUrl, "isUrl");
472
-
473
- // ../shared/src/core/swagger-parser.ts
474
468
  var SwaggerParser = class _SwaggerParser {
475
469
  static {
476
470
  __name(this, "SwaggerParser");
@@ -617,7 +611,7 @@ var SwaggerParser = class _SwaggerParser {
617
611
  };
618
612
 
619
613
  // src/lib/generators/type/type.generator.ts
620
- var TypeGenerator = class _TypeGenerator {
614
+ var TypeGenerator = class {
621
615
  static {
622
616
  __name(this, "TypeGenerator");
623
617
  }
@@ -626,28 +620,16 @@ var TypeGenerator = class _TypeGenerator {
626
620
  sourceFile;
627
621
  generatedTypes = /* @__PURE__ */ new Set();
628
622
  config;
629
- constructor(parser, outputRoot, config) {
623
+ constructor(parser, project, config, outputRoot) {
630
624
  this.config = config;
631
- const outputPath = outputRoot + "/models/index.ts";
632
- this.project = new import_ts_morph.Project({
633
- compilerOptions: {
634
- declaration: true,
635
- target: import_ts_morph.ScriptTarget.ES2022,
636
- module: import_ts_morph.ModuleKind.Preserve,
637
- strict: true,
638
- ...this.config.compilerOptions
639
- }
640
- });
625
+ this.project = project;
641
626
  this.parser = parser;
627
+ const outputPath = outputRoot + "/models/index.ts";
642
628
  this.sourceFile = this.project.createSourceFile(outputPath, "", {
643
629
  overwrite: true
644
630
  });
645
631
  }
646
- static async create(swaggerPathOrUrl, outputRoot, config) {
647
- const parser = await SwaggerParser.create(swaggerPathOrUrl, config);
648
- return new _TypeGenerator(parser, outputRoot, config);
649
- }
650
- generate() {
632
+ async generate() {
651
633
  try {
652
634
  const definitions = this.parser.getDefinitions();
653
635
  if (!definitions || Object.keys(definitions).length === 0) {
@@ -655,9 +637,7 @@ var TypeGenerator = class _TypeGenerator {
655
637
  return;
656
638
  }
657
639
  this.sourceFile.insertText(0, TYPE_GENERATOR_HEADER_COMMENT);
658
- Object.entries(definitions).forEach(([name, definition]) => {
659
- this.generateInterface(name, definition);
660
- });
640
+ await Promise.all(Object.entries(definitions).map(([name, definition]) => this.generateInterface(name, definition)));
661
641
  this.generateSdkTypes();
662
642
  this.sourceFile.formatText();
663
643
  this.sourceFile.saveSync();
@@ -666,7 +646,7 @@ var TypeGenerator = class _TypeGenerator {
666
646
  throw new Error(`Failed to generate types: ${error instanceof Error ? error.message : "Unknown error"}`);
667
647
  }
668
648
  }
669
- generateInterface(name, definition) {
649
+ async generateInterface(name, definition) {
670
650
  const interfaceName = this.pascalCaseForEnums(name);
671
651
  if (this.generatedTypes.has(interfaceName)) {
672
652
  return;
@@ -775,7 +755,11 @@ var TypeGenerator = class _TypeGenerator {
775
755
  return;
776
756
  }
777
757
  if (!definition.properties) {
778
- console.warn(`No properties found for interface ${interfaceDeclaration.getName()}`);
758
+ interfaceDeclaration.addIndexSignature({
759
+ keyName: "key",
760
+ keyType: "string",
761
+ returnType: "unknown"
762
+ });
779
763
  return;
780
764
  }
781
765
  Object.entries(definition.properties).forEach(([propertyName, property]) => {
@@ -977,7 +961,7 @@ var TypeGenerator = class _TypeGenerator {
977
961
  };
978
962
 
979
963
  // src/lib/generators/utility/token.generator.ts
980
- var import_ts_morph2 = require("ts-morph");
964
+ var import_ts_morph = require("ts-morph");
981
965
  var path2 = __toESM(require("path"));
982
966
  var TokenGenerator = class {
983
967
  static {
@@ -1013,7 +997,7 @@ var TokenGenerator = class {
1013
997
  const clientContextTokenName = this.getClientContextTokenName();
1014
998
  sourceFile.addVariableStatement({
1015
999
  isExported: true,
1016
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1000
+ declarationKind: import_ts_morph.VariableDeclarationKind.Const,
1017
1001
  declarations: [
1018
1002
  {
1019
1003
  name: basePathTokenName,
@@ -1030,7 +1014,7 @@ var TokenGenerator = class {
1030
1014
  });
1031
1015
  sourceFile.addVariableStatement({
1032
1016
  isExported: true,
1033
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1017
+ declarationKind: import_ts_morph.VariableDeclarationKind.Const,
1034
1018
  declarations: [
1035
1019
  {
1036
1020
  name: interceptorsTokenName,
@@ -1047,7 +1031,7 @@ var TokenGenerator = class {
1047
1031
  });
1048
1032
  sourceFile.addVariableStatement({
1049
1033
  isExported: true,
1050
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1034
+ declarationKind: import_ts_morph.VariableDeclarationKind.Const,
1051
1035
  declarations: [
1052
1036
  {
1053
1037
  name: clientContextTokenName,
@@ -1062,7 +1046,7 @@ var TokenGenerator = class {
1062
1046
  if (this.clientName === "default") {
1063
1047
  sourceFile.addVariableStatement({
1064
1048
  isExported: true,
1065
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1049
+ declarationKind: import_ts_morph.VariableDeclarationKind.Const,
1066
1050
  declarations: [
1067
1051
  {
1068
1052
  name: "BASE_PATH",
@@ -1076,7 +1060,7 @@ var TokenGenerator = class {
1076
1060
  });
1077
1061
  sourceFile.addVariableStatement({
1078
1062
  isExported: true,
1079
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1063
+ declarationKind: import_ts_morph.VariableDeclarationKind.Const,
1080
1064
  declarations: [
1081
1065
  {
1082
1066
  name: "CLIENT_CONTEXT_TOKEN",
@@ -1249,7 +1233,7 @@ var FileDownloadGenerator = class {
1249
1233
  };
1250
1234
 
1251
1235
  // src/lib/generators/utility/date-transformer.generator.ts
1252
- var import_ts_morph3 = require("ts-morph");
1236
+ var import_ts_morph2 = require("ts-morph");
1253
1237
  var path4 = __toESM(require("path"));
1254
1238
  var DateTransformerGenerator = class {
1255
1239
  static {
@@ -1295,7 +1279,7 @@ var DateTransformerGenerator = class {
1295
1279
  });
1296
1280
  sourceFile.addVariableStatement({
1297
1281
  isExported: true,
1298
- declarationKind: import_ts_morph3.VariableDeclarationKind.Const,
1282
+ declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1299
1283
  declarations: [
1300
1284
  {
1301
1285
  name: "ISO_DATE_REGEX",
@@ -1637,7 +1621,7 @@ return makeEnvironmentProviders(providers);`;
1637
1621
  };
1638
1622
 
1639
1623
  // src/lib/generators/utility/base-interceptor.generator.ts
1640
- var import_ts_morph4 = require("ts-morph");
1624
+ var import_ts_morph3 = require("ts-morph");
1641
1625
  var path7 = __toESM(require("path"));
1642
1626
  var BaseInterceptorGenerator = class {
1643
1627
  static {
@@ -1706,14 +1690,14 @@ var BaseInterceptorGenerator = class {
1706
1690
  {
1707
1691
  name: "httpInterceptors",
1708
1692
  type: "HttpInterceptor[]",
1709
- scope: import_ts_morph4.Scope.Private,
1693
+ scope: import_ts_morph3.Scope.Private,
1710
1694
  isReadonly: true,
1711
1695
  initializer: `inject(${interceptorsTokenName})`
1712
1696
  },
1713
1697
  {
1714
1698
  name: "clientContextToken",
1715
1699
  type: "HttpContextToken<string>",
1716
- scope: import_ts_morph4.Scope.Private,
1700
+ scope: import_ts_morph3.Scope.Private,
1717
1701
  isReadonly: true,
1718
1702
  initializer: clientContextTokenName
1719
1703
  }
@@ -1770,7 +1754,7 @@ var BaseInterceptorGenerator = class {
1770
1754
  };
1771
1755
 
1772
1756
  // src/lib/generators/service/service.generator.ts
1773
- var import_ts_morph5 = require("ts-morph");
1757
+ var import_ts_morph4 = require("ts-morph");
1774
1758
  var path8 = __toESM(require("path"));
1775
1759
 
1776
1760
  // src/lib/generators/service/service-method/service-method-body.generator.ts
@@ -2187,7 +2171,10 @@ var ServiceMethodGenerator = class {
2187
2171
  parameters,
2188
2172
  returnType,
2189
2173
  statements: methodBody,
2190
- overloads: methodOverLoads
2174
+ overloads: methodOverLoads,
2175
+ docs: operation.description ? [
2176
+ operation.description
2177
+ ] : void 0
2191
2178
  });
2192
2179
  }
2193
2180
  generateMethodName(operation) {
@@ -2207,15 +2194,17 @@ var ServiceMethodGenerator = class {
2207
2194
  if (operation.operationId) {
2208
2195
  return camelCase(operation.operationId);
2209
2196
  }
2210
- const method = operation.method.toLowerCase();
2211
- const pathParts = operation.path.split("/").filter((p) => p && !p.startsWith("{"));
2212
- const resource = pathParts[pathParts.length - 1] || "resource";
2213
- return `${method}${pascalCase(resource)}`;
2197
+ const method = pascalCase(operation.method.toLowerCase());
2198
+ const pathParts = operation.path.split("/").map((str) => {
2199
+ return pascalCase(pascalCase(str).replace(/[^a-zA-Z0-9]/g, ""));
2200
+ });
2201
+ const resource = pathParts.join("") || "resource";
2202
+ return `${camelCase(resource)}${method}`;
2214
2203
  }
2215
2204
  };
2216
2205
 
2217
2206
  // src/lib/generators/service/service.generator.ts
2218
- var ServiceGenerator = class _ServiceGenerator {
2207
+ var ServiceGenerator = class {
2219
2208
  static {
2220
2209
  __name(this, "ServiceGenerator");
2221
2210
  }
@@ -2235,11 +2224,7 @@ var ServiceGenerator = class _ServiceGenerator {
2235
2224
  }
2236
2225
  this.methodGenerator = new ServiceMethodGenerator(config);
2237
2226
  }
2238
- static async create(swaggerPathOrUrl, project, config) {
2239
- const parser = await SwaggerParser.create(swaggerPathOrUrl, config);
2240
- return new _ServiceGenerator(parser, project, config);
2241
- }
2242
- generate(outputRoot) {
2227
+ async generate(outputRoot) {
2243
2228
  const outputDir = path8.join(outputRoot, "services");
2244
2229
  const paths = extractPaths(this.spec.paths);
2245
2230
  if (paths.length === 0) {
@@ -2247,9 +2232,7 @@ var ServiceGenerator = class _ServiceGenerator {
2247
2232
  return;
2248
2233
  }
2249
2234
  const controllerGroups = this.groupPathsByController(paths);
2250
- Object.entries(controllerGroups).forEach(([controllerName, operations]) => {
2251
- this.generateServiceFile(controllerName, operations, outputDir);
2252
- });
2235
+ await Promise.all(Object.entries(controllerGroups).map(([controllerName, operations]) => this.generateServiceFile(controllerName, operations, outputDir)));
2253
2236
  }
2254
2237
  groupPathsByController(paths) {
2255
2238
  const groups = {};
@@ -2271,7 +2254,7 @@ var ServiceGenerator = class _ServiceGenerator {
2271
2254
  });
2272
2255
  return groups;
2273
2256
  }
2274
- generateServiceFile(controllerName, operations, outputDir) {
2257
+ async generateServiceFile(controllerName, operations, outputDir) {
2275
2258
  const fileName = `${camelCase(controllerName)}.service.ts`;
2276
2259
  const filePath = path8.join(outputDir, fileName);
2277
2260
  const sourceFile = this.project.createSourceFile(filePath, "", {
@@ -2348,27 +2331,27 @@ var ServiceGenerator = class _ServiceGenerator {
2348
2331
  serviceClass.addProperty({
2349
2332
  name: "httpClient",
2350
2333
  type: "HttpClient",
2351
- scope: import_ts_morph5.Scope.Private,
2334
+ scope: import_ts_morph4.Scope.Private,
2352
2335
  isReadonly: true,
2353
2336
  initializer: "inject(HttpClient)"
2354
2337
  });
2355
2338
  serviceClass.addProperty({
2356
2339
  name: "basePath",
2357
2340
  type: "string",
2358
- scope: import_ts_morph5.Scope.Private,
2341
+ scope: import_ts_morph4.Scope.Private,
2359
2342
  isReadonly: true,
2360
2343
  initializer: `inject(${basePathTokenName})`
2361
2344
  });
2362
2345
  serviceClass.addProperty({
2363
2346
  name: "clientContextToken",
2364
2347
  type: "HttpContextToken<string>",
2365
- scope: import_ts_morph5.Scope.Private,
2348
+ scope: import_ts_morph4.Scope.Private,
2366
2349
  isReadonly: true,
2367
2350
  initializer: clientContextTokenName
2368
2351
  });
2369
2352
  serviceClass.addMethod({
2370
2353
  name: "createContextWithClientId",
2371
- scope: import_ts_morph5.Scope.Private,
2354
+ scope: import_ts_morph4.Scope.Private,
2372
2355
  parameters: [
2373
2356
  {
2374
2357
  name: "existingContext",
@@ -2453,18 +2436,19 @@ async function generateFromConfig(config) {
2453
2436
  });
2454
2437
  }
2455
2438
  try {
2456
- const project = new import_ts_morph6.Project({
2439
+ const project = new import_ts_morph5.Project({
2457
2440
  compilerOptions: {
2458
2441
  declaration: true,
2459
- target: import_ts_morph6.ScriptTarget.ES2022,
2460
- module: import_ts_morph6.ModuleKind.Preserve,
2442
+ target: import_ts_morph5.ScriptTarget.ES2022,
2443
+ module: import_ts_morph5.ModuleKind.Preserve,
2461
2444
  strict: true,
2462
2445
  ...config.compilerOptions
2463
2446
  }
2464
2447
  });
2465
2448
  console.log(`\u{1F4E1} Processing OpenAPI specification from ${inputType}: ${config.input}`);
2466
- const typeGenerator = await TypeGenerator.create(config.input, outputPath, config);
2467
- typeGenerator.generate();
2449
+ const swaggerParser = await SwaggerParser.create(config.input, config);
2450
+ const typeGenerator = new TypeGenerator(swaggerParser, project, config, outputPath);
2451
+ await typeGenerator.generate();
2468
2452
  console.log(`\u2705 TypeScript interfaces generated`);
2469
2453
  if (generateServices) {
2470
2454
  const tokenGenerator = new TokenGenerator(project, config.clientName);
@@ -2475,8 +2459,8 @@ async function generateFromConfig(config) {
2475
2459
  }
2476
2460
  const fileDownloadHelper = new FileDownloadGenerator(project);
2477
2461
  fileDownloadHelper.generate(outputPath);
2478
- const serviceGenerator = await ServiceGenerator.create(config.input, project, config);
2479
- serviceGenerator.generate(outputPath);
2462
+ const serviceGenerator = new ServiceGenerator(swaggerParser, project, config);
2463
+ await serviceGenerator.generate(outputPath);
2480
2464
  const indexGenerator = new ServiceIndexGenerator(project);
2481
2465
  indexGenerator.generateIndex(outputPath);
2482
2466
  console.log(`\u2705 Angular services generated`);
@@ -2487,9 +2471,9 @@ async function generateFromConfig(config) {
2487
2471
  }
2488
2472
  if (config.plugins?.length) {
2489
2473
  for (const plugin of config.plugins) {
2490
- const PluginClass = plugin;
2491
- const pluginGenerator = await PluginClass.create(config.input, project, config);
2492
- pluginGenerator.generate(outputPath);
2474
+ const generatorClass = plugin;
2475
+ const pluginGenerator = new generatorClass(swaggerParser, project, config);
2476
+ await pluginGenerator.generate(outputPath);
2493
2477
  }
2494
2478
  console.log(`\u2705 Plugins are generated`);
2495
2479
  }
@@ -2516,9 +2500,6 @@ async function generateFromConfig(config) {
2516
2500
  }
2517
2501
  __name(generateFromConfig, "generateFromConfig");
2518
2502
 
2519
- // package.json
2520
- var version = "0.1.8";
2521
-
2522
2503
  // src/lib/cli.ts
2523
2504
  var program = new import_commander.Command();
2524
2505
  async function loadConfigFile(configPath) {
@@ -2550,6 +2531,7 @@ async function loadConfigFile(configPath) {
2550
2531
  }
2551
2532
  __name(loadConfigFile, "loadConfigFile");
2552
2533
  async function generateFromOptions(options) {
2534
+ const timestamp = (/* @__PURE__ */ new Date()).getTime();
2553
2535
  try {
2554
2536
  if (options.config) {
2555
2537
  const config = await loadConfigFile(options.config);
@@ -2574,6 +2556,9 @@ async function generateFromOptions(options) {
2574
2556
  console.log("\u2728 Generation completed successfully!");
2575
2557
  } catch (error) {
2576
2558
  console.error("\u274C Generation failed:", error instanceof Error ? error.message : error);
2559
+ } finally {
2560
+ const duration = ((/* @__PURE__ */ new Date()).getTime() - timestamp) / 1e3;
2561
+ console.log(`\u23F1\uFE0F Duration: ${duration.toFixed(2)} seconds`);
2577
2562
  process.exit(1);
2578
2563
  }
2579
2564
  }
package/index.d.ts CHANGED
@@ -166,33 +166,23 @@ declare class SwaggerParser {
166
166
  }
167
167
 
168
168
  /**
169
- * Interface for generator instances
169
+ * Interface for generator class (both constructor and instance)
170
170
  */
171
- interface IPluginGenerator {
171
+ interface IPluginGeneratorClass {
172
172
  /**
173
- * Generate code files
173
+ * Constructor signature
174
174
  */
175
- generate(outputRoot: string): void;
175
+ new (parser: SwaggerParser, project: Project, config: GeneratorConfig): IPluginGenerator;
176
176
  }
177
177
  /**
178
- * Interface for generator constructor with static methods
178
+ * Interface for generator instances
179
179
  */
180
- interface IPluginGeneratorConstructor {
181
- /**
182
- * Create a generator instance
183
- */
184
- create(swaggerPathOrUrl: string, project: Project, config: GeneratorConfig): Promise<IPluginGenerator>;
180
+ interface IPluginGenerator {
185
181
  /**
186
- * Constructor signature
182
+ * Generate code files
187
183
  */
188
- new (parser: SwaggerParser, project: Project, config: GeneratorConfig): IPluginGenerator;
184
+ generate(outputRoot: string): Promise<void>;
189
185
  }
190
- /**
191
- * Combined type that includes both static and instance methods
192
- */
193
- type IPluginGeneratorClass = IPluginGeneratorConstructor & {
194
- prototype: IPluginGenerator;
195
- };
196
186
 
197
187
  interface GeneratorConfig {
198
188
  input: string;
@@ -287,4 +277,4 @@ declare function validateInput(inputPath: string): void;
287
277
  */
288
278
  declare function generateFromConfig(config: GeneratorConfig): Promise<void>;
289
279
 
290
- export { BASE_INTERCEPTOR_HEADER_COMMENT, type EnumValueObject, type GeneratorConfig, type GetMethodGenerationContext, HTTP_RESOURCE_GENERATOR_HEADER_COMMENT, type IPluginGenerator, type IPluginGeneratorClass, type IPluginGeneratorConstructor, MAIN_INDEX_GENERATOR_HEADER_COMMENT, type MethodGenerationContext, type NgOpenapiClientConfig, PROVIDER_GENERATOR_HEADER_COMMENT, type Parameter, type PathInfo, type RequestBody, SERVICE_GENERATOR_HEADER_COMMENT, SERVICE_INDEX_GENERATOR_HEADER_COMMENT, type SwaggerDefinition, SwaggerParser, type SwaggerResponse, type SwaggerSpec, TYPE_GENERATOR_HEADER_COMMENT, type TypeSchema, camelCase, collectUsedTypes, escapeString, extractPaths, generateFromConfig, generateParseRequestTypeParams, getBasePathTokenName, getClientContextTokenName, getRequestBodyType, getResponseType, getResponseTypeFromResponse, getTypeScriptType, hasDuplicateFunctionNames, inferResponseTypeFromContentType, isDataTypeInterface, isPrimitiveType, kebabCase, nullableType, pascalCase, type placeHolder, validateInput };
280
+ export { BASE_INTERCEPTOR_HEADER_COMMENT, type EnumValueObject, type GeneratorConfig, type GetMethodGenerationContext, HTTP_RESOURCE_GENERATOR_HEADER_COMMENT, type IPluginGenerator, type IPluginGeneratorClass, MAIN_INDEX_GENERATOR_HEADER_COMMENT, type MethodGenerationContext, type NgOpenapiClientConfig, PROVIDER_GENERATOR_HEADER_COMMENT, type Parameter, type PathInfo, type RequestBody, SERVICE_GENERATOR_HEADER_COMMENT, SERVICE_INDEX_GENERATOR_HEADER_COMMENT, type SwaggerDefinition, SwaggerParser, type SwaggerResponse, type SwaggerSpec, TYPE_GENERATOR_HEADER_COMMENT, type TypeSchema, camelCase, collectUsedTypes, escapeString, extractPaths, generateFromConfig, generateParseRequestTypeParams, getBasePathTokenName, getClientContextTokenName, getRequestBodyType, getResponseType, getResponseTypeFromResponse, getTypeScriptType, hasDuplicateFunctionNames, inferResponseTypeFromContentType, isDataTypeInterface, isPrimitiveType, kebabCase, nullableType, pascalCase, type placeHolder, validateInput };
package/index.js CHANGED
@@ -105,23 +105,19 @@ __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");
109
-
110
- // src/lib/generators/type/type.generator.ts
111
- var import_ts_morph = require("ts-morph");
108
+ var import_ts_morph5 = require("ts-morph");
112
109
 
113
110
  // ../shared/src/utils/string.utils.ts
114
111
  function camelCase(str) {
115
- const cleaned = str.replace(/[-_](\w)/g, (_, c) => c.toUpperCase());
116
- return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
112
+ return str.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^./, (char) => char.toLowerCase());
117
113
  }
118
114
  __name(camelCase, "camelCase");
119
115
  function kebabCase(str) {
120
- return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
116
+ return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[-_\s]+/g, "-").toLowerCase();
121
117
  }
122
118
  __name(kebabCase, "kebabCase");
123
119
  function pascalCase(str) {
124
- return str.replace(/(?:^|[-_])([a-z])/g, (_, char) => char.toUpperCase());
120
+ return str.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : "").replace(/^./, (char) => char.toUpperCase());
125
121
  }
126
122
  __name(pascalCase, "pascalCase");
127
123
 
@@ -447,6 +443,12 @@ function inferResponseTypeFromContentType(contentType) {
447
443
  __name(inferResponseTypeFromContentType, "inferResponseTypeFromContentType");
448
444
  function getResponseType(response, config) {
449
445
  const responseType = getResponseTypeFromResponse(response);
446
+ const content = response.content || {};
447
+ for (const [contentType, mediaType] of Object.entries(content)) {
448
+ if (mediaType == null ? void 0 : mediaType.schema) {
449
+ return getTypeScriptType(mediaType.schema, config, mediaType.schema.nullable);
450
+ }
451
+ }
450
452
  switch (responseType) {
451
453
  case "blob":
452
454
  return "Blob";
@@ -454,15 +456,6 @@ function getResponseType(response, config) {
454
456
  return "ArrayBuffer";
455
457
  case "text":
456
458
  return "string";
457
- case "json": {
458
- const content = response.content || {};
459
- for (const [contentType, mediaType] of Object.entries(content)) {
460
- if (inferResponseTypeFromContentType(contentType) === "json" && (mediaType == null ? void 0 : mediaType.schema)) {
461
- return getTypeScriptType(mediaType.schema, config, mediaType.schema.nullable);
462
- }
463
- }
464
- return "any";
465
- }
466
459
  default:
467
460
  return "any";
468
461
  }
@@ -724,74 +717,63 @@ var SwaggerParser = _SwaggerParser;
724
717
 
725
718
  // src/lib/generators/type/type.generator.ts
726
719
  var _TypeGenerator = class _TypeGenerator {
727
- constructor(parser, outputRoot, config) {
720
+ constructor(parser, project, config, outputRoot) {
728
721
  __publicField(this, "project");
729
722
  __publicField(this, "parser");
730
723
  __publicField(this, "sourceFile");
731
724
  __publicField(this, "generatedTypes", /* @__PURE__ */ new Set());
732
725
  __publicField(this, "config");
733
726
  this.config = config;
734
- const outputPath = outputRoot + "/models/index.ts";
735
- this.project = new import_ts_morph.Project({
736
- compilerOptions: __spreadValues({
737
- declaration: true,
738
- target: import_ts_morph.ScriptTarget.ES2022,
739
- module: import_ts_morph.ModuleKind.Preserve,
740
- strict: true
741
- }, this.config.compilerOptions)
742
- });
727
+ this.project = project;
743
728
  this.parser = parser;
729
+ const outputPath = outputRoot + "/models/index.ts";
744
730
  this.sourceFile = this.project.createSourceFile(outputPath, "", {
745
731
  overwrite: true
746
732
  });
747
733
  }
748
- static create(swaggerPathOrUrl, outputRoot, config) {
734
+ generate() {
749
735
  return __async(this, null, function* () {
750
- const parser = yield SwaggerParser.create(swaggerPathOrUrl, config);
751
- return new _TypeGenerator(parser, outputRoot, config);
736
+ try {
737
+ const definitions = this.parser.getDefinitions();
738
+ if (!definitions || Object.keys(definitions).length === 0) {
739
+ console.warn("No definitions found in swagger file");
740
+ return;
741
+ }
742
+ this.sourceFile.insertText(0, TYPE_GENERATOR_HEADER_COMMENT);
743
+ yield Promise.all(Object.entries(definitions).map(([name, definition]) => this.generateInterface(name, definition)));
744
+ this.generateSdkTypes();
745
+ this.sourceFile.formatText();
746
+ this.sourceFile.saveSync();
747
+ } catch (error) {
748
+ console.error("Error in generate():", error);
749
+ throw new Error(`Failed to generate types: ${error instanceof Error ? error.message : "Unknown error"}`);
750
+ }
752
751
  });
753
752
  }
754
- generate() {
755
- try {
756
- const definitions = this.parser.getDefinitions();
757
- if (!definitions || Object.keys(definitions).length === 0) {
758
- console.warn("No definitions found in swagger file");
753
+ generateInterface(name, definition) {
754
+ return __async(this, null, function* () {
755
+ const interfaceName = this.pascalCaseForEnums(name);
756
+ if (this.generatedTypes.has(interfaceName)) {
759
757
  return;
760
758
  }
761
- this.sourceFile.insertText(0, TYPE_GENERATOR_HEADER_COMMENT);
762
- Object.entries(definitions).forEach(([name, definition]) => {
763
- this.generateInterface(name, definition);
759
+ this.generatedTypes.add(interfaceName);
760
+ if (definition.enum) {
761
+ this.generateEnum(interfaceName, definition);
762
+ return;
763
+ }
764
+ if (definition.allOf) {
765
+ this.generateCompositeType(interfaceName, definition);
766
+ return;
767
+ }
768
+ const interfaceDeclaration = this.sourceFile.addInterface({
769
+ name: interfaceName,
770
+ isExported: true,
771
+ docs: definition.description ? [
772
+ definition.description
773
+ ] : void 0
764
774
  });
765
- this.generateSdkTypes();
766
- this.sourceFile.formatText();
767
- this.sourceFile.saveSync();
768
- } catch (error) {
769
- console.error("Error in generate():", error);
770
- throw new Error(`Failed to generate types: ${error instanceof Error ? error.message : "Unknown error"}`);
771
- }
772
- }
773
- generateInterface(name, definition) {
774
- const interfaceName = this.pascalCaseForEnums(name);
775
- if (this.generatedTypes.has(interfaceName)) {
776
- return;
777
- }
778
- this.generatedTypes.add(interfaceName);
779
- if (definition.enum) {
780
- this.generateEnum(interfaceName, definition);
781
- return;
782
- }
783
- if (definition.allOf) {
784
- this.generateCompositeType(interfaceName, definition);
785
- return;
786
- }
787
- const interfaceDeclaration = this.sourceFile.addInterface({
788
- name: interfaceName,
789
- isExported: true,
790
- docs: definition.description ? [
791
- definition.description
792
- ] : void 0
775
+ this.addInterfaceProperties(interfaceDeclaration, definition);
793
776
  });
794
- this.addInterfaceProperties(interfaceDeclaration, definition);
795
777
  }
796
778
  generateEnum(name, definition) {
797
779
  var _a;
@@ -880,7 +862,11 @@ var _TypeGenerator = class _TypeGenerator {
880
862
  return;
881
863
  }
882
864
  if (!definition.properties) {
883
- console.warn(`No properties found for interface ${interfaceDeclaration.getName()}`);
865
+ interfaceDeclaration.addIndexSignature({
866
+ keyName: "key",
867
+ keyType: "string",
868
+ returnType: "unknown"
869
+ });
884
870
  return;
885
871
  }
886
872
  Object.entries(definition.properties).forEach(([propertyName, property]) => {
@@ -1087,7 +1073,7 @@ __name(_TypeGenerator, "TypeGenerator");
1087
1073
  var TypeGenerator = _TypeGenerator;
1088
1074
 
1089
1075
  // src/lib/generators/utility/token.generator.ts
1090
- var import_ts_morph2 = require("ts-morph");
1076
+ var import_ts_morph = require("ts-morph");
1091
1077
  var path2 = __toESM(require("path"));
1092
1078
  var _TokenGenerator = class _TokenGenerator {
1093
1079
  constructor(project, clientName = "default") {
@@ -1120,7 +1106,7 @@ var _TokenGenerator = class _TokenGenerator {
1120
1106
  const clientContextTokenName = this.getClientContextTokenName();
1121
1107
  sourceFile.addVariableStatement({
1122
1108
  isExported: true,
1123
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1109
+ declarationKind: import_ts_morph.VariableDeclarationKind.Const,
1124
1110
  declarations: [
1125
1111
  {
1126
1112
  name: basePathTokenName,
@@ -1137,7 +1123,7 @@ var _TokenGenerator = class _TokenGenerator {
1137
1123
  });
1138
1124
  sourceFile.addVariableStatement({
1139
1125
  isExported: true,
1140
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1126
+ declarationKind: import_ts_morph.VariableDeclarationKind.Const,
1141
1127
  declarations: [
1142
1128
  {
1143
1129
  name: interceptorsTokenName,
@@ -1154,7 +1140,7 @@ var _TokenGenerator = class _TokenGenerator {
1154
1140
  });
1155
1141
  sourceFile.addVariableStatement({
1156
1142
  isExported: true,
1157
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1143
+ declarationKind: import_ts_morph.VariableDeclarationKind.Const,
1158
1144
  declarations: [
1159
1145
  {
1160
1146
  name: clientContextTokenName,
@@ -1169,7 +1155,7 @@ var _TokenGenerator = class _TokenGenerator {
1169
1155
  if (this.clientName === "default") {
1170
1156
  sourceFile.addVariableStatement({
1171
1157
  isExported: true,
1172
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1158
+ declarationKind: import_ts_morph.VariableDeclarationKind.Const,
1173
1159
  declarations: [
1174
1160
  {
1175
1161
  name: "BASE_PATH",
@@ -1183,7 +1169,7 @@ var _TokenGenerator = class _TokenGenerator {
1183
1169
  });
1184
1170
  sourceFile.addVariableStatement({
1185
1171
  isExported: true,
1186
- declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1172
+ declarationKind: import_ts_morph.VariableDeclarationKind.Const,
1187
1173
  declarations: [
1188
1174
  {
1189
1175
  name: "CLIENT_CONTEXT_TOKEN",
@@ -1357,7 +1343,7 @@ __name(_FileDownloadGenerator, "FileDownloadGenerator");
1357
1343
  var FileDownloadGenerator = _FileDownloadGenerator;
1358
1344
 
1359
1345
  // src/lib/generators/utility/date-transformer.generator.ts
1360
- var import_ts_morph3 = require("ts-morph");
1346
+ var import_ts_morph2 = require("ts-morph");
1361
1347
  var path4 = __toESM(require("path"));
1362
1348
  var _DateTransformerGenerator = class _DateTransformerGenerator {
1363
1349
  constructor(project) {
@@ -1400,7 +1386,7 @@ var _DateTransformerGenerator = class _DateTransformerGenerator {
1400
1386
  });
1401
1387
  sourceFile.addVariableStatement({
1402
1388
  isExported: true,
1403
- declarationKind: import_ts_morph3.VariableDeclarationKind.Const,
1389
+ declarationKind: import_ts_morph2.VariableDeclarationKind.Const,
1404
1390
  declarations: [
1405
1391
  {
1406
1392
  name: "ISO_DATE_REGEX",
@@ -1742,7 +1728,7 @@ __name(_ProviderGenerator, "ProviderGenerator");
1742
1728
  var ProviderGenerator = _ProviderGenerator;
1743
1729
 
1744
1730
  // src/lib/generators/utility/base-interceptor.generator.ts
1745
- var import_ts_morph4 = require("ts-morph");
1731
+ var import_ts_morph3 = require("ts-morph");
1746
1732
  var path7 = __toESM(require("path"));
1747
1733
  var _project, _clientName;
1748
1734
  var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
@@ -1809,14 +1795,14 @@ var _BaseInterceptorGenerator = class _BaseInterceptorGenerator {
1809
1795
  {
1810
1796
  name: "httpInterceptors",
1811
1797
  type: "HttpInterceptor[]",
1812
- scope: import_ts_morph4.Scope.Private,
1798
+ scope: import_ts_morph3.Scope.Private,
1813
1799
  isReadonly: true,
1814
1800
  initializer: `inject(${interceptorsTokenName})`
1815
1801
  },
1816
1802
  {
1817
1803
  name: "clientContextToken",
1818
1804
  type: "HttpContextToken<string>",
1819
- scope: import_ts_morph4.Scope.Private,
1805
+ scope: import_ts_morph3.Scope.Private,
1820
1806
  isReadonly: true,
1821
1807
  initializer: clientContextTokenName
1822
1808
  }
@@ -1877,7 +1863,7 @@ __name(_BaseInterceptorGenerator, "BaseInterceptorGenerator");
1877
1863
  var BaseInterceptorGenerator = _BaseInterceptorGenerator;
1878
1864
 
1879
1865
  // src/lib/generators/service/service.generator.ts
1880
- var import_ts_morph5 = require("ts-morph");
1866
+ var import_ts_morph4 = require("ts-morph");
1881
1867
  var path8 = __toESM(require("path"));
1882
1868
 
1883
1869
  // src/lib/generators/service/service-method/service-method-body.generator.ts
@@ -2299,7 +2285,10 @@ var _ServiceMethodGenerator = class _ServiceMethodGenerator {
2299
2285
  parameters,
2300
2286
  returnType,
2301
2287
  statements: methodBody,
2302
- overloads: methodOverLoads
2288
+ overloads: methodOverLoads,
2289
+ docs: operation.description ? [
2290
+ operation.description
2291
+ ] : void 0
2303
2292
  });
2304
2293
  }
2305
2294
  generateMethodName(operation) {
@@ -2319,10 +2308,12 @@ var _ServiceMethodGenerator = class _ServiceMethodGenerator {
2319
2308
  if (operation.operationId) {
2320
2309
  return camelCase(operation.operationId);
2321
2310
  }
2322
- const method = operation.method.toLowerCase();
2323
- const pathParts = operation.path.split("/").filter((p) => p && !p.startsWith("{"));
2324
- const resource = pathParts[pathParts.length - 1] || "resource";
2325
- return `${method}${pascalCase(resource)}`;
2311
+ const method = pascalCase(operation.method.toLowerCase());
2312
+ const pathParts = operation.path.split("/").map((str) => {
2313
+ return pascalCase(pascalCase(str).replace(/[^a-zA-Z0-9]/g, ""));
2314
+ });
2315
+ const resource = pathParts.join("") || "resource";
2316
+ return `${camelCase(resource)}${method}`;
2326
2317
  }
2327
2318
  };
2328
2319
  __name(_ServiceMethodGenerator, "ServiceMethodGenerator");
@@ -2346,22 +2337,16 @@ var _ServiceGenerator = class _ServiceGenerator {
2346
2337
  }
2347
2338
  this.methodGenerator = new ServiceMethodGenerator(config);
2348
2339
  }
2349
- static create(swaggerPathOrUrl, project, config) {
2350
- return __async(this, null, function* () {
2351
- const parser = yield SwaggerParser.create(swaggerPathOrUrl, config);
2352
- return new _ServiceGenerator(parser, project, config);
2353
- });
2354
- }
2355
2340
  generate(outputRoot) {
2356
- const outputDir = path8.join(outputRoot, "services");
2357
- const paths = extractPaths(this.spec.paths);
2358
- if (paths.length === 0) {
2359
- console.warn("No API paths found in the specification");
2360
- return;
2361
- }
2362
- const controllerGroups = this.groupPathsByController(paths);
2363
- Object.entries(controllerGroups).forEach(([controllerName, operations]) => {
2364
- this.generateServiceFile(controllerName, operations, outputDir);
2341
+ return __async(this, null, function* () {
2342
+ const outputDir = path8.join(outputRoot, "services");
2343
+ const paths = extractPaths(this.spec.paths);
2344
+ if (paths.length === 0) {
2345
+ console.warn("No API paths found in the specification");
2346
+ return;
2347
+ }
2348
+ const controllerGroups = this.groupPathsByController(paths);
2349
+ yield Promise.all(Object.entries(controllerGroups).map(([controllerName, operations]) => this.generateServiceFile(controllerName, operations, outputDir)));
2365
2350
  });
2366
2351
  }
2367
2352
  groupPathsByController(paths) {
@@ -2385,16 +2370,18 @@ var _ServiceGenerator = class _ServiceGenerator {
2385
2370
  return groups;
2386
2371
  }
2387
2372
  generateServiceFile(controllerName, operations, outputDir) {
2388
- const fileName = `${camelCase(controllerName)}.service.ts`;
2389
- const filePath = path8.join(outputDir, fileName);
2390
- const sourceFile = this.project.createSourceFile(filePath, "", {
2391
- overwrite: true
2373
+ return __async(this, null, function* () {
2374
+ const fileName = `${camelCase(controllerName)}.service.ts`;
2375
+ const filePath = path8.join(outputDir, fileName);
2376
+ const sourceFile = this.project.createSourceFile(filePath, "", {
2377
+ overwrite: true
2378
+ });
2379
+ const usedTypes = collectUsedTypes(operations);
2380
+ this.addImports(sourceFile, usedTypes);
2381
+ this.addServiceClass(sourceFile, controllerName, operations);
2382
+ sourceFile.formatText();
2383
+ sourceFile.saveSync();
2392
2384
  });
2393
- const usedTypes = collectUsedTypes(operations);
2394
- this.addImports(sourceFile, usedTypes);
2395
- this.addServiceClass(sourceFile, controllerName, operations);
2396
- sourceFile.formatText();
2397
- sourceFile.saveSync();
2398
2385
  }
2399
2386
  addImports(sourceFile, usedTypes) {
2400
2387
  const basePathTokenName = getBasePathTokenName(this.config.clientName);
@@ -2461,27 +2448,27 @@ var _ServiceGenerator = class _ServiceGenerator {
2461
2448
  serviceClass.addProperty({
2462
2449
  name: "httpClient",
2463
2450
  type: "HttpClient",
2464
- scope: import_ts_morph5.Scope.Private,
2451
+ scope: import_ts_morph4.Scope.Private,
2465
2452
  isReadonly: true,
2466
2453
  initializer: "inject(HttpClient)"
2467
2454
  });
2468
2455
  serviceClass.addProperty({
2469
2456
  name: "basePath",
2470
2457
  type: "string",
2471
- scope: import_ts_morph5.Scope.Private,
2458
+ scope: import_ts_morph4.Scope.Private,
2472
2459
  isReadonly: true,
2473
2460
  initializer: `inject(${basePathTokenName})`
2474
2461
  });
2475
2462
  serviceClass.addProperty({
2476
2463
  name: "clientContextToken",
2477
2464
  type: "HttpContextToken<string>",
2478
- scope: import_ts_morph5.Scope.Private,
2465
+ scope: import_ts_morph4.Scope.Private,
2479
2466
  isReadonly: true,
2480
2467
  initializer: clientContextTokenName
2481
2468
  });
2482
2469
  serviceClass.addMethod({
2483
2470
  name: "createContextWithClientId",
2484
- scope: import_ts_morph5.Scope.Private,
2471
+ scope: import_ts_morph4.Scope.Private,
2485
2472
  parameters: [
2486
2473
  {
2487
2474
  name: "existingContext",
@@ -2569,17 +2556,18 @@ function generateFromConfig(config) {
2569
2556
  });
2570
2557
  }
2571
2558
  try {
2572
- const project = new import_ts_morph6.Project({
2559
+ const project = new import_ts_morph5.Project({
2573
2560
  compilerOptions: __spreadValues({
2574
2561
  declaration: true,
2575
- target: import_ts_morph6.ScriptTarget.ES2022,
2576
- module: import_ts_morph6.ModuleKind.Preserve,
2562
+ target: import_ts_morph5.ScriptTarget.ES2022,
2563
+ module: import_ts_morph5.ModuleKind.Preserve,
2577
2564
  strict: true
2578
2565
  }, config.compilerOptions)
2579
2566
  });
2580
2567
  console.log(`\u{1F4E1} Processing OpenAPI specification from ${inputType}: ${config.input}`);
2581
- const typeGenerator = yield TypeGenerator.create(config.input, outputPath, config);
2582
- typeGenerator.generate();
2568
+ const swaggerParser = yield SwaggerParser.create(config.input, config);
2569
+ const typeGenerator = new TypeGenerator(swaggerParser, project, config, outputPath);
2570
+ yield typeGenerator.generate();
2583
2571
  console.log(`\u2705 TypeScript interfaces generated`);
2584
2572
  if (generateServices) {
2585
2573
  const tokenGenerator = new TokenGenerator(project, config.clientName);
@@ -2590,8 +2578,8 @@ function generateFromConfig(config) {
2590
2578
  }
2591
2579
  const fileDownloadHelper = new FileDownloadGenerator(project);
2592
2580
  fileDownloadHelper.generate(outputPath);
2593
- const serviceGenerator = yield ServiceGenerator.create(config.input, project, config);
2594
- serviceGenerator.generate(outputPath);
2581
+ const serviceGenerator = new ServiceGenerator(swaggerParser, project, config);
2582
+ yield serviceGenerator.generate(outputPath);
2595
2583
  const indexGenerator = new ServiceIndexGenerator(project);
2596
2584
  indexGenerator.generateIndex(outputPath);
2597
2585
  console.log(`\u2705 Angular services generated`);
@@ -2602,9 +2590,9 @@ function generateFromConfig(config) {
2602
2590
  }
2603
2591
  if ((_b = config.plugins) == null ? void 0 : _b.length) {
2604
2592
  for (const plugin of config.plugins) {
2605
- const PluginClass = plugin;
2606
- const pluginGenerator = yield PluginClass.create(config.input, project, config);
2607
- pluginGenerator.generate(outputPath);
2593
+ const generatorClass = plugin;
2594
+ const pluginGenerator = new generatorClass(swaggerParser, project, config);
2595
+ yield pluginGenerator.generate(outputPath);
2608
2596
  }
2609
2597
  console.log(`\u2705 Plugins are generated`);
2610
2598
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ng-openapi",
3
- "version": "0.1.9-pr-18-feature-schema-validation-65d0501.0",
3
+ "version": "0.1.10",
4
4
  "description": "Generate Angular services and TypeScript types from OpenAPI/Swagger specifications",
5
5
  "keywords": [
6
6
  "ng-openapi",