@sdkgen/node-runtime 2.3.2 → 2.5.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.
Files changed (54) hide show
  1. package/dist/api-config.js +19 -0
  2. package/dist/{src/context.d.ts → context.d.ts} +1 -0
  3. package/dist/context.js +3 -0
  4. package/dist/encode-decode.js +344 -0
  5. package/dist/error.js +33 -0
  6. package/dist/execute.js +57 -0
  7. package/dist/http-client.js +107 -0
  8. package/dist/{src/http-server.d.ts → http-server.d.ts} +1 -0
  9. package/dist/http-server.js +941 -0
  10. package/dist/{src/index.js → index.js} +1 -0
  11. package/dist/swagger.js +454 -0
  12. package/dist/test-wrapper.js +58 -0
  13. package/dist/utils.js +8 -0
  14. package/package.json +50 -34
  15. package/.eslintignore +0 -1
  16. package/.eslintrc.json +0 -3
  17. package/.prettierrc +0 -12
  18. package/.vscode/settings.json +0 -14
  19. package/dist/spec/error.spec.d.ts +0 -1
  20. package/dist/spec/error.spec.js +0 -15
  21. package/dist/spec/rest/rest.spec.d.ts +0 -1
  22. package/dist/spec/rest/rest.spec.js +0 -353
  23. package/dist/spec/runtime/errors.spec.d.ts +0 -1
  24. package/dist/spec/runtime/errors.spec.js +0 -43
  25. package/dist/spec/runtime/middleware.spec.d.ts +0 -1
  26. package/dist/spec/runtime/middleware.spec.js +0 -100
  27. package/dist/spec/simple/legacyNodeClient.d.ts +0 -17
  28. package/dist/spec/simple/legacyNodeClient.js +0 -128
  29. package/dist/spec/simple/simple.spec.d.ts +0 -1
  30. package/dist/spec/simple/simple.spec.js +0 -113
  31. package/dist/spec/types.d.ts +0 -1
  32. package/dist/spec/types.js +0 -60
  33. package/dist/spec/types.spec.d.ts +0 -1
  34. package/dist/spec/types.spec.js +0 -128
  35. package/dist/src/api-config.js +0 -19
  36. package/dist/src/context.js +0 -2
  37. package/dist/src/encode-decode.js +0 -376
  38. package/dist/src/error.js +0 -32
  39. package/dist/src/execute.js +0 -56
  40. package/dist/src/http-client.js +0 -105
  41. package/dist/src/http-server.js +0 -941
  42. package/dist/src/swagger.js +0 -439
  43. package/dist/src/test-wrapper.js +0 -52
  44. package/dist/src/utils.js +0 -7
  45. package/dist/tsconfig.tsbuildinfo +0 -1
  46. /package/dist/{src/api-config.d.ts → api-config.d.ts} +0 -0
  47. /package/dist/{src/encode-decode.d.ts → encode-decode.d.ts} +0 -0
  48. /package/dist/{src/error.d.ts → error.d.ts} +0 -0
  49. /package/dist/{src/execute.d.ts → execute.d.ts} +0 -0
  50. /package/dist/{src/http-client.d.ts → http-client.d.ts} +0 -0
  51. /package/dist/{src/index.d.ts → index.d.ts} +0 -0
  52. /package/dist/{src/swagger.d.ts → swagger.d.ts} +0 -0
  53. /package/dist/{src/test-wrapper.d.ts → test-wrapper.d.ts} +0 -0
  54. /package/dist/{src/utils.d.ts → utils.d.ts} +0 -0
