@ps-aux/api-client-gen 0.7.0-rc.3 → 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/README.md +7 -5
- package/dist/bin.cjs +74 -9
- package/dist/bin.mjs +56 -10
- package/dist/generateApiClient.cjs +661 -166
- package/dist/generateApiClient.mjs +662 -171
- package/dist/index.cjs +2 -1
- package/dist/index.d.cts +80 -5
- package/dist/index.d.mts +80 -5
- package/dist/index.d.ts +80 -5
- package/dist/index.mjs +2 -2
- package/package.json +7 -5
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import Path from 'path';
|
|
1
|
+
import Path$1 from 'path';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
|
-
import fs__default 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
|
|
9
|
-
import fs$2 from 'node:fs';
|
|
8
|
+
import fs__default from 'node:fs';
|
|
10
9
|
import { generate } from 'ts-to-zod';
|
|
11
10
|
|
|
12
11
|
/** A special constant with type `never` */
|
|
@@ -701,6 +700,7 @@ const string$1 = (params) => {
|
|
|
701
700
|
const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
|
|
702
701
|
return new RegExp(`^${regex}$`);
|
|
703
702
|
};
|
|
703
|
+
const number = /^-?\d+(?:\.\d+)?$/;
|
|
704
704
|
const boolean$1 = /^(?:true|false)$/i;
|
|
705
705
|
// regex for string with no uppercase letters
|
|
706
706
|
const lowercase = /^[^A-Z]*$/;
|
|
@@ -1897,6 +1897,122 @@ function handleIntersectionResults(result, left, right) {
|
|
|
1897
1897
|
result.value = merged.data;
|
|
1898
1898
|
return result;
|
|
1899
1899
|
}
|
|
1900
|
+
const $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
|
|
1901
|
+
$ZodType.init(inst, def);
|
|
1902
|
+
inst._zod.parse = (payload, ctx) => {
|
|
1903
|
+
const input = payload.value;
|
|
1904
|
+
if (!isPlainObject(input)) {
|
|
1905
|
+
payload.issues.push({
|
|
1906
|
+
expected: "record",
|
|
1907
|
+
code: "invalid_type",
|
|
1908
|
+
input,
|
|
1909
|
+
inst,
|
|
1910
|
+
});
|
|
1911
|
+
return payload;
|
|
1912
|
+
}
|
|
1913
|
+
const proms = [];
|
|
1914
|
+
const values = def.keyType._zod.values;
|
|
1915
|
+
if (values) {
|
|
1916
|
+
payload.value = {};
|
|
1917
|
+
const recordKeys = new Set();
|
|
1918
|
+
for (const key of values) {
|
|
1919
|
+
if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
|
|
1920
|
+
recordKeys.add(typeof key === "number" ? key.toString() : key);
|
|
1921
|
+
const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);
|
|
1922
|
+
if (result instanceof Promise) {
|
|
1923
|
+
proms.push(result.then((result) => {
|
|
1924
|
+
if (result.issues.length) {
|
|
1925
|
+
payload.issues.push(...prefixIssues(key, result.issues));
|
|
1926
|
+
}
|
|
1927
|
+
payload.value[key] = result.value;
|
|
1928
|
+
}));
|
|
1929
|
+
}
|
|
1930
|
+
else {
|
|
1931
|
+
if (result.issues.length) {
|
|
1932
|
+
payload.issues.push(...prefixIssues(key, result.issues));
|
|
1933
|
+
}
|
|
1934
|
+
payload.value[key] = result.value;
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
let unrecognized;
|
|
1939
|
+
for (const key in input) {
|
|
1940
|
+
if (!recordKeys.has(key)) {
|
|
1941
|
+
unrecognized = unrecognized ?? [];
|
|
1942
|
+
unrecognized.push(key);
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
if (unrecognized && unrecognized.length > 0) {
|
|
1946
|
+
payload.issues.push({
|
|
1947
|
+
code: "unrecognized_keys",
|
|
1948
|
+
input,
|
|
1949
|
+
inst,
|
|
1950
|
+
keys: unrecognized,
|
|
1951
|
+
});
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
else {
|
|
1955
|
+
payload.value = {};
|
|
1956
|
+
for (const key of Reflect.ownKeys(input)) {
|
|
1957
|
+
if (key === "__proto__")
|
|
1958
|
+
continue;
|
|
1959
|
+
let keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);
|
|
1960
|
+
if (keyResult instanceof Promise) {
|
|
1961
|
+
throw new Error("Async schemas not supported in object keys currently");
|
|
1962
|
+
}
|
|
1963
|
+
// Numeric string fallback: if key is a numeric string and failed, retry with Number(key)
|
|
1964
|
+
// This handles z.number(), z.literal([1, 2, 3]), and unions containing numeric literals
|
|
1965
|
+
const checkNumericKey = typeof key === "string" && number.test(key) && keyResult.issues.length;
|
|
1966
|
+
if (checkNumericKey) {
|
|
1967
|
+
const retryResult = def.keyType._zod.run({ value: Number(key), issues: [] }, ctx);
|
|
1968
|
+
if (retryResult instanceof Promise) {
|
|
1969
|
+
throw new Error("Async schemas not supported in object keys currently");
|
|
1970
|
+
}
|
|
1971
|
+
if (retryResult.issues.length === 0) {
|
|
1972
|
+
keyResult = retryResult;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
if (keyResult.issues.length) {
|
|
1976
|
+
if (def.mode === "loose") {
|
|
1977
|
+
// Pass through unchanged
|
|
1978
|
+
payload.value[key] = input[key];
|
|
1979
|
+
}
|
|
1980
|
+
else {
|
|
1981
|
+
// Default "strict" behavior: error on invalid key
|
|
1982
|
+
payload.issues.push({
|
|
1983
|
+
code: "invalid_key",
|
|
1984
|
+
origin: "record",
|
|
1985
|
+
issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
|
|
1986
|
+
input: key,
|
|
1987
|
+
path: [key],
|
|
1988
|
+
inst,
|
|
1989
|
+
});
|
|
1990
|
+
}
|
|
1991
|
+
continue;
|
|
1992
|
+
}
|
|
1993
|
+
const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);
|
|
1994
|
+
if (result instanceof Promise) {
|
|
1995
|
+
proms.push(result.then((result) => {
|
|
1996
|
+
if (result.issues.length) {
|
|
1997
|
+
payload.issues.push(...prefixIssues(key, result.issues));
|
|
1998
|
+
}
|
|
1999
|
+
payload.value[keyResult.value] = result.value;
|
|
2000
|
+
}));
|
|
2001
|
+
}
|
|
2002
|
+
else {
|
|
2003
|
+
if (result.issues.length) {
|
|
2004
|
+
payload.issues.push(...prefixIssues(key, result.issues));
|
|
2005
|
+
}
|
|
2006
|
+
payload.value[keyResult.value] = result.value;
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
if (proms.length) {
|
|
2011
|
+
return Promise.all(proms).then(() => payload);
|
|
2012
|
+
}
|
|
2013
|
+
return payload;
|
|
2014
|
+
};
|
|
2015
|
+
});
|
|
1900
2016
|
const $ZodEnum = /*@__PURE__*/ $constructor("$ZodEnum", (inst, def) => {
|
|
1901
2017
|
$ZodType.init(inst, def);
|
|
1902
2018
|
const values = getEnumValues(def.entries);
|
|
@@ -3293,6 +3409,49 @@ const intersectionProcessor = (schema, ctx, json, params) => {
|
|
|
3293
3409
|
];
|
|
3294
3410
|
json.allOf = allOf;
|
|
3295
3411
|
};
|
|
3412
|
+
const recordProcessor = (schema, ctx, _json, params) => {
|
|
3413
|
+
const json = _json;
|
|
3414
|
+
const def = schema._zod.def;
|
|
3415
|
+
json.type = "object";
|
|
3416
|
+
// For looseRecord with regex patterns, use patternProperties
|
|
3417
|
+
// This correctly represents "only validate keys matching the pattern" semantics
|
|
3418
|
+
// and composes well with allOf (intersections)
|
|
3419
|
+
const keyType = def.keyType;
|
|
3420
|
+
const keyBag = keyType._zod.bag;
|
|
3421
|
+
const patterns = keyBag?.patterns;
|
|
3422
|
+
if (def.mode === "loose" && patterns && patterns.size > 0) {
|
|
3423
|
+
// Use patternProperties for looseRecord with regex patterns
|
|
3424
|
+
const valueSchema = process(def.valueType, ctx, {
|
|
3425
|
+
...params,
|
|
3426
|
+
path: [...params.path, "patternProperties", "*"],
|
|
3427
|
+
});
|
|
3428
|
+
json.patternProperties = {};
|
|
3429
|
+
for (const pattern of patterns) {
|
|
3430
|
+
json.patternProperties[pattern.source] = valueSchema;
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
else {
|
|
3434
|
+
// Default behavior: use propertyNames + additionalProperties
|
|
3435
|
+
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
|
|
3436
|
+
json.propertyNames = process(def.keyType, ctx, {
|
|
3437
|
+
...params,
|
|
3438
|
+
path: [...params.path, "propertyNames"],
|
|
3439
|
+
});
|
|
3440
|
+
}
|
|
3441
|
+
json.additionalProperties = process(def.valueType, ctx, {
|
|
3442
|
+
...params,
|
|
3443
|
+
path: [...params.path, "additionalProperties"],
|
|
3444
|
+
});
|
|
3445
|
+
}
|
|
3446
|
+
// Add required for keys with discrete values (enum, literal, etc.)
|
|
3447
|
+
const keyValues = keyType._zod.values;
|
|
3448
|
+
if (keyValues) {
|
|
3449
|
+
const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
|
|
3450
|
+
if (validKeyValues.length > 0) {
|
|
3451
|
+
json.required = validKeyValues;
|
|
3452
|
+
}
|
|
3453
|
+
}
|
|
3454
|
+
};
|
|
3296
3455
|
const nullableProcessor = (schema, ctx, json, params) => {
|
|
3297
3456
|
const def = schema._zod.def;
|
|
3298
3457
|
const inner = process(def.innerType, ctx, params);
|
|
@@ -3796,6 +3955,21 @@ function intersection(left, right) {
|
|
|
3796
3955
|
right: right,
|
|
3797
3956
|
});
|
|
3798
3957
|
}
|
|
3958
|
+
const ZodRecord = /*@__PURE__*/ $constructor("ZodRecord", (inst, def) => {
|
|
3959
|
+
$ZodRecord.init(inst, def);
|
|
3960
|
+
ZodType.init(inst, def);
|
|
3961
|
+
inst._zod.processJSONSchema = (ctx, json, params) => recordProcessor(inst, ctx, json, params);
|
|
3962
|
+
inst.keyType = def.keyType;
|
|
3963
|
+
inst.valueType = def.valueType;
|
|
3964
|
+
});
|
|
3965
|
+
function record(keyType, valueType, params) {
|
|
3966
|
+
return new ZodRecord({
|
|
3967
|
+
type: "record",
|
|
3968
|
+
keyType,
|
|
3969
|
+
valueType: valueType,
|
|
3970
|
+
...normalizeParams(params),
|
|
3971
|
+
});
|
|
3972
|
+
}
|
|
3799
3973
|
const ZodEnum = /*@__PURE__*/ $constructor("ZodEnum", (inst, def) => {
|
|
3800
3974
|
$ZodEnum.init(inst, def);
|
|
3801
3975
|
ZodType.init(inst, def);
|
|
@@ -4028,8 +4202,19 @@ const vNextOasGeneratorSchema = strictObject({
|
|
|
4028
4202
|
unwrap: boolean().default(true),
|
|
4029
4203
|
withRequestParams: boolean().default(false),
|
|
4030
4204
|
pathParamsStyle: _enum(["object", "positional"]).default("positional"),
|
|
4031
|
-
enumStyle: _enum(["enum", "union"]).default("enum")
|
|
4032
|
-
|
|
4205
|
+
enumStyle: _enum(["enum", "union"]).default("enum"),
|
|
4206
|
+
comments: strictObject({
|
|
4207
|
+
enabled: boolean().default(true),
|
|
4208
|
+
operation: strictObject({
|
|
4209
|
+
tags: boolean().default(true),
|
|
4210
|
+
summary: boolean().default(true),
|
|
4211
|
+
description: boolean().default(true)
|
|
4212
|
+
}).prefault({}),
|
|
4213
|
+
schema: strictObject({
|
|
4214
|
+
metadata: boolean().default(true)
|
|
4215
|
+
}).prefault({})
|
|
4216
|
+
}).prefault({})
|
|
4217
|
+
}).prefault({}),
|
|
4033
4218
|
compat: strictObject({
|
|
4034
4219
|
uppercaseEnumKeys: boolean(),
|
|
4035
4220
|
swaggerTsApiRequiredBooleans: boolean()
|
|
@@ -4040,7 +4225,7 @@ const legacyOasGeneratorSchema = strictObject({
|
|
|
4040
4225
|
ignoreOperationsWithTags: array(string()).optional()
|
|
4041
4226
|
})
|
|
4042
4227
|
});
|
|
4043
|
-
const
|
|
4228
|
+
const profileConfigSchema = strictObject({
|
|
4044
4229
|
srcSpec: string().trim().min(1),
|
|
4045
4230
|
dstDir: string().trim().min(1),
|
|
4046
4231
|
apiName: string().trim().min(1),
|
|
@@ -4058,6 +4243,8 @@ const configSchema = strictObject({
|
|
|
4058
4243
|
localDateTimes: boolean().optional()
|
|
4059
4244
|
}).optional()
|
|
4060
4245
|
});
|
|
4246
|
+
const configSchema = record(string(), profileConfigSchema);
|
|
4247
|
+
const defineConfig = (config) => config;
|
|
4061
4248
|
const parseConfig = (userConfig, filePath) => {
|
|
4062
4249
|
const parsed = configSchema.safeParse(userConfig);
|
|
4063
4250
|
if (parsed.success) return parsed.data;
|
|
@@ -4065,6 +4252,13 @@ const parseConfig = (userConfig, filePath) => {
|
|
|
4065
4252
|
cause: parsed.error
|
|
4066
4253
|
});
|
|
4067
4254
|
};
|
|
4255
|
+
const parseProfileConfig = (userConfig, filePath) => {
|
|
4256
|
+
const parsed = profileConfigSchema.safeParse(userConfig);
|
|
4257
|
+
if (parsed.success) return parsed.data;
|
|
4258
|
+
throw new Error(`Invalid config at ${filePath}: ${parsed.error.message}`, {
|
|
4259
|
+
cause: parsed.error
|
|
4260
|
+
});
|
|
4261
|
+
};
|
|
4068
4262
|
|
|
4069
4263
|
const downloadSpec = async (path, url) => {
|
|
4070
4264
|
let response;
|
|
@@ -4085,6 +4279,34 @@ const downloadSpec = async (path, url) => {
|
|
|
4085
4279
|
await fs$1.writeFile(path, content);
|
|
4086
4280
|
};
|
|
4087
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
|
+
|
|
4088
4310
|
const toPascalCaseIdentifier = (str) => {
|
|
4089
4311
|
const words = str.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/).filter(Boolean);
|
|
4090
4312
|
const pascalCase = words.map((word) => word[0].toUpperCase() + word.substring(1)).join("");
|
|
@@ -4105,6 +4327,12 @@ const groupBy = (values, getKey) => {
|
|
|
4105
4327
|
}
|
|
4106
4328
|
return groups;
|
|
4107
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
|
+
};
|
|
4108
4336
|
|
|
4109
4337
|
const generateOpenApiClient = async (inputFile, {
|
|
4110
4338
|
name,
|
|
@@ -4113,7 +4341,7 @@ const generateOpenApiClient = async (inputFile, {
|
|
|
4113
4341
|
}, log) => {
|
|
4114
4342
|
log(`Will generate API client name=${name} to ${outputDir}`);
|
|
4115
4343
|
const fileName = "index";
|
|
4116
|
-
const dstFile = Path.join(outputDir, `${fileName}.ts`);
|
|
4344
|
+
const dstFile = Path$1.join(outputDir, `${fileName}.ts`);
|
|
4117
4345
|
const prettier = await import('prettier');
|
|
4118
4346
|
const prettierConfig = await prettier.resolveConfig(dstFile) ?? {};
|
|
4119
4347
|
const prettierConfigForGenerator = {
|
|
@@ -4157,12 +4385,12 @@ const generateOpenApiClient = async (inputFile, {
|
|
|
4157
4385
|
return { types: dstFile, promiseWrapper: [dstFile] };
|
|
4158
4386
|
};
|
|
4159
4387
|
const getThisScriptDirname = () => {
|
|
4160
|
-
return Path.dirname(fileURLToPath(import.meta.url));
|
|
4388
|
+
return Path$1.dirname(fileURLToPath(import.meta.url));
|
|
4161
4389
|
};
|
|
4162
4390
|
const getTemplatesDir = () => {
|
|
4163
4391
|
const currentDir = getThisScriptDirname();
|
|
4164
|
-
const templatesRelativePath = Path.basename(currentDir) === "dist" ? "../templates" : "../../../templates";
|
|
4165
|
-
return Path.resolve(currentDir, templatesRelativePath);
|
|
4392
|
+
const templatesRelativePath = Path$1.basename(currentDir) === "dist" ? "../templates" : "../../../templates";
|
|
4393
|
+
return Path$1.resolve(currentDir, templatesRelativePath);
|
|
4166
4394
|
};
|
|
4167
4395
|
|
|
4168
4396
|
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -4219,9 +4447,9 @@ const resolveLocalRef = (root, ref) => {
|
|
|
4219
4447
|
return current;
|
|
4220
4448
|
};
|
|
4221
4449
|
|
|
4222
|
-
var __defProp$
|
|
4223
|
-
var __defNormalProp$
|
|
4224
|
-
var __publicField$
|
|
4450
|
+
var __defProp$a = Object.defineProperty;
|
|
4451
|
+
var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4452
|
+
var __publicField$a = (obj, key, value) => __defNormalProp$a(obj, key + "" , value);
|
|
4225
4453
|
const PARAMETER_LOCATIONS = [
|
|
4226
4454
|
"path",
|
|
4227
4455
|
"query",
|
|
@@ -4247,7 +4475,7 @@ const mergeParameters = (base, override) => {
|
|
|
4247
4475
|
class OpenApiNormalizer {
|
|
4248
4476
|
constructor(doc) {
|
|
4249
4477
|
this.doc = doc;
|
|
4250
|
-
__publicField$
|
|
4478
|
+
__publicField$a(this, "problems", []);
|
|
4251
4479
|
}
|
|
4252
4480
|
load() {
|
|
4253
4481
|
const info = readRecord(this.doc, "info");
|
|
@@ -4590,23 +4818,24 @@ const syntheticOperationId = (method, path) => {
|
|
|
4590
4818
|
return `_${compact}`;
|
|
4591
4819
|
};
|
|
4592
4820
|
|
|
4593
|
-
var __defProp$
|
|
4594
|
-
var __defNormalProp$
|
|
4595
|
-
var __publicField$
|
|
4821
|
+
var __defProp$9 = Object.defineProperty;
|
|
4822
|
+
var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4823
|
+
var __publicField$9 = (obj, key, value) => __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4596
4824
|
class TsCodegen {
|
|
4597
|
-
constructor(typeExprCodegen) {
|
|
4825
|
+
constructor(typeExprCodegen, docRenderer) {
|
|
4598
4826
|
this.typeExprCodegen = typeExprCodegen;
|
|
4599
|
-
__publicField$
|
|
4600
|
-
__publicField$
|
|
4601
|
-
__publicField$
|
|
4827
|
+
__publicField$9(this, "usedTypeRefs", []);
|
|
4828
|
+
__publicField$9(this, "usedTypeRefKeys", /* @__PURE__ */ new Set());
|
|
4829
|
+
__publicField$9(this, "docRenderer");
|
|
4830
|
+
__publicField$9(this, "typeExpr", (typeExpr) => {
|
|
4602
4831
|
this.collectTypeRefsFromExpr(typeExpr);
|
|
4603
4832
|
return this.typeExprCodegen.toCode(typeExpr).code;
|
|
4604
4833
|
});
|
|
4605
|
-
__publicField$
|
|
4834
|
+
__publicField$9(this, "declaration", (name, declaration, options = {}) => {
|
|
4606
4835
|
this.collectTypeRefsFromDeclaration(declaration);
|
|
4607
|
-
return this.toDeclarationCode(name, declaration);
|
|
4836
|
+
return this.toDeclarationCode(name, declaration, options);
|
|
4608
4837
|
});
|
|
4609
|
-
__publicField$
|
|
4838
|
+
__publicField$9(this, "toChunk", (name, code, exports$1) => {
|
|
4610
4839
|
const exportedSymbols = new Set(exports$1);
|
|
4611
4840
|
const refs = this.getTypeRefs().filter((ref) => {
|
|
4612
4841
|
return ref.kind !== "internal" || !exportedSymbols.has(ref.name);
|
|
@@ -4618,17 +4847,25 @@ class TsCodegen {
|
|
|
4618
4847
|
refs
|
|
4619
4848
|
};
|
|
4620
4849
|
});
|
|
4621
|
-
__publicField$
|
|
4850
|
+
__publicField$9(this, "getTypeRefs", () => {
|
|
4622
4851
|
return this.usedTypeRefs.map((ref) => ({ ...ref }));
|
|
4623
4852
|
});
|
|
4624
|
-
__publicField$
|
|
4853
|
+
__publicField$9(this, "toDeclarationCode", (name, d, o) => {
|
|
4854
|
+
let code = this.toDeclarationBodyCode(name, d);
|
|
4855
|
+
if (o.exported) {
|
|
4856
|
+
code = `export ${code}`;
|
|
4857
|
+
}
|
|
4858
|
+
return this.addDoc(code, d.doc);
|
|
4859
|
+
});
|
|
4860
|
+
__publicField$9(this, "toDeclarationBodyCode", (name, declaration) => {
|
|
4625
4861
|
switch (declaration.kind) {
|
|
4626
4862
|
case "typeAlias":
|
|
4627
4863
|
return `type ${name} = ${this.typeExprCodegen.toCode(declaration.typeExpr).code}`;
|
|
4628
4864
|
case "enum": {
|
|
4629
|
-
const members = declaration.members.map(
|
|
4630
|
-
|
|
4631
|
-
|
|
4865
|
+
const members = declaration.members.map((member) => {
|
|
4866
|
+
const code = `${member.name} = ${JSON.stringify(member.value)}`;
|
|
4867
|
+
return this.addDoc(code, member.doc);
|
|
4868
|
+
}).join(",\n");
|
|
4632
4869
|
return `enum ${name} {
|
|
4633
4870
|
${members}
|
|
4634
4871
|
}`;
|
|
@@ -4641,6 +4878,13 @@ ${members}
|
|
|
4641
4878
|
}
|
|
4642
4879
|
}
|
|
4643
4880
|
});
|
|
4881
|
+
__publicField$9(this, "addDoc", (code, doc) => {
|
|
4882
|
+
if (!doc) return code;
|
|
4883
|
+
const rendered = this.docRenderer.render(doc);
|
|
4884
|
+
return rendered ? `${rendered}
|
|
4885
|
+
${code}` : code;
|
|
4886
|
+
});
|
|
4887
|
+
this.docRenderer = docRenderer;
|
|
4644
4888
|
}
|
|
4645
4889
|
collectTypeRef(typeRef) {
|
|
4646
4890
|
if (typeRef.kind === "builtin") return;
|
|
@@ -4766,12 +5010,13 @@ const toTsPropertyKey = (value) => {
|
|
|
4766
5010
|
return isTsIdentifier(value) ? value : JSON.stringify(value);
|
|
4767
5011
|
};
|
|
4768
5012
|
|
|
4769
|
-
var __defProp$
|
|
4770
|
-
var __defNormalProp$
|
|
4771
|
-
var __publicField$
|
|
5013
|
+
var __defProp$8 = Object.defineProperty;
|
|
5014
|
+
var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5015
|
+
var __publicField$8 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4772
5016
|
class TypeExprCodegen {
|
|
4773
|
-
constructor() {
|
|
4774
|
-
__publicField$
|
|
5017
|
+
constructor(docRenderer) {
|
|
5018
|
+
__publicField$8(this, "docRenderer");
|
|
5019
|
+
__publicField$8(this, "toCode", (typeExpr) => {
|
|
4775
5020
|
switch (typeExpr.kind) {
|
|
4776
5021
|
case "reference":
|
|
4777
5022
|
return this.toReferenceCode(typeExpr);
|
|
@@ -4787,7 +5032,7 @@ class TypeExprCodegen {
|
|
|
4787
5032
|
}
|
|
4788
5033
|
}
|
|
4789
5034
|
});
|
|
4790
|
-
__publicField$
|
|
5035
|
+
__publicField$8(this, "toReferenceCode", (typeExpr) => {
|
|
4791
5036
|
if (!typeExpr.typeArgs?.length) {
|
|
4792
5037
|
return {
|
|
4793
5038
|
code: typeExpr.ref.name,
|
|
@@ -4800,7 +5045,7 @@ class TypeExprCodegen {
|
|
|
4800
5045
|
ref: typeExpr.ref
|
|
4801
5046
|
};
|
|
4802
5047
|
});
|
|
4803
|
-
__publicField$
|
|
5048
|
+
__publicField$8(this, "toInlineCode", (expr) => {
|
|
4804
5049
|
switch (expr.node) {
|
|
4805
5050
|
case "scalar":
|
|
4806
5051
|
return expr.name === "integer" ? "number" : expr.name;
|
|
@@ -4825,55 +5070,66 @@ class TypeExprCodegen {
|
|
|
4825
5070
|
}
|
|
4826
5071
|
}
|
|
4827
5072
|
});
|
|
4828
|
-
__publicField$
|
|
5073
|
+
__publicField$8(this, "toIntersectionMemberCode", (typeExpr) => {
|
|
4829
5074
|
const rendered = this.toCode(typeExpr).code;
|
|
4830
5075
|
return this.isUnion(typeExpr) ? `(${rendered})` : rendered;
|
|
4831
5076
|
});
|
|
4832
|
-
__publicField$
|
|
5077
|
+
__publicField$8(this, "toArrayElementCode", (typeExpr) => {
|
|
4833
5078
|
const rendered = this.toCode(typeExpr).code;
|
|
4834
5079
|
return this.needsGroupingForArrayElement(typeExpr) ? `(${rendered})` : rendered;
|
|
4835
5080
|
});
|
|
4836
|
-
__publicField$
|
|
5081
|
+
__publicField$8(this, "isUnion", (typeExpr) => {
|
|
4837
5082
|
return typeExpr.kind === "inline" && typeExpr.expr.node === "union";
|
|
4838
5083
|
});
|
|
4839
|
-
__publicField$
|
|
5084
|
+
__publicField$8(this, "needsGroupingForArrayElement", (typeExpr) => {
|
|
4840
5085
|
return typeExpr.kind === "inline" && (typeExpr.expr.node === "union" || typeExpr.expr.node === "intersection");
|
|
4841
5086
|
});
|
|
4842
|
-
__publicField$
|
|
5087
|
+
__publicField$8(this, "toLiteralCode", (value) => {
|
|
4843
5088
|
if (value === null) return "null";
|
|
4844
5089
|
return JSON.stringify(value);
|
|
4845
5090
|
});
|
|
4846
|
-
__publicField$
|
|
5091
|
+
__publicField$8(this, "toObjectCode", (properties, additionalProperties) => {
|
|
4847
5092
|
const members = properties.map(
|
|
4848
5093
|
(property) => this.toPropertyCode(property)
|
|
4849
5094
|
);
|
|
4850
5095
|
if (additionalProperties === true) {
|
|
4851
|
-
members.push("[key: string]: unknown");
|
|
5096
|
+
members.push("[key: string]: unknown;");
|
|
4852
5097
|
} else if (additionalProperties !== void 0 && additionalProperties !== false) {
|
|
4853
5098
|
members.push(
|
|
4854
|
-
`[key: string]: ${this.toCode(additionalProperties).code}
|
|
5099
|
+
`[key: string]: ${this.toCode(additionalProperties).code};`
|
|
4855
5100
|
);
|
|
4856
5101
|
}
|
|
4857
|
-
|
|
4858
|
-
|
|
5102
|
+
return `{
|
|
5103
|
+
${members.join("\n")}
|
|
5104
|
+
}`;
|
|
4859
5105
|
});
|
|
4860
|
-
__publicField$
|
|
5106
|
+
__publicField$8(this, "toPropertyCode", (property) => {
|
|
4861
5107
|
const name = toTsPropertyKey(property.name);
|
|
4862
5108
|
const optional = property.required ? "" : "?";
|
|
4863
|
-
|
|
4864
|
-
|
|
5109
|
+
const propertyCode = `${name}${optional}: ${this.toCode(property.typeExpr).code}`;
|
|
5110
|
+
const docCode = property.doc ? this.docRenderer.render(property.doc, {
|
|
5111
|
+
compactText: true
|
|
5112
|
+
}) : "";
|
|
5113
|
+
const renderedProperty = `${propertyCode};`;
|
|
5114
|
+
return docCode ? `${docCode}
|
|
5115
|
+
${renderedProperty}` : renderedProperty;
|
|
5116
|
+
});
|
|
5117
|
+
this.docRenderer = docRenderer;
|
|
4865
5118
|
}
|
|
4866
5119
|
}
|
|
4867
5120
|
|
|
4868
|
-
var __defProp$
|
|
4869
|
-
var __defNormalProp$
|
|
4870
|
-
var __publicField$
|
|
5121
|
+
var __defProp$7 = Object.defineProperty;
|
|
5122
|
+
var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5123
|
+
var __publicField$7 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4871
5124
|
class TsCodegenFactory {
|
|
4872
|
-
constructor() {
|
|
4873
|
-
__publicField$
|
|
4874
|
-
__publicField$
|
|
4875
|
-
|
|
4876
|
-
|
|
5125
|
+
constructor(docRenderer) {
|
|
5126
|
+
__publicField$7(this, "typeExprCodegen");
|
|
5127
|
+
__publicField$7(this, "docRenderer");
|
|
5128
|
+
__publicField$7(this, "forNewChunk", () => {
|
|
5129
|
+
return new TsCodegen(this.typeExprCodegen, this.docRenderer);
|
|
5130
|
+
});
|
|
5131
|
+
this.docRenderer = docRenderer;
|
|
5132
|
+
this.typeExprCodegen = new TypeExprCodegen(this.docRenderer);
|
|
4877
5133
|
}
|
|
4878
5134
|
}
|
|
4879
5135
|
|
|
@@ -4922,13 +5178,13 @@ const isReservedWord = (value) => {
|
|
|
4922
5178
|
return RESERVED_WORDS.has(value);
|
|
4923
5179
|
};
|
|
4924
5180
|
|
|
4925
|
-
var __defProp$
|
|
4926
|
-
var __defNormalProp$
|
|
4927
|
-
var __publicField$
|
|
5181
|
+
var __defProp$6 = Object.defineProperty;
|
|
5182
|
+
var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5183
|
+
var __publicField$6 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4928
5184
|
class ParamsConstructor {
|
|
4929
5185
|
constructor(options) {
|
|
4930
5186
|
this.options = options;
|
|
4931
|
-
__publicField$
|
|
5187
|
+
__publicField$6(this, "process", (params, httpPath) => {
|
|
4932
5188
|
const pathParamSpec = validatePathParams(params, httpPath);
|
|
4933
5189
|
const pathParamBindings = pathParamSpec?.bindings;
|
|
4934
5190
|
const funParams = params.flatMap(
|
|
@@ -4948,7 +5204,7 @@ class ParamsConstructor {
|
|
|
4948
5204
|
hasQuery
|
|
4949
5205
|
};
|
|
4950
5206
|
});
|
|
4951
|
-
__publicField$
|
|
5207
|
+
__publicField$6(this, "renderOperationParams", (param, pathParamSpec) => {
|
|
4952
5208
|
if (param.kind !== "path" || !pathParamSpec) {
|
|
4953
5209
|
return [
|
|
4954
5210
|
{
|
|
@@ -4972,7 +5228,7 @@ class ParamsConstructor {
|
|
|
4972
5228
|
}
|
|
4973
5229
|
];
|
|
4974
5230
|
});
|
|
4975
|
-
__publicField$
|
|
5231
|
+
__publicField$6(this, "renderPathTemplateLiteral", (path, pathParamVarName, pathParamBindings) => {
|
|
4976
5232
|
const escapedPath = path.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
4977
5233
|
const pathWithParams = escapedPath.replace(
|
|
4978
5234
|
/\{([^}]+)\}/g,
|
|
@@ -4986,7 +5242,7 @@ class ParamsConstructor {
|
|
|
4986
5242
|
);
|
|
4987
5243
|
return `\`${pathWithParams}\``;
|
|
4988
5244
|
});
|
|
4989
|
-
__publicField$
|
|
5245
|
+
__publicField$6(this, "renderPathParamDestructuring", (pathParamBindings) => {
|
|
4990
5246
|
const members = Object.entries(pathParamBindings).map(
|
|
4991
5247
|
([paramName, binding]) => {
|
|
4992
5248
|
const key = toTsPropertyKey(paramName);
|
|
@@ -4995,7 +5251,7 @@ class ParamsConstructor {
|
|
|
4995
5251
|
);
|
|
4996
5252
|
return `{ ${members.join(", ")} }`;
|
|
4997
5253
|
});
|
|
4998
|
-
__publicField$
|
|
5254
|
+
__publicField$6(this, "paramName", (p) => {
|
|
4999
5255
|
switch (p.kind) {
|
|
5000
5256
|
case "body":
|
|
5001
5257
|
return this.options.paramNames.body;
|
|
@@ -5107,19 +5363,25 @@ const validatePathParams = (params, httpPath) => {
|
|
|
5107
5363
|
};
|
|
5108
5364
|
};
|
|
5109
5365
|
|
|
5110
|
-
const
|
|
5366
|
+
const indentBlock = (value, indent) => {
|
|
5367
|
+
if (!value || !indent) {
|
|
5368
|
+
return value;
|
|
5369
|
+
}
|
|
5370
|
+
return value.split("\n").map((line) => `${indent}${line}`).join("\n");
|
|
5371
|
+
};
|
|
5111
5372
|
|
|
5112
|
-
var __defProp$
|
|
5113
|
-
var __defNormalProp$
|
|
5114
|
-
var __publicField$
|
|
5373
|
+
var __defProp$5 = Object.defineProperty;
|
|
5374
|
+
var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5375
|
+
var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5115
5376
|
const REQUEST_PARAMS_TYPE = "RequestParams";
|
|
5116
5377
|
const REQUEST_PARAMS_DEFAULT = "never";
|
|
5117
5378
|
const REQUEST_PARAMS_ARG = "params";
|
|
5118
5379
|
class ApiClientCodegen {
|
|
5119
|
-
constructor(opts, tsCodegenFactory) {
|
|
5380
|
+
constructor(opts, tsCodegenFactory, docRenderer) {
|
|
5120
5381
|
this.opts = opts;
|
|
5121
5382
|
this.tsCodegenFactory = tsCodegenFactory;
|
|
5122
|
-
|
|
5383
|
+
this.docRenderer = docRenderer;
|
|
5384
|
+
__publicField$5(this, "generate", (apiName, operations, doc) => {
|
|
5123
5385
|
const tsCodegen = this.tsCodegenFactory.forNewChunk();
|
|
5124
5386
|
const httpClientType = tsCodegen.typeExpr(this.opts.httpClient.typeName);
|
|
5125
5387
|
let clientType = httpClientType;
|
|
@@ -5129,16 +5391,18 @@ class ApiClientCodegen {
|
|
|
5129
5391
|
classTypeParams = `<${REQUEST_PARAMS_TYPE} = ${REQUEST_PARAMS_DEFAULT}>`;
|
|
5130
5392
|
}
|
|
5131
5393
|
const methodsCode = Array.isArray(operations) ? this.opsCode(tsCodegen, operations) : this.groupsOpsCode(tsCodegen, operations);
|
|
5394
|
+
const classDocCode = this.renderApiClientDoc(doc, "");
|
|
5132
5395
|
const code = `
|
|
5133
|
-
|
|
5134
|
-
|
|
5396
|
+
${classDocCode ? `${classDocCode}
|
|
5397
|
+
` : ""}export class ${apiName}${classTypeParams} {
|
|
5398
|
+
constructor(private readonly http: ${clientType}) {}
|
|
5135
5399
|
|
|
5136
5400
|
${methodsCode}
|
|
5137
5401
|
}
|
|
5138
5402
|
`;
|
|
5139
5403
|
return tsCodegen.toChunk("api", code, [apiName]);
|
|
5140
5404
|
});
|
|
5141
|
-
__publicField$
|
|
5405
|
+
__publicField$5(this, "groupsOpsCode", (codegen, groupedOps) => Object.entries(groupedOps).map(([groupName, ops]) => {
|
|
5142
5406
|
const methodsCode = this.opsCode(codegen, ops, "object");
|
|
5143
5407
|
return `
|
|
5144
5408
|
${toTsPropertyKey(groupName)} = {
|
|
@@ -5146,14 +5410,14 @@ class ApiClientCodegen {
|
|
|
5146
5410
|
}
|
|
5147
5411
|
`;
|
|
5148
5412
|
}).join("\n\n"));
|
|
5149
|
-
__publicField$
|
|
5413
|
+
__publicField$5(this, "opsCode", (codegen, operations, target = "class") => {
|
|
5150
5414
|
const separator = target === "object" ? `,
|
|
5151
5415
|
${EMPTY_LINE_MARKER}
|
|
5152
5416
|
` : "\n\n";
|
|
5153
5417
|
const methodsCode = operations.map((op) => this.renderOp(op, codegen, target)).join(separator);
|
|
5154
5418
|
return methodsCode;
|
|
5155
5419
|
});
|
|
5156
|
-
__publicField$
|
|
5420
|
+
__publicField$5(this, "renderOp", (op, tsCodegen, target) => {
|
|
5157
5421
|
const { signature: sig, http } = op;
|
|
5158
5422
|
const invocationVars = this.opts.httpClient.invocation.vars;
|
|
5159
5423
|
const paramNames = {
|
|
@@ -5179,6 +5443,7 @@ ${EMPTY_LINE_MARKER}
|
|
|
5179
5443
|
const responseType = tsCodegen.typeExpr(sig.returnType);
|
|
5180
5444
|
const returnType = this.wrapInResponseWrapper(sig.returnType, tsCodegen);
|
|
5181
5445
|
return this.renderFunctionCode({
|
|
5446
|
+
doc: sig.doc,
|
|
5182
5447
|
funName: sig.name,
|
|
5183
5448
|
responseType,
|
|
5184
5449
|
returnType,
|
|
@@ -5194,13 +5459,14 @@ ${EMPTY_LINE_MARKER}
|
|
|
5194
5459
|
target
|
|
5195
5460
|
});
|
|
5196
5461
|
});
|
|
5197
|
-
__publicField$
|
|
5462
|
+
__publicField$5(this, "wrapInResponseWrapper", (typeExpr, tsCodegen) => {
|
|
5198
5463
|
return tsCodegen.typeExpr({
|
|
5199
5464
|
...this.opts.httpClient.responseWrapper,
|
|
5200
5465
|
typeArgs: [typeExpr]
|
|
5201
5466
|
});
|
|
5202
5467
|
});
|
|
5203
|
-
__publicField$
|
|
5468
|
+
__publicField$5(this, "renderFunctionCode", ({
|
|
5469
|
+
doc,
|
|
5204
5470
|
funName,
|
|
5205
5471
|
responseType,
|
|
5206
5472
|
returnType,
|
|
@@ -5232,9 +5498,74 @@ ${EMPTY_LINE_MARKER}
|
|
|
5232
5498
|
invocation = invocation.replaceAll("\n", "");
|
|
5233
5499
|
const operator = target === "object" ? ":" : "=";
|
|
5234
5500
|
const returnTypeCode = this.opts.httpClient.inferMethodReturnType ? "" : `:${returnType}`;
|
|
5235
|
-
|
|
5236
|
-
this.
|
|
5501
|
+
const functionCode = `${funName} ${operator} (${params})${returnTypeCode} =>
|
|
5502
|
+
this.http${invocation}
|
|
5237
5503
|
`;
|
|
5504
|
+
const docCode = this.renderOperationDoc(
|
|
5505
|
+
doc,
|
|
5506
|
+
this.opts.comments,
|
|
5507
|
+
target === "object" ? " " : " "
|
|
5508
|
+
);
|
|
5509
|
+
return docCode ? `${docCode}
|
|
5510
|
+
${functionCode}` : functionCode;
|
|
5511
|
+
});
|
|
5512
|
+
__publicField$5(this, "renderOperationDoc", (doc, comments, indent = "") => {
|
|
5513
|
+
if (!doc) return null;
|
|
5514
|
+
return indentBlock(this.docRenderer.render(this.toTsDoc(doc)), indent);
|
|
5515
|
+
});
|
|
5516
|
+
__publicField$5(this, "renderApiClientDoc", (doc, indent = "") => {
|
|
5517
|
+
if (!doc) return "";
|
|
5518
|
+
return indentBlock(
|
|
5519
|
+
this.docRenderer.render({
|
|
5520
|
+
nodes: [
|
|
5521
|
+
{
|
|
5522
|
+
key: "title",
|
|
5523
|
+
value: doc.title
|
|
5524
|
+
},
|
|
5525
|
+
{
|
|
5526
|
+
key: "version",
|
|
5527
|
+
value: doc.version
|
|
5528
|
+
},
|
|
5529
|
+
...doc.description ? [doc.description] : []
|
|
5530
|
+
]
|
|
5531
|
+
}),
|
|
5532
|
+
indent
|
|
5533
|
+
);
|
|
5534
|
+
});
|
|
5535
|
+
__publicField$5(this, "toTsDoc", (doc) => {
|
|
5536
|
+
const nodes = [
|
|
5537
|
+
{
|
|
5538
|
+
key: "id",
|
|
5539
|
+
value: doc.id
|
|
5540
|
+
}
|
|
5541
|
+
];
|
|
5542
|
+
const comms = this.opts.comments;
|
|
5543
|
+
if ((comms.summary ?? true) && doc.summary) {
|
|
5544
|
+
nodes.push({
|
|
5545
|
+
key: "summary",
|
|
5546
|
+
value: doc.summary
|
|
5547
|
+
});
|
|
5548
|
+
}
|
|
5549
|
+
if ((comms.description ?? true) && doc.description) {
|
|
5550
|
+
nodes.push({
|
|
5551
|
+
key: "description",
|
|
5552
|
+
value: doc.description
|
|
5553
|
+
});
|
|
5554
|
+
}
|
|
5555
|
+
nodes.push({
|
|
5556
|
+
key: "request",
|
|
5557
|
+
value: doc.request
|
|
5558
|
+
});
|
|
5559
|
+
if ((comms.tags ?? true) && doc.tags.length) {
|
|
5560
|
+
nodes.push({
|
|
5561
|
+
key: "tags",
|
|
5562
|
+
value: doc.tags.join(", ")
|
|
5563
|
+
});
|
|
5564
|
+
}
|
|
5565
|
+
return {
|
|
5566
|
+
deprecated: doc.deprecated,
|
|
5567
|
+
nodes
|
|
5568
|
+
};
|
|
5238
5569
|
});
|
|
5239
5570
|
}
|
|
5240
5571
|
}
|
|
@@ -5403,21 +5734,102 @@ const provideHttpClientCode = (gen, opts) => gen.toChunk(
|
|
|
5403
5734
|
["HttpRequest", "HttpResponse", "HttpClient"]
|
|
5404
5735
|
);
|
|
5405
5736
|
|
|
5737
|
+
var __defProp$4 = Object.defineProperty;
|
|
5738
|
+
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5739
|
+
var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5740
|
+
class TsDocRenderer {
|
|
5741
|
+
constructor(options) {
|
|
5742
|
+
this.options = options;
|
|
5743
|
+
__publicField$4(this, "render", (doc, options = {}) => {
|
|
5744
|
+
if (!this.options.enabled) return "";
|
|
5745
|
+
const lines = [];
|
|
5746
|
+
this.appendNodes(lines, doc.nodes, options);
|
|
5747
|
+
if (doc.deprecated) {
|
|
5748
|
+
this.appendDeprecated(lines, { separate: lines.length > 0 });
|
|
5749
|
+
}
|
|
5750
|
+
return this.renderComment(lines);
|
|
5751
|
+
});
|
|
5752
|
+
__publicField$4(this, "renderComment", (lines) => {
|
|
5753
|
+
if (!this.options.enabled) return "";
|
|
5754
|
+
if (!lines.length) return "";
|
|
5755
|
+
if (lines.length === 1) {
|
|
5756
|
+
return `/** ${lines[0]} */`;
|
|
5757
|
+
}
|
|
5758
|
+
const body = lines.map((line) => line ? ` * ${line}` : " *").join("\n");
|
|
5759
|
+
return `/**
|
|
5760
|
+
${body}
|
|
5761
|
+
*/`;
|
|
5762
|
+
});
|
|
5763
|
+
__publicField$4(this, "appendDocText", (lines, value) => {
|
|
5764
|
+
const normalized = this.normalizeLines(value);
|
|
5765
|
+
if (!normalized.length) return;
|
|
5766
|
+
if (lines.length > 0) {
|
|
5767
|
+
lines.push("");
|
|
5768
|
+
}
|
|
5769
|
+
lines.push(...normalized);
|
|
5770
|
+
});
|
|
5771
|
+
__publicField$4(this, "appendField", (lines, key, value) => {
|
|
5772
|
+
const normalized = this.normalizeLines(value);
|
|
5773
|
+
if (!normalized.length) return;
|
|
5774
|
+
lines.push(`@${key} ${normalized[0]}`.trimEnd());
|
|
5775
|
+
lines.push(...normalized.slice(1));
|
|
5776
|
+
});
|
|
5777
|
+
__publicField$4(this, "appendDeprecated", (lines, options) => {
|
|
5778
|
+
if (options.separate) {
|
|
5779
|
+
lines.push("");
|
|
5780
|
+
}
|
|
5781
|
+
lines.push("@deprecated");
|
|
5782
|
+
});
|
|
5783
|
+
__publicField$4(this, "appendNodes", (lines, nodes = [], options = {}) => {
|
|
5784
|
+
nodes.forEach((node) => {
|
|
5785
|
+
if (typeof node === "string") {
|
|
5786
|
+
if (options.compactText) {
|
|
5787
|
+
lines.push(...this.normalizeNonEmptyLines(node));
|
|
5788
|
+
return;
|
|
5789
|
+
}
|
|
5790
|
+
this.appendDocText(lines, node);
|
|
5791
|
+
return;
|
|
5792
|
+
}
|
|
5793
|
+
this.appendField(lines, node.key, node.value);
|
|
5794
|
+
});
|
|
5795
|
+
});
|
|
5796
|
+
__publicField$4(this, "normalizeLines", (value) => {
|
|
5797
|
+
const trimmed = value?.trim();
|
|
5798
|
+
if (!trimmed) return [];
|
|
5799
|
+
return trimmed.split(/\r?\n/u).map((line) => line.trimEnd().replaceAll("*/", "*\\/"));
|
|
5800
|
+
});
|
|
5801
|
+
__publicField$4(this, "normalizeNonEmptyLines", (value) => this.normalizeLines(value).filter((line) => line.length > 0));
|
|
5802
|
+
}
|
|
5803
|
+
}
|
|
5804
|
+
|
|
5406
5805
|
const generateTsCode = (clientName, projectResult, opts) => {
|
|
5407
|
-
const
|
|
5806
|
+
const docRenderer = new TsDocRenderer({
|
|
5807
|
+
enabled: opts.comments.enabled
|
|
5808
|
+
});
|
|
5809
|
+
const tsCodegenFac = new TsCodegenFactory(docRenderer);
|
|
5408
5810
|
const { schemaDefinitions } = projectResult;
|
|
5409
5811
|
const types = [...schemaDefinitions].sort((a, b) => a.name.localeCompare(b.name)).map((def) => {
|
|
5410
5812
|
const cg = tsCodegenFac.forNewChunk();
|
|
5411
|
-
const code =
|
|
5813
|
+
const code = cg.declaration(def.name, def.declaration, {
|
|
5814
|
+
exported: true
|
|
5815
|
+
});
|
|
5412
5816
|
return cg.toChunk(def.name, code, [def.name]);
|
|
5413
5817
|
});
|
|
5414
5818
|
const clientCodegen = new ApiClientCodegen(
|
|
5415
|
-
{
|
|
5416
|
-
|
|
5819
|
+
{
|
|
5820
|
+
httpClient: promiseHttpClientCodegenSpec(),
|
|
5821
|
+
comments: opts.comments.operation,
|
|
5822
|
+
unwrap: opts.unwrap,
|
|
5823
|
+
pathParamsStyle: opts.pathParamsStyle,
|
|
5824
|
+
withRequestParams: opts.withRequestParams
|
|
5825
|
+
},
|
|
5826
|
+
tsCodegenFac,
|
|
5827
|
+
docRenderer
|
|
5417
5828
|
);
|
|
5418
5829
|
const generated = clientCodegen.generate(
|
|
5419
5830
|
clientName,
|
|
5420
|
-
groupsOpsByTag(projectResult.operations)
|
|
5831
|
+
groupsOpsByTag(projectResult.operations),
|
|
5832
|
+
projectResult.api
|
|
5421
5833
|
);
|
|
5422
5834
|
const clientChunk = {
|
|
5423
5835
|
...generated,
|
|
@@ -5627,6 +6039,7 @@ class ToTypeExprConverter {
|
|
|
5627
6039
|
}
|
|
5628
6040
|
return {
|
|
5629
6041
|
kind: "typeAlias",
|
|
6042
|
+
doc: this.getSchemaDoc(schema),
|
|
5630
6043
|
typeExpr: this.fromTypeExpr(schema)
|
|
5631
6044
|
};
|
|
5632
6045
|
});
|
|
@@ -5640,6 +6053,7 @@ class ToTypeExprConverter {
|
|
|
5640
6053
|
}
|
|
5641
6054
|
return {
|
|
5642
6055
|
kind: "enum",
|
|
6056
|
+
doc: this.getSchemaDoc(schema),
|
|
5643
6057
|
valueType,
|
|
5644
6058
|
members: this.toEnumMembers(schema.enum)
|
|
5645
6059
|
};
|
|
@@ -5755,6 +6169,7 @@ class ToTypeExprConverter {
|
|
|
5755
6169
|
);
|
|
5756
6170
|
}
|
|
5757
6171
|
return {
|
|
6172
|
+
doc: this.getSchemaDoc(propertySchema),
|
|
5758
6173
|
name,
|
|
5759
6174
|
required: this.isRequiredProperty(
|
|
5760
6175
|
name,
|
|
@@ -5815,6 +6230,71 @@ class ToTypeExprConverter {
|
|
|
5815
6230
|
__publicField$3(this, "isBinaryFileSchema", (schema) => {
|
|
5816
6231
|
return schema.type === "string" && schema.format === "binary";
|
|
5817
6232
|
});
|
|
6233
|
+
__publicField$3(this, "getSchemaDoc", (schema) => {
|
|
6234
|
+
const summary = typeof schema.summary === "string" ? schema.summary : void 0;
|
|
6235
|
+
const description = typeof schema.description === "string" ? schema.description : void 0;
|
|
6236
|
+
const deprecated = typeof schema.deprecated === "boolean" ? schema.deprecated : void 0;
|
|
6237
|
+
const annotations = this.getSchemaAnnotations(schema);
|
|
6238
|
+
if (!summary && !description && !deprecated && !annotations.length) {
|
|
6239
|
+
return void 0;
|
|
6240
|
+
}
|
|
6241
|
+
const nodes = [];
|
|
6242
|
+
if (summary) {
|
|
6243
|
+
nodes.push(summary);
|
|
6244
|
+
}
|
|
6245
|
+
if (description) {
|
|
6246
|
+
nodes.push(description);
|
|
6247
|
+
}
|
|
6248
|
+
nodes.push(...annotations);
|
|
6249
|
+
return {
|
|
6250
|
+
deprecated,
|
|
6251
|
+
nodes
|
|
6252
|
+
};
|
|
6253
|
+
});
|
|
6254
|
+
__publicField$3(this, "getSchemaAnnotations", (schema) => {
|
|
6255
|
+
if (this.options.comments?.metadata === false) return [];
|
|
6256
|
+
return [
|
|
6257
|
+
this.annotationNode("format", schema.format),
|
|
6258
|
+
this.annotationNode("min", schema.minimum),
|
|
6259
|
+
this.annotationNode("multipleOf", schema.multipleOf),
|
|
6260
|
+
this.annotationNode("exclusiveMin", schema.exclusiveMinimum),
|
|
6261
|
+
this.annotationNode("max", schema.maximum),
|
|
6262
|
+
this.annotationNode("minLength", schema.minLength),
|
|
6263
|
+
this.annotationNode("maxLength", schema.maxLength),
|
|
6264
|
+
this.annotationNode("exclusiveMax", schema.exclusiveMaximum),
|
|
6265
|
+
this.annotationNode("maxItems", schema.maxItems),
|
|
6266
|
+
this.annotationNode("minItems", schema.minItems),
|
|
6267
|
+
this.annotationNode("uniqueItems", schema.uniqueItems),
|
|
6268
|
+
this.annotationNode(
|
|
6269
|
+
"default",
|
|
6270
|
+
this.stringifyAnnotationValue(schema.default)
|
|
6271
|
+
),
|
|
6272
|
+
this.annotationNode("pattern", schema.pattern),
|
|
6273
|
+
this.annotationNode(
|
|
6274
|
+
"example",
|
|
6275
|
+
this.stringifyAnnotationValue(schema.example)
|
|
6276
|
+
)
|
|
6277
|
+
].filter(
|
|
6278
|
+
(value) => value !== void 0
|
|
6279
|
+
);
|
|
6280
|
+
});
|
|
6281
|
+
__publicField$3(this, "annotationNode", (name, value) => {
|
|
6282
|
+
if (value === void 0) return void 0;
|
|
6283
|
+
return {
|
|
6284
|
+
key: name,
|
|
6285
|
+
value: String(value)
|
|
6286
|
+
};
|
|
6287
|
+
});
|
|
6288
|
+
__publicField$3(this, "stringifyAnnotationValue", (value) => {
|
|
6289
|
+
if (value === void 0) return void 0;
|
|
6290
|
+
if (value && typeof value === "object") {
|
|
6291
|
+
return JSON.stringify(value);
|
|
6292
|
+
}
|
|
6293
|
+
if (typeof value === "string") {
|
|
6294
|
+
return JSON.stringify(value);
|
|
6295
|
+
}
|
|
6296
|
+
return String(value);
|
|
6297
|
+
});
|
|
5818
6298
|
__publicField$3(this, "fromSchemaCore", (schema) => {
|
|
5819
6299
|
if (this.isUnconstrainedSchema(schema)) {
|
|
5820
6300
|
return this.scalar("unknown");
|
|
@@ -6001,6 +6481,11 @@ class OperationProjector {
|
|
|
6001
6481
|
return this.projectOne(operationName, operation);
|
|
6002
6482
|
});
|
|
6003
6483
|
return {
|
|
6484
|
+
api: {
|
|
6485
|
+
title: openApi.info.title,
|
|
6486
|
+
version: openApi.info.version,
|
|
6487
|
+
description: openApi.info.description
|
|
6488
|
+
},
|
|
6004
6489
|
operations,
|
|
6005
6490
|
schemaDefinitions: this.typeExprConverter.getSchemaDefinitions()
|
|
6006
6491
|
};
|
|
@@ -6017,6 +6502,7 @@ class OperationProjector {
|
|
|
6017
6502
|
return {
|
|
6018
6503
|
op: {
|
|
6019
6504
|
signature: {
|
|
6505
|
+
doc: this.toOperationDoc(operationName, operation),
|
|
6020
6506
|
name: operationName,
|
|
6021
6507
|
parameters,
|
|
6022
6508
|
returnType: this.projectReturnType(operation)
|
|
@@ -6065,6 +6551,7 @@ class OperationProjector {
|
|
|
6065
6551
|
});
|
|
6066
6552
|
__publicField$2(this, "projectParameterGroupTypeExpr", (params) => {
|
|
6067
6553
|
const properties = Object.entries(params).map(([name, parameter]) => ({
|
|
6554
|
+
doc: this.toParameterDoc(parameter),
|
|
6068
6555
|
name,
|
|
6069
6556
|
required: parameter.required,
|
|
6070
6557
|
typeExpr: this.typeExprConverter.fromTypeExpr(
|
|
@@ -6137,45 +6624,38 @@ class OperationProjector {
|
|
|
6137
6624
|
__publicField$2(this, "selectResponseSchema", (response) => {
|
|
6138
6625
|
return getPreferredMediaTypeEntry(response.content).media?.schema;
|
|
6139
6626
|
});
|
|
6627
|
+
__publicField$2(this, "toParameterDoc", (parameter) => {
|
|
6628
|
+
if (!parameter.description && !parameter.deprecated) {
|
|
6629
|
+
return void 0;
|
|
6630
|
+
}
|
|
6631
|
+
return {
|
|
6632
|
+
deprecated: parameter.deprecated,
|
|
6633
|
+
nodes: parameter.description ? [parameter.description] : []
|
|
6634
|
+
};
|
|
6635
|
+
});
|
|
6636
|
+
__publicField$2(this, "toOperationDoc", (operationName, operation) => {
|
|
6637
|
+
return {
|
|
6638
|
+
id: operationName,
|
|
6639
|
+
request: `${toHttpMethodUpper(operation.method)}:${operation.path}`,
|
|
6640
|
+
summary: operation.summary,
|
|
6641
|
+
description: operation.description,
|
|
6642
|
+
deprecated: operation.deprecated,
|
|
6643
|
+
tags: operation.tags.map((tag) => tag.trim()).filter(Boolean)
|
|
6644
|
+
};
|
|
6645
|
+
});
|
|
6140
6646
|
}
|
|
6141
6647
|
}
|
|
6142
6648
|
|
|
6143
6649
|
var __defProp$1 = Object.defineProperty;
|
|
6144
6650
|
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6145
|
-
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, key + "" , value);
|
|
6146
|
-
const EMPTY_LINE_MARKER_LINE = new RegExp(
|
|
6147
|
-
`\\n[\\t ]*${EMPTY_LINE_MARKER.replaceAll("/", "\\/").replaceAll(
|
|
6148
|
-
"*",
|
|
6149
|
-
"\\*"
|
|
6150
|
-
)}\\n`,
|
|
6151
|
-
"g"
|
|
6152
|
-
);
|
|
6153
|
-
class CodeFormatter {
|
|
6154
|
-
constructor(opts) {
|
|
6155
|
-
this.opts = opts;
|
|
6156
|
-
__publicField$1(this, "format", async (code) => {
|
|
6157
|
-
const filePath = Path$1.resolve(this.opts.resolveConfFrom, "generated.ts");
|
|
6158
|
-
const prettier = await import('prettier');
|
|
6159
|
-
const prettierConfig = await prettier.resolveConfig(filePath) ?? {};
|
|
6160
|
-
const formattedCode = await prettier.format(code, {
|
|
6161
|
-
...prettierConfig,
|
|
6162
|
-
filepath: filePath
|
|
6163
|
-
});
|
|
6164
|
-
return formattedCode.replaceAll(EMPTY_LINE_MARKER_LINE, "\n\n");
|
|
6165
|
-
});
|
|
6166
|
-
}
|
|
6167
|
-
}
|
|
6168
|
-
|
|
6169
|
-
var __defProp = Object.defineProperty;
|
|
6170
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6171
|
-
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);
|
|
6172
6652
|
class CodeWriter {
|
|
6173
6653
|
constructor(formatter) {
|
|
6174
6654
|
this.formatter = formatter;
|
|
6175
|
-
__publicField(this, "symbolChunkMap", /* @__PURE__ */ new Map());
|
|
6176
|
-
__publicField(this, "write", async (dir, chunks) => {
|
|
6655
|
+
__publicField$1(this, "symbolChunkMap", /* @__PURE__ */ new Map());
|
|
6656
|
+
__publicField$1(this, "write", async (dir, chunks) => {
|
|
6177
6657
|
this.symbolChunkMap = this.createSymbolChunkMap(chunks);
|
|
6178
|
-
|
|
6658
|
+
fs__default.mkdirSync(dir, { recursive: true });
|
|
6179
6659
|
for (const chunk of chunks) {
|
|
6180
6660
|
const imports = this.collectImports(chunk);
|
|
6181
6661
|
const importStatements = this.genImportStatements(imports);
|
|
@@ -6185,10 +6665,10 @@ class CodeWriter {
|
|
|
6185
6665
|
let code = importCode + chunk.code;
|
|
6186
6666
|
code = await this.formatter.format(code);
|
|
6187
6667
|
code = ensureSingleTrailingNewline(code);
|
|
6188
|
-
|
|
6668
|
+
fs__default.writeFileSync(`${dir}/${chunk.name}.ts`, code, "utf8");
|
|
6189
6669
|
}
|
|
6190
6670
|
});
|
|
6191
|
-
__publicField(this, "createSymbolChunkMap", (chunks) => {
|
|
6671
|
+
__publicField$1(this, "createSymbolChunkMap", (chunks) => {
|
|
6192
6672
|
const map = /* @__PURE__ */ new Map();
|
|
6193
6673
|
for (const chunk of chunks) {
|
|
6194
6674
|
for (const exportedSymbol of chunk.exports) {
|
|
@@ -6202,7 +6682,7 @@ class CodeWriter {
|
|
|
6202
6682
|
}
|
|
6203
6683
|
return map;
|
|
6204
6684
|
});
|
|
6205
|
-
__publicField(this, "collectImports", (chunk) => {
|
|
6685
|
+
__publicField$1(this, "collectImports", (chunk) => {
|
|
6206
6686
|
const imports = [];
|
|
6207
6687
|
for (const ref of chunk.refs) {
|
|
6208
6688
|
if (ref.kind === "builtin") continue;
|
|
@@ -6225,7 +6705,7 @@ class CodeWriter {
|
|
|
6225
6705
|
}
|
|
6226
6706
|
return imports;
|
|
6227
6707
|
});
|
|
6228
|
-
__publicField(this, "genImportStatements", (imports) => {
|
|
6708
|
+
__publicField$1(this, "genImportStatements", (imports) => {
|
|
6229
6709
|
const symbolsBySource = groupBy(
|
|
6230
6710
|
imports.map((i) => ({
|
|
6231
6711
|
name: i.name,
|
|
@@ -6238,7 +6718,7 @@ class CodeWriter {
|
|
|
6238
6718
|
return `import type { ${sortedSymbols.join(", ")} } from '${source}'`;
|
|
6239
6719
|
});
|
|
6240
6720
|
});
|
|
6241
|
-
__publicField(this, "importSourcetoString", (src) => {
|
|
6721
|
+
__publicField$1(this, "importSourcetoString", (src) => {
|
|
6242
6722
|
return "externalModule" in src ? src.externalModule : (
|
|
6243
6723
|
// TODO generalize later when we have different paths
|
|
6244
6724
|
`./${src.name}`
|
|
@@ -6253,7 +6733,7 @@ class VNextOasClientGenerator {
|
|
|
6253
6733
|
this.options = options;
|
|
6254
6734
|
this.log = log;
|
|
6255
6735
|
}
|
|
6256
|
-
async generate(cmd) {
|
|
6736
|
+
async generate(cmd, formatter) {
|
|
6257
6737
|
const { inputFile, outputDir, apiName } = cmd;
|
|
6258
6738
|
this.log(`Will generate API client name=${apiName} to ${outputDir}`);
|
|
6259
6739
|
const sourceSchema = await loadSourceSchema(inputFile);
|
|
@@ -6262,6 +6742,7 @@ class VNextOasClientGenerator {
|
|
|
6262
6742
|
const projectResult = new OperationProjector({
|
|
6263
6743
|
includeAllSchema: this.options.selection?.allSchemas === true,
|
|
6264
6744
|
typeExtraction: {
|
|
6745
|
+
comments: this.options.codegen.comments.schema,
|
|
6265
6746
|
enumStyle: this.options.codegen.enumStyle,
|
|
6266
6747
|
uppercaseEnumKeys: this.options.compat?.uppercaseEnumKeys,
|
|
6267
6748
|
swaggerTsApiRequiredBooleans: this.options.compat?.swaggerTsApiRequiredBooleans
|
|
@@ -6273,12 +6754,9 @@ class VNextOasClientGenerator {
|
|
|
6273
6754
|
projectResult,
|
|
6274
6755
|
this.options.codegen
|
|
6275
6756
|
);
|
|
6276
|
-
const
|
|
6277
|
-
resolveConfFrom: outputDir
|
|
6278
|
-
});
|
|
6279
|
-
const writer = new CodeWriter(codeFormatter);
|
|
6757
|
+
const writer = new CodeWriter(formatter);
|
|
6280
6758
|
await writer.write(outputDir, chunks.all);
|
|
6281
|
-
const tsFilePath = (name) => Path.join(outputDir, `${name}.ts`);
|
|
6759
|
+
const tsFilePath = (name) => Path$1.join(outputDir, `${name}.ts`);
|
|
6282
6760
|
return {
|
|
6283
6761
|
promiseWrapper: chunks.promiseWrappersNames.map(tsFilePath),
|
|
6284
6762
|
types: tsFilePath(chunks.typesName)
|
|
@@ -6344,7 +6822,7 @@ const toErrorMessage = (error) => {
|
|
|
6344
6822
|
return error instanceof Error ? error.message : String(error);
|
|
6345
6823
|
};
|
|
6346
6824
|
|
|
6347
|
-
const generateOpenApiModel = async (spectPath, config, log) => {
|
|
6825
|
+
const generateOpenApiModel = async (spectPath, config, log, codeFormatter) => {
|
|
6348
6826
|
let outFiles;
|
|
6349
6827
|
const { openApiGenerator, responseWrapper } = config;
|
|
6350
6828
|
if ("legacy" in openApiGenerator) {
|
|
@@ -6361,11 +6839,14 @@ const generateOpenApiModel = async (spectPath, config, log) => {
|
|
|
6361
6839
|
outFiles = await new VNextOasClientGenerator(
|
|
6362
6840
|
openApiGenerator,
|
|
6363
6841
|
log
|
|
6364
|
-
).generate(
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6842
|
+
).generate(
|
|
6843
|
+
{
|
|
6844
|
+
inputFile: spectPath,
|
|
6845
|
+
apiName: config.apiName,
|
|
6846
|
+
outputDir: config.dstDir
|
|
6847
|
+
},
|
|
6848
|
+
codeFormatter
|
|
6849
|
+
);
|
|
6369
6850
|
}
|
|
6370
6851
|
if (responseWrapper) {
|
|
6371
6852
|
await modifyHttpClientAsyncWrapper(
|
|
@@ -6454,46 +6935,51 @@ const findMatchingBrace = (code, openBraceIndex) => {
|
|
|
6454
6935
|
return -1;
|
|
6455
6936
|
};
|
|
6456
6937
|
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
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
|
+
});
|
|
6469
6963
|
}
|
|
6470
|
-
|
|
6471
|
-
const prettierConfig = await prettier.resolveConfig(outputFile) ?? {};
|
|
6472
|
-
const formatted = await prettier.format(f, {
|
|
6473
|
-
...prettierConfig,
|
|
6474
|
-
filepath: outputFile
|
|
6475
|
-
});
|
|
6476
|
-
fs__default.writeFileSync(outputFile, formatted);
|
|
6477
|
-
};
|
|
6478
|
-
const getModuleImportPath = (inputFile, outputFile) => {
|
|
6479
|
-
const sourceDir = Path.dirname(outputFile);
|
|
6480
|
-
const relativePath = Path.relative(sourceDir, inputFile);
|
|
6481
|
-
const withoutExtension = relativePath.replace(/\.ts$/u, "");
|
|
6482
|
-
const normalizedPath = withoutExtension.split(Path.sep).join("/");
|
|
6483
|
-
return normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
|
|
6484
|
-
};
|
|
6964
|
+
}
|
|
6485
6965
|
|
|
6486
6966
|
const generateApiClient = async (params, configFilePath, log = console.log) => {
|
|
6487
|
-
const config =
|
|
6967
|
+
const config = parseProfileConfig(params, configFilePath);
|
|
6968
|
+
return generateApiClientFromConfig(config, log);
|
|
6969
|
+
};
|
|
6970
|
+
const generateApiClientFromConfig = async (config, log = console.log) => {
|
|
6488
6971
|
const { dstDir, apiName, srcSpec, zodSchemas } = config;
|
|
6489
|
-
const dir = Path.resolve(dstDir, apiName);
|
|
6972
|
+
const dir = Path$1.resolve(dstDir, apiName);
|
|
6490
6973
|
if (!fs.existsSync(dir)) {
|
|
6491
6974
|
log(`Creating dir ${dir}`);
|
|
6492
6975
|
fs.mkdirSync(dir, {
|
|
6493
6976
|
recursive: true
|
|
6494
6977
|
});
|
|
6495
6978
|
}
|
|
6496
|
-
const clientDir = Path.resolve(dir, "client");
|
|
6979
|
+
const clientDir = Path$1.resolve(dir, "client");
|
|
6980
|
+
const formatter = new CodeFormatter({
|
|
6981
|
+
resolveConfFrom: dir
|
|
6982
|
+
});
|
|
6497
6983
|
const specPath = await getSpecPath(srcSpec, dir, log);
|
|
6498
6984
|
log(`Cleaning client output dir ${clientDir}`);
|
|
6499
6985
|
fs.rmSync(clientDir, {
|
|
@@ -6509,15 +6995,20 @@ const generateApiClient = async (params, configFilePath, log = console.log) => {
|
|
|
6509
6995
|
...config,
|
|
6510
6996
|
dstDir: clientDir
|
|
6511
6997
|
},
|
|
6512
|
-
log
|
|
6998
|
+
log,
|
|
6999
|
+
formatter
|
|
6513
7000
|
);
|
|
6514
7001
|
if (zodSchemas?.enabled === false) return;
|
|
6515
7002
|
log("Generating Zod schemas");
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
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);
|
|
6521
7012
|
};
|
|
6522
7013
|
const getSpecPath = async (urlOrPath, dir, log) => {
|
|
6523
7014
|
if (!urlOrPath.startsWith("http")) {
|
|
@@ -6525,10 +7016,10 @@ const getSpecPath = async (urlOrPath, dir, log) => {
|
|
|
6525
7016
|
throw new Error(`Spec file ${urlOrPath} does not exists`);
|
|
6526
7017
|
return urlOrPath;
|
|
6527
7018
|
}
|
|
6528
|
-
const specPath = Path.resolve(dir, `spec.json`);
|
|
7019
|
+
const specPath = Path$1.resolve(dir, `spec.json`);
|
|
6529
7020
|
log(`Will download the API spec from ${urlOrPath} to ${specPath}`);
|
|
6530
7021
|
await downloadSpec(specPath, urlOrPath);
|
|
6531
7022
|
return specPath;
|
|
6532
7023
|
};
|
|
6533
7024
|
|
|
6534
|
-
export { generateApiClient as g };
|
|
7025
|
+
export { generateApiClientFromConfig as a, defineConfig as d, generateApiClient as g, parseConfig as p };
|