@ps-aux/api-client-gen 0.7.0-rc.4 → 0.7.0-rc.5

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.
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var Path = require('path');
3
+ var Path$1 = require('path');
4
4
  var fs$2 = require('fs');
5
5
  var fs = require('fs/promises');
6
+ var Path = require('node:path');
6
7
  var swaggerTypescriptApi = require('swagger-typescript-api');
7
8
  var node_url = require('node:url');
8
9
  var promises = require('node:fs/promises');
9
- var Path$1 = require('node:path');
10
10
  var fs$1 = require('node:fs');
11
11
  var tsToZod = require('ts-to-zod');
12
12
 
@@ -4301,6 +4301,34 @@ const downloadSpec = async (path, url) => {
4301
4301
  await fs.writeFile(path, content);
4302
4302
  };
4303
4303
 
4304
+ const EMPTY_LINE_MARKER = "/*__EMPTY_LINE_MARKER__*/";
4305
+
4306
+ var __defProp$b = Object.defineProperty;
4307
+ var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4308
+ var __publicField$b = (obj, key, value) => __defNormalProp$b(obj, key + "" , value);
4309
+ const EMPTY_LINE_MARKER_LINE = new RegExp(
4310
+ `\\n[\\t ]*${EMPTY_LINE_MARKER.replaceAll("/", "\\/").replaceAll(
4311
+ "*",
4312
+ "\\*"
4313
+ )}\\n`,
4314
+ "g"
4315
+ );
4316
+ class CodeFormatter {
4317
+ constructor(opts) {
4318
+ this.opts = opts;
4319
+ __publicField$b(this, "format", async (code) => {
4320
+ const filePath = Path.resolve(this.opts.resolveConfFrom, "generated.ts");
4321
+ const prettier = await import('prettier');
4322
+ const prettierConfig = await prettier.resolveConfig(filePath) ?? {};
4323
+ const formattedCode = await prettier.format(code, {
4324
+ ...prettierConfig,
4325
+ filepath: filePath
4326
+ });
4327
+ return formattedCode.replaceAll(EMPTY_LINE_MARKER_LINE, "\n\n");
4328
+ });
4329
+ }
4330
+ }
4331
+
4304
4332
  const toPascalCaseIdentifier = (str) => {
4305
4333
  const words = str.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/).filter(Boolean);
4306
4334
  const pascalCase = words.map((word) => word[0].toUpperCase() + word.substring(1)).join("");
@@ -4321,6 +4349,12 @@ const groupBy = (values, getKey) => {
4321
4349
  }
4322
4350
  return groups;
4323
4351
  };
4352
+ const findRelativePath = (src, dst) => {
4353
+ const relativePath = Path$1.relative(Path$1.dirname(src), dst);
4354
+ const withoutExtension = relativePath.replace(/\.ts$/u, "");
4355
+ const normalizedPath = withoutExtension.split(Path$1.sep).join("/");
4356
+ return normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
4357
+ };
4324
4358
 
4325
4359
  const generateOpenApiClient = async (inputFile, {
4326
4360
  name,
@@ -4329,7 +4363,7 @@ const generateOpenApiClient = async (inputFile, {
4329
4363
  }, log) => {
4330
4364
  log(`Will generate API client name=${name} to ${outputDir}`);
4331
4365
  const fileName = "index";
4332
- const dstFile = Path.join(outputDir, `${fileName}.ts`);
4366
+ const dstFile = Path$1.join(outputDir, `${fileName}.ts`);
4333
4367
  const prettier = await import('prettier');
4334
4368
  const prettierConfig = await prettier.resolveConfig(dstFile) ?? {};
4335
4369
  const prettierConfigForGenerator = {
@@ -4373,12 +4407,12 @@ const generateOpenApiClient = async (inputFile, {
4373
4407
  return { types: dstFile, promiseWrapper: [dstFile] };
4374
4408
  };
4375
4409
  const getThisScriptDirname = () => {
4376
- return Path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('generateApiClient.cjs', document.baseURI).href))));
4410
+ return Path$1.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('generateApiClient.cjs', document.baseURI).href))));
4377
4411
  };
4378
4412
  const getTemplatesDir = () => {
4379
4413
  const currentDir = getThisScriptDirname();
4380
- const templatesRelativePath = Path.basename(currentDir) === "dist" ? "../templates" : "../../../templates";
4381
- return Path.resolve(currentDir, templatesRelativePath);
4414
+ const templatesRelativePath = Path$1.basename(currentDir) === "dist" ? "../templates" : "../../../templates";
4415
+ return Path$1.resolve(currentDir, templatesRelativePath);
4382
4416
  };
