@accelbyte/codegen 3.1.0 → 4.0.1
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/PATCHING.md +1 -1
- package/README.md +3 -3
- package/dist/accelbyte-codegen.js +1336 -1200
- package/dist/accelbyte-codegen.js.map +1 -1
- package/dist/accelbyte-codegen.mjs +1248 -1111
- package/dist/accelbyte-codegen.mjs.map +1 -1
- package/package.json +22 -6
- package/scripts/get-swaggers-configs.mjs +54 -0
|
@@ -1,74 +1,158 @@
|
|
|
1
|
-
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import * as fs from 'fs';
|
|
4
|
-
import fs__default, { writeFileSync, readFileSync } from 'fs';
|
|
5
|
-
import * as path from 'path';
|
|
6
|
-
import path__default from 'path';
|
|
7
|
-
import SwaggerParser from '@apidevtools/swagger-parser';
|
|
8
|
-
import { applyPatch } from 'fast-json-patch';
|
|
9
|
-
import _ from 'lodash';
|
|
10
|
-
import semver from 'semver';
|
|
11
|
-
import * as https from 'https';
|
|
1
|
+
#!/usr/bin/env node
|
|
12
2
|
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import yargs from "yargs";
|
|
5
|
+
import path6 from "path";
|
|
6
|
+
|
|
7
|
+
// src/CliParser.ts
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
import * as path from "path";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
var SwaggersConfig = z.array(z.array(z.string()));
|
|
12
|
+
var CliParser = class _CliParser {
|
|
15
13
|
static _instance;
|
|
16
14
|
argv;
|
|
17
|
-
constructor(
|
|
18
|
-
this.argv =
|
|
15
|
+
constructor(yargs2) {
|
|
16
|
+
this.argv = yargs2.parse();
|
|
19
17
|
}
|
|
20
|
-
static createInstance = (
|
|
21
|
-
|
|
22
|
-
return
|
|
18
|
+
static createInstance = (yargs2) => {
|
|
19
|
+
_CliParser._instance = new _CliParser(yargs2);
|
|
20
|
+
return _CliParser._instance;
|
|
23
21
|
};
|
|
24
|
-
static instance = (
|
|
25
|
-
if (!
|
|
26
|
-
return
|
|
22
|
+
static instance = (yargs2) => {
|
|
23
|
+
if (!_CliParser._instance && yargs2) {
|
|
24
|
+
return _CliParser.createInstance(yargs2);
|
|
27
25
|
}
|
|
28
|
-
return
|
|
26
|
+
return _CliParser._instance;
|
|
29
27
|
};
|
|
30
28
|
static getConfigPath = () => {
|
|
31
|
-
return
|
|
29
|
+
return _CliParser.instance().argv.config;
|
|
32
30
|
};
|
|
33
31
|
static getConfigFile = () => {
|
|
34
|
-
const configPath =
|
|
35
|
-
if (!configPath)
|
|
36
|
-
|
|
37
|
-
const config = JSON.parse(fs__default.readFileSync(configPath, "utf8"));
|
|
32
|
+
const configPath = _CliParser.getConfigPath();
|
|
33
|
+
if (!configPath) throw new Error("Missing config file");
|
|
34
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
38
35
|
if (!SwaggersConfig.safeParse(config).success) {
|
|
39
36
|
throw new Error("Wrong config file format");
|
|
40
37
|
}
|
|
41
38
|
return config;
|
|
42
39
|
};
|
|
43
40
|
static getOutputPath = () => {
|
|
44
|
-
return
|
|
41
|
+
return _CliParser.instance().argv.output;
|
|
45
42
|
};
|
|
46
43
|
static getSwaggersOutputPath = () => {
|
|
47
|
-
return
|
|
44
|
+
return _CliParser.instance().argv.swaggersOutput;
|
|
48
45
|
};
|
|
49
46
|
static getResolvedSwaggersOutputPath = () => {
|
|
50
|
-
return path.resolve(
|
|
47
|
+
return path.resolve(_CliParser.getSwaggersOutputPath());
|
|
51
48
|
};
|
|
52
49
|
static getSnippetOutputPath = () => {
|
|
53
|
-
return
|
|
50
|
+
return _CliParser.instance().argv.snippetOutput;
|
|
51
|
+
};
|
|
52
|
+
static skipReactQuery = () => {
|
|
53
|
+
return _CliParser.instance().argv.skipReactQuery;
|
|
54
54
|
};
|
|
55
|
-
static
|
|
56
|
-
return
|
|
55
|
+
static isGenerateSnippetOnly = () => {
|
|
56
|
+
return _CliParser.instance().argv.snippetOnly;
|
|
57
57
|
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// src/CodeGenerator.ts
|
|
61
|
+
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
62
|
+
import fs4 from "fs";
|
|
63
|
+
import path4 from "path";
|
|
64
|
+
|
|
65
|
+
// src/ParserUtils.ts
|
|
66
|
+
import { applyPatch } from "fast-json-patch";
|
|
67
|
+
import fs3 from "fs";
|
|
68
|
+
import _ from "lodash";
|
|
69
|
+
import path3 from "path";
|
|
70
|
+
|
|
71
|
+
// src/helpers/utils.ts
|
|
72
|
+
import fs2 from "fs";
|
|
73
|
+
import path2 from "path";
|
|
74
|
+
var capitalize = (string) => {
|
|
75
|
+
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
76
|
+
};
|
|
77
|
+
function isObject(o) {
|
|
78
|
+
return o instanceof Object && o.constructor === Object;
|
|
58
79
|
}
|
|
80
|
+
var getPermission = (endpoint) => {
|
|
81
|
+
const xSecurity = endpoint["x-security"];
|
|
82
|
+
let xSecurityPerm = void 0;
|
|
83
|
+
if (Array.isArray(xSecurity)) {
|
|
84
|
+
for (const obj of xSecurity) {
|
|
85
|
+
if (obj?.userPermissions) {
|
|
86
|
+
xSecurityPerm = obj.userPermissions;
|
|
87
|
+
}
|
|
88
|
+
if (obj?.groupPermissions) {
|
|
89
|
+
xSecurityPerm = obj.groupPermissions;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} else if (isObject(xSecurity)) {
|
|
93
|
+
xSecurityPerm = xSecurity?.userPermission;
|
|
94
|
+
}
|
|
95
|
+
return xSecurityPerm;
|
|
96
|
+
};
|
|
97
|
+
var PermissionRegex = /\[(\w+)\]/;
|
|
98
|
+
var getPermissionType = (permission) => {
|
|
99
|
+
if (!permission) return null;
|
|
100
|
+
if (Array.isArray(permission)) {
|
|
101
|
+
const perm = permission?.[0];
|
|
102
|
+
if (!perm) return null;
|
|
103
|
+
const [_3, type2] = perm?.match(PermissionRegex);
|
|
104
|
+
return type2 || null;
|
|
105
|
+
}
|
|
106
|
+
const [_2, type] = permission?.match(PermissionRegex);
|
|
107
|
+
return type || null;
|
|
108
|
+
};
|
|
109
|
+
var removeAdminPrefix = (name) => name.startsWith("Admin") && name !== "Admin" ? name.replace(/^Admin/, "") : name;
|
|
110
|
+
var escapeComment = (string) => string.replace(/\*\//g, "*\\/").replace(/\n/g, "\n * ");
|
|
111
|
+
var generateJsDoc = ({ indentation = 4, lines }) => {
|
|
112
|
+
const indent = " ".repeat(indentation);
|
|
113
|
+
const formattedLines = lines.filter(Boolean).map((line) => `${indent} * ${line}`).join("\n");
|
|
114
|
+
return `${indent}/**
|
|
115
|
+
${formattedLines}
|
|
116
|
+
${indent} */`;
|
|
117
|
+
};
|
|
118
|
+
var extractDescription = (description, options) => {
|
|
119
|
+
const { indentation = 2, responseClasses, other, isDeprecated } = options;
|
|
120
|
+
return description ? generateJsDoc({
|
|
121
|
+
lines: [
|
|
122
|
+
isDeprecated ? "@deprecated" : "",
|
|
123
|
+
escapeComment(description),
|
|
124
|
+
...responseClasses.length > 1 ? [" ", "#### Response type:", ...responseClasses.map((val) => `- \`${val}\``)] : "",
|
|
125
|
+
...options?.other ? other : ""
|
|
126
|
+
],
|
|
127
|
+
indentation
|
|
128
|
+
}) : "";
|
|
129
|
+
};
|
|
130
|
+
var getResponseType = ({
|
|
131
|
+
responseClasses,
|
|
132
|
+
defaultType = "unknown"
|
|
133
|
+
}) => {
|
|
134
|
+
const responseClass = responseClasses.length === 1 ? responseClasses?.[0] : "unknown";
|
|
135
|
+
const responseType = responseClass !== "unknown" ? responseClasses?.[0] : defaultType;
|
|
136
|
+
return {
|
|
137
|
+
responseType,
|
|
138
|
+
responseTypeInAxiosResponse: `Promise<AxiosResponse<${responseType}>>`,
|
|
139
|
+
responseTypeInResponse: `Promise<Response<${responseType}>>`
|
|
140
|
+
};
|
|
141
|
+
};
|
|
59
142
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
143
|
+
// src/templates/template-class.ts
|
|
144
|
+
var getImportableVarMap = () => ({
|
|
145
|
+
"@accelbyte/sdk": ["CodeGenUtil", "Response", "Validate", "SdkSetConfigParam"],
|
|
146
|
+
axios: ["AxiosResponse"],
|
|
63
147
|
zod: ["z"]
|
|
64
148
|
});
|
|
65
|
-
|
|
66
|
-
axios: ["AxiosInstance"],
|
|
149
|
+
var makeNewImportVarMap = () => ({
|
|
150
|
+
axios: ["AxiosInstance", "AxiosRequestConfig"],
|
|
67
151
|
"@accelbyte/sdk": ["SDKRequestConfig"]
|
|
68
152
|
});
|
|
69
|
-
|
|
70
|
-
const usedImportVarMap =
|
|
71
|
-
const importableVarMap =
|
|
153
|
+
var generateImports = (body, importStatements, makeNewImportVarMap3, getImportableVarMap3) => {
|
|
154
|
+
const usedImportVarMap = makeNewImportVarMap3;
|
|
155
|
+
const importableVarMap = getImportableVarMap3;
|
|
72
156
|
for (const [moduleSource, importableVars] of Object.entries(importableVarMap)) {
|
|
73
157
|
for (const importableVar of importableVars) {
|
|
74
158
|
const importVarRegex = new RegExp(`(?<![\\d\\w_])${importableVar}(?![\\d\\w_])`);
|
|
@@ -83,33 +167,125 @@ const generateImports$1 = (body, importStatements, makeNewImportVarMap2, getImpo
|
|
|
83
167
|
return `${generatedImports}
|
|
84
168
|
${importStatements.sort().join("\n")}`;
|
|
85
169
|
};
|
|
86
|
-
|
|
170
|
+
var templateClass = (className, body, importStatements) => {
|
|
87
171
|
return `/**
|
|
88
172
|
* AUTO GENERATED
|
|
89
173
|
*/
|
|
90
|
-
${generateImports
|
|
174
|
+
${generateImports(body, importStatements, makeNewImportVarMap(), getImportableVarMap())}
|
|
91
175
|
|
|
92
176
|
export class ${className} {
|
|
93
177
|
// @ts-ignore
|
|
178
|
+
// prettier-ignore
|
|
94
179
|
constructor(private axiosInstance: AxiosInstance, private namespace: string, private useSchemaValidation = true) {}
|
|
95
180
|
${body}
|
|
96
181
|
}
|
|
97
182
|
`;
|
|
98
183
|
};
|
|
99
184
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
185
|
+
// src/templates/template-api-class.ts
|
|
186
|
+
var getImportableVarMap2 = () => ({
|
|
187
|
+
"@accelbyte/sdk": ["CodeGenUtil", "Response", "Validate", "SdkSetConfigParam", "Network", "AccelByteSDK"],
|
|
188
|
+
axios: ["AxiosDefaults", "HeadersDefaults"]
|
|
189
|
+
});
|
|
190
|
+
var makeNewImportVarMap2 = () => ({
|
|
191
|
+
"@accelbyte/sdk": ["AccelByteSDK", "SdkSetConfigParam", "ApiUtils", "Network"],
|
|
192
|
+
axios: ["AxiosRequestConfig", "AxiosResponse"]
|
|
193
|
+
});
|
|
194
|
+
var templateApiClass = (className, body, importStatements, returnMethods) => {
|
|
195
|
+
const returnsMethodsWithDescription = Object.keys(returnMethods).reduce((acc, key) => {
|
|
196
|
+
acc += `
|
|
197
|
+
${returnMethods[key]}
|
|
198
|
+
${key},`;
|
|
199
|
+
return acc;
|
|
200
|
+
}, "");
|
|
201
|
+
const $className = className.replace(/Api$/, "$");
|
|
202
|
+
return `/**
|
|
203
|
+
* AUTO GENERATED
|
|
204
|
+
*/
|
|
205
|
+
/* eslint-disable camelcase */
|
|
206
|
+
// @ts-ignore -> ts-expect-error TS6133
|
|
207
|
+
${generateImports(body, importStatements, makeNewImportVarMap2(), getImportableVarMap2())}
|
|
208
|
+
${`import { ${$className} } from './endpoints/${$className}.js'
|
|
209
|
+
`}
|
|
210
|
+
|
|
211
|
+
export function ${className}(sdk: AccelByteSDK, args?: SdkSetConfigParam) {
|
|
212
|
+
const sdkAssembly = sdk.assembly()
|
|
213
|
+
|
|
214
|
+
const namespace = args?.coreConfig?.namespace ?? sdkAssembly.coreConfig.namespace
|
|
215
|
+
const useSchemaValidation = args?.coreConfig?.useSchemaValidation ?? sdkAssembly.coreConfig.useSchemaValidation
|
|
216
|
+
|
|
217
|
+
let axiosInstance = sdkAssembly.axiosInstance
|
|
218
|
+
const requestConfigOverrides = args?.axiosConfig?.request
|
|
219
|
+
const baseURLOverride = args?.coreConfig?.baseURL
|
|
220
|
+
const interceptorsOverride = args?.axiosConfig?.interceptors ?? []
|
|
221
|
+
|
|
222
|
+
if (requestConfigOverrides || baseURLOverride || interceptorsOverride.length > 0) {
|
|
223
|
+
const requestConfig = ApiUtils.mergeAxiosConfigs(sdkAssembly.axiosInstance.defaults as AxiosRequestConfig, {
|
|
224
|
+
...(baseURLOverride ? { baseURL: baseURLOverride } : {}),
|
|
225
|
+
...requestConfigOverrides
|
|
226
|
+
})
|
|
227
|
+
axiosInstance = Network.create(requestConfig)
|
|
228
|
+
|
|
229
|
+
for (const interceptor of interceptorsOverride) {
|
|
230
|
+
if (interceptor.type === 'request') {
|
|
231
|
+
axiosInstance.interceptors.request.use(interceptor.onRequest, interceptor.onError)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (interceptor.type === 'response') {
|
|
235
|
+
axiosInstance.interceptors.response.use(interceptor.onSuccess, interceptor.onError)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
${body}
|
|
241
|
+
|
|
242
|
+
return {
|
|
243
|
+
${returnsMethodsWithDescription}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
`;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// src/ParserQueryUtils.ts
|
|
250
|
+
var ParserQueryUtils = class {
|
|
251
|
+
/**
|
|
252
|
+
* convert csv 'aa,bb' into "aa='aa', bb='bb'"
|
|
253
|
+
*/
|
|
254
|
+
static createQueryKeys(classNameWithoutApi, csvMethodNames, sdkName) {
|
|
255
|
+
const keys = csvMethodNames.split(",");
|
|
256
|
+
const processedKeys = /* @__PURE__ */ new Set();
|
|
257
|
+
const enumString = keys.reduce((acc, key, index) => {
|
|
258
|
+
const trimmedKey = key.trim();
|
|
259
|
+
if (trimmedKey) {
|
|
260
|
+
const cleanedKey = trimmedKey.replace(/^(get|update|create|patch|delete|post|fetch)[_]?/, "");
|
|
261
|
+
if (!processedKeys.has(cleanedKey)) {
|
|
262
|
+
processedKeys.add(cleanedKey);
|
|
263
|
+
acc += `${cleanedKey} = '${capitalize(sdkName)}.${classNameWithoutApi}.${cleanedKey}'`;
|
|
264
|
+
if (index < keys.length - 1) {
|
|
265
|
+
acc += ",\n";
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return acc;
|
|
270
|
+
}, "");
|
|
271
|
+
return enumString;
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// src/templates/template-query.ts
|
|
276
|
+
var generateImports2 = (body, className) => {
|
|
277
|
+
const generatedImports = `import { AccelByteSDK, SdkSetConfigParam, ApiError } from '@accelbyte/sdk'
|
|
278
|
+
import { AxiosError, AxiosResponse } from 'axios'
|
|
103
279
|
// @ts-ignore
|
|
104
280
|
import { useQuery, UseQueryOptions, UseQueryResult, useMutation, UseMutationOptions, UseMutationResult } from '@tanstack/react-query'
|
|
105
281
|
import { ${className} } from "../${className}.js"
|
|
106
282
|
`;
|
|
107
283
|
return generatedImports;
|
|
108
284
|
};
|
|
109
|
-
|
|
285
|
+
var templateQuery = (className, body, importStatements, serviceNameTitle, returnMethods, paramImports, sdkName) => {
|
|
110
286
|
const classNameWithoutApi = className.replace("Api", "");
|
|
111
|
-
const queryKeys =
|
|
112
|
-
const generatedImports =
|
|
287
|
+
const queryKeys = ParserQueryUtils.createQueryKeys(classNameWithoutApi, returnMethods, sdkName);
|
|
288
|
+
const generatedImports = generateImports2(body, className);
|
|
113
289
|
return `/**
|
|
114
290
|
* AUTO GENERATED
|
|
115
291
|
*/
|
|
@@ -125,117 +301,19 @@ export enum Key_${classNameWithoutApi} {
|
|
|
125
301
|
`;
|
|
126
302
|
};
|
|
127
303
|
function filterUsedImports(importArr, body) {
|
|
128
|
-
return importArr.filter((
|
|
129
|
-
const start =
|
|
130
|
-
const end =
|
|
304
|
+
return importArr.filter((path7) => {
|
|
305
|
+
const start = path7.indexOf("{") + 1;
|
|
306
|
+
const end = path7.indexOf("}");
|
|
131
307
|
if (start > 0 && end > start) {
|
|
132
|
-
const importName =
|
|
308
|
+
const importName = path7.slice(start, end).trim();
|
|
133
309
|
return body.includes(importName);
|
|
134
310
|
}
|
|
135
311
|
return false;
|
|
136
|
-
}).map((
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const getImportableVarMap = () => ({
|
|
140
|
-
"@accelbyte/sdk": ["CodeGenUtil", "IResponse", "Validate", "ApiArgs", "Network", "AccelbyteSDK"]
|
|
141
|
-
});
|
|
142
|
-
const makeNewImportVarMap = () => ({
|
|
143
|
-
"@accelbyte/sdk": ["AccelbyteSDK", "ApiArgs", "ApiUtils"]
|
|
144
|
-
});
|
|
145
|
-
const templateApiClass = (className, body, importStatements, returnMethods) => {
|
|
146
|
-
const $className = className.replace("Api", "$");
|
|
147
|
-
return `/**
|
|
148
|
-
* AUTO GENERATED
|
|
149
|
-
*/
|
|
150
|
-
/* eslint-disable camelcase */
|
|
151
|
-
// @ts-ignore -> ts-expect-error TS6133
|
|
152
|
-
${generateImports$1(body, importStatements, makeNewImportVarMap(), getImportableVarMap())}
|
|
153
|
-
${`import { ${$className} } from './endpoints/${$className}.js'
|
|
154
|
-
`}
|
|
155
|
-
|
|
156
|
-
export function ${className}(sdk: AccelbyteSDK, args?: ApiArgs) {
|
|
157
|
-
const sdkAssembly = sdk.assembly()
|
|
158
|
-
|
|
159
|
-
const namespace = args?.namespace ? args?.namespace : sdkAssembly.namespace
|
|
160
|
-
const requestConfig = ApiUtils.mergedConfigs(sdkAssembly.config, args)
|
|
161
|
-
const useSchemaValidation = sdkAssembly.useSchemaValidation
|
|
162
|
-
${body}
|
|
163
|
-
|
|
164
|
-
return {
|
|
165
|
-
${returnMethods}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
`;
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
const VersionBumpType = z.enum(["CUTOFF", "RELEASE", "HOTFIX", "BREAKING"]);
|
|
172
|
-
class VersionHelpers {
|
|
173
|
-
static getNextVersion = ({
|
|
174
|
-
serviceVersion,
|
|
175
|
-
versionBumpType,
|
|
176
|
-
sdkVersion,
|
|
177
|
-
nextPrereleaseId
|
|
178
|
-
}) => {
|
|
179
|
-
if (versionBumpType !== void 0) {
|
|
180
|
-
const parsed = VersionBumpType.safeParse(versionBumpType);
|
|
181
|
-
if (!parsed.success) {
|
|
182
|
-
throw new Error(`Invalid process.env.VERSION_BUMP_TYPE: ${versionBumpType}`);
|
|
183
|
-
}
|
|
184
|
-
if ((parsed.data === "HOTFIX" || parsed.data === "RELEASE") && nextPrereleaseId) {
|
|
185
|
-
throw new Error(`process.env.PRERELEASE_ID should be empty when process.env.VERSION_BUMP_TYPE is "HOTFIX" or "PRELEASE".`);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
const serviceSemvers = semver.parse(serviceVersion);
|
|
189
|
-
const sdkSemvers = semver.parse(sdkVersion);
|
|
190
|
-
if (serviceSemvers === null) {
|
|
191
|
-
throw new Error(`Invalid service version: ${serviceVersion}`);
|
|
192
|
-
}
|
|
193
|
-
if (sdkSemvers === null) {
|
|
194
|
-
throw new Error(`Invalid sdk version: ${sdkVersion}`);
|
|
195
|
-
}
|
|
196
|
-
const { major: currentMajor, minor: currentMinor, patch: currentPatch, prerelease: currentPrerelease } = sdkSemvers;
|
|
197
|
-
let nextMajor = currentMajor;
|
|
198
|
-
let nextMinor = currentMinor;
|
|
199
|
-
let nextPatch = currentPatch;
|
|
200
|
-
switch (versionBumpType) {
|
|
201
|
-
case VersionBumpType.Enum.BREAKING: {
|
|
202
|
-
nextMajor++;
|
|
203
|
-
nextMinor = 0;
|
|
204
|
-
nextPatch = 0;
|
|
205
|
-
break;
|
|
206
|
-
}
|
|
207
|
-
case VersionBumpType.Enum.CUTOFF: {
|
|
208
|
-
nextMinor++;
|
|
209
|
-
nextPatch = 0;
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
case VersionBumpType.Enum.RELEASE:
|
|
213
|
-
break;
|
|
214
|
-
case VersionBumpType.Enum.HOTFIX: {
|
|
215
|
-
nextPatch++;
|
|
216
|
-
break;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
let nextVersion = [
|
|
220
|
-
nextMajor,
|
|
221
|
-
nextMinor,
|
|
222
|
-
nextPatch
|
|
223
|
-
].join(".");
|
|
224
|
-
if (nextPrereleaseId) {
|
|
225
|
-
if (nextMinor !== currentMinor) {
|
|
226
|
-
nextVersion += `-${nextPrereleaseId}.0`;
|
|
227
|
-
} else {
|
|
228
|
-
if (currentPrerelease.length)
|
|
229
|
-
nextVersion += `-${currentPrerelease.join(".")}`;
|
|
230
|
-
nextVersion = semver.inc(nextVersion, "prerelease", void 0, nextPrereleaseId);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return nextVersion;
|
|
234
|
-
};
|
|
312
|
+
}).map((path7) => path7).join("\n") + "\n";
|
|
235
313
|
}
|
|
236
314
|
|
|
237
|
-
|
|
238
|
-
|
|
315
|
+
// src/ParserUtils.ts
|
|
316
|
+
var REMOVED_KEYWORDS = [
|
|
239
317
|
"/admin/",
|
|
240
318
|
"/public/",
|
|
241
319
|
"/v1/",
|
|
@@ -247,52 +325,34 @@ const REMOVED_KEYWORDS = [
|
|
|
247
325
|
"/namespaces/",
|
|
248
326
|
"/{namespace}/"
|
|
249
327
|
];
|
|
250
|
-
|
|
251
|
-
static
|
|
252
|
-
const
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
const trimmedKey = key.trim();
|
|
256
|
-
const isDeprecated = key.indexOf("_DEPRECATED") > 0;
|
|
257
|
-
if (trimmedKey && !isDeprecated) {
|
|
258
|
-
const cleanedKey = trimmedKey.replace(/^(get|update|create|patch|delete)[_]?/, "");
|
|
259
|
-
if (!processedKeys.has(cleanedKey)) {
|
|
260
|
-
processedKeys.add(cleanedKey);
|
|
261
|
-
acc += `${cleanedKey} = '${classNameWithoutApi}.${cleanedKey}'`;
|
|
262
|
-
if (index < keys.length - 1) {
|
|
263
|
-
acc += ",\n";
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
return acc;
|
|
268
|
-
}, "");
|
|
269
|
-
return enumString;
|
|
270
|
-
}
|
|
271
|
-
static addDeprecatedSuffix(isDeprecated, methodName) {
|
|
272
|
-
if (isDeprecated) {
|
|
273
|
-
return methodName + "_DEPRECATED";
|
|
274
|
-
} else {
|
|
275
|
-
return methodName;
|
|
276
|
-
}
|
|
328
|
+
var ParserUtils = class _ParserUtils {
|
|
329
|
+
static getVersionSuffixFromPath(path7) {
|
|
330
|
+
const version2_3_4_etc = path7.match(/\/v([2-9]|[1-9]\d+)\/+/);
|
|
331
|
+
const methodSuffix = version2_3_4_etc ? `_v${version2_3_4_etc[1]}` : "";
|
|
332
|
+
return methodSuffix;
|
|
277
333
|
}
|
|
278
334
|
static replaceAll = (text, search, replace) => {
|
|
279
335
|
return text.split(search).join(replace);
|
|
280
336
|
};
|
|
281
337
|
static generateClassName = (tag, isAdmin) => {
|
|
282
338
|
const className = _.upperFirst(_.camelCase(tag));
|
|
283
|
-
const
|
|
284
|
-
|
|
339
|
+
const formattedApiName = removeAdminPrefix(className);
|
|
340
|
+
const classGenName = isAdmin ? formattedApiName + "Admin$" : formattedApiName + "$";
|
|
341
|
+
return { className: formattedApiName, classGenName };
|
|
285
342
|
};
|
|
286
343
|
static generateApiName = (tag, isAdmin) => {
|
|
287
344
|
const apiName = _.upperFirst(_.camelCase(tag));
|
|
288
|
-
const
|
|
345
|
+
const formattedApiName = removeAdminPrefix(apiName);
|
|
346
|
+
const apiGenName = isAdmin ? formattedApiName + "AdminApi" : formattedApiName + "Api";
|
|
289
347
|
return { apiName, apiGenName };
|
|
290
348
|
};
|
|
291
349
|
static parseQueryParamAttributeDefault = (definition) => {
|
|
292
350
|
const attrName = definition.name.slice(definition.name.lastIndexOf(".") + 1);
|
|
293
351
|
let defaultValue = definition.default;
|
|
294
352
|
if (definition.type === "array" && Array.isArray(definition.default)) {
|
|
295
|
-
const mappedDefaultValue = definition.default.map(
|
|
353
|
+
const mappedDefaultValue = definition.default.map(
|
|
354
|
+
(defaultValue2) => typeof defaultValue2 === "string" ? `'${defaultValue2}'` : defaultValue2
|
|
355
|
+
);
|
|
296
356
|
defaultValue = `[${mappedDefaultValue.join(", ")}]`;
|
|
297
357
|
}
|
|
298
358
|
if (definition.type === "string") {
|
|
@@ -301,24 +361,21 @@ class ParserUtils {
|
|
|
301
361
|
return `${attrName}: ${defaultValue}`;
|
|
302
362
|
};
|
|
303
363
|
static parseType = (pathParam) => {
|
|
304
|
-
if (isSwaggerIntegerType(pathParam.type || pathParam?.schema?.type))
|
|
305
|
-
return "number";
|
|
364
|
+
if (isSwaggerIntegerType(pathParam.type || pathParam?.schema?.type)) return "number";
|
|
306
365
|
if (pathParam.type === "array") {
|
|
307
|
-
if (isSwaggerIntegerType(pathParam.items.type))
|
|
308
|
-
return "number[]";
|
|
366
|
+
if (isSwaggerIntegerType(pathParam.items.type)) return "number[]";
|
|
309
367
|
return `${pathParam.items.type ?? "any"}[]`;
|
|
310
368
|
}
|
|
311
369
|
if (pathParam?.schema?.type === "array") {
|
|
312
|
-
if (isSwaggerIntegerType(pathParam.schema.items.type))
|
|
313
|
-
return "number[]";
|
|
370
|
+
if (isSwaggerIntegerType(pathParam.schema.items.type)) return "number[]";
|
|
314
371
|
return `${pathParam.schema.items.type ?? "any"}[]`;
|
|
315
372
|
}
|
|
316
|
-
if (pathParam?.schema?.type)
|
|
317
|
-
return pathParam.schema.type;
|
|
373
|
+
if (pathParam?.schema?.type) return pathParam.schema.type;
|
|
318
374
|
return pathParam.type;
|
|
319
375
|
};
|
|
320
376
|
static parseQueryParamsType = (queryParams) => {
|
|
321
|
-
|
|
377
|
+
const result = queryParams.map((queryParam) => _ParserUtils.parseAttributeType(queryParam)).join(", ");
|
|
378
|
+
return result;
|
|
322
379
|
};
|
|
323
380
|
static isAnyQueryParamRequired = (queryParams) => {
|
|
324
381
|
return queryParams.some((queryParam) => queryParam.required);
|
|
@@ -333,11 +390,11 @@ class ParserUtils {
|
|
|
333
390
|
return result;
|
|
334
391
|
};
|
|
335
392
|
static parseQueryParamsDefault = (queryParams) => {
|
|
336
|
-
const result = queryParams.filter((queryParam) => !!queryParam.default && !queryParam.required).map(
|
|
393
|
+
const result = queryParams.filter((queryParam) => !!queryParam.default && !queryParam.required).map(_ParserUtils.parseQueryParamAttributeDefault).join(",");
|
|
337
394
|
return result ? `${result},` : "";
|
|
338
395
|
};
|
|
339
396
|
static parseBodyParamsImports = (bodyParams) => {
|
|
340
|
-
return bodyParams.map((bodyParams2) =>
|
|
397
|
+
return bodyParams.map((bodyParams2) => _ParserUtils.parseRefImport(bodyParams2)).filter(Boolean);
|
|
341
398
|
};
|
|
342
399
|
static parseImportDir = ($ref) => {
|
|
343
400
|
let ref = $ref.replace(".", "/");
|
|
@@ -355,7 +412,7 @@ class ParserUtils {
|
|
|
355
412
|
if (!$ref) {
|
|
356
413
|
return null;
|
|
357
414
|
}
|
|
358
|
-
const type =
|
|
415
|
+
const type = _ParserUtils.parseRefType($ref);
|
|
359
416
|
return `import { ${type} } from '../../generated-definitions/${type}.js'`;
|
|
360
417
|
};
|
|
361
418
|
static parseRefType = ($ref) => {
|
|
@@ -373,10 +430,13 @@ class ParserUtils {
|
|
|
373
430
|
const enums = definition.enum.map((enm) => definition.type === "string" ? `'${enm}'` : enm).join(" | ");
|
|
374
431
|
return `${attrName}${required}: ${enums}`;
|
|
375
432
|
}
|
|
376
|
-
if (definition.type &&
|
|
433
|
+
if (definition.type && _ParserUtils.parseType(definition) === "number") {
|
|
377
434
|
return `${attrName}${required}: number`;
|
|
378
435
|
}
|
|
379
|
-
if (definition
|
|
436
|
+
if (definition.type && _ParserUtils.parseType(definition) === "number[]") {
|
|
437
|
+
return `${attrName}${required}: number[]`;
|
|
438
|
+
}
|
|
439
|
+
if (definition?.schema?.type && _ParserUtils.parseType(definition) === "number") {
|
|
380
440
|
return `${attrName}${required}: number`;
|
|
381
441
|
}
|
|
382
442
|
if (definition.type && definition.type === "array") {
|
|
@@ -401,47 +461,44 @@ class ParserUtils {
|
|
|
401
461
|
};
|
|
402
462
|
static parseBodyParamsType = (bodyParams) => {
|
|
403
463
|
const [bodyParam] = bodyParams;
|
|
404
|
-
if (!bodyParam)
|
|
405
|
-
return null;
|
|
464
|
+
if (!bodyParam) return null;
|
|
406
465
|
if (bodyParams.length > 0 && bodyParam?.name !== "body" && !bodyParam?.schema) {
|
|
407
|
-
let retBodyParams = `{${bodyParams.map((bodyParam2) =>
|
|
466
|
+
let retBodyParams = `{${bodyParams.map((bodyParam2) => _ParserUtils.parseAttributeType(bodyParam2)).join(",")}}`;
|
|
408
467
|
retBodyParams = retBodyParams.replace("file?: file", "file?: File");
|
|
409
468
|
return retBodyParams;
|
|
410
469
|
}
|
|
411
470
|
if (bodyParam?.schema?.type === "array" && !bodyParam?.schema?.items?.$ref) {
|
|
412
|
-
if (isSwaggerIntegerType(bodyParam.schema.items.type))
|
|
413
|
-
return "number[]";
|
|
471
|
+
if (isSwaggerIntegerType(bodyParam.schema.items.type)) return "number[]";
|
|
414
472
|
return `${bodyParam.schema.items.type ?? "any"}[]`;
|
|
415
473
|
}
|
|
416
474
|
if (bodyParam?.schema?.type === "array" && bodyParam?.schema?.items?.$ref) {
|
|
417
|
-
return `${
|
|
475
|
+
return `${_ParserUtils.parseRefType(bodyParam.schema.items.$ref)}[]`;
|
|
418
476
|
}
|
|
419
477
|
if (bodyParam?.schema?.$ref) {
|
|
420
|
-
return
|
|
478
|
+
return _ParserUtils.parseRefType(bodyParam.schema.$ref);
|
|
421
479
|
}
|
|
422
480
|
if (bodyParam?.schema?.additionalProperties?.type === "object") {
|
|
423
481
|
return "any";
|
|
424
482
|
}
|
|
425
483
|
return null;
|
|
426
484
|
};
|
|
427
|
-
static
|
|
485
|
+
static get2xxResponses(methodEntity) {
|
|
428
486
|
const keys = Object.keys(methodEntity);
|
|
429
|
-
|
|
430
|
-
keys.
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
} else ;
|
|
487
|
+
const responseClasses = [];
|
|
488
|
+
const statusCodes = keys.filter((key) => String(key).startsWith("2"));
|
|
489
|
+
statusCodes.forEach((key) => {
|
|
490
|
+
const sch = methodEntity[key].schema;
|
|
491
|
+
const schV3 = methodEntity[key].content && methodEntity[key].content["application/json"].schema;
|
|
492
|
+
if (sch?.$ref) {
|
|
493
|
+
responseClasses.push(_ParserUtils.parseRefType(sch.$ref));
|
|
494
|
+
} else if (sch?.type === "array" && sch.items?.$ref) {
|
|
495
|
+
responseClasses.push(`${_ParserUtils.parseRefType(sch.items.$ref)}Array`);
|
|
496
|
+
} else if (schV3?.$ref) {
|
|
497
|
+
responseClasses.push(_ParserUtils.parseRefType(schV3.$ref));
|
|
498
|
+
} else {
|
|
442
499
|
}
|
|
443
500
|
});
|
|
444
|
-
return
|
|
501
|
+
return responseClasses;
|
|
445
502
|
}
|
|
446
503
|
static isFormUrlEncoded(httpMethod, contentTypes) {
|
|
447
504
|
if (!contentTypes || contentTypes.length < 1) {
|
|
@@ -458,17 +515,24 @@ class ParserUtils {
|
|
|
458
515
|
}
|
|
459
516
|
return parameters.filter((parameter) => parameter.in === "path");
|
|
460
517
|
}
|
|
461
|
-
|
|
462
|
-
|
|
518
|
+
/**
|
|
519
|
+
* This method converts this
|
|
520
|
+
* POST `/gdpr/public/namespaces/{namespace}/users/{userId}/requests/{requestDate}/generate`
|
|
521
|
+
*
|
|
522
|
+
* to this
|
|
523
|
+
* `createGenerateByRequestIdByUserId`
|
|
524
|
+
*/
|
|
525
|
+
static generateNaturalLangMethod = ({ servicePrefix, path: path7, httpMethod, isForm, existingMethods, permissionType }) => {
|
|
526
|
+
let path_ = path7;
|
|
463
527
|
path_ = path_.replace(`/${servicePrefix}/`, "/");
|
|
464
528
|
REMOVED_KEYWORDS.forEach((prefix) => {
|
|
465
529
|
path_ = path_.replace(prefix, "/");
|
|
466
530
|
});
|
|
467
531
|
path_ = path_.substring(1);
|
|
468
|
-
const isPlural = httpMethod === "get" && !(
|
|
532
|
+
const isPlural = httpMethod === "get" && !(path7.slice(-1) === "}");
|
|
469
533
|
if (!isPlural) {
|
|
470
|
-
path_ =
|
|
471
|
-
path_ =
|
|
534
|
+
path_ = _ParserUtils.replaceAll(path_, "ies/", "y/");
|
|
535
|
+
path_ = _ParserUtils.replaceAll(path_, "s/", "/");
|
|
472
536
|
if (path_.indexOf("status") < 0) {
|
|
473
537
|
path_ = path_.replace(/ies$/, "y");
|
|
474
538
|
path_ = path_.replace(/s$/, "");
|
|
@@ -506,9 +570,11 @@ class ParserUtils {
|
|
|
506
570
|
}
|
|
507
571
|
});
|
|
508
572
|
const genPath = _.upperFirst(lastWords) + "/" + listBeforeLastWords.join("/") + listByParams.reverse().join("/");
|
|
509
|
-
let generatedMethod = _.camelCase(mappedMethod(httpMethod, isForm) + genPath);
|
|
510
|
-
generatedMethod =
|
|
511
|
-
|
|
573
|
+
let generatedMethod = _.camelCase(mappedMethod(httpMethod, isForm, permissionType) + genPath);
|
|
574
|
+
generatedMethod = _ParserUtils.replaceAll(generatedMethod, "Byword", "_By");
|
|
575
|
+
const testedGeneratedMethod = generatedMethod + _ParserUtils.getVersionSuffixFromPath(path7);
|
|
576
|
+
generatedMethod = resolveConflicts({ path: path7, generatedMethod, testedGeneratedMethod, existingMethods });
|
|
577
|
+
generatedMethod = generatedMethod + _ParserUtils.getVersionSuffixFromPath(path7);
|
|
512
578
|
return generatedMethod;
|
|
513
579
|
};
|
|
514
580
|
static filterBodyParams(parameters) {
|
|
@@ -524,90 +590,76 @@ class ParserUtils {
|
|
|
524
590
|
return parameters.filter((parameter) => parameter.in === "query");
|
|
525
591
|
}
|
|
526
592
|
static mkdirIfNotExist(dirToCreate) {
|
|
527
|
-
if (!
|
|
528
|
-
|
|
593
|
+
if (!fs3.existsSync(dirToCreate)) {
|
|
594
|
+
fs3.mkdirSync(dirToCreate, { recursive: true });
|
|
529
595
|
}
|
|
530
596
|
}
|
|
531
597
|
static writeClassFile(distDir, apiName, apiBuffer, imports) {
|
|
532
598
|
const fileContent = templateClass(apiName, apiBuffer, imports);
|
|
533
|
-
|
|
599
|
+
fs3.writeFileSync(`${distDir}/${apiName}.ts`, _ParserUtils.prependCopyrightHeader(fileContent));
|
|
534
600
|
}
|
|
535
601
|
static writeAtomFile(distDir, apiName, fileContent) {
|
|
536
|
-
|
|
537
|
-
|
|
602
|
+
_ParserUtils.mkdirIfNotExist(distDir);
|
|
603
|
+
fs3.writeFileSync(`${distDir}/${apiName}.atom.ts`, _ParserUtils.prependCopyrightHeader(fileContent));
|
|
538
604
|
}
|
|
539
|
-
static writeQueryFile(distDir, apiName, apiBuffer, imports, serviceNameTitle, returnMethods, paramImports) {
|
|
605
|
+
static writeQueryFile(distDir, apiName, apiBuffer, imports, serviceNameTitle, returnMethods, paramImports, sdkName) {
|
|
540
606
|
if (apiBuffer.length < 1) {
|
|
541
607
|
return null;
|
|
542
608
|
}
|
|
543
609
|
const queryFileName = `${apiName.replace("Api", "")}.query`;
|
|
544
|
-
|
|
545
|
-
const fileContent = templateQuery(apiName, apiBuffer, imports, serviceNameTitle, returnMethods, paramImports);
|
|
546
|
-
|
|
610
|
+
_ParserUtils.mkdirIfNotExist(distDir);
|
|
611
|
+
const fileContent = templateQuery(apiName, apiBuffer, imports, serviceNameTitle, returnMethods, paramImports, sdkName);
|
|
612
|
+
fs3.writeFileSync(`${distDir}/${queryFileName}.ts`, _ParserUtils.prependCopyrightHeader(fileContent));
|
|
547
613
|
return queryFileName;
|
|
548
614
|
}
|
|
549
615
|
static writeXVersion(distDir, xversionJson, apiInfo) {
|
|
550
616
|
if (xversionJson) {
|
|
551
617
|
console.log("x-version:", xversionJson);
|
|
552
|
-
|
|
618
|
+
fs3.writeFileSync(`${distDir}/version.json`, JSON.stringify(xversionJson, null, 2));
|
|
553
619
|
} else {
|
|
554
620
|
const customVersion = {
|
|
555
621
|
...apiInfo,
|
|
556
622
|
gitHash: apiInfo.version
|
|
557
623
|
};
|
|
558
|
-
console.error(
|
|
559
|
-
|
|
624
|
+
console.error(`!!!! Missing x-version for ${distDir} ${customVersion}`);
|
|
625
|
+
fs3.writeFileSync(`${distDir}/version.json`, JSON.stringify(customVersion, null, 2));
|
|
560
626
|
}
|
|
561
627
|
}
|
|
562
|
-
static writeApiFile(distDir, apiName, apiBuffer, imports,
|
|
628
|
+
static writeApiFile(distDir, apiName, apiBuffer, imports, returnMethodsDescription) {
|
|
563
629
|
const newImports = [];
|
|
564
|
-
imports.forEach((el
|
|
630
|
+
imports.forEach((el) => {
|
|
565
631
|
newImports.push(el.replace("../../generated-definitions", "../generated-definitions"));
|
|
566
632
|
});
|
|
567
|
-
const fileContent = templateApiClass(apiName, apiBuffer, newImports,
|
|
568
|
-
|
|
633
|
+
const fileContent = templateApiClass(apiName, apiBuffer, newImports, returnMethodsDescription);
|
|
634
|
+
fs3.writeFileSync(`${distDir}/${apiName}.ts`, _ParserUtils.prependCopyrightHeader(fileContent));
|
|
569
635
|
}
|
|
570
636
|
static writeApiMainFile(distDir, serviceName, fileContent) {
|
|
571
|
-
|
|
637
|
+
fs3.writeFileSync(`${distDir}/${serviceName}.ts`, _ParserUtils.prependCopyrightHeader(fileContent));
|
|
572
638
|
}
|
|
573
639
|
static writeSnippetFile(distDir, name, docBuffer) {
|
|
574
|
-
let snippetFileName =
|
|
640
|
+
let snippetFileName = _ParserUtils.replaceAll(name, " ", "-").toLowerCase();
|
|
575
641
|
snippetFileName = snippetFileName.replace("justice-", "");
|
|
576
642
|
snippetFileName = "snippet-" + snippetFileName + ".json";
|
|
577
|
-
|
|
643
|
+
fs3.writeFileSync(`${distDir}/${snippetFileName}`, docBuffer);
|
|
578
644
|
}
|
|
579
645
|
static writeDefinitionFile(distDir, name, buffer) {
|
|
580
|
-
|
|
581
|
-
|
|
646
|
+
_ParserUtils.mkdirIfNotExist(distDir);
|
|
647
|
+
fs3.writeFileSync(path3.join(distDir, `${name}.ts`), _ParserUtils.prependCopyrightHeader(buffer));
|
|
582
648
|
}
|
|
583
649
|
static writeAllImportsFile(distDir, buffer) {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
}
|
|
587
|
-
static syncPackageVersion(apiInfo, skipVersionSync, prereleaseId) {
|
|
588
|
-
if (skipVersionSync)
|
|
589
|
-
return;
|
|
590
|
-
const currDir = process.cwd();
|
|
591
|
-
const { packageJSON, pathToPackageJSON } = ParserUtils.getPackageJSONInfo(currDir);
|
|
592
|
-
const nextSemver = VersionHelpers.getNextVersion({
|
|
593
|
-
serviceVersion: apiInfo["x-version"] || apiInfo.version || UNDEFINED_SWAGGER_SEMVER,
|
|
594
|
-
versionBumpType: process.env.VERSION_BUMP_TYPE,
|
|
595
|
-
sdkVersion: packageJSON.version,
|
|
596
|
-
nextPrereleaseId: prereleaseId
|
|
597
|
-
});
|
|
598
|
-
packageJSON.version = nextSemver;
|
|
599
|
-
writeFileSync(pathToPackageJSON, JSON.stringify(packageJSON, null, 2));
|
|
650
|
+
_ParserUtils.mkdirIfNotExist(distDir);
|
|
651
|
+
fs3.writeFileSync(path3.join(distDir, "all-imports.ts"), _ParserUtils.prependCopyrightHeader(buffer));
|
|
600
652
|
}
|
|
601
|
-
static
|
|
602
|
-
|
|
603
|
-
|
|
653
|
+
static writeAllQueryImportsFile(distDir, buffer) {
|
|
654
|
+
_ParserUtils.mkdirIfNotExist(distDir);
|
|
655
|
+
fs3.writeFileSync(path3.join(distDir, "all-query-imports.ts"), _ParserUtils.prependCopyrightHeader(buffer));
|
|
604
656
|
}
|
|
605
657
|
static toCamelCase(str) {
|
|
606
658
|
return str.split("/").map(function(word, index) {
|
|
607
659
|
if (index === 0) {
|
|
608
660
|
return word.toLowerCase();
|
|
609
661
|
}
|
|
610
|
-
return
|
|
662
|
+
return _ParserUtils.toCamelCaseWord(word);
|
|
611
663
|
}).join("");
|
|
612
664
|
}
|
|
613
665
|
static toCamelCaseWord(word) {
|
|
@@ -626,15 +678,15 @@ class ParserUtils {
|
|
|
626
678
|
});
|
|
627
679
|
}
|
|
628
680
|
static applyPatchIfExists(swaggerFilePath, possibleSwaggerPatchFilePath, swaggerPatchedFilePath, swaggerPatchedDir) {
|
|
629
|
-
if (!
|
|
630
|
-
|
|
681
|
+
if (!fs3.existsSync(swaggerPatchedDir)) {
|
|
682
|
+
fs3.mkdirSync(swaggerPatchedDir, { recursive: true });
|
|
631
683
|
}
|
|
632
|
-
if (!
|
|
633
|
-
|
|
684
|
+
if (!fs3.existsSync(possibleSwaggerPatchFilePath)) {
|
|
685
|
+
fs3.copyFileSync(swaggerFilePath, swaggerPatchedFilePath);
|
|
634
686
|
return;
|
|
635
687
|
}
|
|
636
|
-
const swaggerContent = JSON.parse(
|
|
637
|
-
const swaggerPatchFileContent = JSON.parse(
|
|
688
|
+
const swaggerContent = JSON.parse(fs3.readFileSync(swaggerFilePath, "utf8"));
|
|
689
|
+
const swaggerPatchFileContent = JSON.parse(fs3.readFileSync(possibleSwaggerPatchFilePath, "utf8"));
|
|
638
690
|
for (const patchEntry of swaggerPatchFileContent) {
|
|
639
691
|
const segments = patchEntry.path.split("/").filter(Boolean);
|
|
640
692
|
let currentNode = swaggerContent;
|
|
@@ -644,29 +696,32 @@ class ParserUtils {
|
|
|
644
696
|
aggregatedPath += `/${segment}`;
|
|
645
697
|
const effectiveSegment = segment.replace(/(~1)/g, "/").replace(/(~0)/g, "~");
|
|
646
698
|
if (!currentNode[effectiveSegment]) {
|
|
647
|
-
if (i + 1 === segments.length && patchEntry.op === "add")
|
|
648
|
-
|
|
649
|
-
|
|
699
|
+
if (i + 1 === segments.length && patchEntry.op === "add") {
|
|
700
|
+
} else {
|
|
701
|
+
throw new Error(
|
|
702
|
+
[
|
|
703
|
+
`JSON patch error: operation "${patchEntry.op}" on path "${aggregatedPath}" fails because the path doesn't exist in ${swaggerFilePath}. This may be caused by:
|
|
650
704
|
`,
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
705
|
+
"1. The related service has patched the service, so patch is no longer needed.",
|
|
706
|
+
"2. There is a breaking change on the service that causes the path to change.\n",
|
|
707
|
+
`In any case, revisit this file: "${possibleSwaggerPatchFilePath}", then try again.
|
|
654
708
|
`
|
|
655
|
-
|
|
709
|
+
].join("\n")
|
|
710
|
+
);
|
|
656
711
|
}
|
|
657
712
|
}
|
|
658
713
|
currentNode = currentNode[effectiveSegment];
|
|
659
714
|
}
|
|
660
715
|
}
|
|
661
716
|
const { newDocument } = applyPatch(swaggerContent, swaggerPatchFileContent);
|
|
662
|
-
|
|
717
|
+
fs3.writeFileSync(swaggerPatchedFilePath, JSON.stringify(newDocument, null, 2));
|
|
663
718
|
}
|
|
664
719
|
static getRelativePathToWebSdkSrcFolder(srcFolder, targetSrcFolder) {
|
|
665
720
|
const replaced = srcFolder.replace(/\\/g, "/");
|
|
666
721
|
return replaced.replace(/\\/g, "/").replace(targetSrcFolder, "./");
|
|
667
722
|
}
|
|
668
723
|
static prependCopyrightHeader = (content) => {
|
|
669
|
-
const currentYear = new Date().getFullYear();
|
|
724
|
+
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
670
725
|
return `/*
|
|
671
726
|
* Copyright (c) 2022${currentYear > 2022 ? `-${currentYear}` : ""} AccelByte Inc. All Rights Reserved
|
|
672
727
|
* This is licensed software from AccelByte Inc, for limitations
|
|
@@ -674,17 +729,21 @@ class ParserUtils {
|
|
|
674
729
|
*/
|
|
675
730
|
${content}`;
|
|
676
731
|
};
|
|
677
|
-
static sortPathParamsByPath = (pathParams,
|
|
678
|
-
const params =
|
|
732
|
+
static sortPathParamsByPath = (pathParams, path7) => {
|
|
733
|
+
const params = path7.match(/{\w*}/g) || [];
|
|
679
734
|
const cleanParams = params.map((param) => param.replace("{", "").replace("}", ""));
|
|
680
735
|
return pathParams.sort((a, b) => cleanParams.indexOf(a.name) - cleanParams.indexOf(b.name));
|
|
681
736
|
};
|
|
682
|
-
}
|
|
683
|
-
|
|
737
|
+
};
|
|
738
|
+
var mappedMethod = (httpMethod, isForm, permissionType) => {
|
|
684
739
|
if (httpMethod === "get") {
|
|
685
740
|
return "get";
|
|
686
741
|
} else if (httpMethod === "post" && isForm) {
|
|
687
742
|
return "post";
|
|
743
|
+
} else if (httpMethod === "post" && permissionType === "READ") {
|
|
744
|
+
return "fetch";
|
|
745
|
+
} else if (httpMethod === "post" && permissionType === "UPDATE") {
|
|
746
|
+
return "update";
|
|
688
747
|
} else if (httpMethod === "post") {
|
|
689
748
|
return "create";
|
|
690
749
|
} else if (httpMethod === "put") {
|
|
@@ -695,440 +754,221 @@ const mappedMethod = (httpMethod, isForm) => {
|
|
|
695
754
|
return "delete";
|
|
696
755
|
}
|
|
697
756
|
};
|
|
698
|
-
|
|
757
|
+
var resolveConflicts = ({ path: path7, generatedMethod, testedGeneratedMethod, existingMethods }) => {
|
|
758
|
+
let _testedGenMethod = testedGeneratedMethod;
|
|
699
759
|
try {
|
|
700
|
-
testConflict(
|
|
760
|
+
testConflict(path7, _testedGenMethod, existingMethods);
|
|
701
761
|
} catch (e) {
|
|
702
|
-
if (
|
|
762
|
+
if (path7.indexOf("/namespaces/") >= 0) {
|
|
703
763
|
generatedMethod += "_ByNS";
|
|
764
|
+
_testedGenMethod += "_ByNS";
|
|
704
765
|
}
|
|
705
766
|
}
|
|
706
767
|
try {
|
|
707
|
-
testConflict(
|
|
768
|
+
testConflict(path7, _testedGenMethod, existingMethods);
|
|
708
769
|
} catch (e) {
|
|
709
|
-
if (
|
|
710
|
-
generatedMethod += "_v4";
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
try {
|
|
714
|
-
testConflict(path2, generatedMethod, existingMethods);
|
|
715
|
-
} catch (e) {
|
|
716
|
-
if (path2.indexOf("/v3/") >= 0) {
|
|
717
|
-
generatedMethod += "_v3";
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
try {
|
|
721
|
-
testConflict(path2, generatedMethod, existingMethods);
|
|
722
|
-
} catch (e) {
|
|
723
|
-
if (path2.indexOf("/v2/") >= 0) {
|
|
724
|
-
generatedMethod += "_v2";
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
try {
|
|
728
|
-
testConflict(path2, generatedMethod, existingMethods);
|
|
729
|
-
} catch (e) {
|
|
730
|
-
if (path2.indexOf("/admin/") >= 0) {
|
|
770
|
+
if (path7.indexOf("/admin/") >= 0) {
|
|
731
771
|
generatedMethod += "_admin";
|
|
772
|
+
_testedGenMethod += "_admin";
|
|
732
773
|
}
|
|
733
774
|
}
|
|
734
|
-
testConflict(
|
|
775
|
+
testConflict(path7, _testedGenMethod, existingMethods);
|
|
735
776
|
return generatedMethod;
|
|
736
777
|
};
|
|
737
|
-
|
|
778
|
+
var testConflict = (path7, generatedMethod, existingMethods) => {
|
|
738
779
|
if (existingMethods[generatedMethod]) {
|
|
739
|
-
const conflictingMethod = { path:
|
|
740
|
-
throw Error(
|
|
741
|
-
|
|
780
|
+
const conflictingMethod = { path: path7, generatedMethod };
|
|
781
|
+
throw Error(
|
|
782
|
+
`Duplicate method conflict in ${JSON.stringify(conflictingMethod)},
|
|
783
|
+
existingMethods: ${JSON.stringify(existingMethods, null, 2)}`
|
|
784
|
+
);
|
|
742
785
|
}
|
|
743
786
|
};
|
|
744
|
-
|
|
787
|
+
var isSwaggerIntegerType = (type) => {
|
|
745
788
|
return type === "integer" || type === "int";
|
|
746
789
|
};
|
|
747
790
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
791
|
+
// src/Swagger.ts
|
|
792
|
+
import { z as z2 } from "zod";
|
|
793
|
+
var Schema = z2.object({
|
|
794
|
+
$ref: z2.string().nullish(),
|
|
795
|
+
type: z2.union([z2.literal("array"), z2.literal("object"), z2.literal("file"), z2.literal("string"), z2.literal("boolean"), z2.literal("integer")]).nullish(),
|
|
796
|
+
items: z2.object({
|
|
797
|
+
$ref: z2.string().nullish(),
|
|
798
|
+
type: z2.string().nullish()
|
|
799
|
+
}).nullish(),
|
|
800
|
+
properties: z2.union([z2.array(z2.string()).nullish(), z2.record(z2.object({ type: z2.string() })).nullish()]),
|
|
801
|
+
description: z2.string().nullish(),
|
|
802
|
+
additionalProperties: z2.object({
|
|
803
|
+
type: z2.string().nullish()
|
|
804
|
+
}).nullish()
|
|
805
|
+
});
|
|
806
|
+
var Definition = z2.object({
|
|
807
|
+
required: z2.array(z2.string()).nullish(),
|
|
808
|
+
properties: z2.record(
|
|
809
|
+
z2.object({
|
|
810
|
+
type: z2.string()
|
|
811
|
+
})
|
|
812
|
+
).nullish()
|
|
813
|
+
});
|
|
814
|
+
var Definitions = z2.record(Definition);
|
|
815
|
+
var EndpointParametersType = z2.enum(["apiKey", "boolean", "int", "integer", "number", "string", "array", "file"]);
|
|
816
|
+
var EndpointParametersIn = z2.enum(["body", "formData", "header", "path", "query"]);
|
|
817
|
+
var EndpointParameters = z2.object({
|
|
818
|
+
type: EndpointParametersType.nullish(),
|
|
819
|
+
description: z2.string().nullish(),
|
|
820
|
+
name: z2.string(),
|
|
821
|
+
in: EndpointParametersIn,
|
|
822
|
+
required: z2.boolean().nullish(),
|
|
823
|
+
schema: Schema.nullish(),
|
|
824
|
+
default: z2.union([z2.boolean(), z2.string(), z2.number(), z2.array(z2.any())]).nullish(),
|
|
825
|
+
enum: z2.array(z2.union([z2.boolean(), z2.string(), z2.number()])).nullish(),
|
|
826
|
+
items: z2.object({
|
|
827
|
+
type: z2.string(),
|
|
828
|
+
enum: z2.array(z2.any()).nullish()
|
|
829
|
+
}).nullish()
|
|
830
|
+
});
|
|
831
|
+
var Endpoint = z2.object({
|
|
832
|
+
description: z2.string().nullish(),
|
|
833
|
+
consumes: z2.array(z2.string()).nullish(),
|
|
834
|
+
produces: z2.array(z2.string()).nullish(),
|
|
835
|
+
tags: z2.array(z2.string()).nullish(),
|
|
836
|
+
summary: z2.string().nullish(),
|
|
837
|
+
operationId: z2.string(),
|
|
838
|
+
deprecated: z2.boolean().nullish(),
|
|
839
|
+
responses: z2.record(
|
|
840
|
+
z2.object({
|
|
841
|
+
description: z2.string().nullish(),
|
|
842
|
+
schema: Schema.nullish(),
|
|
843
|
+
content: z2.object({
|
|
844
|
+
"application/json": z2.object({
|
|
845
|
+
schema: Schema.nullish()
|
|
846
|
+
})
|
|
847
|
+
}).nullish()
|
|
848
|
+
})
|
|
849
|
+
),
|
|
850
|
+
parameters: z2.array(EndpointParameters).nullish(),
|
|
851
|
+
requestBody: z2.object({
|
|
852
|
+
required: z2.boolean().nullish(),
|
|
853
|
+
content: z2.object({
|
|
854
|
+
"application/json": z2.object({
|
|
855
|
+
schema: Schema.nullish()
|
|
856
|
+
}).nullish()
|
|
857
|
+
}).nullish()
|
|
858
|
+
}).nullish(),
|
|
859
|
+
// The proper type is z.array(z.record(z.array(z.string()))).nullish() but somehow there are endpoints with
|
|
860
|
+
// an object type instead of an array type, so, yeah.
|
|
861
|
+
//
|
|
862
|
+
// Services with this error: sdk-iam, sdk-ugc.
|
|
863
|
+
"x-security": z2.any().nullish()
|
|
864
|
+
});
|
|
865
|
+
var Operation2 = z2.object({
|
|
866
|
+
get: Endpoint.nullish(),
|
|
867
|
+
post: Endpoint.nullish(),
|
|
868
|
+
patch: Endpoint.nullish(),
|
|
869
|
+
delete: Endpoint.nullish(),
|
|
870
|
+
put: Endpoint.nullish()
|
|
871
|
+
});
|
|
872
|
+
var Paths = z2.record(Operation2);
|
|
873
|
+
var OpenApiSpec = z2.object({
|
|
874
|
+
paths: Paths,
|
|
875
|
+
definitions: Definitions,
|
|
876
|
+
basePath: z2.string(),
|
|
877
|
+
info: z2.object({
|
|
878
|
+
description: z2.string(),
|
|
879
|
+
title: z2.string(),
|
|
880
|
+
contact: z2.object({
|
|
881
|
+
name: z2.string(),
|
|
882
|
+
url: z2.string(),
|
|
883
|
+
email: z2.string()
|
|
884
|
+
}),
|
|
885
|
+
version: z2.string()
|
|
886
|
+
}),
|
|
887
|
+
schemes: z2.array(z2.string()).nullish(),
|
|
888
|
+
components: z2.object({
|
|
889
|
+
schemas: Definitions
|
|
890
|
+
}).nullish()
|
|
891
|
+
});
|
|
892
|
+
|
|
893
|
+
// src/templates/template-api-method.ts
|
|
894
|
+
var templateApiMethod = ({
|
|
895
|
+
classMethod,
|
|
896
|
+
httpMethod,
|
|
897
|
+
path: path7,
|
|
898
|
+
pathParams,
|
|
899
|
+
bodyParams,
|
|
900
|
+
responseClasses,
|
|
901
|
+
classGenName,
|
|
902
|
+
methodParams,
|
|
903
|
+
methodParamsNoTypes,
|
|
904
|
+
xSecurity
|
|
905
|
+
}) => {
|
|
906
|
+
let newPath = `'${path7}'`;
|
|
907
|
+
let snippetMethod = "";
|
|
908
|
+
for (const pathParam of pathParams) {
|
|
909
|
+
const type = ParserUtils.parseType(pathParam);
|
|
910
|
+
const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
|
|
911
|
+
if (path7.match(`{${pathParam.name}}`)) {
|
|
912
|
+
if (type === "string") {
|
|
913
|
+
newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
|
|
914
|
+
} else {
|
|
915
|
+
newPath = `${newPath}.replace('{${pathParam.name}}', String(${pName}))`;
|
|
916
|
+
}
|
|
763
917
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
} else {
|
|
778
|
-
exportedVariableString = `export const ${fileName} = ${content.schemaString}`;
|
|
779
|
-
exportedTypeString = `export interface ${fileName} extends z.TypeOf<typeof ${fileName}> {}`;
|
|
918
|
+
}
|
|
919
|
+
const snippetShellArgs = ["--location --request", `${httpMethod} '__DOMAIN__${path7}'`, "--header 'accept: application/json'"];
|
|
920
|
+
const snippetApiArgs = [];
|
|
921
|
+
if (xSecurity !== void 0 || path7.includes("/admin")) {
|
|
922
|
+
snippetShellArgs.push("--header 'Authorization: Bearer {access_token}'");
|
|
923
|
+
snippetApiArgs.push("{ axiosConfig: { request: { headers: { Authorization: 'Bearer {access_token}' } } } }".trim());
|
|
924
|
+
}
|
|
925
|
+
if (httpMethod !== "get") {
|
|
926
|
+
const curlParams = bodyParams?.map((ob) => {
|
|
927
|
+
return ` "${ob.name}": ""`;
|
|
928
|
+
});
|
|
929
|
+
if (curlParams.length > 0) {
|
|
930
|
+
snippetShellArgs.push(`--data-raw '{ ${curlParams}}'`);
|
|
780
931
|
}
|
|
781
|
-
|
|
782
|
-
${
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
${
|
|
932
|
+
}
|
|
933
|
+
const snippetShell = `curl ${snippetShellArgs.join(" \\\n ")}`;
|
|
934
|
+
const { responseType, responseTypeInAxiosResponse } = getResponseType({ responseClasses });
|
|
935
|
+
const methodImpl = `
|
|
936
|
+
async function ${classMethod}(${methodParams}): ${responseTypeInAxiosResponse} {
|
|
937
|
+
const $ = new ${classGenName}(axiosInstance, namespace, useSchemaValidation)
|
|
938
|
+
const resp = await $.${classMethod}(${methodParamsNoTypes})
|
|
939
|
+
if (resp.error) throw resp.error
|
|
940
|
+
return resp.response
|
|
941
|
+
}
|
|
787
942
|
`;
|
|
788
|
-
|
|
943
|
+
const snippetPromiseString = responseType !== "unknown" ? `Promise<${responseType}>` : "Promise";
|
|
944
|
+
snippetMethod += `${classMethod}(${methodParams})
|
|
945
|
+
// return ${snippetPromiseString}`;
|
|
946
|
+
return {
|
|
947
|
+
generatedMethodString: methodImpl,
|
|
948
|
+
snippetApiArgs,
|
|
949
|
+
snippetMethod,
|
|
950
|
+
snippetShell
|
|
789
951
|
};
|
|
790
|
-
parseToZodSchema = (definition, requiredAttrs) => {
|
|
791
|
-
if (definition.additionalProperties) {
|
|
792
|
-
return this.parseToZodAttribute("", definition, []);
|
|
793
|
-
}
|
|
794
|
-
let properties;
|
|
795
|
-
if (definition.properties) {
|
|
796
|
-
properties = Object.entries(definition.properties);
|
|
797
|
-
} else if (definition.items?.properties) {
|
|
798
|
-
properties = Object.entries(definition.items.properties);
|
|
799
|
-
} else {
|
|
800
|
-
return {
|
|
801
|
-
schemaString: "z.any()",
|
|
802
|
-
typeString: "any"
|
|
803
|
-
};
|
|
804
|
-
}
|
|
805
|
-
const schemaFields = [];
|
|
806
|
-
const typeFields = [];
|
|
807
|
-
for (const property of properties) {
|
|
808
|
-
const [name, definition2] = property;
|
|
809
|
-
const result = this.parseToZodAttribute(name, definition2, requiredAttrs);
|
|
810
|
-
schemaFields.push(result.schemaString);
|
|
811
|
-
typeFields.push(result.typeString);
|
|
812
|
-
}
|
|
813
|
-
if (definition?.type === "array") {
|
|
814
|
-
return {
|
|
815
|
-
schemaString: `z.array(z.object({${schemaFields.join(",")}}))`,
|
|
816
|
-
typeString: typeFields.join(";")
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
|
-
return {
|
|
820
|
-
schemaString: `z.object({${schemaFields.join(",")}})`,
|
|
821
|
-
typeString: typeFields.join(";")
|
|
822
|
-
};
|
|
823
|
-
};
|
|
824
|
-
parseToZodAttribute = (name, definition, requiredAttrs) => {
|
|
825
|
-
const isRequired = requiredAttrs.includes(name) || name === "";
|
|
826
|
-
const schemaRequired = isRequired ? "" : ".nullish()";
|
|
827
|
-
const typeRequired = isRequired ? "" : "?";
|
|
828
|
-
const typeNullishability = isRequired ? "" : " | null | undefined";
|
|
829
|
-
const schemaAttribute = name ? `'${name}':` : "";
|
|
830
|
-
const typeAttribute = name ? `'${name}'${typeRequired}:` : "";
|
|
831
|
-
const type = definition?.type;
|
|
832
|
-
if (definition.properties) {
|
|
833
|
-
const result = this.parseToZodSchema(definition, requiredAttrs);
|
|
834
|
-
return {
|
|
835
|
-
schemaString: `${schemaAttribute} ${result.schemaString}${schemaRequired}`,
|
|
836
|
-
typeString: `${typeAttribute} ${result.typeString}${typeNullishability}`
|
|
837
|
-
};
|
|
838
|
-
} else if (type) {
|
|
839
|
-
if (type === "object" && definition.additionalProperties) {
|
|
840
|
-
const zodAttribute = this.parseToZodAttribute("", definition.additionalProperties, [""]);
|
|
841
|
-
return {
|
|
842
|
-
schemaString: `${schemaAttribute} z.record(${zodAttribute.schemaString})${schemaRequired}`,
|
|
843
|
-
typeString: `${typeAttribute} Record<string, ${zodAttribute.typeString}>${typeNullishability}`
|
|
844
|
-
};
|
|
845
|
-
}
|
|
846
|
-
if (type === "object" && !definition.additionalProperties && !name) {
|
|
847
|
-
return {
|
|
848
|
-
schemaString: `z.any()`,
|
|
849
|
-
typeString: "any"
|
|
850
|
-
};
|
|
851
|
-
}
|
|
852
|
-
if (type === "object" && !definition.additionalProperties) {
|
|
853
|
-
return {
|
|
854
|
-
schemaString: `${schemaAttribute} z.record(z.any())${schemaRequired}`,
|
|
855
|
-
typeString: `${typeAttribute} Record<string, any>${typeNullishability}`
|
|
856
|
-
};
|
|
857
|
-
}
|
|
858
|
-
if (type === "integer" || type === "number") {
|
|
859
|
-
const effectiveType = getZodNumberType(type);
|
|
860
|
-
return {
|
|
861
|
-
schemaString: `${schemaAttribute} z.${effectiveType.schemaString}()${schemaRequired}`,
|
|
862
|
-
typeString: `${typeAttribute} ${effectiveType.typeString}${typeNullishability}`
|
|
863
|
-
};
|
|
864
|
-
}
|
|
865
|
-
if (type === "array") {
|
|
866
|
-
const items = definition.items;
|
|
867
|
-
const ref2 = items?.$ref;
|
|
868
|
-
let model2;
|
|
869
|
-
if (ref2) {
|
|
870
|
-
const refType = ParserUtils.parseRefType(ref2);
|
|
871
|
-
this.importClasses.add(refType);
|
|
872
|
-
model2 = {
|
|
873
|
-
schemaString: refType,
|
|
874
|
-
typeString: refType
|
|
875
|
-
};
|
|
876
|
-
} else if (items) {
|
|
877
|
-
if (items.type === "array") {
|
|
878
|
-
const ref3 = items.items?.$ref;
|
|
879
|
-
if (ref3) {
|
|
880
|
-
const refType = ParserUtils.parseRefType(ref3);
|
|
881
|
-
this.importClasses.add(refType);
|
|
882
|
-
model2 = {
|
|
883
|
-
schemaString: refType,
|
|
884
|
-
typeString: refType
|
|
885
|
-
};
|
|
886
|
-
} else if (items.items) {
|
|
887
|
-
model2 = this.parseEnumItems(items.items);
|
|
888
|
-
}
|
|
889
|
-
return {
|
|
890
|
-
schemaString: `${schemaAttribute} z.array(z.array(${model2.schemaString}))${schemaRequired}`,
|
|
891
|
-
typeString: `${typeAttribute} ${model2.typeString}[]${typeNullishability}`
|
|
892
|
-
};
|
|
893
|
-
} else {
|
|
894
|
-
model2 = this.parseEnumItems(items);
|
|
895
|
-
}
|
|
896
|
-
} else {
|
|
897
|
-
return {
|
|
898
|
-
schemaString: `${schemaAttribute} z.array(z.any())${schemaRequired}`,
|
|
899
|
-
typeString: `${typeAttribute} any[]${typeNullishability}`
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
return {
|
|
903
|
-
schemaString: `${schemaAttribute} z.array(${model2.schemaString})${schemaRequired}`,
|
|
904
|
-
typeString: `${typeAttribute} ${model2.typeString}[]${typeNullishability}`
|
|
905
|
-
};
|
|
906
|
-
}
|
|
907
|
-
if (type !== "object") {
|
|
908
|
-
const result = extractEnumObject(type, isRequired, definition.enum);
|
|
909
|
-
return {
|
|
910
|
-
schemaString: `${schemaAttribute} ${result.schemaString}`,
|
|
911
|
-
typeString: `${typeAttribute} ${result.typeString}`
|
|
912
|
-
};
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
const ref = definition.$ref;
|
|
916
|
-
let model = `z.record(z.any())`;
|
|
917
|
-
if (ref) {
|
|
918
|
-
model = ParserUtils.parseRefType(ref);
|
|
919
|
-
const fullModelName = ref.replace("#/definitions/", "");
|
|
920
|
-
this.duplicateFound = this.duplicates.has(fullModelName);
|
|
921
|
-
if (this.duplicateFound) {
|
|
922
|
-
model = this.duplicates.get(fullModelName);
|
|
923
|
-
}
|
|
924
|
-
this.importClasses.add(model);
|
|
925
|
-
model = `${model}`;
|
|
926
|
-
}
|
|
927
|
-
return {
|
|
928
|
-
schemaString: `${schemaAttribute} ${model}${schemaRequired}`,
|
|
929
|
-
typeString: `${typeAttribute} ${model}${typeNullishability}`
|
|
930
|
-
};
|
|
931
|
-
};
|
|
932
|
-
parseEnumItems = (items) => {
|
|
933
|
-
if (items.enum) {
|
|
934
|
-
const enumStr = items.enum.map((e) => {
|
|
935
|
-
return `"${e}"`;
|
|
936
|
-
});
|
|
937
|
-
return {
|
|
938
|
-
schemaString: `z.enum([${enumStr}])`,
|
|
939
|
-
typeString: `(${enumStr.join(" | ")})`
|
|
940
|
-
};
|
|
941
|
-
}
|
|
942
|
-
if (items.type === "object") {
|
|
943
|
-
return this.parseToZodSchema(items, items.required);
|
|
944
|
-
}
|
|
945
|
-
let effectiveType;
|
|
946
|
-
if (items.type === "integer" || items.type === "number") {
|
|
947
|
-
effectiveType = getZodNumberType(items.type);
|
|
948
|
-
} else {
|
|
949
|
-
effectiveType = { typeString: items.type, schemaString: items.type };
|
|
950
|
-
}
|
|
951
|
-
return {
|
|
952
|
-
schemaString: `z.${effectiveType.schemaString}()`,
|
|
953
|
-
typeString: effectiveType.typeString
|
|
954
|
-
};
|
|
955
|
-
};
|
|
956
|
-
}
|
|
957
|
-
class TemplateZodArray {
|
|
958
|
-
render = (name) => {
|
|
959
|
-
const cls = name.replace("Array", "");
|
|
960
|
-
const template = `import { z } from 'zod'
|
|
961
|
-
import { ${cls} } from './${cls}.js'
|
|
962
|
-
|
|
963
|
-
export const ${name} = z.array(${cls})
|
|
964
|
-
|
|
965
|
-
export interface ${name} extends z.TypeOf<typeof ${name}> {}
|
|
966
|
-
`;
|
|
967
|
-
return template;
|
|
968
|
-
};
|
|
969
|
-
}
|
|
970
|
-
const getZodNumberType = (type) => {
|
|
971
|
-
if (type === "integer") {
|
|
972
|
-
return {
|
|
973
|
-
schemaString: "number().int",
|
|
974
|
-
typeString: "number"
|
|
975
|
-
};
|
|
976
|
-
}
|
|
977
|
-
return {
|
|
978
|
-
schemaString: type,
|
|
979
|
-
typeString: type
|
|
980
|
-
};
|
|
981
|
-
};
|
|
982
|
-
const extractEnumObject = (type, isRequired, enumArr) => {
|
|
983
|
-
const schemaRequired = isRequired ? "" : ".nullish()";
|
|
984
|
-
const typeNullishability = isRequired ? "" : " | null | undefined";
|
|
985
|
-
if (enumArr) {
|
|
986
|
-
const enumStr = enumArr.map((e) => {
|
|
987
|
-
return `"${e}"`;
|
|
988
|
-
});
|
|
989
|
-
return {
|
|
990
|
-
schemaString: `z.enum([${enumStr}])${schemaRequired}`,
|
|
991
|
-
typeString: `(${enumStr.join(" | ")}${typeNullishability})`
|
|
992
|
-
};
|
|
993
|
-
}
|
|
994
|
-
return {
|
|
995
|
-
schemaString: `z.${type}()${schemaRequired}`,
|
|
996
|
-
typeString: `${type}${typeNullishability}`
|
|
997
|
-
};
|
|
998
|
-
};
|
|
999
|
-
|
|
1000
|
-
const templateApiIndex = (serviceName, serviceNameTitle, apiList) => {
|
|
1001
|
-
let imports = "";
|
|
1002
|
-
let returnStatement = "";
|
|
1003
|
-
for (const cl of apiList) {
|
|
1004
|
-
const dir = cl.toLowerCase().includes("admin") && cl !== "AdminApi" ? "generated-admin" : "generated-public";
|
|
1005
|
-
imports += `
|
|
1006
|
-
import { ${cl} } from './${dir}/${cl}.js'`;
|
|
1007
|
-
returnStatement += `
|
|
1008
|
-
${cl}, `;
|
|
1009
|
-
}
|
|
1010
|
-
return `/**
|
|
1011
|
-
* AUTO GENERATED
|
|
1012
|
-
*/
|
|
1013
|
-
${imports}
|
|
1014
|
-
|
|
1015
|
-
const apis = {
|
|
1016
|
-
${returnStatement}
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
export const ${serviceNameTitle} = apis
|
|
1020
|
-
`;
|
|
1021
952
|
};
|
|
1022
953
|
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
type: z.union([z.literal("array"), z.literal("object"), z.literal("file"), z.literal("string"), z.literal("boolean"), z.literal("integer")]).nullish(),
|
|
1026
|
-
items: z.object({
|
|
1027
|
-
$ref: z.string().nullish(),
|
|
1028
|
-
type: z.string().nullish()
|
|
1029
|
-
}).nullish(),
|
|
1030
|
-
properties: z.union([z.array(z.string()).nullish(), z.record(z.object({ type: z.string() })).nullish()]),
|
|
1031
|
-
description: z.string().nullish(),
|
|
1032
|
-
additionalProperties: z.object({
|
|
1033
|
-
type: z.string().nullish()
|
|
1034
|
-
}).nullish()
|
|
1035
|
-
});
|
|
1036
|
-
const Definition = z.object({
|
|
1037
|
-
required: z.array(z.string()).nullish(),
|
|
1038
|
-
properties: z.record(z.object({
|
|
1039
|
-
type: z.string()
|
|
1040
|
-
})).nullish()
|
|
1041
|
-
});
|
|
1042
|
-
const Definitions = z.record(Definition);
|
|
1043
|
-
const EndpointParametersType = z.enum(["apiKey", "boolean", "int", "integer", "number", "string", "array", "file"]);
|
|
1044
|
-
const EndpointParametersIn = z.enum(["body", "formData", "header", "path", "query"]);
|
|
1045
|
-
const EndpointParameters = z.object({
|
|
1046
|
-
type: EndpointParametersType.nullish(),
|
|
1047
|
-
description: z.string().nullish(),
|
|
1048
|
-
name: z.string(),
|
|
1049
|
-
in: EndpointParametersIn,
|
|
1050
|
-
required: z.boolean().nullish(),
|
|
1051
|
-
schema: Schema.nullish(),
|
|
1052
|
-
default: z.union([z.boolean(), z.string(), z.number(), z.array(z.any())]).nullish(),
|
|
1053
|
-
enum: z.array(z.union([z.boolean(), z.string(), z.number()])).nullish(),
|
|
1054
|
-
items: z.object({
|
|
1055
|
-
type: z.string(),
|
|
1056
|
-
enum: z.array(z.any()).nullish()
|
|
1057
|
-
}).nullish()
|
|
1058
|
-
});
|
|
1059
|
-
const Endpoint = z.object({
|
|
1060
|
-
description: z.string().nullish(),
|
|
1061
|
-
consumes: z.array(z.string()).nullish(),
|
|
1062
|
-
produces: z.array(z.string()).nullish(),
|
|
1063
|
-
tags: z.array(z.string()).nullish(),
|
|
1064
|
-
summary: z.string().nullish(),
|
|
1065
|
-
operationId: z.string(),
|
|
1066
|
-
deprecated: z.boolean().nullish(),
|
|
1067
|
-
responses: z.record(z.object({
|
|
1068
|
-
description: z.string().nullish(),
|
|
1069
|
-
schema: Schema.nullish(),
|
|
1070
|
-
content: z.object({
|
|
1071
|
-
"application/json": z.object({
|
|
1072
|
-
schema: Schema.nullish()
|
|
1073
|
-
})
|
|
1074
|
-
}).nullish()
|
|
1075
|
-
})),
|
|
1076
|
-
parameters: z.array(EndpointParameters).nullish(),
|
|
1077
|
-
requestBody: z.object({
|
|
1078
|
-
required: z.boolean().nullish(),
|
|
1079
|
-
content: z.object({
|
|
1080
|
-
"application/json": z.object({
|
|
1081
|
-
schema: Schema.nullish()
|
|
1082
|
-
}).nullish()
|
|
1083
|
-
}).nullish()
|
|
1084
|
-
}).nullish(),
|
|
1085
|
-
"x-security": z.any().nullish()
|
|
1086
|
-
});
|
|
1087
|
-
const Operation = z.object({
|
|
1088
|
-
get: Endpoint.nullish(),
|
|
1089
|
-
post: Endpoint.nullish(),
|
|
1090
|
-
patch: Endpoint.nullish(),
|
|
1091
|
-
delete: Endpoint.nullish(),
|
|
1092
|
-
put: Endpoint.nullish()
|
|
1093
|
-
});
|
|
1094
|
-
const Paths = z.record(Operation);
|
|
1095
|
-
z.object({
|
|
1096
|
-
paths: Paths,
|
|
1097
|
-
definitions: Definitions,
|
|
1098
|
-
basePath: z.string(),
|
|
1099
|
-
info: z.object({
|
|
1100
|
-
description: z.string(),
|
|
1101
|
-
title: z.string(),
|
|
1102
|
-
contact: z.object({
|
|
1103
|
-
name: z.string(),
|
|
1104
|
-
url: z.string(),
|
|
1105
|
-
email: z.string()
|
|
1106
|
-
}),
|
|
1107
|
-
version: z.string()
|
|
1108
|
-
}),
|
|
1109
|
-
schemes: z.array(z.string()).nullish(),
|
|
1110
|
-
components: z.object({
|
|
1111
|
-
schemas: Definitions
|
|
1112
|
-
}).nullish()
|
|
1113
|
-
});
|
|
1114
|
-
|
|
1115
|
-
const templateMethod = ({
|
|
954
|
+
// src/templates/template-method.ts
|
|
955
|
+
var templateMethod = ({
|
|
1116
956
|
classMethod,
|
|
1117
957
|
description,
|
|
1118
958
|
httpMethod,
|
|
1119
|
-
path,
|
|
959
|
+
path: path7,
|
|
1120
960
|
pathParams,
|
|
1121
961
|
bodyParams,
|
|
1122
962
|
queryParams,
|
|
1123
963
|
isFormUrlEncoded,
|
|
1124
|
-
|
|
964
|
+
responseClasses,
|
|
1125
965
|
deprecated
|
|
1126
966
|
}) => {
|
|
1127
967
|
let methodParams = "";
|
|
1128
968
|
let methodParamsNoTypes = "";
|
|
1129
|
-
let newPath = `'${
|
|
969
|
+
let newPath = `'${path7}'`;
|
|
1130
970
|
let importStatements = [];
|
|
1131
|
-
const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams,
|
|
971
|
+
const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams, path7);
|
|
1132
972
|
for (const pathParam of sortedPathParams) {
|
|
1133
973
|
const type = ParserUtils.parseType(pathParam);
|
|
1134
974
|
if (pathParam.name !== "namespace") {
|
|
@@ -1136,7 +976,7 @@ const templateMethod = ({
|
|
|
1136
976
|
methodParamsNoTypes += pathParam.name + ", ";
|
|
1137
977
|
}
|
|
1138
978
|
const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
|
|
1139
|
-
if (
|
|
979
|
+
if (path7.match(`{${pathParam.name}}`)) {
|
|
1140
980
|
if (type === "string") {
|
|
1141
981
|
newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
|
|
1142
982
|
} else {
|
|
@@ -1153,14 +993,11 @@ const templateMethod = ({
|
|
|
1153
993
|
}
|
|
1154
994
|
const isAnyRequired = ParserUtils.isAnyQueryParamRequired(queryParams);
|
|
1155
995
|
const queryParamsType = queryParams.length ? `queryParams${isAnyRequired ? "" : "?"}: {${ParserUtils.parseQueryParamsType(queryParams)}}` : "";
|
|
1156
|
-
const queryParamsDefault = queryParams.length ? `const params = {${ParserUtils.parseQueryParamsDefault(queryParams)} ...queryParams} as
|
|
996
|
+
const queryParamsDefault = queryParams.length ? `const params = {${ParserUtils.parseQueryParamsDefault(queryParams)} ...queryParams} as AxiosRequestConfig` : "const params = {} as AxiosRequestConfig";
|
|
1157
997
|
const isPostPutPatch = ["post", "put", "patch"].includes(httpMethod);
|
|
1158
998
|
const isDelete = ["delete"].includes(httpMethod);
|
|
1159
999
|
let dataPayload = "{params}";
|
|
1160
|
-
const descriptionText = description
|
|
1161
|
-
/**${deprecated ? "\n * @deprecated" : ""}
|
|
1162
|
-
* ${description.replace(/\n/g, "\n * ")}
|
|
1163
|
-
*/` : "";
|
|
1000
|
+
const descriptionText = extractDescription(description, { isDeprecated: deprecated, responseClasses });
|
|
1164
1001
|
let formPayloadString = "";
|
|
1165
1002
|
if (isFormUrlEncoded) {
|
|
1166
1003
|
formPayloadString = ``;
|
|
@@ -1172,17 +1009,14 @@ const templateMethod = ({
|
|
|
1172
1009
|
dataPayload = dataType ? `{data, params}` : "{params}";
|
|
1173
1010
|
}
|
|
1174
1011
|
const isFileUpload = methodParams.indexOf("data: {file") > -1;
|
|
1175
|
-
const
|
|
1176
|
-
const resolvedResponseClassValidated =
|
|
1012
|
+
const { responseType, responseTypeInResponse } = getResponseType({ responseClasses });
|
|
1013
|
+
const resolvedResponseClassValidated = responseType !== "unknown" ? `${responseType}` : "z.unknown()";
|
|
1177
1014
|
methodParams = (queryParamsType ? `${methodParams} ${queryParamsType}` : methodParams).replace(/,\s*$/, "");
|
|
1178
1015
|
methodParamsNoTypes = queryParamsType ? `${methodParamsNoTypes} queryParams` : methodParamsNoTypes;
|
|
1179
|
-
let methodImpl = "";
|
|
1180
1016
|
const isGuardInvoked = ["get", "post", "put", "patch", "delete"].includes(httpMethod);
|
|
1181
|
-
const
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
methodImpl = `${descriptionText}
|
|
1185
|
-
${generateMethodName()} {
|
|
1017
|
+
const generatedMethodName = `${classMethod}(${methodParams}): ${responseTypeInResponse}`;
|
|
1018
|
+
let methodImpl = `${descriptionText}
|
|
1019
|
+
${generatedMethodName} {
|
|
1186
1020
|
${queryParamsDefault}
|
|
1187
1021
|
const url = ${newPath} ${formPayloadString} ${isFileUpload ? "\n// TODO file upload not implemented" : ""}
|
|
1188
1022
|
const resultPromise = this.axiosInstance.${httpMethod}(url, ${dataPayload})
|
|
@@ -1202,26 +1036,35 @@ ${` return Validate.validateOrReturnResponse(this.useSchemaValidation, () =>
|
|
|
1202
1036
|
return res;
|
|
1203
1037
|
};
|
|
1204
1038
|
|
|
1205
|
-
|
|
1039
|
+
// src/templates/template-query-method.ts
|
|
1040
|
+
var POST_FETCH_INCLUDES_PATH = ["/table-query/"];
|
|
1041
|
+
var templateQueryMethod = ({
|
|
1206
1042
|
classMethod,
|
|
1207
|
-
description,
|
|
1208
1043
|
httpMethod,
|
|
1209
|
-
path,
|
|
1044
|
+
path: path7,
|
|
1210
1045
|
pathParams,
|
|
1211
|
-
|
|
1212
|
-
responseClass,
|
|
1213
|
-
classGenName,
|
|
1046
|
+
responseClasses,
|
|
1214
1047
|
methodParams,
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1048
|
+
apiGenName,
|
|
1049
|
+
description,
|
|
1050
|
+
deprecated
|
|
1218
1051
|
}) => {
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1052
|
+
const isPostFetch = httpMethod === "post" && (POST_FETCH_INCLUDES_PATH.some((p) => path7.includes(p)) || path7.endsWith("/list"));
|
|
1053
|
+
const isFetch = classMethod.startsWith("fetch");
|
|
1054
|
+
const isGet = httpMethod === "get" || isPostFetch || isFetch;
|
|
1055
|
+
const queryMethod = isGet ? "useQuery" : "useMutation";
|
|
1056
|
+
let mParams = "";
|
|
1057
|
+
let mParamsNoTypes = "";
|
|
1058
|
+
let newPath = `'${path7}'`;
|
|
1059
|
+
const sortedPathParams = ParserUtils.sortPathParamsByPath(pathParams, path7);
|
|
1060
|
+
for (const pathParam of sortedPathParams) {
|
|
1222
1061
|
const type = ParserUtils.parseType(pathParam);
|
|
1062
|
+
if (pathParam.name !== "namespace") {
|
|
1063
|
+
mParams += pathParam.name + `:${type}, `;
|
|
1064
|
+
mParamsNoTypes += pathParam.name + ", ";
|
|
1065
|
+
}
|
|
1223
1066
|
const pName = pathParam.name === "namespace" ? "this.namespace" : pathParam.name;
|
|
1224
|
-
if (
|
|
1067
|
+
if (path7.match(`{${pathParam.name}}`)) {
|
|
1225
1068
|
if (type === "string") {
|
|
1226
1069
|
newPath = `${newPath}.replace('{${pathParam.name}}', ${pName})`;
|
|
1227
1070
|
} else {
|
|
@@ -1229,48 +1072,121 @@ const templateApiMethod = ({
|
|
|
1229
1072
|
}
|
|
1230
1073
|
}
|
|
1231
1074
|
}
|
|
1232
|
-
const
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1075
|
+
const { responseType } = getResponseType({ responseClasses });
|
|
1076
|
+
let _methodName = convertMethodNameToHook({ classMethod, apiGenName, isGet });
|
|
1077
|
+
const _methodParams = methodParams && methodParams.length > 0 ? `& { ${methodParams} }` : "";
|
|
1078
|
+
const _methodParamsImpl = convertToMethodImplArgs(methodParams);
|
|
1079
|
+
const queryKey = createQueryKey(apiGenName, classMethod);
|
|
1080
|
+
const descriptionText = extractDescription(description, {
|
|
1081
|
+
isDeprecated: deprecated,
|
|
1082
|
+
responseClasses,
|
|
1083
|
+
other: [" ", "#### Default Query Options", "The default options include:", "```", "{", ` queryKey: [${queryKey}, input]`, "}", "```"]
|
|
1084
|
+
});
|
|
1085
|
+
const queryMethodImpl = `
|
|
1086
|
+
|
|
1087
|
+
${descriptionText}
|
|
1088
|
+
export const ${_methodName} = (
|
|
1089
|
+
sdk: AccelByteSDK,
|
|
1090
|
+
input: SdkSetConfigParam ${_methodParams},
|
|
1091
|
+
options?: Omit<UseQueryOptions<${responseType}, AxiosError<ApiError>>, 'queryKey'>,
|
|
1092
|
+
callback?: (data: AxiosResponse<${responseType}>) => void
|
|
1093
|
+
): UseQueryResult<${responseType}, AxiosError<ApiError>> => {
|
|
1094
|
+
|
|
1095
|
+
const queryFn = (
|
|
1096
|
+
sdk: AccelByteSDK,
|
|
1097
|
+
input: Parameters<typeof ${_methodName}>[1]
|
|
1098
|
+
) => async () => {
|
|
1099
|
+
const response =
|
|
1100
|
+
(await ${apiGenName}(sdk, { coreConfig: input.coreConfig, axiosConfig: input.axiosConfig }).
|
|
1101
|
+
${classMethod}(${_methodParamsImpl}))
|
|
1102
|
+
callback && callback(response)
|
|
1103
|
+
return response.data
|
|
1245
1104
|
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1105
|
+
|
|
1106
|
+
return ${queryMethod}<${responseType}, AxiosError<ApiError>>({
|
|
1107
|
+
queryKey: [${queryKey}, input],
|
|
1108
|
+
queryFn: queryFn(sdk, input),
|
|
1109
|
+
...options
|
|
1110
|
+
})
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
`;
|
|
1114
|
+
const mutationMethodImpl = `
|
|
1115
|
+
|
|
1254
1116
|
${descriptionText}
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1117
|
+
export const ${_methodName} = (
|
|
1118
|
+
sdk: AccelByteSDK,
|
|
1119
|
+
options?: Omit<UseMutationOptions<${responseType}, AxiosError<ApiError>, SdkSetConfigParam ${_methodParams}>, 'mutationKey'>,
|
|
1120
|
+
callback?: (data: ${responseType}) => void
|
|
1121
|
+
): UseMutationResult<${responseType}, AxiosError<ApiError>, SdkSetConfigParam ${_methodParams}> => {
|
|
1122
|
+
|
|
1123
|
+
const mutationFn = async (input: SdkSetConfigParam ${_methodParams}) => {
|
|
1124
|
+
const response =
|
|
1125
|
+
(await ${apiGenName}(sdk, { coreConfig: input.coreConfig, axiosConfig: input.axiosConfig }).
|
|
1126
|
+
${classMethod}(${_methodParamsImpl}))
|
|
1127
|
+
callback && callback(response.data)
|
|
1128
|
+
return response.data
|
|
1260
1129
|
}
|
|
1130
|
+
|
|
1131
|
+
return useMutation({
|
|
1132
|
+
mutationKey: [${queryKey}],
|
|
1133
|
+
mutationFn,
|
|
1134
|
+
...options
|
|
1135
|
+
})
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1261
1138
|
`;
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1139
|
+
return isGet ? queryMethodImpl : mutationMethodImpl;
|
|
1140
|
+
};
|
|
1141
|
+
function versionMutationSuffixMethodName(baseMethodName) {
|
|
1142
|
+
const parts = baseMethodName.split(/(_v\d+)$/);
|
|
1143
|
+
const name = parts[0];
|
|
1144
|
+
const versionSuffix = parts[1] || "";
|
|
1145
|
+
const res = `${name}Mutation${versionSuffix}`;
|
|
1146
|
+
return res;
|
|
1147
|
+
}
|
|
1148
|
+
function createQueryKey(className, methodName) {
|
|
1149
|
+
const prefixRegex = /^(get|create|update|delete|patch|post|fetch)[_]?/i;
|
|
1150
|
+
const cleanedMethodName = methodName.replace(prefixRegex, "").trim();
|
|
1151
|
+
const finalMethodName = cleanedMethodName.charAt(0).toUpperCase() + cleanedMethodName.slice(1);
|
|
1152
|
+
return `Key_${className.replace("Api", "")}.${finalMethodName}`;
|
|
1153
|
+
}
|
|
1154
|
+
var prefixMappings = {
|
|
1155
|
+
get: "use",
|
|
1156
|
+
create: "useCreate",
|
|
1157
|
+
patch: "usePatch",
|
|
1158
|
+
update: "useUpdate",
|
|
1159
|
+
delete: "useDelete",
|
|
1160
|
+
post: "usePost",
|
|
1161
|
+
fetch: "useFetch"
|
|
1271
1162
|
};
|
|
1163
|
+
function convertMethodNameToHook({ classMethod, apiGenName, isGet }) {
|
|
1164
|
+
for (const [originalPrefix] of Object.entries(prefixMappings)) {
|
|
1165
|
+
if (classMethod.startsWith(originalPrefix)) {
|
|
1166
|
+
const methodName = !isGet ? versionMutationSuffixMethodName(classMethod) : classMethod;
|
|
1167
|
+
return `use${apiGenName}_${capitalize(methodName)}`;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
return classMethod;
|
|
1171
|
+
}
|
|
1172
|
+
function convertToMethodImplArgs(methodArgs) {
|
|
1173
|
+
const properties = methodArgs.split(/,\s*(?![^{}]*\})/).map((prop) => prop.trim()).filter(Boolean);
|
|
1174
|
+
const formattedProperties = [];
|
|
1175
|
+
properties.forEach((prop) => {
|
|
1176
|
+
if (prop.includes(": {")) {
|
|
1177
|
+
const propertyName = prop.split(": {")[0].replace("?", "").trim();
|
|
1178
|
+
formattedProperties.push(`input.${propertyName}`);
|
|
1179
|
+
} else {
|
|
1180
|
+
const colonIndex = prop.indexOf(":");
|
|
1181
|
+
const propertyName = prop.substring(0, colonIndex).replace("?", "").trim();
|
|
1182
|
+
formattedProperties.push(`input.${propertyName}`);
|
|
1183
|
+
}
|
|
1184
|
+
});
|
|
1185
|
+
return formattedProperties.join(", ");
|
|
1186
|
+
}
|
|
1272
1187
|
|
|
1273
|
-
|
|
1188
|
+
// src/templates/template-sdk-snippet.ts
|
|
1189
|
+
var templateSdkSnippet = ({
|
|
1274
1190
|
serviceNameTitle,
|
|
1275
1191
|
apiName,
|
|
1276
1192
|
snippetMethod,
|
|
@@ -1282,11 +1198,11 @@ const templateSdkSnippet = ({
|
|
|
1282
1198
|
normMethod = normalizeMethodSnippet(normMethod, "queryParams:");
|
|
1283
1199
|
normMethod = normalizeMethodSnippet(normMethod, "queryParams?:");
|
|
1284
1200
|
normMethod += "\n\n//" + methodArr[1];
|
|
1285
|
-
const sdkSnippet = `import {
|
|
1201
|
+
const sdkSnippet = `import { AccelByte } from '@accelbyte/sdk'
|
|
1286
1202
|
import { ${serviceNameTitle} } from '@accelbyte/sdk-${serviceNameTitle.toLowerCase()}'
|
|
1287
1203
|
|
|
1288
|
-
const sdk =
|
|
1289
|
-
|
|
1204
|
+
const sdk = AccelByte.SDK({
|
|
1205
|
+
coreConfig: {
|
|
1290
1206
|
baseURL: 'https://demo.accelbyte.io',
|
|
1291
1207
|
clientId: '77f88506b6174c3ea4d925f5b4096ce8',
|
|
1292
1208
|
namespace: 'accelbyte',
|
|
@@ -1298,7 +1214,7 @@ ${serviceNameTitle}.${apiName}(${snippetApiArgs.join(", ")})
|
|
|
1298
1214
|
.${normMethod}`;
|
|
1299
1215
|
return sdkSnippet;
|
|
1300
1216
|
};
|
|
1301
|
-
|
|
1217
|
+
var normalizeMethodSnippet = (methodInput, splitWord) => {
|
|
1302
1218
|
const split1 = methodInput.split(splitWord);
|
|
1303
1219
|
if (!split1[1]) {
|
|
1304
1220
|
return methodInput;
|
|
@@ -1316,327 +1232,486 @@ const normalizeMethodSnippet = (methodInput, splitWord) => {
|
|
|
1316
1232
|
return result;
|
|
1317
1233
|
};
|
|
1318
1234
|
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1235
|
+
// src/helpers/SwaggerReaderHelpers.ts
|
|
1236
|
+
var GIT_URL = "https://github.com/AccelByte/accelbyte-web-sdk/blob/main/packages";
|
|
1237
|
+
var SwaggerReaderHelpers = class _SwaggerReaderHelpers {
|
|
1238
|
+
static getServicePrefix = (servicePaths) => servicePaths[servicePaths.length - 1].split("/")[1];
|
|
1239
|
+
static parseAllEndpoints = async ({
|
|
1240
|
+
api,
|
|
1241
|
+
sdkName,
|
|
1242
|
+
serviceName
|
|
1243
|
+
}) => {
|
|
1244
|
+
const result = {
|
|
1245
|
+
admin: {
|
|
1246
|
+
arrayDefinitions: [],
|
|
1247
|
+
snippetMap: {},
|
|
1248
|
+
tagToClassImportsRecord: {},
|
|
1249
|
+
tagToEndpointClassesRecord: {},
|
|
1250
|
+
tagToSdkClientRecord: {},
|
|
1251
|
+
tagToSdkFunctionNamesRecord: {},
|
|
1252
|
+
tagToSdkImportsRecord: {},
|
|
1253
|
+
tagToEndpointQueryRecord: {},
|
|
1254
|
+
tagToSdkFunctionDescription: {}
|
|
1255
|
+
},
|
|
1256
|
+
public: {
|
|
1257
|
+
arrayDefinitions: [],
|
|
1258
|
+
snippetMap: {},
|
|
1259
|
+
tagToClassImportsRecord: {},
|
|
1260
|
+
tagToEndpointClassesRecord: {},
|
|
1261
|
+
tagToSdkClientRecord: {},
|
|
1262
|
+
tagToSdkFunctionNamesRecord: {},
|
|
1263
|
+
tagToSdkImportsRecord: {},
|
|
1264
|
+
tagToEndpointQueryRecord: {},
|
|
1265
|
+
tagToSdkFunctionDescription: {}
|
|
1266
|
+
}
|
|
1267
|
+
};
|
|
1268
|
+
const sortedPathsByLength = new Map(
|
|
1269
|
+
Object.entries(api.paths).sort((a, b) => {
|
|
1270
|
+
if (a[0].length === b[0].length) {
|
|
1271
|
+
return a[0].localeCompare(b[0]);
|
|
1272
|
+
} else {
|
|
1273
|
+
return a[0].length - b[0].length;
|
|
1274
|
+
}
|
|
1275
|
+
})
|
|
1276
|
+
);
|
|
1277
|
+
const sortedKeys = Array.from(sortedPathsByLength.keys());
|
|
1278
|
+
const servicePrefix = _SwaggerReaderHelpers.getServicePrefix(sortedKeys);
|
|
1279
|
+
const tagToClassMethodsMap = {
|
|
1280
|
+
admin: {},
|
|
1281
|
+
public: {}
|
|
1282
|
+
};
|
|
1283
|
+
for (const [path7, operation] of sortedPathsByLength) {
|
|
1284
|
+
if (path7.indexOf("/healthz") >= 0) {
|
|
1285
|
+
continue;
|
|
1286
|
+
}
|
|
1287
|
+
const isAdminEndpoint = path7.indexOf("/admin/") > -1;
|
|
1288
|
+
const picked = isAdminEndpoint ? result.admin : result.public;
|
|
1289
|
+
const {
|
|
1290
|
+
arrayDefinitions,
|
|
1291
|
+
snippetMap,
|
|
1292
|
+
tagToClassImportsRecord,
|
|
1293
|
+
tagToEndpointClassesRecord,
|
|
1294
|
+
tagToSdkClientRecord,
|
|
1295
|
+
tagToSdkFunctionNamesRecord,
|
|
1296
|
+
tagToSdkImportsRecord,
|
|
1297
|
+
tagToEndpointQueryRecord,
|
|
1298
|
+
tagToSdkFunctionDescription
|
|
1299
|
+
} = picked;
|
|
1300
|
+
const tagToClassMethodsMapByType = isAdminEndpoint ? tagToClassMethodsMap.admin : tagToClassMethodsMap.public;
|
|
1301
|
+
const generatedMethods = {};
|
|
1302
|
+
const httpMethods = Object.keys(operation);
|
|
1303
|
+
for (const httpMethod of httpMethods) {
|
|
1304
|
+
const endpoint = await Endpoint.parseAsync(operation[httpMethod]).catch((error) => {
|
|
1305
|
+
console.error(JSON.stringify({ path: path7, httpMethod }, null, 2));
|
|
1306
|
+
throw error;
|
|
1307
|
+
});
|
|
1308
|
+
if (!endpoint.tags) continue;
|
|
1309
|
+
const [tag] = endpoint.tags;
|
|
1310
|
+
const pathWithBase = `${api.basePath ?? ""}${path7}`;
|
|
1311
|
+
const permissionType = getPermissionType(getPermission(endpoint));
|
|
1312
|
+
tagToClassMethodsMapByType[tag] = tagToClassMethodsMapByType[tag] ? tagToClassMethodsMapByType[tag] : {};
|
|
1313
|
+
const isForm = endpoint.consumes && endpoint.consumes[0] === "application/x-www-form-urlencoded";
|
|
1314
|
+
const classMethod = ParserUtils.generateNaturalLangMethod({
|
|
1315
|
+
servicePrefix,
|
|
1316
|
+
path: path7,
|
|
1317
|
+
httpMethod,
|
|
1318
|
+
isForm,
|
|
1319
|
+
existingMethods: tagToClassMethodsMapByType[tag],
|
|
1320
|
+
permissionType
|
|
1321
|
+
});
|
|
1322
|
+
tagToClassMethodsMapByType[tag][classMethod] = `${path7} ${httpMethod}`;
|
|
1323
|
+
generatedMethods[`${path7} ${httpMethod}`] = `${classMethod}`;
|
|
1324
|
+
if (!snippetMap[pathWithBase]) {
|
|
1325
|
+
snippetMap[pathWithBase] = {};
|
|
1326
|
+
}
|
|
1327
|
+
const description = endpoint.description?.replace(/\s+/g, " ") || "";
|
|
1328
|
+
const responseClasses = ParserUtils.get2xxResponses(endpoint.responses);
|
|
1329
|
+
const responseClass = responseClasses.length > 1 ? null : responseClasses?.[0];
|
|
1330
|
+
const { className, classGenName } = ParserUtils.generateClassName(tag, isAdminEndpoint);
|
|
1331
|
+
tagToClassImportsRecord[className] = tagToClassImportsRecord[className] ? tagToClassImportsRecord[className] : {};
|
|
1332
|
+
if (responseClass) {
|
|
1333
|
+
tagToClassImportsRecord[className][responseClass] = `import { ${responseClass} } from '../../generated-definitions/${responseClass}.js'`;
|
|
1334
|
+
}
|
|
1335
|
+
if (responseClass && responseClass.endsWith("Array")) {
|
|
1336
|
+
arrayDefinitions.push(responseClass);
|
|
1337
|
+
}
|
|
1338
|
+
const queryParams = ParserUtils.filterQueryParameters(endpoint.parameters);
|
|
1339
|
+
const isFormUrlEncoded = ParserUtils.isFormUrlEncoded(httpMethod, endpoint.consumes);
|
|
1340
|
+
const pathParams = ParserUtils.filterPathParams(endpoint.parameters);
|
|
1341
|
+
let bodyParams = ParserUtils.filterBodyParams(endpoint.parameters);
|
|
1342
|
+
const deprecated = !!endpoint.deprecated;
|
|
1343
|
+
if (endpoint.requestBody) {
|
|
1344
|
+
bodyParams = [
|
|
1345
|
+
{
|
|
1346
|
+
name: "body",
|
|
1347
|
+
in: "body",
|
|
1348
|
+
schema: endpoint.requestBody.content["application/json"]?.schema
|
|
1349
|
+
}
|
|
1350
|
+
];
|
|
1351
|
+
}
|
|
1352
|
+
const { methodImpl, methodParams, methodParamsNoTypes, importStatements } = templateMethod({
|
|
1353
|
+
classMethod,
|
|
1354
|
+
description,
|
|
1355
|
+
httpMethod,
|
|
1356
|
+
path: pathWithBase,
|
|
1357
|
+
pathParams,
|
|
1358
|
+
bodyParams,
|
|
1359
|
+
queryParams,
|
|
1360
|
+
isFormUrlEncoded,
|
|
1361
|
+
responseClasses,
|
|
1362
|
+
deprecated
|
|
1363
|
+
});
|
|
1364
|
+
tagToEndpointClassesRecord[tag] = (tagToEndpointClassesRecord[tag] || "") + methodImpl;
|
|
1365
|
+
const { apiGenName } = ParserUtils.generateApiName(tag, isAdminEndpoint);
|
|
1366
|
+
const queryMethodImpl = templateQueryMethod({
|
|
1367
|
+
classMethod,
|
|
1368
|
+
httpMethod,
|
|
1369
|
+
path: pathWithBase,
|
|
1370
|
+
pathParams,
|
|
1371
|
+
responseClasses,
|
|
1372
|
+
methodParams,
|
|
1373
|
+
apiGenName,
|
|
1374
|
+
deprecated,
|
|
1375
|
+
description
|
|
1376
|
+
});
|
|
1377
|
+
tagToEndpointQueryRecord[tag] = (tagToEndpointQueryRecord[tag] || "") + queryMethodImpl;
|
|
1378
|
+
const fnDescription = extractDescription(description, { isDeprecated: deprecated, responseClasses });
|
|
1379
|
+
const tagFnDescriptions = tagToSdkFunctionDescription[tag];
|
|
1380
|
+
tagToSdkFunctionDescription[tag] = {
|
|
1381
|
+
...tagFnDescriptions,
|
|
1382
|
+
[classMethod]: fnDescription
|
|
1383
|
+
};
|
|
1384
|
+
const { generatedMethodString, snippetApiArgs, snippetMethod, snippetShell } = templateApiMethod({
|
|
1385
|
+
classMethod,
|
|
1386
|
+
httpMethod,
|
|
1387
|
+
path: pathWithBase,
|
|
1388
|
+
pathParams,
|
|
1389
|
+
bodyParams,
|
|
1390
|
+
responseClasses,
|
|
1391
|
+
classGenName,
|
|
1392
|
+
methodParams,
|
|
1393
|
+
methodParamsNoTypes,
|
|
1394
|
+
xSecurity: endpoint["x-security"]
|
|
1395
|
+
});
|
|
1396
|
+
tagToSdkClientRecord[tag] = (tagToSdkClientRecord[tag] || "") + generatedMethodString;
|
|
1397
|
+
tagToSdkFunctionNamesRecord[tag] = (tagToSdkFunctionNamesRecord[tag] || "") + classMethod + ",";
|
|
1398
|
+
tagToSdkImportsRecord[tag] = tagToSdkImportsRecord[tag] ? [.../* @__PURE__ */ new Set([...importStatements, ...tagToSdkImportsRecord[tag]])] : [...new Set(importStatements)];
|
|
1399
|
+
const serviceNameTitle = ParserUtils.convertDashesToTitleCase(serviceName);
|
|
1400
|
+
const resultSnippet = templateSdkSnippet({
|
|
1401
|
+
serviceNameTitle,
|
|
1402
|
+
apiName: apiGenName,
|
|
1403
|
+
snippetMethod,
|
|
1404
|
+
snippetApiArgs
|
|
1405
|
+
});
|
|
1406
|
+
const currentSnippetMap = {};
|
|
1407
|
+
snippetMap[pathWithBase][httpMethod] = currentSnippetMap;
|
|
1408
|
+
currentSnippetMap.web = resultSnippet;
|
|
1409
|
+
const generatedDirName = isAdminEndpoint ? "generated-admin" : "generated-public";
|
|
1410
|
+
currentSnippetMap.webGit = GIT_URL + `/sdk-${sdkName}/src/${generatedDirName}/${apiGenName}.ts`;
|
|
1411
|
+
currentSnippetMap.shell = snippetShell;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
for (const key in result) {
|
|
1415
|
+
result[key].arrayDefinitions = Array.from(new Set(result[key].arrayDefinitions));
|
|
1416
|
+
}
|
|
1417
|
+
return result;
|
|
1418
|
+
};
|
|
1419
|
+
};
|
|
1420
|
+
|
|
1421
|
+
// src/templates/template-api-index.ts
|
|
1422
|
+
var templateApiIndex = (serviceNameTitle, apiList) => {
|
|
1423
|
+
let imports = "";
|
|
1424
|
+
let returnStatement = "";
|
|
1425
|
+
for (const cl of apiList) {
|
|
1426
|
+
const dir = cl.toLowerCase().includes("admin") && cl !== "AdminApi" ? "generated-admin" : "generated-public";
|
|
1427
|
+
imports += `
|
|
1428
|
+
import { ${cl} } from './${dir}/${cl}.js'`;
|
|
1429
|
+
returnStatement += `
|
|
1430
|
+
${cl}, `;
|
|
1332
1431
|
}
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1432
|
+
return `/**
|
|
1433
|
+
* AUTO GENERATED
|
|
1434
|
+
*/
|
|
1435
|
+
${imports}
|
|
1436
|
+
import { author, name, version } from '../package.json'
|
|
1437
|
+
|
|
1438
|
+
console.log(\`\${name}@\${version}\`)
|
|
1439
|
+
|
|
1440
|
+
const apis = {
|
|
1441
|
+
${returnStatement}
|
|
1442
|
+
version: () => console.log({
|
|
1443
|
+
version,
|
|
1444
|
+
name,
|
|
1445
|
+
author
|
|
1446
|
+
})
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
export const ${serviceNameTitle} = apis
|
|
1450
|
+
`;
|
|
1451
|
+
};
|
|
1452
|
+
|
|
1453
|
+
// src/templates/template-zod.ts
|
|
1454
|
+
var TemplateZod = class {
|
|
1455
|
+
duplicates;
|
|
1456
|
+
duplicateFound = false;
|
|
1457
|
+
//
|
|
1458
|
+
importClasses = /* @__PURE__ */ new Set();
|
|
1459
|
+
// --
|
|
1460
|
+
render = (fileName, definition, duplicates) => {
|
|
1461
|
+
this.duplicates = duplicates;
|
|
1462
|
+
const content = this.parseToZodSchema(definition, definition.required || []);
|
|
1463
|
+
const containsRecursiveType = this.importClasses.has(fileName);
|
|
1464
|
+
if (containsRecursiveType) {
|
|
1465
|
+
this.importClasses.delete(fileName);
|
|
1346
1466
|
}
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1467
|
+
let imports = "";
|
|
1468
|
+
for (const cl of Array.from(this.importClasses).sort()) {
|
|
1469
|
+
imports += `import { ${cl} } from './${cl}.js'
|
|
1470
|
+
`;
|
|
1471
|
+
}
|
|
1472
|
+
let exportedVariableString;
|
|
1473
|
+
let exportedTypeString;
|
|
1474
|
+
if (containsRecursiveType) {
|
|
1475
|
+
exportedVariableString = `
|
|
1476
|
+
export const ${fileName}: z.ZodType<${fileName}> = z.lazy(() =>
|
|
1477
|
+
${content.schemaString}
|
|
1478
|
+
)
|
|
1479
|
+
`;
|
|
1480
|
+
exportedTypeString = `
|
|
1481
|
+
export interface ${fileName} {
|
|
1482
|
+
${content.typeString}
|
|
1483
|
+
}
|
|
1484
|
+
`;
|
|
1485
|
+
} else {
|
|
1486
|
+
exportedVariableString = `export const ${fileName} = ${content.schemaString}`;
|
|
1487
|
+
exportedTypeString = `export interface ${fileName} extends z.TypeOf<typeof ${fileName}> {}`;
|
|
1488
|
+
}
|
|
1489
|
+
const template = `import { z } from 'zod'
|
|
1490
|
+
${imports}
|
|
1491
|
+
|
|
1492
|
+
${exportedVariableString}
|
|
1493
|
+
|
|
1494
|
+
${exportedTypeString}
|
|
1495
|
+
`;
|
|
1496
|
+
return { buffer: template, duplicateFound: this.duplicateFound };
|
|
1497
|
+
};
|
|
1498
|
+
// --
|
|
1499
|
+
parseToZodSchema = (definition, requiredAttrs) => {
|
|
1500
|
+
if (definition.additionalProperties) {
|
|
1501
|
+
return this.parseToZodAttribute("", definition, []);
|
|
1502
|
+
}
|
|
1503
|
+
let properties;
|
|
1504
|
+
if (definition.properties) {
|
|
1505
|
+
properties = Object.entries(definition.properties);
|
|
1506
|
+
} else if (definition.items?.properties) {
|
|
1507
|
+
properties = Object.entries(definition.items.properties);
|
|
1508
|
+
} else {
|
|
1509
|
+
return {
|
|
1510
|
+
schemaString: "z.any()",
|
|
1511
|
+
typeString: "any"
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
const schemaFields = [];
|
|
1515
|
+
const typeFields = [];
|
|
1516
|
+
for (const property of properties) {
|
|
1517
|
+
const [name, definition2] = property;
|
|
1518
|
+
const result = this.parseToZodAttribute(name, definition2, requiredAttrs);
|
|
1519
|
+
schemaFields.push(result.schemaString);
|
|
1520
|
+
typeFields.push(result.typeString);
|
|
1521
|
+
}
|
|
1522
|
+
if (definition?.type === "array") {
|
|
1523
|
+
return {
|
|
1524
|
+
schemaString: `z.array(z.object({${schemaFields.join(",")}}))`,
|
|
1525
|
+
typeString: typeFields.join(";")
|
|
1526
|
+
};
|
|
1527
|
+
}
|
|
1528
|
+
return {
|
|
1529
|
+
schemaString: `z.object({${schemaFields.join(",")}})`,
|
|
1530
|
+
typeString: typeFields.join(";")
|
|
1531
|
+
};
|
|
1532
|
+
};
|
|
1533
|
+
// --
|
|
1534
|
+
parseToZodAttribute = (name, definition, requiredAttrs) => {
|
|
1535
|
+
const isRequired = requiredAttrs.includes(name) || name === "";
|
|
1536
|
+
const schemaRequired = isRequired ? "" : ".nullish()";
|
|
1537
|
+
const typeRequired = isRequired ? "" : "?";
|
|
1538
|
+
const typeNullishability = isRequired ? "" : " | null | undefined";
|
|
1539
|
+
const schemaAttribute = name ? `'${name}':` : "";
|
|
1540
|
+
const typeAttribute = name ? `'${name}'${typeRequired}:` : "";
|
|
1541
|
+
const type = definition?.type;
|
|
1542
|
+
if (definition.properties) {
|
|
1543
|
+
const result = this.parseToZodSchema(definition, requiredAttrs);
|
|
1544
|
+
return {
|
|
1545
|
+
schemaString: `${schemaAttribute} ${result.schemaString}${schemaRequired}`,
|
|
1546
|
+
typeString: `${typeAttribute} ${result.typeString}${typeNullishability}`
|
|
1547
|
+
};
|
|
1548
|
+
} else if (type) {
|
|
1549
|
+
if (type === "object" && definition.additionalProperties) {
|
|
1550
|
+
const zodAttribute = this.parseToZodAttribute("", definition.additionalProperties, [""]);
|
|
1551
|
+
return {
|
|
1552
|
+
schemaString: `${schemaAttribute} z.record(${zodAttribute.schemaString})${schemaRequired}`,
|
|
1553
|
+
typeString: `${typeAttribute} Record<string, ${zodAttribute.typeString}>${typeNullishability}`
|
|
1554
|
+
};
|
|
1555
|
+
}
|
|
1556
|
+
if (type === "object" && !definition.additionalProperties && !name) {
|
|
1557
|
+
return {
|
|
1558
|
+
schemaString: `z.any()`,
|
|
1559
|
+
typeString: "any"
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1562
|
+
if (type === "object" && !definition.additionalProperties) {
|
|
1563
|
+
return {
|
|
1564
|
+
schemaString: `${schemaAttribute} z.record(z.any())${schemaRequired}`,
|
|
1565
|
+
typeString: `${typeAttribute} Record<string, any>${typeNullishability}`
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1568
|
+
if (type === "integer" || type === "number") {
|
|
1569
|
+
const effectiveType = getZodNumberType(type);
|
|
1570
|
+
return {
|
|
1571
|
+
schemaString: `${schemaAttribute} z.${effectiveType.schemaString}()${schemaRequired}`,
|
|
1572
|
+
typeString: `${typeAttribute} ${effectiveType.typeString}${typeNullishability}`
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
if (type === "array") {
|
|
1576
|
+
const items = definition.items;
|
|
1577
|
+
const ref2 = items?.$ref;
|
|
1578
|
+
let model2;
|
|
1579
|
+
if (ref2) {
|
|
1580
|
+
const refType = ParserUtils.parseRefType(ref2);
|
|
1581
|
+
this.importClasses.add(refType);
|
|
1582
|
+
model2 = {
|
|
1583
|
+
schemaString: refType,
|
|
1584
|
+
typeString: refType
|
|
1585
|
+
};
|
|
1586
|
+
} else if (items) {
|
|
1587
|
+
if (items.type === "array") {
|
|
1588
|
+
const ref3 = items.items?.$ref;
|
|
1589
|
+
if (ref3) {
|
|
1590
|
+
const refType = ParserUtils.parseRefType(ref3);
|
|
1591
|
+
this.importClasses.add(refType);
|
|
1592
|
+
model2 = {
|
|
1593
|
+
schemaString: refType,
|
|
1594
|
+
typeString: refType
|
|
1595
|
+
};
|
|
1596
|
+
} else if (items.items) {
|
|
1597
|
+
model2 = this.parseEnumItems(items.items);
|
|
1598
|
+
}
|
|
1599
|
+
return {
|
|
1600
|
+
schemaString: `${schemaAttribute} z.array(z.array(${model2.schemaString}))${schemaRequired}`,
|
|
1601
|
+
typeString: `${typeAttribute} ${model2.typeString}[]${typeNullishability}`
|
|
1602
|
+
};
|
|
1603
|
+
} else {
|
|
1604
|
+
model2 = this.parseEnumItems(items);
|
|
1605
|
+
}
|
|
1606
|
+
} else {
|
|
1607
|
+
return {
|
|
1608
|
+
schemaString: `${schemaAttribute} z.array(z.any())${schemaRequired}`,
|
|
1609
|
+
typeString: `${typeAttribute} any[]${typeNullishability}`
|
|
1610
|
+
};
|
|
1611
|
+
}
|
|
1612
|
+
return {
|
|
1613
|
+
schemaString: `${schemaAttribute} z.array(${model2.schemaString})${schemaRequired}`,
|
|
1614
|
+
typeString: `${typeAttribute} ${model2.typeString}[]${typeNullishability}`
|
|
1615
|
+
};
|
|
1353
1616
|
}
|
|
1617
|
+
if (type !== "object") {
|
|
1618
|
+
const result = extractEnumObject(type, isRequired, definition.enum);
|
|
1619
|
+
return {
|
|
1620
|
+
schemaString: `${schemaAttribute} ${result.schemaString}`,
|
|
1621
|
+
typeString: `${typeAttribute} ${result.typeString}`
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
const ref = definition.$ref;
|
|
1626
|
+
let model = `z.record(z.any())`;
|
|
1627
|
+
if (ref) {
|
|
1628
|
+
model = ParserUtils.parseRefType(ref);
|
|
1629
|
+
const fullModelName = ref.replace("#/definitions/", "");
|
|
1630
|
+
this.duplicateFound = this.duplicates.has(fullModelName);
|
|
1631
|
+
if (this.duplicateFound) {
|
|
1632
|
+
model = this.duplicates.get(fullModelName);
|
|
1633
|
+
}
|
|
1634
|
+
this.importClasses.add(model);
|
|
1635
|
+
model = `${model}`;
|
|
1636
|
+
}
|
|
1637
|
+
return {
|
|
1638
|
+
schemaString: `${schemaAttribute} ${model}${schemaRequired}`,
|
|
1639
|
+
typeString: `${typeAttribute} ${model}${typeNullishability}`
|
|
1640
|
+
};
|
|
1641
|
+
};
|
|
1642
|
+
parseEnumItems = (items) => {
|
|
1643
|
+
if (items.enum) {
|
|
1644
|
+
const enumStr = items.enum.map((e) => {
|
|
1645
|
+
return `"${e}"`;
|
|
1646
|
+
});
|
|
1647
|
+
return {
|
|
1648
|
+
schemaString: `z.enum([${enumStr}])`,
|
|
1649
|
+
typeString: `(${enumStr.join(" | ")})`
|
|
1650
|
+
};
|
|
1651
|
+
}
|
|
1652
|
+
if (items.type === "object") {
|
|
1653
|
+
return this.parseToZodSchema(items, items.required);
|
|
1354
1654
|
}
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
callback?: (data: ${_responseType}) => void
|
|
1369
|
-
): UseQueryResult<${_responseType}, AxiosError<ApiError>> => {
|
|
1655
|
+
let effectiveType;
|
|
1656
|
+
if (items.type === "integer" || items.type === "number") {
|
|
1657
|
+
effectiveType = getZodNumberType(items.type);
|
|
1658
|
+
} else {
|
|
1659
|
+
effectiveType = { typeString: items.type, schemaString: items.type };
|
|
1660
|
+
}
|
|
1661
|
+
return {
|
|
1662
|
+
schemaString: `z.${effectiveType.schemaString}()`,
|
|
1663
|
+
typeString: effectiveType.typeString
|
|
1664
|
+
};
|
|
1665
|
+
};
|
|
1666
|
+
};
|
|
1667
|
+
var TemplateZodArray = class {
|
|
1370
1668
|
//
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
const data =
|
|
1376
|
-
(await ${apiGenName}(sdk, { namespace: input.namespace }).
|
|
1377
|
-
${classMethod}(${_methodParamsImpl}))
|
|
1378
|
-
callback && callback(data)
|
|
1379
|
-
return data
|
|
1380
|
-
}
|
|
1381
|
-
|
|
1382
|
-
return ${queryMethod}<${_responseType}, AxiosError<ApiError>>({
|
|
1383
|
-
queryKey: [${createQueryKey(apiGenName, classMethod)}, input],
|
|
1384
|
-
queryFn: queryFn(sdk, input),
|
|
1385
|
-
...options
|
|
1386
|
-
})
|
|
1387
|
-
}
|
|
1669
|
+
render = (name) => {
|
|
1670
|
+
const cls = name.replace("Array", "");
|
|
1671
|
+
const template = `import { z } from 'zod'
|
|
1672
|
+
import { ${cls} } from './${cls}.js'
|
|
1388
1673
|
|
|
1389
|
-
|
|
1390
|
-
const mutationMethodImpl = `
|
|
1674
|
+
export const ${name} = z.array(${cls})
|
|
1391
1675
|
|
|
1392
|
-
export
|
|
1393
|
-
sdk: AccelbyteSDK,
|
|
1394
|
-
options?: Omit<UseMutationOptions<${_responseType}, AxiosError<ApiError>, ApiArgs ${_methodParams}>, 'mutationKey'>,
|
|
1395
|
-
callback?: (data: ${_responseType}) => void
|
|
1396
|
-
): UseMutationResult<${_responseType}, AxiosError<ApiError>, ApiArgs ${_methodParams}> => {
|
|
1397
|
-
//
|
|
1398
|
-
const mutationFn = async (input: ApiArgs ${_methodParams}) => {
|
|
1399
|
-
const data =
|
|
1400
|
-
(await ${apiGenName}(sdk, { namespace: input.namespace, config: input.config }).
|
|
1401
|
-
${classMethod}(${_methodParamsImpl}))
|
|
1402
|
-
callback && callback(data)
|
|
1403
|
-
return data
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
|
-
return useMutation({
|
|
1407
|
-
mutationKey: [${createQueryKey(apiGenName, classMethod)}],
|
|
1408
|
-
mutationFn,
|
|
1409
|
-
...options
|
|
1410
|
-
})
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1676
|
+
export interface ${name} extends z.TypeOf<typeof ${name}> {}
|
|
1413
1677
|
`;
|
|
1414
|
-
|
|
1678
|
+
return template;
|
|
1679
|
+
};
|
|
1415
1680
|
};
|
|
1416
|
-
|
|
1417
|
-
if (
|
|
1418
|
-
return
|
|
1681
|
+
var getZodNumberType = (type) => {
|
|
1682
|
+
if (type === "integer") {
|
|
1683
|
+
return {
|
|
1684
|
+
schemaString: "number().int",
|
|
1685
|
+
typeString: "number"
|
|
1686
|
+
};
|
|
1419
1687
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
}
|
|
1425
|
-
const prefixMappings = {
|
|
1426
|
-
get: "use",
|
|
1427
|
-
create: "useCreate",
|
|
1428
|
-
patch: "usePatch",
|
|
1429
|
-
update: "useUpdate",
|
|
1430
|
-
delete: "useDelete"
|
|
1688
|
+
return {
|
|
1689
|
+
schemaString: type,
|
|
1690
|
+
typeString: type
|
|
1691
|
+
};
|
|
1431
1692
|
};
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
return newMethodName + "Mutation";
|
|
1443
|
-
}
|
|
1444
|
-
}
|
|
1445
|
-
}
|
|
1446
|
-
return classMethod;
|
|
1447
|
-
}
|
|
1448
|
-
function convertToMethodImplArgs(methodArgs) {
|
|
1449
|
-
let properties = methodArgs.split(/,\s*(?![^{}]*\})/).map((prop) => prop.trim()).filter(Boolean);
|
|
1450
|
-
let formattedProperties = [];
|
|
1451
|
-
properties.forEach((prop) => {
|
|
1452
|
-
if (prop.includes(": {")) {
|
|
1453
|
-
const propertyName = prop.split(": {")[0].replace("?", "").trim();
|
|
1454
|
-
formattedProperties.push(`input.${propertyName}`);
|
|
1455
|
-
} else {
|
|
1456
|
-
const colonIndex = prop.indexOf(":");
|
|
1457
|
-
const propertyName = prop.substring(0, colonIndex).replace("?", "").trim();
|
|
1458
|
-
formattedProperties.push(`input.${propertyName}`);
|
|
1459
|
-
}
|
|
1460
|
-
});
|
|
1461
|
-
return formattedProperties.join(", ");
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
const GIT_URL = "https://github.com/AccelByte/accelbyte-web-sdk/blob/main/packages";
|
|
1465
|
-
class SwaggerReaderHelpers {
|
|
1466
|
-
static getServicePrefix = (servicePaths) => servicePaths[servicePaths.length - 1].split("/")[1];
|
|
1467
|
-
static parseAllEndpoints = async ({
|
|
1468
|
-
api,
|
|
1469
|
-
sdkName,
|
|
1470
|
-
serviceName
|
|
1471
|
-
}) => {
|
|
1472
|
-
const result = {
|
|
1473
|
-
admin: {
|
|
1474
|
-
arrayDefinitions: [],
|
|
1475
|
-
snippetMap: {},
|
|
1476
|
-
tagToClassImportsRecord: {},
|
|
1477
|
-
tagToEndpointClassesRecord: {},
|
|
1478
|
-
tagToSdkClientRecord: {},
|
|
1479
|
-
tagToSdkFunctionNamesRecord: {},
|
|
1480
|
-
tagToSdkImportsRecord: {},
|
|
1481
|
-
tagToEndpointQueryRecord: {}
|
|
1482
|
-
},
|
|
1483
|
-
public: {
|
|
1484
|
-
arrayDefinitions: [],
|
|
1485
|
-
snippetMap: {},
|
|
1486
|
-
tagToClassImportsRecord: {},
|
|
1487
|
-
tagToEndpointClassesRecord: {},
|
|
1488
|
-
tagToSdkClientRecord: {},
|
|
1489
|
-
tagToSdkFunctionNamesRecord: {},
|
|
1490
|
-
tagToSdkImportsRecord: {},
|
|
1491
|
-
tagToEndpointQueryRecord: {}
|
|
1492
|
-
}
|
|
1493
|
-
};
|
|
1494
|
-
const sortedPathsByLength = new Map(Object.entries(api.paths).sort((a, b) => {
|
|
1495
|
-
if (a[0].length === b[0].length) {
|
|
1496
|
-
return a[0].localeCompare(b[0]);
|
|
1497
|
-
} else {
|
|
1498
|
-
return a[0].length - b[0].length;
|
|
1499
|
-
}
|
|
1500
|
-
}));
|
|
1501
|
-
const sortedKeys = Array.from(sortedPathsByLength.keys());
|
|
1502
|
-
const servicePrefix = SwaggerReaderHelpers.getServicePrefix(sortedKeys);
|
|
1503
|
-
const tagToClassMethodsMap = {
|
|
1504
|
-
admin: {},
|
|
1505
|
-
public: {}
|
|
1693
|
+
var extractEnumObject = (type, isRequired, enumArr) => {
|
|
1694
|
+
const schemaRequired = isRequired ? "" : ".nullish()";
|
|
1695
|
+
const typeNullishability = isRequired ? "" : " | null | undefined";
|
|
1696
|
+
if (enumArr) {
|
|
1697
|
+
const enumStr = enumArr.map((e) => {
|
|
1698
|
+
return `"${e}"`;
|
|
1699
|
+
});
|
|
1700
|
+
return {
|
|
1701
|
+
schemaString: `z.enum([${enumStr}])${schemaRequired}`,
|
|
1702
|
+
typeString: `(${enumStr.join(" | ")}${typeNullishability})`
|
|
1506
1703
|
};
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
const isAdminEndpoint = path.indexOf("/admin/") > -1;
|
|
1512
|
-
const picked = isAdminEndpoint ? result.admin : result.public;
|
|
1513
|
-
const {
|
|
1514
|
-
arrayDefinitions,
|
|
1515
|
-
snippetMap,
|
|
1516
|
-
tagToClassImportsRecord,
|
|
1517
|
-
tagToEndpointClassesRecord,
|
|
1518
|
-
tagToSdkClientRecord,
|
|
1519
|
-
tagToSdkFunctionNamesRecord,
|
|
1520
|
-
tagToSdkImportsRecord,
|
|
1521
|
-
tagToEndpointQueryRecord
|
|
1522
|
-
} = picked;
|
|
1523
|
-
const tagToClassMethodsMapByType = isAdminEndpoint ? tagToClassMethodsMap.admin : tagToClassMethodsMap.public;
|
|
1524
|
-
const httpMethods = Object.keys(operation);
|
|
1525
|
-
for (const httpMethod of httpMethods) {
|
|
1526
|
-
const endpoint = await Endpoint.parseAsync(operation[httpMethod]).catch((error) => {
|
|
1527
|
-
console.error(JSON.stringify({ path, httpMethod }, null, 2));
|
|
1528
|
-
throw error;
|
|
1529
|
-
});
|
|
1530
|
-
if (!endpoint.tags)
|
|
1531
|
-
continue;
|
|
1532
|
-
const [tag] = endpoint.tags;
|
|
1533
|
-
const pathWithBase = `${api.basePath ?? ""}${path}`;
|
|
1534
|
-
tagToClassMethodsMapByType[tag] = tagToClassMethodsMapByType[tag] ? tagToClassMethodsMapByType[tag] : {};
|
|
1535
|
-
const isForm = endpoint.consumes && endpoint.consumes[0] === "application/x-www-form-urlencoded";
|
|
1536
|
-
const classMethod = ParserUtils.generateNaturalLangMethod({
|
|
1537
|
-
servicePrefix,
|
|
1538
|
-
path,
|
|
1539
|
-
httpMethod,
|
|
1540
|
-
isForm,
|
|
1541
|
-
existingMethods: tagToClassMethodsMapByType[tag]
|
|
1542
|
-
});
|
|
1543
|
-
tagToClassMethodsMapByType[tag][classMethod] = `${path} ${httpMethod}`;
|
|
1544
|
-
if (!snippetMap[pathWithBase]) {
|
|
1545
|
-
snippetMap[pathWithBase] = {};
|
|
1546
|
-
}
|
|
1547
|
-
const description = endpoint.description?.replace(/\s+/g, " ") || "";
|
|
1548
|
-
const responseClass = ParserUtils.get2xxResponse(endpoint.responses);
|
|
1549
|
-
const { className, classGenName } = ParserUtils.generateClassName(tag, isAdminEndpoint);
|
|
1550
|
-
tagToClassImportsRecord[className] = tagToClassImportsRecord[className] ? tagToClassImportsRecord[className] : {};
|
|
1551
|
-
if (responseClass) {
|
|
1552
|
-
const importTypeClass = ParserUtils.parseRefType(responseClass);
|
|
1553
|
-
tagToClassImportsRecord[className][importTypeClass] = `import { ${importTypeClass} } from '../../generated-definitions/${importTypeClass}.js'`;
|
|
1554
|
-
}
|
|
1555
|
-
if (responseClass && responseClass.endsWith("Array")) {
|
|
1556
|
-
arrayDefinitions.push(responseClass);
|
|
1557
|
-
}
|
|
1558
|
-
const queryParams = ParserUtils.filterQueryParameters(endpoint.parameters);
|
|
1559
|
-
const isFormUrlEncoded = ParserUtils.isFormUrlEncoded(httpMethod, endpoint.consumes);
|
|
1560
|
-
const pathParams = ParserUtils.filterPathParams(endpoint.parameters);
|
|
1561
|
-
let bodyParams = ParserUtils.filterBodyParams(endpoint.parameters);
|
|
1562
|
-
const deprecated = !!endpoint.deprecated;
|
|
1563
|
-
if (endpoint.requestBody) {
|
|
1564
|
-
bodyParams = [
|
|
1565
|
-
{
|
|
1566
|
-
name: "body",
|
|
1567
|
-
in: "body",
|
|
1568
|
-
schema: endpoint.requestBody.content["application/json"]?.schema
|
|
1569
|
-
}
|
|
1570
|
-
];
|
|
1571
|
-
}
|
|
1572
|
-
const { methodImpl, methodParams, methodParamsNoTypes, importStatements } = templateMethod({
|
|
1573
|
-
classMethod: ParserUtils.addDeprecatedSuffix(deprecated, classMethod),
|
|
1574
|
-
description,
|
|
1575
|
-
httpMethod,
|
|
1576
|
-
path: pathWithBase,
|
|
1577
|
-
pathParams,
|
|
1578
|
-
bodyParams,
|
|
1579
|
-
queryParams,
|
|
1580
|
-
isFormUrlEncoded,
|
|
1581
|
-
responseClass,
|
|
1582
|
-
deprecated
|
|
1583
|
-
});
|
|
1584
|
-
tagToEndpointClassesRecord[tag] = (tagToEndpointClassesRecord[tag] || "") + methodImpl;
|
|
1585
|
-
const { apiGenName } = ParserUtils.generateApiName(tag, isAdminEndpoint);
|
|
1586
|
-
const queryMethodImpl = templateQueryMethod({
|
|
1587
|
-
classMethod: ParserUtils.addDeprecatedSuffix(deprecated, classMethod),
|
|
1588
|
-
httpMethod,
|
|
1589
|
-
path: pathWithBase,
|
|
1590
|
-
pathParams,
|
|
1591
|
-
responseClass,
|
|
1592
|
-
methodParams,
|
|
1593
|
-
apiGenName,
|
|
1594
|
-
isFormUrlEncoded,
|
|
1595
|
-
deprecated
|
|
1596
|
-
});
|
|
1597
|
-
tagToEndpointQueryRecord[tag] = (tagToEndpointQueryRecord[tag] || "") + queryMethodImpl;
|
|
1598
|
-
const { generatedMethodString, snippetApiArgs, snippetMethod, snippetShell } = templateApiMethod({
|
|
1599
|
-
classMethod: ParserUtils.addDeprecatedSuffix(deprecated, classMethod),
|
|
1600
|
-
description,
|
|
1601
|
-
httpMethod,
|
|
1602
|
-
path: pathWithBase,
|
|
1603
|
-
pathParams,
|
|
1604
|
-
bodyParams,
|
|
1605
|
-
responseClass,
|
|
1606
|
-
classGenName,
|
|
1607
|
-
methodParams,
|
|
1608
|
-
methodParamsNoTypes,
|
|
1609
|
-
deprecated,
|
|
1610
|
-
xSecurity: endpoint["x-security"]
|
|
1611
|
-
});
|
|
1612
|
-
tagToSdkClientRecord[tag] = (tagToSdkClientRecord[tag] || "") + generatedMethodString;
|
|
1613
|
-
tagToSdkFunctionNamesRecord[tag] = (tagToSdkFunctionNamesRecord[tag] || "") + ParserUtils.addDeprecatedSuffix(deprecated, classMethod) + ",";
|
|
1614
|
-
tagToSdkImportsRecord[tag] = tagToSdkImportsRecord[tag] ? [.../* @__PURE__ */ new Set([...importStatements, ...tagToSdkImportsRecord[tag]])] : [...new Set(importStatements)];
|
|
1615
|
-
const serviceNameTitle = ParserUtils.convertDashesToTitleCase(serviceName);
|
|
1616
|
-
const resultSnippet = templateSdkSnippet({
|
|
1617
|
-
serviceNameTitle,
|
|
1618
|
-
apiName: apiGenName,
|
|
1619
|
-
snippetMethod,
|
|
1620
|
-
snippetApiArgs
|
|
1621
|
-
});
|
|
1622
|
-
const currentSnippetMap = {};
|
|
1623
|
-
snippetMap[pathWithBase][httpMethod] = currentSnippetMap;
|
|
1624
|
-
currentSnippetMap.web = resultSnippet;
|
|
1625
|
-
const generatedDirName = isAdminEndpoint ? "generated-admin" : "generated-public";
|
|
1626
|
-
currentSnippetMap.webGit = GIT_URL + `/sdk-${sdkName}/src/${generatedDirName}/${apiGenName}.ts`;
|
|
1627
|
-
currentSnippetMap.shell = snippetShell;
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
for (const key in result) {
|
|
1631
|
-
result[key].arrayDefinitions = Array.from(new Set(result[key].arrayDefinitions));
|
|
1632
|
-
}
|
|
1633
|
-
return result;
|
|
1704
|
+
}
|
|
1705
|
+
return {
|
|
1706
|
+
schemaString: `z.${type}()${schemaRequired}`,
|
|
1707
|
+
typeString: `${type}${typeNullishability}`
|
|
1634
1708
|
};
|
|
1635
|
-
}
|
|
1709
|
+
};
|
|
1636
1710
|
|
|
1637
|
-
|
|
1711
|
+
// src/CodeGenerator.ts
|
|
1712
|
+
var CodeGenerator = class _CodeGenerator {
|
|
1638
1713
|
static srcFolder = () => CliParser.getOutputPath();
|
|
1639
|
-
static getGeneratedFolder = (isAdmin) => isAdmin ? `${
|
|
1714
|
+
static getGeneratedFolder = (isAdmin) => isAdmin ? `${_CodeGenerator.srcFolder()}/generated-admin` : `${_CodeGenerator.srcFolder()}/generated-public`;
|
|
1640
1715
|
static getGeneratedSnippetsFolder = () => `${CliParser.getSnippetOutputPath()}/generated-snippets`;
|
|
1641
1716
|
static prepareDirs = (DIST_DEFINITION_DIR, DIST_DIR, DIST_DIR_ENDPOINTS, DIST_DIR_QUERIES) => {
|
|
1642
1717
|
ParserUtils.mkdirIfNotExist(DIST_DEFINITION_DIR);
|
|
@@ -1655,28 +1730,42 @@ class CodeGenerator {
|
|
|
1655
1730
|
const api = await parser.parse(swaggerFilePath);
|
|
1656
1731
|
const serviceNameTitle = ParserUtils.convertDashesToTitleCase(serviceName);
|
|
1657
1732
|
const indexImportsSet = /* @__PURE__ */ new Set();
|
|
1733
|
+
const queryImportsSet = /* @__PURE__ */ new Set();
|
|
1658
1734
|
const apiInfo = { ...api.info, "x-version": api["x-version"]?.version };
|
|
1659
1735
|
console.log("----------\nGenerating API:", { title: apiInfo.title, version: apiInfo.version });
|
|
1660
|
-
ParserUtils.
|
|
1661
|
-
ParserUtils.writeXVersion(CodeGenerator.srcFolder(), api["x-version"], api.info);
|
|
1736
|
+
ParserUtils.writeXVersion(_CodeGenerator.srcFolder(), api["x-version"], api.info);
|
|
1662
1737
|
const parsedInformation = await SwaggerReaderHelpers.parseAllEndpoints({ api, sdkName, serviceName });
|
|
1663
1738
|
if (CliParser.getSnippetOutputPath()) {
|
|
1664
1739
|
try {
|
|
1665
|
-
ParserUtils.
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1740
|
+
ParserUtils.mkdirIfNotExist(_CodeGenerator.getGeneratedSnippetsFolder());
|
|
1741
|
+
ParserUtils.writeSnippetFile(
|
|
1742
|
+
_CodeGenerator.getGeneratedSnippetsFolder(),
|
|
1743
|
+
api.info.title,
|
|
1744
|
+
JSON.stringify(
|
|
1745
|
+
{
|
|
1746
|
+
...parsedInformation.public.snippetMap,
|
|
1747
|
+
...parsedInformation.admin.snippetMap
|
|
1748
|
+
},
|
|
1749
|
+
null,
|
|
1750
|
+
2
|
|
1751
|
+
)
|
|
1752
|
+
);
|
|
1669
1753
|
} catch (err) {
|
|
1670
|
-
console.
|
|
1754
|
+
console.error("Error generating snippets", err);
|
|
1671
1755
|
}
|
|
1672
1756
|
}
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
const
|
|
1678
|
-
|
|
1757
|
+
if (CliParser.isGenerateSnippetOnly()) {
|
|
1758
|
+
console.log("\nSuccessfully generate SDK snippets only\n----------\n\n");
|
|
1759
|
+
return;
|
|
1760
|
+
}
|
|
1761
|
+
const DIST_DIR = (isAdmin) => `${_CodeGenerator.getGeneratedFolder(isAdmin)}`;
|
|
1762
|
+
const DIST_DIR_ENDPOINTS = (isAdmin) => path4.join(DIST_DIR(isAdmin), "endpoints");
|
|
1763
|
+
const DIST_DIR_QUERIES = (isAdmin) => path4.join(DIST_DIR(isAdmin), "queries");
|
|
1764
|
+
const DIST_DEFINITION_DIR = path4.join(_CodeGenerator.srcFolder(), "generated-definitions");
|
|
1765
|
+
const targetSrcFolder = `${_CodeGenerator.srcFolder()}/`;
|
|
1766
|
+
_CodeGenerator.prepareDirs(DIST_DEFINITION_DIR, DIST_DIR, DIST_DIR_ENDPOINTS, DIST_DIR_QUERIES);
|
|
1679
1767
|
const mainApiList = [];
|
|
1768
|
+
const generatedDefinitions = [];
|
|
1680
1769
|
const generatePublicOrAdmin = (isAdmin) => {
|
|
1681
1770
|
const parsedInformationByType = isAdmin ? parsedInformation.admin : parsedInformation.public;
|
|
1682
1771
|
const {
|
|
@@ -1686,7 +1775,8 @@ class CodeGenerator {
|
|
|
1686
1775
|
tagToSdkClientRecord,
|
|
1687
1776
|
tagToSdkFunctionNamesRecord,
|
|
1688
1777
|
tagToSdkImportsRecord,
|
|
1689
|
-
tagToEndpointQueryRecord
|
|
1778
|
+
tagToEndpointQueryRecord,
|
|
1779
|
+
tagToSdkFunctionDescription
|
|
1690
1780
|
} = parsedInformationByType;
|
|
1691
1781
|
const writeApiEndpointFiles = (isAdminEndpoint) => {
|
|
1692
1782
|
const apiList = [];
|
|
@@ -1699,16 +1789,36 @@ class CodeGenerator {
|
|
|
1699
1789
|
ParserUtils.writeClassFile(DIST_DIR_ENDPOINTS(isAdminEndpoint), classGenName, classBuffer, imports);
|
|
1700
1790
|
const { apiGenName } = ParserUtils.generateApiName(tag, isAdminEndpoint);
|
|
1701
1791
|
const queryBuffer = tagToEndpointQueryRecord[tag];
|
|
1702
|
-
const queryFileName =
|
|
1792
|
+
const queryFileName = !CliParser.skipReactQuery() && ParserUtils.writeQueryFile(
|
|
1793
|
+
DIST_DIR_QUERIES(isAdminEndpoint),
|
|
1794
|
+
apiGenName,
|
|
1795
|
+
queryBuffer,
|
|
1796
|
+
apiImports,
|
|
1797
|
+
serviceNameTitle,
|
|
1798
|
+
tagToSdkFunctionNamesRecord[tag],
|
|
1799
|
+
imports,
|
|
1800
|
+
sdkName
|
|
1801
|
+
);
|
|
1703
1802
|
const apiBuffer = tagToSdkClientRecord[tag];
|
|
1704
|
-
ParserUtils.writeApiFile(DIST_DIR(isAdminEndpoint), apiGenName, apiBuffer, imports,
|
|
1803
|
+
ParserUtils.writeApiFile(DIST_DIR(isAdminEndpoint), apiGenName, apiBuffer, imports, tagToSdkFunctionDescription[tag]);
|
|
1705
1804
|
apiList.push(apiGenName);
|
|
1706
|
-
indexImportsSet.add(
|
|
1707
|
-
|
|
1708
|
-
|
|
1805
|
+
indexImportsSet.add(
|
|
1806
|
+
ParserUtils.getRelativePathToWebSdkSrcFolder(path4.join(DIST_DIR_ENDPOINTS(isAdminEndpoint), `${classGenName}`), targetSrcFolder)
|
|
1807
|
+
);
|
|
1808
|
+
indexImportsSet.add(
|
|
1809
|
+
ParserUtils.getRelativePathToWebSdkSrcFolder(path4.join(DIST_DIR(isAdminEndpoint), `${apiGenName}`), targetSrcFolder)
|
|
1810
|
+
);
|
|
1811
|
+
queryFileName && queryImportsSet.add(
|
|
1812
|
+
ParserUtils.getRelativePathToWebSdkSrcFolder(
|
|
1813
|
+
path4.join(DIST_DIR(isAdminEndpoint), "queries", `${queryFileName}`),
|
|
1814
|
+
targetSrcFolder
|
|
1815
|
+
)
|
|
1816
|
+
);
|
|
1709
1817
|
}
|
|
1710
1818
|
mainApiList.push(...apiList);
|
|
1711
|
-
indexImportsSet.add(
|
|
1819
|
+
indexImportsSet.add(
|
|
1820
|
+
ParserUtils.getRelativePathToWebSdkSrcFolder(path4.join(_CodeGenerator.srcFolder(), serviceNameTitle), targetSrcFolder)
|
|
1821
|
+
);
|
|
1712
1822
|
};
|
|
1713
1823
|
const writeDefinitions = (api2) => {
|
|
1714
1824
|
const duplicates = /* @__PURE__ */ new Map();
|
|
@@ -1716,19 +1826,21 @@ class CodeGenerator {
|
|
|
1716
1826
|
for (const ref in definitions) {
|
|
1717
1827
|
const definition = definitions[ref];
|
|
1718
1828
|
const fileName = ParserUtils.parseRefType(ref);
|
|
1719
|
-
const fileExist =
|
|
1829
|
+
const fileExist = fs4.existsSync(path4.join(DIST_DEFINITION_DIR, `${fileName}.ts`));
|
|
1720
1830
|
if (fileExist) {
|
|
1721
1831
|
const duplicateName = ParserUtils.toCamelCaseWord(ref).replace(".", "").replace(".", "");
|
|
1722
1832
|
duplicates.set(ref, duplicateName);
|
|
1723
1833
|
}
|
|
1724
1834
|
const { buffer } = new TemplateZod().render(fileName, definition, /* @__PURE__ */ new Map());
|
|
1835
|
+
generatedDefinitions.push(fileName);
|
|
1725
1836
|
ParserUtils.writeDefinitionFile(DIST_DEFINITION_DIR, fileName, buffer);
|
|
1726
|
-
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(
|
|
1837
|
+
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(path4.join(DIST_DEFINITION_DIR, fileName), targetSrcFolder));
|
|
1727
1838
|
}
|
|
1728
1839
|
for (const arrayClass of arrayDefinitions) {
|
|
1729
1840
|
const buffer = new TemplateZodArray().render(arrayClass);
|
|
1841
|
+
generatedDefinitions.push(arrayClass);
|
|
1730
1842
|
ParserUtils.writeDefinitionFile(DIST_DEFINITION_DIR, arrayClass, buffer);
|
|
1731
|
-
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(
|
|
1843
|
+
indexImportsSet.add(ParserUtils.getRelativePathToWebSdkSrcFolder(path4.join(DIST_DEFINITION_DIR, arrayClass), targetSrcFolder));
|
|
1732
1844
|
}
|
|
1733
1845
|
};
|
|
1734
1846
|
writeApiEndpointFiles(isAdmin);
|
|
@@ -1736,44 +1848,47 @@ class CodeGenerator {
|
|
|
1736
1848
|
};
|
|
1737
1849
|
generatePublicOrAdmin(true);
|
|
1738
1850
|
generatePublicOrAdmin(false);
|
|
1739
|
-
const apiIndexBuff = templateApiIndex(
|
|
1740
|
-
ParserUtils.writeApiMainFile(
|
|
1851
|
+
const apiIndexBuff = templateApiIndex(serviceNameTitle, mainApiList);
|
|
1852
|
+
ParserUtils.writeApiMainFile(_CodeGenerator.srcFolder(), serviceNameTitle, apiIndexBuff);
|
|
1741
1853
|
console.log("\nCOMPLETED\n----------\n\n");
|
|
1742
|
-
return indexImportsSet;
|
|
1854
|
+
return { indexImports: indexImportsSet, queryImports: queryImportsSet };
|
|
1743
1855
|
};
|
|
1744
|
-
|
|
1856
|
+
// end of main
|
|
1857
|
+
};
|
|
1745
1858
|
|
|
1746
|
-
|
|
1859
|
+
// src/SwaggerDownloader.ts
|
|
1860
|
+
import * as https from "https";
|
|
1861
|
+
import * as fs5 from "fs";
|
|
1862
|
+
import * as path5 from "path";
|
|
1863
|
+
var SwaggerDownloader = class _SwaggerDownloader {
|
|
1747
1864
|
static getDestFile = (targetFileName) => {
|
|
1748
1865
|
const destPath = CliParser.getResolvedSwaggersOutputPath();
|
|
1749
|
-
const destFile =
|
|
1750
|
-
if (
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
fs.mkdirSync(destPath);
|
|
1754
|
-
fs.writeFileSync(destFile, "");
|
|
1866
|
+
const destFile = path5.join(destPath, targetFileName);
|
|
1867
|
+
if (fs5.existsSync(destFile)) return destFile;
|
|
1868
|
+
if (!fs5.existsSync(destPath)) fs5.mkdirSync(destPath);
|
|
1869
|
+
fs5.writeFileSync(destFile, "");
|
|
1755
1870
|
return destFile;
|
|
1756
1871
|
};
|
|
1872
|
+
// session-api.json contains illegal URL encoded character that breaks the codegen
|
|
1873
|
+
// e.g. "$ref": "#/definitions/map%5Bstring%5Dinterface%20%7B%7D"
|
|
1757
1874
|
static postSanitizeDownloadedFile = (filePath) => {
|
|
1758
1875
|
const searchStr = ["%5B", "%5D", "%20", "%7B", "%7D"];
|
|
1759
|
-
|
|
1760
|
-
if (err)
|
|
1761
|
-
throw err;
|
|
1876
|
+
fs5.readFile(filePath, "utf8", (err, data) => {
|
|
1877
|
+
if (err) throw err;
|
|
1762
1878
|
let result = data;
|
|
1763
1879
|
searchStr.forEach((s) => {
|
|
1764
1880
|
result = result.replace(new RegExp(s, "g"), " ");
|
|
1765
1881
|
});
|
|
1766
|
-
|
|
1767
|
-
if (err2)
|
|
1768
|
-
throw err2;
|
|
1882
|
+
fs5.writeFile(filePath, result, "utf8", (err2) => {
|
|
1883
|
+
if (err2) throw err2;
|
|
1769
1884
|
console.log("File updated successfully.");
|
|
1770
1885
|
});
|
|
1771
1886
|
});
|
|
1772
1887
|
};
|
|
1773
1888
|
static downloadFile = async (targetFileName, url) => {
|
|
1774
|
-
const destFile =
|
|
1889
|
+
const destFile = _SwaggerDownloader.getDestFile(targetFileName);
|
|
1775
1890
|
let data = "";
|
|
1776
|
-
return new Promise((
|
|
1891
|
+
return new Promise((resolve2) => {
|
|
1777
1892
|
const request = https.get(url, function(response) {
|
|
1778
1893
|
response.on("data", (chunk) => {
|
|
1779
1894
|
data += chunk;
|
|
@@ -1782,11 +1897,11 @@ class SwaggerDownloader {
|
|
|
1782
1897
|
if (response.statusCode !== 200) {
|
|
1783
1898
|
console.log(`SwaggerDownload error with status code: ${response.statusCode}`);
|
|
1784
1899
|
} else {
|
|
1785
|
-
|
|
1786
|
-
|
|
1900
|
+
fs5.writeFileSync(destFile, JSON.stringify(JSON.parse(data), null, 2), "utf-8");
|
|
1901
|
+
_SwaggerDownloader.postSanitizeDownloadedFile(destFile);
|
|
1787
1902
|
console.log(`SwaggerDownload ${url} completed with status code: ${response.statusCode}`);
|
|
1788
1903
|
}
|
|
1789
|
-
|
|
1904
|
+
resolve2(void 0);
|
|
1790
1905
|
});
|
|
1791
1906
|
});
|
|
1792
1907
|
request.on("error", (err) => {
|
|
@@ -1799,29 +1914,45 @@ class SwaggerDownloader {
|
|
|
1799
1914
|
for (const ref in swaggers) {
|
|
1800
1915
|
const targetFileName = swaggers[ref][2];
|
|
1801
1916
|
const url = swaggers[ref][3];
|
|
1802
|
-
await
|
|
1917
|
+
await _SwaggerDownloader.downloadFile(targetFileName, url);
|
|
1803
1918
|
}
|
|
1804
1919
|
};
|
|
1805
|
-
}
|
|
1920
|
+
};
|
|
1806
1921
|
|
|
1807
|
-
|
|
1922
|
+
// src/cli.ts
|
|
1923
|
+
var generateSdk = async () => {
|
|
1808
1924
|
const arrayOfSets = await Promise.all(CliParser.getConfigFile().map((config) => CodeGenerator.main(config)));
|
|
1925
|
+
if (CliParser.isGenerateSnippetOnly()) {
|
|
1926
|
+
return;
|
|
1927
|
+
}
|
|
1809
1928
|
const indexImportsSet = /* @__PURE__ */ new Set();
|
|
1929
|
+
const queryImportsSet = /* @__PURE__ */ new Set();
|
|
1810
1930
|
const filenamesSet = /* @__PURE__ */ new Set();
|
|
1811
1931
|
for (const set of arrayOfSets) {
|
|
1812
|
-
set.forEach((value) => {
|
|
1813
|
-
const fileName =
|
|
1932
|
+
set.indexImports.forEach((value) => {
|
|
1933
|
+
const fileName = path6.basename(value);
|
|
1814
1934
|
if (!filenamesSet.has(fileName)) {
|
|
1815
1935
|
indexImportsSet.add(value);
|
|
1816
1936
|
filenamesSet.add(fileName);
|
|
1817
1937
|
}
|
|
1818
1938
|
});
|
|
1939
|
+
set.queryImports.forEach((value) => {
|
|
1940
|
+
const fileName = path6.basename(value);
|
|
1941
|
+
if (!filenamesSet.has(fileName)) {
|
|
1942
|
+
queryImportsSet.add(value);
|
|
1943
|
+
}
|
|
1944
|
+
});
|
|
1819
1945
|
}
|
|
1820
1946
|
const indexImportsArray = Array.from(indexImportsSet).sort();
|
|
1947
|
+
const queryImportsArray = Array.from(queryImportsSet).sort();
|
|
1821
1948
|
const filesToImport = indexImportsArray.map((fileToImport) => {
|
|
1822
1949
|
return `export * from '${fileToImport.replace("\\", "/")}.js'`;
|
|
1823
1950
|
});
|
|
1951
|
+
const queryFilesToImport = queryImportsArray.map((fileToImport) => {
|
|
1952
|
+
return `export * from '${fileToImport.replace("\\", "/")}.js'`;
|
|
1953
|
+
});
|
|
1824
1954
|
ParserUtils.writeAllImportsFile(CliParser.getOutputPath(), filesToImport.join("\n"));
|
|
1955
|
+
ParserUtils.writeAllQueryImportsFile(CliParser.getOutputPath(), queryFilesToImport.join("\n"));
|
|
1825
1956
|
};
|
|
1826
1957
|
yargs.command("download-swaggers", "Download swaggers JSON files", (yargs2) => {
|
|
1827
1958
|
CliParser.createInstance(yargs2);
|
|
@@ -1846,5 +1977,11 @@ yargs.command("download-swaggers", "Download swaggers JSON files", (yargs2) => {
|
|
|
1846
1977
|
}).option("output", {
|
|
1847
1978
|
description: "Output path for generated code. Required for generate-code",
|
|
1848
1979
|
type: "string"
|
|
1980
|
+
}).option("skipReactQuery", {
|
|
1981
|
+
description: "Skip generating react query",
|
|
1982
|
+
type: "boolean"
|
|
1983
|
+
}).option("snippetOnly", {
|
|
1984
|
+
description: "Only generate snippet",
|
|
1985
|
+
type: "boolean"
|
|
1849
1986
|
}).demandCommand(1).help().argv;
|
|
1850
|
-
//# sourceMappingURL=accelbyte-codegen.mjs.map
|
|
1987
|
+
//# sourceMappingURL=accelbyte-codegen.mjs.map
|