@@ -0,0 +1,941 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SdkgenHttpServer = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const crypto_1 = require("crypto");
6
+ const fs_1 = require("fs");
7
+ const http_1 = require("http");
8
+ const os_1 = require("os");
9
+ const querystring_1 = require("querystring");
10
+ const url_1 = require("url");
11
+ const util_1 = require("util");
12
+ const csharp_generator_1 = require("@sdkgen/csharp-generator");
13
+ const dart_generator_1 = require("@sdkgen/dart-generator");
14
+ const fsharp_generator_1 = require("@sdkgen/fsharp-generator");
15
+ const kotlin_generator_1 = require("@sdkgen/kotlin-generator");
16
+ const parser_1 = require("@sdkgen/parser");
17
+ const playground_1 = require("@sdkgen/playground");
18
+ const swift_generator_1 = require("@sdkgen/swift-generator");
19
+ const typescript_generator_1 = require("@sdkgen/typescript-generator");
20
+ const busboy_1 = tslib_1.__importDefault(require("busboy"));
21
+ const file_type_1 = tslib_1.__importDefault(require("file-type"));
22
+ const request_ip_1 = require("request-ip");
23
+ const serve_handler_1 = tslib_1.__importDefault(require("serve-handler"));
24
+ const encode_decode_1 = require("./encode-decode");
25
+ const error_1 = require("./error");
26
+ const execute_1 = require("./execute");
27
+ const swagger_1 = require("./swagger");
28
+ const utils_1 = require("./utils");
29
+ class SdkgenHttpServer {
30
+ constructor(apiConfig, ...maybeExtraContext) {
31
+ this.apiConfig = apiConfig;
32
+ this.headers = new Map();
33
+ this.healthChecks = [];
34
+ this.handlers = [];
35
+ this.dynamicCorsOrigin = true;
36
+ this.introspection = true;
37
+ this.log = (message) => {
38
+ console.log(`${new Date().toISOString()} ${message}`);
39
+ };
40
+ this.logError = console.error;
41
+ this.hasSwagger = false;
42
+ this.ignoredUrlPrefix = "";
43
+ this.handleRequest = (req, res) => {
44
+ const hrStart = process.hrtime();
45
+ req.on("error", err => {
46
+ this.logError(err);
47
+ res.end();
48
+ });
49
+ res.on("error", err => {
50
+ this.logError(err);
51
+ res.end();
52
+ });
53
+ if (this.dynamicCorsOrigin && req.headers.origin) {
54
+ res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
55
+ res.setHeader("Vary", "Origin");
56
+ }
57
+ for (const [header, value] of this.headers) {
58
+ if (req.method === "OPTIONS" && !header.startsWith("access-control-")) {
59
+ continue;
60
+ }
61
+ res.setHeader(header, value);
62
+ }
63
+ if (req.method === "OPTIONS") {
64
+ res.writeHead(200);
65
+ res.end();
66
+ return;
67
+ }
68
+ new Promise(resolve => {
69
+ // Google Cloud Functions add a rawBody property to the request object
70
+ if ((0, utils_1.has)(req, "rawBody") && req.rawBody instanceof Buffer) {
71
+ resolve(req.rawBody);
72
+ }
73
+ else {
74
+ const body = [];
75
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
76
+ req.on("data", chunk => body.push(chunk));
77
+ req.on("end", () => {
78
+ resolve(Buffer.concat(body));
79
+ });
80
+ }
81
+ })
82
+ .then(async (body) => this.handleRequestWithBody(req, res, body, hrStart))
83
+ .catch((e) => this.writeReply(res, null, { error: e }, hrStart));
84
+ };
85
+ this.extraContext = (maybeExtraContext[0] ?? {});
86
+ this.httpServer = (0, http_1.createServer)(this.handleRequest.bind(this));
87
+ this.enableCors();
88
+ this.attachRestHandlers();
89
+ const targetTable = [
90
+ ["/targets/android/client.kt", (ast) => (0, kotlin_generator_1.generateAndroidClientSource)(ast, true)],
91
+ ["/targets/android/client_without_callbacks.kt", (ast) => (0, kotlin_generator_1.generateAndroidClientSource)(ast, false)],
92
+ ["/targets/dotnet/api.cs", csharp_generator_1.generateCSharpServerSource],
93
+ ["/targets/dotnet/api.fs", fsharp_generator_1.generateFSharpServerSource],
94
+ ["/targets/flutter/client.dart", dart_generator_1.generateDartClientSource],
95
+ ["/targets/ios/client.swift", (ast) => (0, swift_generator_1.generateSwiftClientSource)(ast, false)],
96
+ ["/targets/ios/client-rx.swift", (ast) => (0, swift_generator_1.generateSwiftClientSource)(ast, true)],
97
+ ["/targets/node/api.ts", typescript_generator_1.generateNodeServerSource],
98
+ ["/targets/node/client.ts", typescript_generator_1.generateNodeClientSource],
99
+ ["/targets/web/client.ts", typescript_generator_1.generateBrowserClientSource],
100
+ ];
101
+ for (const [path, generateFn] of targetTable) {
102
+ this.addHttpHandler("GET", path, (_req, res) => {
103
+ if (!this.introspection) {
104
+ res.statusCode = 404;
105
+ res.end();
106
+ return;
107
+ }
108
+ try {
109
+ res.setHeader("Content-Type", "application/octet-stream");
110
+ res.write(generateFn(this.apiConfig.ast));
111
+ }
112
+ catch (e) {
113
+ this.logError(e);
114
+ res.statusCode = 500;
115
+ res.write(`${e}`);
116
+ }
117
+ res.end();
118
+ });
119
+ }
120
+ this.addHttpHandler("GET", "/ast.json", (_req, res) => {
121
+ if (!this.introspection) {
122
+ res.statusCode = 404;
123
+ res.end();
124
+ return;
125
+ }
126
+ res.setHeader("Content-Type", "application/json");
127
+ res.write(JSON.stringify(apiConfig.astJson));
128
+ res.end();
129
+ });
130
+ this.addHttpHandler("GET", /^\/playground.*/u, (req, res) => {
131
+ if (!this.introspection) {
132
+ res.statusCode = 404;
133
+ res.end();
134
+ return;
135
+ }
136
+ if (req.url) {
137
+ req.url = req.url.endsWith("/playground") ? req.url.replace(/\/playground/u, "/index.html") : req.url.replace(/\/playground/u, "");
138
+ }
139
+ (0, serve_handler_1.default)(req, res, {
140
+ cleanUrls: false,
141
+ directoryListing: false,
142
+ etag: true,
143
+ public: playground_1.PLAYGROUND_PUBLIC_PATH,
144
+ }).catch(e => {
145
+ this.logError(e);
146
+ res.statusCode = 500;
147
+ res.write(`${e}`);
148
+ res.end();
149
+ });
150
+ });
151
+ }
152
+ registerHealthCheck(healthCheck) {
153
+ this.healthChecks.push(healthCheck);
154
+ }
155
+ ignoreUrlPrefix(urlPrefix) {
156
+ this.ignoredUrlPrefix = urlPrefix;
157
+ }
158
+ async listen(port = 8000) {
159
+ return new Promise(resolve => {
160
+ this.httpServer.listen(port, () => {
161
+ const addr = this.httpServer.address();
162
+ let urlHost;
163
+ if (addr.address === "::") {
164
+ urlHost = `localhost:${addr.port}`;
165
+ }
166
+ else if (addr.family === "ipv6") {
167
+ urlHost = `[${addr.address}]:${addr.port}`;
168
+ }
169
+ else {
170
+ urlHost = `${addr.address}:${addr.port}`;
171
+ }
172
+ if (addr.address === "::" || addr.address === "0.0.0.0") {
173
+ console.log(`\nListening on port ${addr.port}`);
174
+ }
175
+ else {
176
+ console.log(`\nListening on port ${addr.port} (${addr.address})`);
177
+ }
178
+ if (this.introspection) {
179
+ console.log(`Playground: http://${urlHost}/playground`);
180
+ }
181
+ if (this.hasSwagger) {
182
+ console.log(`Swagger UI: http://${urlHost}/swagger`);
183
+ }
184
+ console.log("");
185
+ resolve();
186
+ });
187
+ });
188
+ }
189
+ async close() {
190
+ return (0, util_1.promisify)(this.httpServer.close.bind(this.httpServer))();
191
+ }
192
+ enableCors() {
193
+ this.addHeader("Access-Control-Allow-Methods", "DELETE, HEAD, PUT, POST, PATCH, GET, OPTIONS");
194
+ this.addHeader("Access-Control-Allow-Headers", "Content-Type");
195
+ this.addHeader("Access-Control-Max-Age", "86400");
196
+ }
197
+ addHeader(header, value) {
198
+ const cleanHeader = header.toLowerCase().trim();
199
+ const existing = this.headers.get(cleanHeader);
200
+ if (existing) {
201
+ if (!existing.includes(value)) {
202
+ this.headers.set(cleanHeader, `${existing}, ${value}`);
203
+ }
204
+ }
205
+ else {
206
+ this.headers.set(cleanHeader, value);
207
+ }
208
+ }
209
+ addHttpHandler(method, matcher, handler) {
210
+ this.handlers.push({ handler, matcher, method });
211
+ }
212
+ findBestHandler(path, req) {
213
+ const matchingHandlers = this.handlers
214
+ .filter(({ method }) => method === req.method)
215
+ .filter(({ matcher }) => {
216
+ if (typeof matcher === "string") {
217
+ return matcher === path;
218
+ }
219
+ return matcher.exec(path)?.[0] === path;
220
+ })
221
+ .sort(({ matcher: first }, { matcher: second }) => {
222
+ // Prefer string matches instead of Regexp matches
223
+ if (typeof first === "string" && typeof second === "string") {
224
+ return 0;
225
+ }
226
+ else if (typeof first === "string") {
227
+ return -1;
228
+ }
229
+ else if (typeof second === "string") {
230
+ return 1;
231
+ }
232
+ const firstMatch = first.exec(path);
233
+ const secondMatch = second.exec(path);
234
+ if (!firstMatch) {
235
+ return -1;
236
+ }
237
+ if (!secondMatch) {
238
+ return 1;
239
+ }
240
+ // Compute how many characters were NOT part of a capture group
241
+ const firstLength = firstMatch[0].length - firstMatch.slice(1).reduce((acc, cur) => acc + cur.length, 0);
242
+ const secondLength = secondMatch[0].length - secondMatch.slice(1).reduce((acc, cur) => acc + cur.length, 0);
243
+ // Prefer the maximum number of non-captured characters
244
+ return secondLength - firstLength;
245
+ });
246
+ return matchingHandlers.length ? matchingHandlers[0] : null;
247
+ }
248
+ attachRestHandlers() {
249
+ function escapeRegExp(str) {
250
+ return str.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
251
+ }
252
+ for (const op of this.apiConfig.ast.operations) {
253
+ for (const ann of op.annotations) {
254
+ if (!(ann instanceof parser_1.RestAnnotation)) {
255
+ continue;
256
+ }
257
+ if (!this.hasSwagger) {
258
+ (0, swagger_1.setupSwagger)(this);
259
+ this.hasSwagger = true;
260
+ }
261
+ const pathFragments = ann.path.split(/\{\w+\}/u);
262
+ let pathRegex = "^";
263
+ for (let i = 0; i < pathFragments.length; ++i) {
264
+ if (i > 0) {
265
+ pathRegex += "([^/]+?)";
266
+ }
267
+ pathRegex += escapeRegExp(pathFragments[i]);
268
+ }
269
+ pathRegex += "/?$";
270
+ for (const header of ann.headers.keys()) {
271
+ this.addHeader("Access-Control-Allow-Headers", header.toLowerCase());
272
+ }
273
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
274
+ this.addHttpHandler(ann.method, new RegExp(pathRegex, "u"), async (req, res, body) => {
275
+ try {
276
+ const args = {};
277
+ const files = [];
278
+ const { pathname, query } = (0, url_1.parse)(req.url ?? "");
279
+ const match = pathname?.match(pathRegex);
280
+ if (!match) {
281
+ res.statusCode = 404;
282
+ return;
283
+ }
284
+ const simpleArgs = new Map();
285
+ for (let i = 0; i < ann.pathVariables.length; ++i) {
286
+ const argName = ann.pathVariables[i];
287
+ const argValue = match[i + 1];
288
+ simpleArgs.set(argName, argValue);
289
+ }
290
+ const parsedQuery = query ? (0, querystring_1.parse)(query) : {};
291
+ for (const argName of ann.queryVariables) {
292
+ const argValue = parsedQuery[argName] ?? null;
293
+ if (argValue === null) {
294
+ continue;
295
+ }
296
+ simpleArgs.set(argName, Array.isArray(argValue) ? argValue.join("") : argValue);
297
+ }
298
+ for (const [headerName, argName] of ann.headers) {
299
+ const argValue = req.headers[headerName.toLowerCase()] ?? null;
300
+ if (argValue === null) {
301
+ continue;
302
+ }
303
+ simpleArgs.set(argName, Array.isArray(argValue) ? argValue.join("") : argValue);
304
+ }
305
+ if (!ann.bodyVariable && req.headers["content-type"]?.match(/^application\/x-www-form-urlencoded/iu)) {
306
+ const parsedBody = (0, querystring_1.parse)(body.toString());
307
+ for (const argName of ann.queryVariables) {
308
+ const argValue = parsedBody[argName] ?? null;
309
+ if (argValue === null) {
310
+ continue;
311
+ }
312
+ simpleArgs.set(argName, Array.isArray(argValue) ? argValue.join("") : argValue);
313
+ }
314
+ }
315
+ else if (!ann.bodyVariable && req.headers["content-type"]?.match(/^multipart\/form-data/iu)) {
316
+ const busboy = (0, busboy_1.default)({ headers: req.headers });
317
+ const filePromises = [];
318
+ busboy.on("field", (field, value) => {
319
+ if (ann.queryVariables.includes(field)) {
320
+ simpleArgs.set(field, `${value}`);
321
+ }
322
+ });
323
+ busboy.on("file", (_field, stream, info) => {
324
+ const tempName = (0, crypto_1.randomBytes)(32).toString("hex");
325
+ const writeStream = (0, fs_1.createWriteStream)(tempName);
326
+ filePromises.push(new Promise((resolve, reject) => {
327
+ writeStream.on("error", reject);
328
+ writeStream.on("close", () => {
329
+ const contents = (0, fs_1.createReadStream)(tempName);
330
+ files.push({ contents, name: info.filename });
331
+ contents.on("open", () => {
332
+ (0, fs_1.unlink)(tempName, err => {
333
+ if (err) {
334
+ reject(err);
335
+ }
336
+ else {
337
+ resolve();
338
+ }
339
+ });
340
+ });
341
+ });
342
+ writeStream.on("open", () => {
343
+ stream.pipe(writeStream);
344
+ });
345
+ }));
346
+ });
347
+ await new Promise((resolve, reject) => {
348
+ busboy.on("finish", resolve);
349
+ busboy.on("error", reject);
350
+ busboy.write(body);
351
+ });
352
+ await Promise.all(filePromises);
353
+ }
354
+ else if (ann.bodyVariable) {
355
+ const argName = ann.bodyVariable;
356
+ const arg = op.args.find(x => x.name === argName);
357
+ if (/application\/json/iu.test(req.headers["content-type"] ?? "")) {
358
+ args[argName] = JSON.parse(body.toString());
359
+ }
360
+ else if (arg) {
361
+ let { type } = arg;
362
+ let solved = false;
363
+ if (type instanceof parser_1.OptionalType) {
364
+ if (body.length === 0) {
365
+ args[argName] = null;
366
+ solved = true;
367
+ }
368
+ else {
369
+ type = type.base;
370
+ }
371
+ }
372
+ if (!solved) {
373
+ if (type instanceof parser_1.BoolPrimitiveType ||
374
+ type instanceof parser_1.IntPrimitiveType ||
375
+ type instanceof parser_1.UIntPrimitiveType ||
376
+ type instanceof parser_1.FloatPrimitiveType ||
377
+ type instanceof parser_1.StringPrimitiveType ||
378
+ type instanceof parser_1.DatePrimitiveType ||
379
+ type instanceof parser_1.DateTimePrimitiveType ||
380
+ type instanceof parser_1.MoneyPrimitiveType ||
381
+ type instanceof parser_1.DecimalPrimitiveType ||
382
+ type instanceof parser_1.BigIntPrimitiveType ||
383
+ type instanceof parser_1.CpfPrimitiveType ||
384
+ type instanceof parser_1.CnpjPrimitiveType ||
385
+ type instanceof parser_1.UuidPrimitiveType ||
386
+ type instanceof parser_1.HexPrimitiveType ||
387
+ type instanceof parser_1.Base64PrimitiveType) {
388
+ simpleArgs.set(argName, body.toString());
389
+ }
390
+ else if (type instanceof parser_1.BytesPrimitiveType) {
391
+ args[argName] = body.toString("base64");
392
+ }
393
+ else {
394
+ args[argName] = JSON.parse(body.toString());
395
+ }
396
+ }
397
+ }
398
+ }
399
+ for (const [argName, argValue] of simpleArgs) {
400
+ const arg = op.args.find(x => x.name === argName);
401
+ if (!arg) {
402
+ continue;
403
+ }
404
+ let { type } = arg;
405
+ if (type instanceof parser_1.OptionalType) {
406
+ if (argValue === null) {
407
+ args[argName] = null;
408
+ continue;
409
+ }
410
+ else {
411
+ type = type.base;
412
+ }
413
+ }
414
+ else if (argValue === null) {
415
+ args[argName] = argValue;
416
+ continue;
417
+ }
418
+ if (type instanceof parser_1.BoolPrimitiveType) {
419
+ if (argValue === "true") {
420
+ args[argName] = true;
421
+ }
422
+ else if (argValue === "false") {
423
+ args[argName] = false;
424
+ }
425
+ else {
426
+ args[argName] = argValue;
427
+ }
428
+ }
429
+ else if (type instanceof parser_1.UIntPrimitiveType || type instanceof parser_1.IntPrimitiveType || type instanceof parser_1.MoneyPrimitiveType) {
430
+ args[argName] = parseInt(argValue, 10);
431
+ }
432
+ else if (type instanceof parser_1.FloatPrimitiveType) {
433
+ args[argName] = parseFloat(argValue);
434
+ }
435
+ else {
436
+ args[argName] = argValue;
437
+ }
438
+ }
439
+ const ip = (0, request_ip_1.getClientIp)(req);
440
+ if (!ip) {
441
+ throw new Error("Couldn't determine client IP");
442
+ }
443
+ const request = {
444
+ args,
445
+ deviceInfo: {
446
+ fingerprint: null,
447
+ id: (0, crypto_1.randomBytes)(16).toString("hex"),
448
+ language: null,
449
+ platform: null,
450
+ timezone: null,
451
+ type: "rest",
452
+ version: null,
453
+ },
454
+ extra: {},
455
+ files,
456
+ headers: req.headers,
457
+ id: (0, crypto_1.randomBytes)(16).toString("hex"),
458
+ ip,
459
+ query,
460
+ name: op.name,
461
+ version: 3,
462
+ };
463
+ await this.executeRequest(request, (ctx, reply) => {
464
+ try {
465
+ if (ctx) {
466
+ for (const [headerKey, headerValue] of ctx.response.headers.entries()) {
467
+ res.setHeader(headerKey, headerValue);
468
+ }
469
+ }
470
+ if (ctx?.response.statusCode) {
471
+ res.statusCode = ctx.response.statusCode;
472
+ }
473
+ if (reply.error) {
474
+ const error = this.makeResponseError(reply.error);
475
+ if (!ctx?.response.statusCode) {
476
+ const errorNode = this.apiConfig.ast.errors.find(node => node.name === error.type);
477
+ const statusAnnotation = errorNode?.annotations.find(x => x instanceof parser_1.StatusCodeAnnotation);
478
+ res.statusCode = statusAnnotation ? statusAnnotation.statusCode : error.type === "Fatal" ? 500 : 400;
479
+ }
480
+ res.setHeader("content-type", "application/json");
481
+ res.write(JSON.stringify(error));
482
+ res.end();
483
+ return;
484
+ }
485
+ if (req.headers.accept === "application/json") {
486
+ res.setHeader("content-type", "application/json");
487
+ res.write(JSON.stringify(reply.result));
488
+ res.end();
489
+ }
490
+ else {
491
+ let type = op.returnType;
492
+ if (type instanceof parser_1.OptionalType) {
493
+ if (reply.result === null) {
494
+ if (!ctx?.response.statusCode) {
495
+ res.statusCode = ann.method === "GET" ? 404 : 204;
496
+ }
497
+ res.end();
498
+ return;
499
+ }
500
+ type = type.base;
501
+ }
502
+ if (type instanceof parser_1.BoolPrimitiveType ||
503
+ type instanceof parser_1.IntPrimitiveType ||
504
+ type instanceof parser_1.UIntPrimitiveType ||
505
+ type instanceof parser_1.FloatPrimitiveType ||
506
+ type instanceof parser_1.StringPrimitiveType ||
507
+ type instanceof parser_1.DatePrimitiveType ||
508
+ type instanceof parser_1.DateTimePrimitiveType ||
509
+ type instanceof parser_1.MoneyPrimitiveType ||
510
+ type instanceof parser_1.DecimalPrimitiveType ||
511
+ type instanceof parser_1.BigIntPrimitiveType ||
512
+ type instanceof parser_1.CpfPrimitiveType ||
513
+ type instanceof parser_1.CnpjPrimitiveType ||
514
+ type instanceof parser_1.UuidPrimitiveType ||
515
+ type instanceof parser_1.HexPrimitiveType ||
516
+ type instanceof parser_1.Base64PrimitiveType) {
517
+ res.setHeader("content-type", "text/plain");
518
+ res.write(`${reply.result}`);
519
+ res.end();
520
+ }
521
+ else if (type instanceof parser_1.HtmlPrimitiveType) {
522
+ res.setHeader("content-type", "text/html");
523
+ res.write(`${reply.result}`);
524
+ res.end();
525
+ }
526
+ else if (type instanceof parser_1.XmlPrimitiveType) {
527
+ res.setHeader("content-type", "text/xml");
528
+ res.write(`${reply.result}`);
529
+ res.end();
530
+ }
531
+ else if (type instanceof parser_1.BytesPrimitiveType) {
532
+ const buffer = Buffer.from(reply.result, "base64");
533
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
534
+ file_type_1.default.fromBuffer(buffer)
535
+ .then(fileType => {
536
+ res.setHeader("content-type", fileType?.mime ?? "application/octet-stream");
537
+ })
538
+ .catch(err => {
539
+ this.logError(err);
540
+ res.setHeader("content-type", "application/octet-stream");
541
+ })
542
+ .then(() => {
543
+ res.write(buffer);
544
+ res.end();
545
+ })
546
+ .catch(() => { });
547
+ }
548
+ else {
549
+ res.setHeader("content-type", "application/json");
550
+ res.write(JSON.stringify(reply.result));
551
+ res.end();
552
+ }
553
+ }
554
+ }
555
+ catch (error) {
556
+ this.logError(error);
557
+ if (!res.headersSent) {
558
+ res.statusCode = 500;
559
+ }
560
+ res.end();
561
+ }
562
+ });
563
+ }
564
+ catch (error) {
565
+ this.logError(error);
566
+ if (!res.headersSent) {
567
+ res.statusCode = 500;
568
+ }
569
+ res.end();
570
+ }
571
+ });
572
+ }
573
+ }
574
+ }
575
+ async handleRequestWithBody(req, res, body, hrStart) {
576
+ const { pathname, query } = (0, url_1.parse)(req.url ?? "");
577
+ let path = pathname ?? "";
578
+ if (path.startsWith(this.ignoredUrlPrefix)) {
579
+ path = path.slice(this.ignoredUrlPrefix.length);
580
+ }
581
+ if (!req.headers["content-type"]?.match(/application\/sdkgen/iu)) {
582
+ const externalHandler = this.findBestHandler(path, req);
583
+ if (externalHandler) {
584
+ this.log(`HTTP ${req.method} ${path}${query ? `?${query}` : ""}`);
585
+ externalHandler.handler(req, res, body);
586
+ return;
587
+ }
588
+ }
589
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
590
+ if (req.method === "HEAD") {
591
+ res.writeHead(200);
592
+ res.end();
593
+ return;
594
+ }
595
+ if (req.method === "GET") {
596
+ if (path !== "/") {
597
+ res.writeHead(404);
598
+ res.end();
599
+ return;
600
+ }
601
+ let ok = true;
602
+ try {
603
+ for (const healthCheck of this.healthChecks) {
604
+ if (!ok) {
605
+ break;
606
+ }
607
+ ok = await healthCheck();
608
+ }
609
+ }
610
+ catch (e) {
611
+ ok = false;
612
+ }
613
+ res.statusCode = ok ? 200 : 500;
614
+ res.write(JSON.stringify({ ok }));
615
+ res.end();
616
+ return;
617
+ }
618
+ if (req.method !== "POST") {
619
+ res.writeHead(400);
620
+ res.end();
621
+ return;
622
+ }
623
+ const clientIp = (0, request_ip_1.getClientIp)(req);
624
+ if (!clientIp) {
625
+ this.writeReply(res, null, {
626
+ error: new error_1.Fatal("Couldn't determine client IP"),
627
+ }, hrStart);
628
+ return;
629
+ }
630
+ const request = this.parseRequest(req, body.toString(), clientIp, query);
631
+ if (!request) {
632
+ this.writeReply(res, null, {
633
+ error: new error_1.Fatal("Couldn't parse request"),
634
+ }, hrStart);
635
+ return;
636
+ }
637
+ await this.executeRequest(request, (ctx, reply) => this.writeReply(res, ctx, reply, hrStart));
638
+ }
639
+ async executeRequest(request, writeReply) {
640
+ const ctx = {
641
+ ...this.extraContext,
642
+ request,
643
+ response: {
644
+ headers: new Map(),
645
+ },
646
+ };
647
+ writeReply(ctx, await (0, execute_1.executeRequest)(ctx, this.apiConfig));
648
+ }
649
+ parseRequest(req, body, ip, query) {
650
+ switch (this.identifyRequestVersion(req, body)) {
651
+ case 1:
652
+ return this.parseRequestV1(req, body, ip, query);
653
+ case 2:
654
+ return this.parseRequestV2(req, body, ip, query);
655
+ case 3:
656
+ return this.parseRequestV3(req, body, ip, query);
657
+ default:
658
+ throw new Error("Failed to understand request");
659
+ }
660
+ }
661
+ identifyRequestVersion(_req, body) {
662
+ const parsed = JSON.parse(body);
663
+ if (typeof parsed === "object" && parsed && (0, utils_1.has)(parsed, "version") && typeof parsed.version === "number") {
664
+ return parsed.version;
665
+ }
666
+ else if (typeof parsed === "object" && parsed && (0, utils_1.has)(parsed, "requestId")) {
667
+ return 2;
668
+ }
669
+ else if (typeof parsed === "object" && parsed && (0, utils_1.has)(parsed, "device")) {
670
+ return 1;
671
+ }
672
+ return 3;
673
+ }
674
+ // Old Sdkgen format
675
+ parseRequestV1(req, body, ip, query) {
676
+ const parsed = (0, encode_decode_1.decode)({
677
+ Request: {
678
+ args: "json",
679
+ device: "RequestDevice",
680
+ id: "string",
681
+ name: "string",
682
+ },
683
+ RequestDevice: {
684
+ fingerprint: "string?",
685
+ id: "string?",
686
+ language: "string?",
687
+ platform: "json?",
688
+ timezone: "string?",
689
+ type: "string?",
690
+ version: "string?",
691
+ },
692
+ }, "root", "Request", JSON.parse(body));
693
+ const deviceId = parsed.device.id ?? (0, crypto_1.randomBytes)(20).toString("hex");
694
+ if (!parsed.args || Array.isArray(parsed.args) || typeof parsed.args !== "object") {
695
+ throw new Error("Expected 'args' to be an object");
696
+ }
697
+ return {
698
+ args: parsed.args,
699
+ deviceInfo: {
700
+ fingerprint: parsed.device.fingerprint,
701
+ id: deviceId,
702
+ language: parsed.device.language,
703
+ platform: parsed.device.platform,
704
+ timezone: parsed.device.timezone,
705
+ type: parsed.device.type ?? (typeof parsed.device.platform === "string" ? parsed.device.platform : ""),
706
+ version: parsed.device.version,
707
+ },
708
+ extra: {},
709
+ files: [],
710
+ headers: req.headers,
711
+ id: `${deviceId}-${parsed.id}`,
712
+ query,
713
+ ip,
714
+ name: parsed.name,
715
+ version: 1,
716
+ };
717
+ }
718
+ // Maxima sdkgen format
719
+ parseRequestV2(req, body, ip, query) {
720
+ const parsed = (0, encode_decode_1.decode)({
721
+ Request: {
722
+ args: "json",
723
+ deviceFingerprint: "string?",
724
+ deviceId: "string",
725
+ info: "RequestInfo",
726
+ name: "string",
727
+ partnerId: "string?",
728
+ requestId: "string?",
729
+ sessionId: "string?",
730
+ },
731
+ RequestInfo: {
732
+ browserUserAgent: "string?",
733
+ language: "string",
734
+ type: "string",
735
+ },
736
+ }, "root", "Request", JSON.parse(body));
737
+ if (!parsed.args || Array.isArray(parsed.args) || typeof parsed.args !== "object") {
738
+ throw new Error("Expected 'args' to be an object");
739
+ }
740
+ return {
741
+ args: parsed.args,
742
+ deviceInfo: {
743
+ fingerprint: parsed.deviceFingerprint,
744
+ id: parsed.deviceId,
745
+ language: parsed.info.language,
746
+ platform: {
747
+ browserUserAgent: parsed.info.browserUserAgent ?? null,
748
+ },
749
+ timezone: null,
750
+ type: parsed.info.type,
751
+ version: "",
752
+ },
753
+ extra: {
754
+ partnerId: parsed.partnerId,
755
+ sessionId: parsed.sessionId,
756
+ },
757
+ files: [],
758
+ headers: req.headers,
759
+ id: `${parsed.deviceId}-${parsed.requestId ?? (0, crypto_1.randomBytes)(16).toString("hex")}`,
760
+ query,
761
+ ip,
762
+ name: parsed.name,
763
+ version: 2,
764
+ };
765
+ }
766
+ // New sdkgen format
767
+ parseRequestV3(req, body, ip, query) {
768
+ const parsed = (0, encode_decode_1.decode)({
769
+ DeviceInfo: {
770
+ fingerprint: "string?",
771
+ id: "string?",
772
+ language: "string?",
773
+ platform: "json?",
774
+ timezone: "string?",
775
+ type: "string?",
776
+ version: "string?",
777
+ },
778
+ Request: {
779
+ args: "json",
780
+ deviceInfo: "DeviceInfo?",
781
+ extra: "json?",
782
+ name: "string",
783
+ requestId: "string?",
784
+ },
785
+ }, "root", "Request", JSON.parse(body));
786
+ const deviceInfo = parsed.deviceInfo ?? {
787
+ fingerprint: null,
788
+ id: null,
789
+ language: null,
790
+ platform: null,
791
+ timezone: null,
792
+ type: null,
793
+ version: null,
794
+ };
795
+ const deviceId = deviceInfo.id ?? (0, crypto_1.randomBytes)(16).toString("hex");
796
+ if (!parsed.args || Array.isArray(parsed.args) || typeof parsed.args !== "object") {
797
+ throw new Error("Expected 'args' to be an object");
798
+ }
799
+ return {
800
+ args: parsed.args,
801
+ deviceInfo: {
802
+ fingerprint: deviceInfo.fingerprint,
803
+ id: deviceId,
804
+ language: deviceInfo.language,
805
+ platform: typeof deviceInfo.platform === "object" ? { ...deviceInfo.platform } : {},
806
+ timezone: deviceInfo.timezone,
807
+ type: deviceInfo.type ?? "api",
808
+ version: deviceInfo.version,
809
+ },
810
+ extra: typeof parsed.extra === "object" ? { ...parsed.extra } : {},
811
+ files: [],
812
+ headers: req.headers,
813
+ id: `${deviceId}-${parsed.requestId ?? (0, crypto_1.randomBytes)(16).toString("hex")}`,
814
+ ip,
815
+ query,
816
+ name: parsed.name,
817
+ version: 3,
818
+ };
819
+ }
820
+ makeResponseError(err) {
821
+ let type = "Fatal";
822
+ if (typeof err === "object" && err !== null && (0, utils_1.has)(err, "type") && typeof err.type === "string") {
823
+ ({ type } = err);
824
+ }
825
+ let message;
826
+ if (typeof err === "object" && err !== null && (0, utils_1.has)(err, "message") && typeof err.message === "string") {
827
+ ({ message } = err);
828
+ }
829
+ else if (err instanceof Error) {
830
+ message = err.toString();
831
+ }
832
+ else if (typeof err === "object") {
833
+ message = JSON.stringify(err);
834
+ }
835
+ else {
836
+ message = `${err}`;
837
+ }
838
+ let data;
839
+ if (typeof err === "object" && err !== null && (0, utils_1.has)(err, "data")) {
840
+ ({ data } = err);
841
+ }
842
+ const error = this.apiConfig.ast.errors.find(x => x.name === type);
843
+ if (error) {
844
+ if (!(error.dataType instanceof parser_1.VoidPrimitiveType)) {
845
+ try {
846
+ data = (0, encode_decode_1.encode)(this.apiConfig.astJson.typeTable, `error.${type}`, error.dataType.name, data);
847
+ }
848
+ catch (encodeError) {
849
+ message = `Failed to encode error ${type} because: ${encodeError}. Original message: ${message}`;
850
+ type = "Fatal";
851
+ }
852
+ }
853
+ }
854
+ else {
855
+ type = "Fatal";
856
+ }
857
+ return { data, message, type };
858
+ }
859
+ writeReply(res, ctx, reply, hrStart) {
860
+ if (!ctx) {
861
+ res.statusCode = 500;
862
+ res.write(JSON.stringify({
863
+ error: this.makeResponseError(reply.error ?? new error_1.Fatal("Response without context")),
864
+ }));
865
+ res.end();
866
+ return;
867
+ }
868
+ const deltaTime = process.hrtime(hrStart);
869
+ const duration = deltaTime[0] + deltaTime[1] * 1e-9;
870
+ if (reply.error) {
871
+ this.logError(reply.error);
872
+ }
873
+ this.log(`${ctx.request.id} [${duration.toFixed(6)}s] ${ctx.request.name}() -> ${reply.error ? this.makeResponseError(reply.error).type : "OK"}`);
874
+ if (ctx.response.statusCode) {
875
+ res.statusCode = ctx.response.statusCode;
876
+ }
877
+ for (const [headerKey, headerValue] of ctx.response.headers.entries()) {
878
+ res.setHeader(headerKey, headerValue);
879
+ }
880
+ switch (ctx.request.version) {
881
+ case 1: {
882
+ const response = {
883
+ deviceId: ctx.request.deviceInfo.id,
884
+ duration,
885
+ error: reply.error ? this.makeResponseError(reply.error) : null,
886
+ host: (0, os_1.hostname)(),
887
+ id: ctx.request.id,
888
+ ok: !reply.error,
889
+ result: reply.error ? null : reply.result,
890
+ };
891
+ if (response.error && !ctx.response.statusCode) {
892
+ res.statusCode = this.makeResponseError(response.error).type === "Fatal" ? 500 : 400;
893
+ }
894
+ res.write(JSON.stringify(response));
895
+ res.end();
896
+ break;
897
+ }
898
+ case 2: {
899
+ const response = {
900
+ deviceId: ctx.request.deviceInfo.id,
901
+ error: reply.error ? this.makeResponseError(reply.error) : null,
902
+ ok: !reply.error,
903
+ requestId: ctx.request.id,
904
+ result: reply.error ? null : reply.result,
905
+ sessionId: ctx.request.extra.sessionId,
906
+ };
907
+ if (response.error && !ctx.response.statusCode) {
908
+ res.statusCode = this.makeResponseError(response.error).type === "Fatal" ? 500 : 400;
909
+ }
910
+ res.write(JSON.stringify(response));
911
+ res.end();
912
+ break;
913
+ }
914
+ case 3: {
915
+ const response = {
916
+ duration,
917
+ error: reply.error ? this.makeResponseError(reply.error) : null,
918
+ host: (0, os_1.hostname)(),
919
+ result: reply.error ? null : reply.result,
920
+ };
921
+ if (response.error && !ctx.response.statusCode) {
922
+ res.statusCode = this.makeResponseError(response.error).type === "Fatal" ? 500 : 400;
923
+ }
924
+ res.setHeader("x-request-id", ctx.request.id);
925
+ res.write(JSON.stringify(response));
926
+ res.end();
927
+ break;
928
+ }
929
+ default: {
930
+ res.statusCode = 500;
931
+ res.write(JSON.stringify({
932
+ error: this.makeResponseError(reply.error ?? new error_1.Fatal("Unknown request version")),
933
+ }));
934
+ res.end();
935
+ return;
936
+ }
937
+ }
938
+ }
939
+ }
940
+ exports.SdkgenHttpServer = SdkgenHttpServer;
941
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1zZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaHR0cC1zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLG1DQUFxQztBQUNyQywyQkFBaUU7QUFFakUsK0JBQW9DO0FBRXBDLDJCQUE4QjtBQUM5Qiw2Q0FBd0Q7QUFDeEQsNkJBQXdDO0FBQ3hDLCtCQUFpQztBQUVqQywrREFBc0U7QUFDdEUsMkRBQWtFO0FBQ2xFLCtEQUFzRTtBQUN0RSwrREFBdUU7QUFFdkUsMkNBdUJ3QjtBQUN4QixtREFBNEQ7QUFDNUQsNkRBQW9FO0FBQ3BFLHVFQUErSDtBQUMvSCw0REFBNEI7QUFDNUIsa0VBQWlDO0FBQ2pDLDJDQUF5QztBQUN6QywwRUFBK0M7QUFJL0MsbURBQWlEO0FBQ2pELG1DQUFnQztBQUNoQyx1Q0FBMkM7QUFDM0MsdUNBQXlDO0FBQ3pDLG1DQUE4QjtBQUU5QixNQUFhLGdCQUFnQjtJQTZCM0IsWUFDUyxTQUF1QyxFQUM5QyxHQUFHLGlCQUFxRTtRQURqRSxjQUFTLEdBQVQsU0FBUyxDQUE4QjtRQTNCL0IsWUFBTyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBRXBDLGlCQUFZLEdBQWtDLEVBQUUsQ0FBQztRQUUxRCxhQUFRLEdBSVgsRUFBRSxDQUFDO1FBRUQsc0JBQWlCLEdBQUcsSUFBSSxDQUFDO1FBRXpCLGtCQUFhLEdBQUcsSUFBSSxDQUFDO1FBRXJCLFFBQUcsR0FBRyxDQUFDLE9BQWUsRUFBRSxFQUFFO1lBQy9CLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxJQUFJLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFDO1FBRUssYUFBUSxHQUFrQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBRXZELGVBQVUsR0FBRyxLQUFLLENBQUM7UUFFbkIscUJBQWdCLEdBQUcsRUFBRSxDQUFDO1FBd2pCdkIsa0JBQWEsR0FB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