@accelbyte/codegen 0.0.0-dev-20260320085237 → 0.0.0-dev-20260406042959
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 +12 -4
- package/dist/accelbyte-codegen.d.mts +22 -0
- package/dist/accelbyte-codegen.d.ts +22 -0
- package/dist/accelbyte-codegen.js +44 -10
- package/dist/accelbyte-codegen.js.map +1 -1
- package/dist/accelbyte-codegen.mjs +41 -10
- package/dist/accelbyte-codegen.mjs.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -124,14 +124,16 @@ Place an `abcodegen.config.ts` file next to your `swaggers.json` to customize co
|
|
|
124
124
|
|
|
125
125
|
```typescript
|
|
126
126
|
// abcodegen.config.ts
|
|
127
|
+
import { type CodegenConfigOptions } from '@accelbyte/codegen'
|
|
128
|
+
|
|
127
129
|
export default {
|
|
128
130
|
// Override the base path prepended to all API routes.
|
|
129
131
|
// Default: uses basePath from the swagger spec.
|
|
130
132
|
basePath: '/custom',
|
|
131
133
|
|
|
132
|
-
//
|
|
134
|
+
// Generate barrel index files (index.ts, all-imports.ts, all-query-imports.ts).
|
|
133
135
|
// Default: true
|
|
134
|
-
|
|
136
|
+
unstable_shouldProduceIndexFiles: false,
|
|
135
137
|
|
|
136
138
|
// Force specific definitions to emit `z.any()` instead of a full schema.
|
|
137
139
|
// Keyed by definition file name. Value can be `true` or a function receiving the schema.
|
|
@@ -139,7 +141,7 @@ export default {
|
|
|
139
141
|
ProtobufAny: true,
|
|
140
142
|
SomeOther: (schema) => schema.properties?.['@type'] !== undefined
|
|
141
143
|
}
|
|
142
|
-
}
|
|
144
|
+
} satisfies CodegenConfigOptions
|
|
143
145
|
```
|
|
144
146
|
|
|
145
147
|
## Design Decisions
|
|
@@ -156,4 +158,10 @@ This triggers `@typescript-eslint/no-empty-object-type`. That rule guards agains
|
|
|
156
158
|
files: ['src/generated-definitions/**'],
|
|
157
159
|
rules: { '@typescript-eslint/no-empty-object-type': 'off' }
|
|
158
160
|
}
|
|
159
|
-
```
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Troubleshooting
|
|
164
|
+
|
|
165
|
+
### Type or lint errors in generated files
|
|
166
|
+
|
|
167
|
+
The generated code aims to use neutral, unopinionated style defaults. However, some generated syntax may conflict with your tsconfig or linter settings. In that case, you can ignore specific lint rules in the codegen folder, or create a `tsconfig.json` inside it to override your top-level configuration.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface CodegenConfigOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Force specific definitions to emit `z.any()` instead of a full schema.
|
|
4
|
+
* Keyed by definition file name. Value can be `true` or a function receiving the schema.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* { ProtobufAny: true, SomeOther: (schema) => schema.properties?.['@type'] !== undefined }
|
|
8
|
+
*/
|
|
9
|
+
unstable_overrideAsAny?: Record<string, boolean | ((schema: Record<string, any>) => boolean)>;
|
|
10
|
+
/**
|
|
11
|
+
* Generate barrel index files (index.ts, all-imports.ts, all-query-imports.ts).
|
|
12
|
+
* @default true
|
|
13
|
+
*/
|
|
14
|
+
unstable_shouldProduceIndexFiles?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Override the base path prepended to all API routes.
|
|
17
|
+
* @default `basePath` from the swagger spec
|
|
18
|
+
*/
|
|
19
|
+
basePath?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type { CodegenConfigOptions };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface CodegenConfigOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Force specific definitions to emit `z.any()` instead of a full schema.
|
|
4
|
+
* Keyed by definition file name. Value can be `true` or a function receiving the schema.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* { ProtobufAny: true, SomeOther: (schema) => schema.properties?.['@type'] !== undefined }
|
|
8
|
+
*/
|
|
9
|
+
unstable_overrideAsAny?: Record<string, boolean | ((schema: Record<string, any>) => boolean)>;
|
|
10
|
+
/**
|
|
11
|
+
* Generate barrel index files (index.ts, all-imports.ts, all-query-imports.ts).
|
|
12
|
+
* @default true
|
|
13
|
+
*/
|
|
14
|
+
unstable_shouldProduceIndexFiles?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Override the base path prepended to all API routes.
|
|
17
|
+
* @default `basePath` from the swagger spec
|
|
18
|
+
*/
|
|
19
|
+
basePath?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type { CodegenConfigOptions };
|
|
@@ -21,8 +21,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
22
|
mod
|
|
23
23
|
));
|
|
24
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
24
25
|
|
|
25
26
|
// src/cli.ts
|
|
27
|
+
var cli_exports = {};
|
|
28
|
+
module.exports = __toCommonJS(cli_exports);
|
|
26
29
|
var import_path6 = __toESM(require("path"));
|
|
27
30
|
var import_yargs = __toESM(require("yargs"));
|
|
28
31
|
|
|
@@ -105,8 +108,8 @@ var CodegenConfig = class _CodegenConfig {
|
|
|
105
108
|
const loaded = await import((0, import_url.pathToFileURL)(configPath).href);
|
|
106
109
|
_CodegenConfig.config = loaded.default ?? loaded ?? {};
|
|
107
110
|
}
|
|
108
|
-
static
|
|
109
|
-
return _CodegenConfig.config.
|
|
111
|
+
static shouldProduceIndexFiles() {
|
|
112
|
+
return _CodegenConfig.config.unstable_shouldProduceIndexFiles ?? true;
|
|
110
113
|
}
|
|
111
114
|
static getBasePath() {
|
|
112
115
|
return _CodegenConfig.config.basePath;
|
|
@@ -194,7 +197,8 @@ var getResponseType = ({
|
|
|
194
197
|
defaultType = "unknown"
|
|
195
198
|
}) => {
|
|
196
199
|
const responseClass = responseClasses.length === 1 ? responseClasses?.[0] : "unknown";
|
|
197
|
-
const
|
|
200
|
+
const rawResponseType = responseClass !== "unknown" ? responseClasses?.[0] : defaultType;
|
|
201
|
+
const responseType = rawResponseType === "__dictionary__" ? "Record<string, any>" : rawResponseType;
|
|
198
202
|
return {
|
|
199
203
|
responseType,
|
|
200
204
|
responseTypeInAxiosResponse: `Promise<AxiosResponse<${responseType}>>`,
|
|
@@ -240,13 +244,28 @@ var generateImports = (body, importStatements, makeNewImportVarMap3, getImportab
|
|
|
240
244
|
${importStatements.sort().join("\n")}`;
|
|
241
245
|
};
|
|
242
246
|
var templateClass = (className, body, importStatements) => {
|
|
247
|
+
const attributes = {
|
|
248
|
+
definitions: ["private axiosInstance: AxiosInstance", "private namespace: string", "private useSchemaValidation: boolean"],
|
|
249
|
+
assignments: ["this.axiosInstance = axiosInstance", "this.namespace = namespace", "this.useSchemaValidation = useSchemaValidation"]
|
|
250
|
+
};
|
|
251
|
+
let namespaceConstructor = "namespace";
|
|
252
|
+
if (!body.includes(".replace('{namespace}', this.namespace)")) {
|
|
253
|
+
namespaceConstructor = "_namespace";
|
|
254
|
+
attributes.definitions.splice(1, 1);
|
|
255
|
+
attributes.assignments.splice(1, 1);
|
|
256
|
+
}
|
|
243
257
|
return `/**
|
|
244
258
|
* AUTO GENERATED
|
|
245
259
|
*/
|
|
246
260
|
${generateImports(body, importStatements, makeNewImportVarMap(), getImportableVarMap(), CLASS_TYPE_ONLY_VARS)}
|
|
247
261
|
|
|
248
262
|
export class ${className} {
|
|
249
|
-
|
|
263
|
+
${attributes.definitions.join("\n")}
|
|
264
|
+
|
|
265
|
+
constructor(axiosInstance: AxiosInstance, ${namespaceConstructor}: string, useSchemaValidation = true) {
|
|
266
|
+
${attributes.assignments.join("\n")}
|
|
267
|
+
}
|
|
268
|
+
|
|
250
269
|
${body}
|
|
251
270
|
}
|
|
252
271
|
`;
|
|
@@ -499,13 +518,14 @@ var ParserUtils = class _ParserUtils {
|
|
|
499
518
|
};
|
|
500
519
|
static parseRefImport = (bodyParam) => {
|
|
501
520
|
const $ref = bodyParam?.schema?.$ref || bodyParam?.schema?.items?.$ref;
|
|
502
|
-
if (!$ref) {
|
|
521
|
+
if (!$ref || $ref.endsWith("__dictionary__")) {
|
|
503
522
|
return null;
|
|
504
523
|
}
|
|
505
524
|
const type = _ParserUtils.parseRefType($ref);
|
|
506
525
|
return `import { ${type} } from '../../generated-definitions/${type}.js'`;
|
|
507
526
|
};
|
|
508
527
|
static parseRefType = ($ref) => {
|
|
528
|
+
if ($ref.endsWith("__dictionary__")) return "__dictionary__";
|
|
509
529
|
let ref = $ref.replace(".", "/");
|
|
510
530
|
if (ref[ref.length - 1] === "." || ref[ref.length - 1] === "/") {
|
|
511
531
|
ref = ref.slice(0, -1);
|
|
@@ -703,6 +723,7 @@ var ParserUtils = class _ParserUtils {
|
|
|
703
723
|
return queryFileName;
|
|
704
724
|
}
|
|
705
725
|
static writeXVersion(distDir, xversionJson, apiInfo) {
|
|
726
|
+
import_fs4.default.mkdirSync(distDir, { recursive: true });
|
|
706
727
|
if (xversionJson) {
|
|
707
728
|
console.log("x-version:", xversionJson);
|
|
708
729
|
import_fs4.default.writeFileSync(`${distDir}/version.json`, JSON.stringify(xversionJson, null, 2));
|
|
@@ -1077,6 +1098,7 @@ var templateMethod = ({
|
|
|
1077
1098
|
let dataType = null;
|
|
1078
1099
|
if (httpMethod !== "get") {
|
|
1079
1100
|
dataType = ParserUtils.parseBodyParamsType(bodyParams);
|
|
1101
|
+
if (dataType === "__dictionary__") dataType = "Record<string, any>";
|
|
1080
1102
|
importStatements = ParserUtils.parseBodyParamsImports(bodyParams);
|
|
1081
1103
|
methodParams += dataType ? `data: ${dataType},` : "";
|
|
1082
1104
|
methodParamsNoTypes += dataType ? `data,` : "";
|
|
@@ -1100,7 +1122,7 @@ var templateMethod = ({
|
|
|
1100
1122
|
}
|
|
1101
1123
|
const isFileUpload = methodParams.indexOf("data: {file") > -1;
|
|
1102
1124
|
const { responseType, responseTypeInResponse } = getResponseType({ responseClasses });
|
|
1103
|
-
const resolvedResponseClassValidated = responseType !== "unknown" ? `${responseType}` : "z.unknown()";
|
|
1125
|
+
const resolvedResponseClassValidated = responseClasses.length === 1 && responseClasses[0] === "__dictionary__" ? "z.record(z.string(), z.any())" : responseType !== "unknown" ? `${responseType}` : "z.unknown()";
|
|
1104
1126
|
methodParams = (queryParamsType ? `${methodParams} ${queryParamsType}` : methodParams).replace(/,\s*$/, "");
|
|
1105
1127
|
methodParamsNoTypes = queryParamsType ? `${methodParamsNoTypes} queryParams` : methodParamsNoTypes;
|
|
1106
1128
|
const isGuardInvoked = ["get", "post", "put", "patch", "delete"].includes(httpMethod);
|
|
@@ -1444,7 +1466,7 @@ var SwaggerReaderHelpers = class _SwaggerReaderHelpers {
|
|
|
1444
1466
|
const responseClass = responseClasses.length > 1 ? null : responseClasses?.[0];
|
|
1445
1467
|
const { className, classGenName } = ParserUtils.generateClassName(tag, isAdminEndpoint);
|
|
1446
1468
|
tagToClassImportsRecord[className] = tagToClassImportsRecord[className] ? tagToClassImportsRecord[className] : {};
|
|
1447
|
-
if (responseClass) {
|
|
1469
|
+
if (responseClass && responseClass !== "__dictionary__") {
|
|
1448
1470
|
tagToClassImportsRecord[className][responseClass] = `import { ${responseClass} } from '../../generated-definitions/${responseClass}.js'`;
|
|
1449
1471
|
}
|
|
1450
1472
|
if (responseClass && responseClass.endsWith("Array")) {
|
|
@@ -1692,7 +1714,14 @@ ${exportedTypeString}
|
|
|
1692
1714
|
};
|
|
1693
1715
|
} else if (type) {
|
|
1694
1716
|
if (type === "object" && definition.additionalProperties) {
|
|
1695
|
-
const
|
|
1717
|
+
const additionalProps = definition.additionalProperties;
|
|
1718
|
+
if (Object.keys(additionalProps).length === 0) {
|
|
1719
|
+
return {
|
|
1720
|
+
schemaString: `${schemaAttribute} z.record(z.any())${schemaRequired}`,
|
|
1721
|
+
typeString: `${typeAttribute} Record<string, any>${typeNullishability}`
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1724
|
+
const zodAttribute = this.parseToZodAttribute("", additionalProps, [""]);
|
|
1696
1725
|
return {
|
|
1697
1726
|
schemaString: `${schemaAttribute} z.record(${zodAttribute.schemaString})${schemaRequired}`,
|
|
1698
1727
|
typeString: `${typeAttribute} Record<string, ${zodAttribute.typeString}>${typeNullishability}`
|
|
@@ -1963,7 +1992,7 @@ var CodeGenerator = class _CodeGenerator {
|
|
|
1963
1992
|
);
|
|
1964
1993
|
}
|
|
1965
1994
|
mainApiList.push(...apiList);
|
|
1966
|
-
if (CodegenConfig.
|
|
1995
|
+
if (CodegenConfig.shouldProduceIndexFiles()) {
|
|
1967
1996
|
indexImportsSet.add(
|
|
1968
1997
|
ParserUtils.getRelativePathToWebSdkSrcFolder(import_path4.default.join(_CodeGenerator.srcFolder(), serviceNameTitle), targetSrcFolder)
|
|
1969
1998
|
);
|
|
@@ -1973,6 +2002,7 @@ var CodeGenerator = class _CodeGenerator {
|
|
|
1973
2002
|
const duplicates = /* @__PURE__ */ new Map();
|
|
1974
2003
|
const definitions = api2?.components?.schemas || api2.definitions;
|
|
1975
2004
|
for (const ref in definitions) {
|
|
2005
|
+
if (ref === "__dictionary__") continue;
|
|
1976
2006
|
const definition = definitions[ref];
|
|
1977
2007
|
const fileName = ParserUtils.parseRefType(ref);
|
|
1978
2008
|
const fileExist = import_fs5.default.existsSync(import_path4.default.join(DIST_DEFINITION_DIR, `${fileName}.ts`));
|
|
@@ -1997,7 +2027,7 @@ var CodeGenerator = class _CodeGenerator {
|
|
|
1997
2027
|
};
|
|
1998
2028
|
generatePublicOrAdmin(true);
|
|
1999
2029
|
generatePublicOrAdmin(false);
|
|
2000
|
-
if (CodegenConfig.
|
|
2030
|
+
if (CodegenConfig.shouldProduceIndexFiles()) {
|
|
2001
2031
|
const isGenerateWebSocket = CliParser.isGenerateWebSocket();
|
|
2002
2032
|
const apiIndexBuff = templateApiIndex(serviceNameTitle, mainApiList, isGenerateWebSocket);
|
|
2003
2033
|
ParserUtils.writeApiMainFile(_CodeGenerator.srcFolder(), serviceNameTitle, apiIndexBuff);
|
|
@@ -2028,6 +2058,7 @@ var SwaggerDownloader = class _SwaggerDownloader {
|
|
|
2028
2058
|
fs6.readFile(filePath, "utf8", (err, data) => {
|
|
2029
2059
|
if (err) throw err;
|
|
2030
2060
|
let result = data;
|
|
2061
|
+
result = result.replace(new RegExp("map%5Bstring%5Dinterface%20%7B%7D", "g"), "__dictionary__").replace(new RegExp("map\\[string\\]interface \\{\\}", "g"), "__dictionary__").replace(new RegExp("map\\[string\\]any", "g"), "__dictionary__");
|
|
2031
2062
|
searchStr.forEach((s) => {
|
|
2032
2063
|
result = result.replace(new RegExp(s, "g"), " ");
|
|
2033
2064
|
});
|
|
@@ -2425,6 +2456,9 @@ var generateSdk = async () => {
|
|
|
2425
2456
|
if (CliParser.isGenerateWebSocket()) {
|
|
2426
2457
|
WebsocketGenerator.main();
|
|
2427
2458
|
}
|
|
2459
|
+
if (!CodegenConfig.shouldProduceIndexFiles()) {
|
|
2460
|
+
return;
|
|
2461
|
+
}
|
|
2428
2462
|
const indexImportsSet = /* @__PURE__ */ new Set();
|
|
2429
2463
|
const queryImportsSet = /* @__PURE__ */ new Set();
|
|
2430
2464
|
const filenamesSet = /* @__PURE__ */ new Set();
|