@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.
- package/dist/generateApiClient.cjs +102 -89
- package/dist/generateApiClient.mjs +102 -90
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
|
@@ -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
|
|
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
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
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
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
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
|
-
|
|
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
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
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
|
|
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
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
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
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
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.
|
|
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
|
|
18
|
-
"test:generated-code": "vitest run
|
|
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"
|