4383
4417
 
4384
4418
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -5358,8 +5392,6 @@ const indentBlock = (value, indent) => {
5358
5392
  return value.split("\n").map((line) => `${indent}${line}`).join("\n");
5359
5393
  };
5360
5394
 
5361
- const EMPTY_LINE_MARKER = "/*__EMPTY_LINE_MARKER__*/";
5362
-
5363
5395
  var __defProp$5 = Object.defineProperty;
5364
5396
  var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5365
5397
  var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -6638,38 +6670,12 @@ class OperationProjector {
6638
6670
 
6639
6671
  var __defProp$1 = Object.defineProperty;
6640
6672
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6641
- var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, key + "" , value);
6642
- const EMPTY_LINE_MARKER_LINE = new RegExp(
6643
- `\\n[\\t ]*${EMPTY_LINE_MARKER.replaceAll("/", "\\/").replaceAll(
6644
- "*",
6645
- "\\*"
6646
- )}\\n`,
6647
- "g"
6648
- );
6649
- class CodeFormatter {
6650
- constructor(opts) {
6651
- this.opts = opts;
6652
- __publicField$1(this, "format", async (code) => {
6653
- const filePath = Path$1.resolve(this.opts.resolveConfFrom, "generated.ts");
6654
- const prettier = await import('prettier');
6655
- const prettierConfig = await prettier.resolveConfig(filePath) ?? {};
6656
- const formattedCode = await prettier.format(code, {
6657
- ...prettierConfig,
6658
- filepath: filePath
6659
- });
6660
- return formattedCode.replaceAll(EMPTY_LINE_MARKER_LINE, "\n\n");
6661
- });
6662
- }
6663
- }
6664
-
6665
- var __defProp = Object.defineProperty;
6666
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6667
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6673
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
6668
6674
  class CodeWriter {
6669
6675
  constructor(formatter) {
6670
6676
  this.formatter = formatter;
6671
- __publicField(this, "symbolChunkMap", /* @__PURE__ */ new Map());
6672
- __publicField(this, "write", async (dir, chunks) => {
6677
+ __publicField$1(this, "symbolChunkMap", /* @__PURE__ */ new Map());
6678
+ __publicField$1(this, "write", async (dir, chunks) => {
6673
6679
  this.symbolChunkMap = this.createSymbolChunkMap(chunks);
6674
6680
  fs$1.mkdirSync(dir, { recursive: true });
6675
6681
  for (const chunk of chunks) {
@@ -6684,7 +6690,7 @@ class CodeWriter {
6684
6690
  fs$1.writeFileSync(`${dir}/${chunk.name}.ts`, code, "utf8");
6685
6691
  }
6686
6692
  });
6687
- __publicField(this, "createSymbolChunkMap", (chunks) => {
6693
+ __publicField$1(this, "createSymbolChunkMap", (chunks) => {
6688
6694
  const map = /* @__PURE__ */ new Map();
6689
6695
  for (const chunk of chunks) {
6690
6696
  for (const exportedSymbol of chunk.exports) {
@@ -6698,7 +6704,7 @@ class CodeWriter {
6698
6704
  }
6699
6705
  return map;
6700
6706
  });
6701
- __publicField(this, "collectImports", (chunk) => {
6707
+ __publicField$1(this, "collectImports", (chunk) => {
6702
6708
  const imports = [];
6703
6709
  for (const ref of chunk.refs) {
6704
6710
  if (ref.kind === "builtin") continue;
@@ -6721,7 +6727,7 @@ class CodeWriter {
6721
6727
  }
6722
6728
  return imports;
6723
6729
  });
6724
- __publicField(this, "genImportStatements", (imports) => {
6730
+ __publicField$1(this, "genImportStatements", (imports) => {
6725
6731
  const symbolsBySource = groupBy(
6726
6732
  imports.map((i) => ({
6727
6733
  name: i.name,
@@ -6734,7 +6740,7 @@ class CodeWriter {
6734
6740
  return `import type { ${sortedSymbols.join(", ")} } from '${source}'`;
6735
6741
  });
6736
6742
  });
6737
- __publicField(this, "importSourcetoString", (src) => {
6743
+ __publicField$1(this, "importSourcetoString", (src) => {
6738
6744
  return "externalModule" in src ? src.externalModule : (
6739
6745
  // TODO generalize later when we have different paths
6740
6746
  `./${src.name}`
@@ -6749,7 +6755,7 @@ class VNextOasClientGenerator {
6749
6755
  this.options = options;
6750
6756
  this.log = log;
6751
6757
  }
6752
- async generate(cmd) {
6758
+ async generate(cmd, formatter) {
6753
6759
  const { inputFile, outputDir, apiName } = cmd;
6754
6760
  this.log(`Will generate API client name=${apiName} to ${outputDir}`);
6755
6761
  const sourceSchema = await loadSourceSchema(inputFile);
@@ -6770,12 +6776,9 @@ class VNextOasClientGenerator {
6770
6776
  projectResult,
6771
6777
  this.options.codegen
6772
6778
  );
6773
- const codeFormatter = new CodeFormatter({
6774
- resolveConfFrom: outputDir
6775
- });
6776
- const writer = new CodeWriter(codeFormatter);
6779
+ const writer = new CodeWriter(formatter);
6777
6780
  await writer.write(outputDir, chunks.all);
6778
- const tsFilePath = (name) => Path.join(outputDir, `${name}.ts`);
6781
+ const tsFilePath = (name) => Path$1.join(outputDir, `${name}.ts`);
6779
6782
  return {
6780
6783
  promiseWrapper: chunks.promiseWrappersNames.map(tsFilePath),
6781
6784
  types: tsFilePath(chunks.typesName)
@@ -6841,7 +6844,7 @@ const toErrorMessage = (error) => {
6841
6844
  return error instanceof Error ? error.message : String(error);
6842
6845
  };
6843
6846
 
6844
- const generateOpenApiModel = async (spectPath, config, log) => {
6847
+ const generateOpenApiModel = async (spectPath, config, log, codeFormatter) => {
6845
6848
  let outFiles;
6846
6849
  const { openApiGenerator, responseWrapper } = config;
6847
6850
  if ("legacy" in openApiGenerator) {
@@ -6858,11 +6861,14 @@ const generateOpenApiModel = async (spectPath, config, log) => {
6858
6861
  outFiles = await new VNextOasClientGenerator(
6859
6862
  openApiGenerator,
6860
6863
  log
6861
- ).generate({
6862
- inputFile: spectPath,
6863
- apiName: config.apiName,
6864
- outputDir: config.dstDir
6865
- });
6864
+ ).generate(
6865
+ {
6866
+ inputFile: spectPath,
6867
+ apiName: config.apiName,
6868
+ outputDir: config.dstDir
6869
+ },
6870
+ codeFormatter
6871
+ );
6866
6872
  }
6867
6873
  if (responseWrapper) {
6868
6874
  await modifyHttpClientAsyncWrapper(
@@ -6951,34 +6957,33 @@ const findMatchingBrace = (code, openBraceIndex) => {
6951
6957
  return -1;
6952
6958
  };
6953
6959
 
6954
- const generateSchemas = async (inputFile, outputFile, opts = {}) => {
6955
- const code = fs$2.readFileSync(inputFile).toString();
6956
- const { getZodSchemasFile } = tsToZod.generate({
6957
- sourceText: removeGenericTypes(code)
6958
- });
6959
- let f = getZodSchemasFile(getModuleImportPath(inputFile, outputFile));
6960
- f = f.replaceAll(".optional()", ".nullable()");
6961
- if (opts.localDateTimes) {
6962
- f = f.replaceAll(
6963
- "z.string().datetime()",
6964
- "z.string().datetime({local: true})"
6965
- );
6960
+ var __defProp = Object.defineProperty;
6961
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6962
+ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
6963
+ class ZodSchemaGenerator {
6964
+ constructor(codeFormatter) {
6965
+ this.codeFormatter = codeFormatter;
6966
+ __publicField(this, "generate", async ({
6967
+ sourceText,
6968
+ moduleImportPath,
6969
+ options = {}
6970
+ }) => {
6971
+ const { getZodSchemasFile } = tsToZod.generate({
6972
+ sourceText: removeGenericTypes(sourceText)
6973
+ });
6974
+ let generated = getZodSchemasFile(moduleImportPath);
6975
+ generated = generated.replaceAll(".optional()", ".nullable()");
6976
+ generated = generated.replaceAll(".int64()", ".int()");
6977
+ if (options.localDateTimes) {
6978
+ generated = generated.replaceAll(
6979
+ "z.string().datetime()",
6980
+ "z.string().datetime({local: true})"
6981
+ );
6982
+ }
6983
+ return this.codeFormatter.format(generated);
6984
+ });
6966
6985
  }
6967
- const prettier = await import('prettier');
6968
- const prettierConfig = await prettier.resolveConfig(outputFile) ?? {};
6969
- const formatted = await prettier.format(f, {
6970
- ...prettierConfig,
6971
- filepath: outputFile
6972
- });
6973
- fs$2.writeFileSync(outputFile, formatted);
6974
- };
6975
- const getModuleImportPath = (inputFile, outputFile) => {
6976
- const sourceDir = Path.dirname(outputFile);
6977
- const relativePath = Path.relative(sourceDir, inputFile);
6978
- const withoutExtension = relativePath.replace(/\.ts$/u, "");
6979
- const normalizedPath = withoutExtension.split(Path.sep).join("/");
6980
- return normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
6981
- };
6986
+ }
6982
6987
 
6983
6988
  const generateApiClient = async (params, configFilePath, log = console.log) => {
6984
6989
  const config = parseProfileConfig(params, configFilePath);
@@ -6986,14 +6991,17 @@ const generateApiClient = async (params, configFilePath, log = console.log) => {
6986
6991
  };
6987
6992
  const generateApiClientFromConfig = async (config, log = console.log) => {
6988
6993
  const { dstDir, apiName, srcSpec, zodSchemas } = config;
6989
- const dir = Path.resolve(dstDir, apiName);
6994
+ const dir = Path$1.resolve(dstDir, apiName);
6990
6995
  if (!fs__namespace.existsSync(dir)) {
6991
6996
  log(`Creating dir ${dir}`);
6992
6997
  fs__namespace.mkdirSync(dir, {
6993
6998
  recursive: true
6994
6999
  });
6995
7000
  }
6996
- const clientDir = Path.resolve(dir, "client");
7001
+ const clientDir = Path$1.resolve(dir, "client");
7002
+ const formatter = new CodeFormatter({
7003
+ resolveConfFrom: dir
7004
+ });
6997
7005
  const specPath = await getSpecPath(srcSpec, dir, log);
6998
7006
  log(`Cleaning client output dir ${clientDir}`);
6999
7007
  fs__namespace.rmSync(clientDir, {
@@ -7009,15 +7017,20 @@ const generateApiClientFromConfig = async (config, log = console.log) => {
7009
7017
  ...config,
7010
7018
  dstDir: clientDir
7011
7019
  },
7012
- log
7020
+ log,
7021
+ formatter
7013
7022
  );
7014
7023
  if (zodSchemas?.enabled === false) return;
7015
7024
  log("Generating Zod schemas");
7016
- await generateSchemas(
7017
- typesFilePath,
7018
- Path.resolve(dir, "./zod.ts"),
7019
- zodSchemas
7020
- );
7025
+ const zodOutputFile = Path$1.resolve(dir, "./zod.ts");
7026
+ const generator = new ZodSchemaGenerator(formatter);
7027
+ const sourceText = fs__namespace.readFileSync(typesFilePath, "utf8");
7028
+ const generated = await generator.generate({
7029
+ sourceText,
7030
+ moduleImportPath: findRelativePath(zodOutputFile, typesFilePath),
7031
+ options: zodSchemas
7032
+ });
7033
+ fs__namespace.writeFileSync(zodOutputFile, generated);
7021
7034
  };
7022
7035
  const getSpecPath = async (urlOrPath, dir, log) => {
7023
7036
  if (!urlOrPath.startsWith("http")) {
@@ -7025,7 +7038,7 @@ const getSpecPath = async (urlOrPath, dir, log) => {
7025
7038
  throw new Error(`Spec file ${urlOrPath} does not exists`);
7026
7039
  return urlOrPath;
7027
7040
  }
7028
- const specPath = Path.resolve(dir, `spec.json`);
7041
+ const specPath = Path$1.resolve(dir, `spec.json`);
7029
7042
  log(`Will download the API spec from ${urlOrPath} to ${specPath}`);
7030
7043
  await downloadSpec(specPath, urlOrPath);
7031
7044
  return specPath;
@@ -1,11 +1,10 @@
1
- import Path from 'path';
1
+ import Path$1 from 'path';
2
2
  import * as fs from 'fs';
3
- import fs__default$1 from 'fs';
4
3
  import fs$1 from 'fs/promises';
4
+ import Path from 'node:path';
5
5
  import { generateApi } from 'swagger-typescript-api';
6
6
  import { fileURLToPath } from 'node:url';
7
7
  import { readFile } from 'node:fs/promises';
8
- import Path$1 from 'node:path';
9
8
  import fs__default from 'node:fs';
10
9
  import { generate } from 'ts-to-zod';
11
10
 
@@ -4280,6 +4279,34 @@ const downloadSpec = async (path, url) => {
4280
4279
  await fs$1.writeFile(path, content);
4281
4280
  };
4282
4281
 
4282
+ const EMPTY_LINE_MARKER = "/*__EMPTY_LINE_MARKER__*/";
4283
+
4284
+ var __defProp$b = Object.defineProperty;
4285
+ var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4286
+ var __publicField$b = (obj, key, value) => __defNormalProp$b(obj, key + "" , value);
4287
+ const EMPTY_LINE_MARKER_LINE = new RegExp(
4288
+ `\\n[\\t ]*${EMPTY_LINE_MARKER.replaceAll("/", "\\/").replaceAll(
4289
+ "*",
4290
+ "\\*"
4291
+ )}\\n`,
4292
+ "g"
4293
+ );
4294
+ class CodeFormatter {
4295
+ constructor(opts) {
4296
+ this.opts = opts;
4297
+ __publicField$b(this, "format", async (code) => {
4298
+ const filePath = Path.resolve(this.opts.resolveConfFrom, "generated.ts");
4299
+ const prettier = await import('prettier');
4300
+ const prettierConfig = await prettier.resolveConfig(filePath) ?? {};
4301
+ const formattedCode = await prettier.format(code, {
4302
+ ...prettierConfig,
4303
+ filepath: filePath
4304
+ });
4305
+ return formattedCode.replaceAll(EMPTY_LINE_MARKER_LINE, "\n\n");
4306
+ });
4307
+ }
4308
+ }
4309
+
4283
4310
  const toPascalCaseIdentifier = (str) => {
4284
4311
  const words = str.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/).filter(Boolean);
4285
4312
  const pascalCase = words.map((word) => word[0].toUpperCase() + word.substring(1)).join("");
@@ -4300,6 +4327,12 @@ const groupBy = (values, getKey) => {
4300
4327
  }
4301
4328
  return groups;
4302
4329
  };
4330
+ const findRelativePath = (src, dst) => {
4331
+ const relativePath = Path$1.relative(Path$1.dirname(src), dst);
4332
+ const withoutExtension = relativePath.replace(/\.ts$/u, "");
4333
+ const normalizedPath = withoutExtension.split(Path$1.sep).join("/");
4334
+ return normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
4335
+ };
4303
4336
 
4304
4337
  const generateOpenApiClient = async (inputFile, {
4305
4338
  name,
@@ -4308,7 +4341,7 @@ const generateOpenApiClient = async (inputFile, {
4308
4341
  }, log) => {
4309
4342
  log(`Will generate API client name=${name} to ${outputDir}`);
4310
4343
  const fileName = "index";
4311
- const dstFile = Path.join(outputDir, `${fileName}.ts`);
4344
+ const dstFile = Path$1.join(outputDir, `${fileName}.ts`);
4312
4345
  const prettier = await import('prettier');
4313
4346
  const prettierConfig = await prettier.resolveConfig(dstFile) ?? {};
4314
4347
  const prettierConfigForGenerator = {
@@ -4352,12 +4385,12 @@ const generateOpenApiClient = async (inputFile, {
4352
4385
  return { types: dstFile, promiseWrapper: [dstFile] };
4353
4386
  };
4354
4387
  const getThisScriptDirname = () => {
4355
- return Path.dirname(fileURLToPath(import.meta.url));
4388
+ return Path$1.dirname(fileURLToPath(import.meta.url));
4356
4389
  };
4357
4390
  const getTemplatesDir = () => {
4358
4391
  const currentDir = getThisScriptDirname();
4359
- const templatesRelativePath = Path.basename(currentDir) === "dist" ? "../templates" : "../../../templates";
4360
- return Path.resolve(currentDir, templatesRelativePath);
4392
+ const templatesRelativePath = Path$1.basename(currentDir) === "dist" ? "../templates" : "../../../templates";
4393
+ return Path$1.resolve(currentDir, templatesRelativePath);
4361
4394
  };
4362
4395
 
4363
4396
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -5337,8 +5370,6 @@ const indentBlock = (value, indent) => {
5337
5370
  return value.split("\n").map((line) => `${indent}${line}`).join("\n");
5338
5371
  };
5339
5372
 
5340
- const EMPTY_LINE_MARKER = "/*__EMPTY_LINE_MARKER__*/";
5341
-
5342
5373
  var __defProp$5 = Object.defineProperty;
5343
5374
  var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5344
5375
  var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -6617,38 +6648,12 @@ class OperationProjector {
6617
6648
 
6618
6649
  var __defProp$1 = Object.defineProperty;
6619
6650
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6620
- var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, key + "" , value);
6621
- const EMPTY_LINE_MARKER_LINE = new RegExp(
6622
- `\\n[\\t ]*${EMPTY_LINE_MARKER.replaceAll("/", "\\/").replaceAll(
6623
- "*",
6624
- "\\*"
6625
- )}\\n`,
6626
- "g"
6627
- );
6628
- class CodeFormatter {
6629
- constructor(opts) {
6630
- this.opts = opts;
6631
- __publicField$1(this, "format", async (code) => {
6632
- const filePath = Path$1.resolve(this.opts.resolveConfFrom, "generated.ts");
6633
- const prettier = await import('prettier');
6634
- const prettierConfig = await prettier.resolveConfig(filePath) ?? {};
6635
- const formattedCode = await prettier.format(code, {
6636
- ...prettierConfig,
6637
- filepath: filePath
6638
- });
6639
- return formattedCode.replaceAll(EMPTY_LINE_MARKER_LINE, "\n\n");
6640
- });
6641
- }
6642
- }
6643
-
6644
- var __defProp = Object.defineProperty;
6645
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6646
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6651
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
6647
6652
  class CodeWriter {
6648
6653
  constructor(formatter) {
6649
6654
  this.formatter = formatter;
6650
- __publicField(this, "symbolChunkMap", /* @__PURE__ */ new Map());
6651
- __publicField(this, "write", async (dir, chunks) => {
6655
+ __publicField$1(this, "symbolChunkMap", /* @__PURE__ */ new Map());
6656
+ __publicField$1(this, "write", async (dir, chunks) => {
6652
6657
  this.symbolChunkMap = this.createSymbolChunkMap(chunks);
6653
6658
  fs__default.mkdirSync(dir, { recursive: true });
6654
6659
  for (const chunk of chunks) {
@@ -6663,7 +6668,7 @@ class CodeWriter {
6663
6668
  fs__default.writeFileSync(`${dir}/${chunk.name}.ts`, code, "utf8");
6664
6669
  }
6665
6670
  });
6666
- __publicField(this, "createSymbolChunkMap", (chunks) => {
6671
+ __publicField$1(this, "createSymbolChunkMap", (chunks) => {
6667
6672
  const map = /* @__PURE__ */ new Map();
6668
6673
  for (const chunk of chunks) {
6669
6674
  for (const exportedSymbol of chunk.exports) {
@@ -6677,7 +6682,7 @@ class CodeWriter {
6677
6682
  }
6678
6683
  return map;
6679
6684
  });
6680
- __publicField(this, "collectImports", (chunk) => {
6685
+ __publicField$1(this, "collectImports", (chunk) => {
6681
6686
  const imports = [];
6682
6687
  for (const ref of chunk.refs) {
6683
6688
  if (ref.kind === "builtin") continue;
@@ -6700,7 +6705,7 @@ class CodeWriter {
6700
6705
  }
6701
6706
  return imports;
6702
6707
  });
6703
- __publicField(this, "genImportStatements", (imports) => {
6708
+ __publicField$1(this, "genImportStatements", (imports) => {
6704
6709
  const symbolsBySource = groupBy(
6705
6710
  imports.map((i) => ({
6706
6711
  name: i.name,
@@ -6713,7 +6718,7 @@ class CodeWriter {
6713
6718
  return `import type { ${sortedSymbols.join(", ")} } from '${source}'`;
6714
6719
  });
6715
6720
  });
6716
- __publicField(this, "importSourcetoString", (src) => {
6721
+ __publicField$1(this, "importSourcetoString", (src) => {
6717
6722
  return "externalModule" in src ? src.externalModule : (
6718
6723
  // TODO generalize later when we have different paths
6719
6724
  `./${src.name}`
@@ -6728,7 +6733,7 @@ class VNextOasClientGenerator {
6728
6733
  this.options = options;
6729
6734
  this.log = log;
6730
6735
  }
6731
- async generate(cmd) {
6736
+ async generate(cmd, formatter) {
6732
6737
  const { inputFile, outputDir, apiName } = cmd;
6733
6738
  this.log(`Will generate API client name=${apiName} to ${outputDir}`);
6734
6739
  const sourceSchema = await loadSourceSchema(inputFile);
@@ -6749,12 +6754,9 @@ class VNextOasClientGenerator {
6749
6754
  projectResult,
6750
6755
  this.options.codegen
6751
6756
  );
6752
- const codeFormatter = new CodeFormatter({
6753
- resolveConfFrom: outputDir
6754
- });
6755
- const writer = new CodeWriter(codeFormatter);
6757
+ const writer = new CodeWriter(formatter);
6756
6758
  await writer.write(outputDir, chunks.all);
6757
- const tsFilePath = (name) => Path.join(outputDir, `${name}.ts`);
6759
+ const tsFilePath = (name) => Path$1.join(outputDir, `${name}.ts`);
6758
6760
  return {
6759
6761
  promiseWrapper: chunks.promiseWrappersNames.map(tsFilePath),
6760
6762
  types: tsFilePath(chunks.typesName)
@@ -6820,7 +6822,7 @@ const toErrorMessage = (error) => {
6820
6822
  return error instanceof Error ? error.message : String(error);
6821
6823
  };
6822
6824
 
6823
- const generateOpenApiModel = async (spectPath, config, log) => {
6825
+ const generateOpenApiModel = async (spectPath, config, log, codeFormatter) => {
6824
6826
  let outFiles;
6825
6827
  const { openApiGenerator, responseWrapper } = config;
6826
6828
  if ("legacy" in openApiGenerator) {
@@ -6837,11 +6839,14 @@ const generateOpenApiModel = async (spectPath, config, log) => {
6837
6839
  outFiles = await new VNextOasClientGenerator(
6838
6840
  openApiGenerator,
6839
6841
  log
6840
- ).generate({
6841
- inputFile: spectPath,
6842
- apiName: config.apiName,
6843
- outputDir: config.dstDir
6844
- });
6842
+ ).generate(
6843
+ {
6844
+ inputFile: spectPath,
6845
+ apiName: config.apiName,
6846
+ outputDir: config.dstDir
6847
+ },
6848
+ codeFormatter
6849
+ );
6845
6850
  }
6846
6851
  if (responseWrapper) {
6847
6852
  await modifyHttpClientAsyncWrapper(
@@ -6930,34 +6935,33 @@ const findMatchingBrace = (code, openBraceIndex) => {
6930
6935
  return -1;
6931
6936
  };
6932
6937
 
6933
- const generateSchemas = async (inputFile, outputFile, opts = {}) => {
6934
- const code = fs__default$1.readFileSync(inputFile).toString();
6935
- const { getZodSchemasFile } = generate({
6936
- sourceText: removeGenericTypes(code)
6937
- });
6938
- let f = getZodSchemasFile(getModuleImportPath(inputFile, outputFile));
6939
- f = f.replaceAll(".optional()", ".nullable()");
6940
- if (opts.localDateTimes) {
6941
- f = f.replaceAll(
6942
- "z.string().datetime()",
6943
- "z.string().datetime({local: true})"
6944
- );
6938
+ var __defProp = Object.defineProperty;
6939
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6940
+ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
6941
+ class ZodSchemaGenerator {
6942
+ constructor(codeFormatter) {
6943
+ this.codeFormatter = codeFormatter;
6944
+ __publicField(this, "generate", async ({
6945
+ sourceText,
6946
+ moduleImportPath,
6947
+ options = {}
6948
+ }) => {
6949
+ const { getZodSchemasFile } = generate({
6950
+ sourceText: removeGenericTypes(sourceText)
6951
+ });
6952
+ let generated = getZodSchemasFile(moduleImportPath);
6953
+ generated = generated.replaceAll(".optional()", ".nullable()");
6954
+ generated = generated.replaceAll(".int64()", ".int()");
6955
+ if (options.localDateTimes) {
6956
+ generated = generated.replaceAll(
6957
+ "z.string().datetime()",
6958
+ "z.string().datetime({local: true})"
6959
+ );
6960
+ }
6961
+ return this.codeFormatter.format(generated);
6962
+ });
6945
6963
  }
6946
- const prettier = await import('prettier');
6947
- const prettierConfig = await prettier.resolveConfig(outputFile) ?? {};
6948
- const formatted = await prettier.format(f, {
6949
- ...prettierConfig,
6950
- filepath: outputFile
6951
- });
6952
- fs__default$1.writeFileSync(outputFile, formatted);
6953
- };
6954
- const getModuleImportPath = (inputFile, outputFile) => {
6955
- const sourceDir = Path.dirname(outputFile);
6956
- const relativePath = Path.relative(sourceDir, inputFile);
6957
- const withoutExtension = relativePath.replace(/\.ts$/u, "");
6958
- const normalizedPath = withoutExtension.split(Path.sep).join("/");
6959
- return normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
6960
- };
6964
+ }
6961
6965
 
6962
6966
  const generateApiClient = async (params, configFilePath, log = console.log) => {
6963
6967
  const config = parseProfileConfig(params, configFilePath);
@@ -6965,14 +6969,17 @@ const generateApiClient = async (params, configFilePath, log = console.log) => {
6965
6969
  };
6966
6970
  const generateApiClientFromConfig = async (config, log = console.log) => {
6967
6971
  const { dstDir, apiName, srcSpec, zodSchemas } = config;
6968
- const dir = Path.resolve(dstDir, apiName);
6972
+ const dir = Path$1.resolve(dstDir, apiName);
6969
6973
  if (!fs.existsSync(dir)) {
6970
6974
  log(`Creating dir ${dir}`);
6971
6975
  fs.mkdirSync(dir, {
6972
6976
  recursive: true
6973
6977
  });
6974
6978
  }
6975
- const clientDir = Path.resolve(dir, "client");
6979
+ const clientDir = Path$1.resolve(dir, "client");
6980
+ const formatter = new CodeFormatter({
6981
+ resolveConfFrom: dir
6982
+ });
6976
6983
  const specPath = await getSpecPath(srcSpec, dir, log);
6977
6984
  log(`Cleaning client output dir ${clientDir}`);
6978
6985
  fs.rmSync(clientDir, {
@@ -6988,15 +6995,20 @@ const generateApiClientFromConfig = async (config, log = console.log) => {
6988
6995
  ...config,
6989
6996
  dstDir: clientDir
6990
6997
  },
6991
- log
6998
+ log,
6999
+ formatter
6992
7000
  );
6993
7001
  if (zodSchemas?.enabled === false) return;
6994
7002
  log("Generating Zod schemas");
6995
- await generateSchemas(
6996
- typesFilePath,
6997
- Path.resolve(dir, "./zod.ts"),
6998
- zodSchemas
6999
- );
7003
+ const zodOutputFile = Path$1.resolve(dir, "./zod.ts");
7004
+ const generator = new ZodSchemaGenerator(formatter);
7005
+ const sourceText = fs.readFileSync(typesFilePath, "utf8");
7006
+ const generated = await generator.generate({
7007
+ sourceText,
7008
+ moduleImportPath: findRelativePath(zodOutputFile, typesFilePath),
7009
+ options: zodSchemas
7010
+ });
7011
+ fs.writeFileSync(zodOutputFile, generated);
7000
7012
  };
7001
7013
  const getSpecPath = async (urlOrPath, dir, log) => {
7002
7014
  if (!urlOrPath.startsWith("http")) {
@@ -7004,7 +7016,7 @@ const getSpecPath = async (urlOrPath, dir, log) => {
7004
7016
  throw new Error(`Spec file ${urlOrPath} does not exists`);
7005
7017
  return urlOrPath;
7006
7018
  }
7007
- const specPath = Path.resolve(dir, `spec.json`);
7019
+ const specPath = Path$1.resolve(dir, `spec.json`);
7008
7020
  log(`Will download the API spec from ${urlOrPath} to ${specPath}`);
7009
7021
  await downloadSpec(specPath, urlOrPath);
7010
7022
  return specPath;
package/dist/index.cjs CHANGED
@@ -4,10 +4,10 @@ var generateApiClient = require('./generateApiClient.cjs');
4
4
  require('path');
5
5
  require('fs');
6
6
  require('fs/promises');
7
+ require('node:path');
7
8
  require('swagger-typescript-api');
8
9
  require('node:url');
9
10
  require('node:fs/promises');
10
- require('node:path');
11
11
  require('node:fs');
12
12
  require('ts-to-zod');
13
13
 
package/dist/index.mjs CHANGED
@@ -2,9 +2,9 @@ export { d as defineConfig, g as generateApiClient } from './generateApiClient.m
2
2
  import 'path';
3
3
  import 'fs';
4
4
  import 'fs/promises';
5
+ import 'node:path';
5
6
  import 'swagger-typescript-api';
6
7
  import 'node:url';
7
8
  import 'node:fs/promises';
8
- import 'node:path';
9
9
  import 'node:fs';
10
10
  import 'ts-to-zod';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ps-aux/api-client-gen",
3
- "version": "0.7.0-rc.4",
3
+ "version": "0.7.0-rc.5",
4
4
  "main": "dist/index.cjs",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,8 +14,8 @@
14
14
  "pack:tarball": "npm run build && npm pack",
15
15
  "prepublishOnly": "echo \"Publishing disabled for this repo. Use CI workflow.\" && exit 1",
16
16
  "test": "npm run test:generation && npm run test:generated-code && npm run tc:after-gen",
17
- "test:generation": "vitest run test/generateApiClient.spec.ts test/e2e/e2e.spec.ts test/gen-open-api/*/generate*.spec.ts test/gen-open-api/*/integration.spec.ts",
18
- "test:generated-code": "vitest run test/gen-open-api/swagger-ts-api/contract.spec.ts test/gen-open-api/v-next/contract.spec.ts",
17
+ "test:generation": "vitest run --project generation",
18
+ "test:generated-code": "vitest run --project generated-code",
19
19
  "tc": "echo 'No typecheck'",
20
20
  "tc:after-gen": "tsc",
21
21
  "tc:v-next-compat": "tsc -p tsconfig.v-next-compat.json"