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