@tramvai/module-server 2.70.1 → 2.72.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 (48) hide show
  1. package/lib/browser.js +2 -31
  2. package/lib/modules/debugRequests.es.js +143 -0
  3. package/lib/modules/debugRequests.js +151 -0
  4. package/lib/modules/dependenciesVersion.es.js +47 -0
  5. package/lib/modules/dependenciesVersion.js +49 -0
  6. package/lib/modules/gracefulShutdown.es.js +104 -0
  7. package/lib/modules/gracefulShutdown.js +106 -0
  8. package/lib/modules/keepAlive.es.js +47 -0
  9. package/lib/modules/keepAlive.js +49 -0
  10. package/lib/modules/papi/api/index.es.js +80 -0
  11. package/lib/modules/papi/api/index.js +88 -0
  12. package/lib/modules/papi/papi.browser.browser.js +13 -0
  13. package/lib/modules/papi/papi.browser.es.js +13 -0
  14. package/lib/modules/papi/papi.browser.js +15 -0
  15. package/lib/modules/papi/papi.es.js +111 -0
  16. package/lib/modules/papi/papi.js +118 -0
  17. package/lib/modules/papi/server/executor.es.js +39 -0
  18. package/lib/modules/papi/server/executor.js +43 -0
  19. package/lib/modules/papi/server/fileApi.es.js +44 -0
  20. package/lib/modules/papi/server/fileApi.js +52 -0
  21. package/lib/modules/papi/shared.browser.js +25 -0
  22. package/lib/modules/papi/shared.es.js +25 -0
  23. package/lib/modules/papi/shared.js +29 -0
  24. package/lib/modules/proxy.es.js +65 -0
  25. package/lib/modules/proxy.js +73 -0
  26. package/lib/modules/serverTiming.es.js +30 -0
  27. package/lib/modules/serverTiming.js +34 -0
  28. package/lib/modules/statics.es.js +48 -0
  29. package/lib/modules/statics.js +54 -0
  30. package/lib/modules/utilityServer.es.js +99 -0
  31. package/lib/modules/utilityServer.js +101 -0
  32. package/lib/modules/utils/require.es.js +11 -0
  33. package/lib/modules/utils/require.js +16 -0
  34. package/lib/modules/utils/tramvaiDepsFilter.es.js +8 -0
  35. package/lib/modules/utils/tramvaiDepsFilter.js +16 -0
  36. package/lib/server/error.es.js +54 -0
  37. package/lib/server/error.js +62 -0
  38. package/lib/server/server.es.js +17 -0
  39. package/lib/server/server.js +26 -0
  40. package/lib/server/static.es.js +34 -0
  41. package/lib/server/static.js +44 -0
  42. package/lib/server/webApp.es.js +103 -0
  43. package/lib/server/webApp.js +113 -0
  44. package/lib/server/xHeaders.es.js +21 -0
  45. package/lib/server/xHeaders.js +30 -0
  46. package/lib/server.es.js +24 -1035
  47. package/lib/server.js +29 -1055
  48. package/package.json +19 -20
package/lib/server.js CHANGED
@@ -11,1050 +11,24 @@ var tokensServerPrivate = require('@tramvai/tokens-server-private');
11
11
  var tokensCommon = require('@tramvai/tokens-common');
12
12
  var moduleMetrics = require('@tramvai/module-metrics');
13
13
  var moduleCacheWarmup = require('@tramvai/module-cache-warmup');
14
- var http = require('http');
15
- var fastify = require('fastify');
16
- var cookie = require('@fastify/cookie');
17
- var fastifyFormBody = require('@fastify/formbody');
18
- var dippy = require('@tinkoff/dippy');
19
- var isNil = require('@tinkoff/utils/is/nil');
20
- var errors = require('@tinkoff/errors');
21
- var fastifyCompress = require('@fastify/compress');
22
- var FastifyStatic = require('@fastify/static');
23
- var os = require('os');
24
- var filterObj = require('@tinkoff/utils/object/filter');
25
- var flatten = require('@tinkoff/utils/array/flatten');
26
- var toArray = require('@tinkoff/utils/array/toArray');
27
- var papi = require('@tramvai/papi');
28
- var eachObj = require('@tinkoff/utils/object/each');
29
- var path = require('path');
30
- var terminus = require('@tinkoff/terminus');
31
- var url = require('@tinkoff/url');
32
- var monkeypatch = require('@tinkoff/monkeypatch');
33
- var https = require('https');
34
- var isArray = require('@tinkoff/utils/is/array');
35
- var isObject = require('@tinkoff/utils/is/object');
36
- var httpProxyMiddleware = require('http-proxy-middleware');
37
- var moduleCommon = require('@tramvai/module-common');
38
- var tokensCorePrivate = require('@tramvai/tokens-core-private');
14
+ var server = require('./server/server.js');
15
+ var webApp = require('./server/webApp.js');
16
+ var _static = require('./server/static.js');
17
+ var xHeaders = require('./server/xHeaders.js');
18
+ var papi = require('./modules/papi/papi.js');
19
+ require('./modules/papi/papi.browser.js');
20
+ var statics = require('./modules/statics.js');
21
+ var gracefulShutdown = require('./modules/gracefulShutdown.js');
22
+ var debugRequests = require('./modules/debugRequests.js');
23
+ var proxy = require('./modules/proxy.js');
24
+ var dependenciesVersion = require('./modules/dependenciesVersion.js');
25
+ var utilityServer = require('./modules/utilityServer.js');
26
+ var keepAlive = require('./modules/keepAlive.js');
27
+ var serverTiming = require('./modules/serverTiming.js');
39
28
 
40
29
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
41
30
 
42
31
  var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
43
- var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
44
- var fastify__default = /*#__PURE__*/_interopDefaultLegacy(fastify);
45
- var fastifyFormBody__default = /*#__PURE__*/_interopDefaultLegacy(fastifyFormBody);
46
- var isNil__default = /*#__PURE__*/_interopDefaultLegacy(isNil);
47
- var fastifyCompress__default = /*#__PURE__*/_interopDefaultLegacy(fastifyCompress);
48
- var FastifyStatic__default = /*#__PURE__*/_interopDefaultLegacy(FastifyStatic);
49
- var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
50
- var filterObj__default = /*#__PURE__*/_interopDefaultLegacy(filterObj);
51
- var flatten__default = /*#__PURE__*/_interopDefaultLegacy(flatten);
52
- var toArray__default = /*#__PURE__*/_interopDefaultLegacy(toArray);
53
- var eachObj__default = /*#__PURE__*/_interopDefaultLegacy(eachObj);
54
- var monkeypatch__default = /*#__PURE__*/_interopDefaultLegacy(monkeypatch);
55
- var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
56
- var isArray__default = /*#__PURE__*/_interopDefaultLegacy(isArray);
57
- var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
58
-
59
- const serverFactory = () => {
60
- return http__default["default"].createServer();
61
- };
62
- const serverListenCommand = ({ server, logger, envManager, }) => {
63
- const log = logger('server');
64
- const port = envManager.get('PORT');
65
- return function serverListen() {
66
- server.listen({
67
- host: '',
68
- port,
69
- }, () => log.warn({ event: 'server-listen-port', message: `Server listen ${port} port` }));
70
- };
71
- };
72
-
73
- const errorHandler = (app, { log, beforeError, processError, afterError, }) => {
74
- app.setErrorHandler(async (error, request, reply) => {
75
- const runHandlers = async (handlers) => {
76
- if (handlers) {
77
- for (const handler of handlers) {
78
- const result = await handler(error, request, reply);
79
- if (result) {
80
- return result;
81
- }
82
- }
83
- }
84
- };
85
- const requestInfo = {
86
- ip: request.ip,
87
- requestId: request.headers['x-request-id'],
88
- url: request.url,
89
- };
90
- const beforeErrorResult = await runHandlers(beforeError);
91
- if (!isNil__default["default"](beforeErrorResult)) {
92
- return beforeErrorResult;
93
- }
94
- if (errors.isRedirectFoundError(error)) {
95
- reply.header('cache-control', 'no-cache, no-store, must-revalidate');
96
- reply.redirect(error.httpStatus || 307, error.nextUrl);
97
- return;
98
- }
99
- if (errors.isNotFoundError(error)) {
100
- reply.status(404);
101
- return '';
102
- }
103
- const processErrorResult = await runHandlers(processError);
104
- if (!isNil__default["default"](processErrorResult)) {
105
- return processErrorResult;
106
- }
107
- if (errors.isHttpError(error)) {
108
- if (error.httpStatus >= 500) {
109
- log.error({ event: 'send-server-error', error, requestInfo });
110
- }
111
- reply.status(error.httpStatus);
112
- return '';
113
- }
114
- log.error({ event: 'send-server-error', error, requestInfo });
115
- const afterErrorResult = await runHandlers(afterError);
116
- if (!isNil__default["default"](afterErrorResult)) {
117
- return afterErrorResult;
118
- }
119
- throw error;
120
- });
121
- };
122
-
123
- const webAppFactory = ({ server }) => {
124
- const app = fastify__default["default"]({
125
- ignoreTrailingSlash: true,
126
- bodyLimit: 2097152,
127
- serverFactory: (handler) => {
128
- server.on('request', handler);
129
- return server;
130
- },
131
- });
132
- return app;
133
- };
134
- const webAppInitCommand = ({ app, logger, commandLineRunner, executionContextManager, beforeInit, requestMetrics, limiterRequest, init, afterInit, beforeError, processError, afterError, }) => {
135
- const log = logger('server:webapp');
136
- const runHandlers = (instance, handlers) => {
137
- return Promise.all([handlers && Promise.all(handlers.map((handler) => handler(instance)))]);
138
- };
139
- return async function webAppInit() {
140
- errorHandler(app, { log, beforeError, processError, afterError });
141
- await app.register(async (instance) => {
142
- await runHandlers(instance, beforeInit);
143
- });
144
- await app.register(async (instance) => {
145
- await runHandlers(instance, requestMetrics);
146
- await runHandlers(instance, limiterRequest);
147
- await app.register(cookie.fastifyCookie);
148
- await app.register(fastifyFormBody__default["default"]);
149
- await runHandlers(instance, init);
150
- // break the cycle of event loop to allow server to handle other requests
151
- // while current on is in processing
152
- // mainly to prevent problems and response hanging in case the response process
153
- // uses only sync and microtask code
154
- instance.addHook('preHandler', (req, res, next) => {
155
- setImmediate(next);
156
- });
157
- instance.all('*', async (request, reply) => {
158
- try {
159
- log.debug({
160
- event: 'start:request',
161
- message: 'Клиент зашел на страницу',
162
- url: request.url,
163
- });
164
- await executionContextManager.withContext(null, 'root', async (rootExecutionContext) => {
165
- const di = await commandLineRunner.run('server', 'customer', [
166
- dippy.provide({
167
- provide: tokensCommon.ROOT_EXECUTION_CONTEXT_TOKEN,
168
- useValue: rootExecutionContext,
169
- }),
170
- {
171
- provide: tokensServerPrivate.FASTIFY_REQUEST,
172
- scope: core.Scope.REQUEST,
173
- useValue: request,
174
- },
175
- {
176
- provide: tokensServerPrivate.FASTIFY_RESPONSE,
177
- scope: core.Scope.REQUEST,
178
- useValue: reply,
179
- },
180
- ]);
181
- const responseManager = di.get(tokensCommon.RESPONSE_MANAGER_TOKEN);
182
- if (reply.sent) {
183
- log.debug({
184
- event: 'response-ended',
185
- message: 'Response was already ended.',
186
- url: request.url,
187
- });
188
- }
189
- else {
190
- reply
191
- .header('content-type', 'text/html')
192
- .headers(responseManager.getHeaders())
193
- .status(responseManager.getStatus())
194
- .send(responseManager.getBody());
195
- }
196
- });
197
- }
198
- catch (err) {
199
- if (err.di) {
200
- const responseManager = err.di.get(tokensCommon.RESPONSE_MANAGER_TOKEN);
201
- if (responseManager && !reply.sent) {
202
- reply.headers(responseManager.getHeaders());
203
- }
204
- }
205
- throw err;
206
- }
207
- });
208
- });
209
- await app.register(async (instance) => {
210
- await runHandlers(instance, afterInit);
211
- });
212
- await app.ready();
213
- };
214
- };
215
-
216
- const staticAppCommand = ({ logger, envManager, appInfo, }) => {
217
- if (!envManager.get('DEV_STATIC')) {
218
- return function staticAppNoop() { };
219
- }
220
- const log = logger('server:static');
221
- const port = +envManager.get('PORT_STATIC');
222
- const appVersion = envManager.get('APP_VERSION');
223
- return async function staticApp() {
224
- const appStatic = fastify__default["default"]();
225
- await appStatic.register(fastifyCompress__default["default"]);
226
- await appStatic.register(FastifyStatic.fastifyStatic, {
227
- root: process.cwd(),
228
- prefix: '/',
229
- setHeaders: (res) => {
230
- res.headers({
231
- 'Access-Control-Allow-Origin': '*',
232
- 'Timing-Allow-Origin': '*',
233
- 'X-App-Id': appInfo.appName,
234
- 'X-App-Version': appVersion,
235
- 'X-Host': os__default["default"].hostname(),
236
- });
237
- },
238
- });
239
- appStatic.listen({ port }, () => log.info(`Running static server on port: ${port}`));
240
- return appStatic;
241
- };
242
- };
243
-
244
- const xHeadersFactory = ({ app, envManager, appInfo, }) => {
245
- const xHeaders = filterObj__default["default"]((val) => !!val, {
246
- 'x-app-id': appInfo.appName,
247
- 'x-host': encodeURIComponent(os__default["default"].hostname()),
248
- 'x-app-version': envManager.get('APP_VERSION'),
249
- 'x-deploy-branch': envManager.get('DEPLOY_BRANCH'),
250
- 'x-deploy-commit': envManager.get('DEPLOY_COMMIT'),
251
- 'x-deploy-version': envManager.get('DEPLOY_VERSION'),
252
- 'x-deploy-repository': envManager.get('DEPLOY_REPOSITORY'),
253
- });
254
- return async () => {
255
- app.addHook('preHandler', async (_, reply) => {
256
- reply.headers(xHeaders);
257
- });
258
- };
259
- };
260
-
261
- function createApi(rootApp, papiList, { baseUrl, di, logger }) {
262
- const paths = new Set();
263
- const papiLog = logger('papi');
264
- rootApp.register(async (app) => {
265
- await app.register(cookie.fastifyCookie);
266
- await app.register(fastifyFormBody__default["default"], { bodyLimit: 2097152 }); // 2mb
267
- for (const papi$1 of papiList) {
268
- const papiParams = papi.getPapiParameters(papi$1);
269
- if (!papiParams) {
270
- throw new Error(`papi should be created using createPapiMethod from @tramvai/papi,
271
- got: ${JSON.stringify(papi$1)}`);
272
- }
273
- const { method, path, options } = papiParams;
274
- const { timeout, schema } = options;
275
- if (!path) {
276
- throw new Error(`No path in papi handler, got: ${JSON.stringify(papi$1)}`);
277
- }
278
- const key = `${method} ${path}`;
279
- if (paths.has(key)) {
280
- throw new Error(`papi: route '${key}' already registered`);
281
- }
282
- paths.add(key);
283
- const childLog = papiLog.child(`${papiParams.method}_${papiParams.path}`);
284
- app[method](path, {
285
- schema,
286
- errorHandler: async (error, req, res) => {
287
- var _a;
288
- res.status(error.validation ? 400 : 503);
289
- childLog.error(error);
290
- return {
291
- resultCode: 'INTERNAL_ERROR',
292
- errorMessage: (_a = error.message) !== null && _a !== void 0 ? _a : 'internal error',
293
- };
294
- },
295
- }, async (req, res) => {
296
- const childDi = dippy.createChildContainer(di, [
297
- {
298
- provide: tokensServerPrivate.FASTIFY_REQUEST,
299
- scope: dippy.Scope.REQUEST,
300
- useValue: req,
301
- },
302
- {
303
- provide: tokensServerPrivate.FASTIFY_RESPONSE,
304
- scope: dippy.Scope.REQUEST,
305
- useValue: res,
306
- },
307
- ]);
308
- const papiExecutor = childDi.get(tokensServerPrivate.PAPI_EXECUTOR);
309
- // TODO: use abortSignal
310
- const payload = await Promise.race([
311
- papiExecutor(papi$1),
312
- new Promise((resolve, reject) => setTimeout(() => reject(new errors.HttpError({ httpStatus: 503, message: 'Execution timeout' })), timeout)),
313
- ]);
314
- const responseManager = childDi.get(tokensCommon.RESPONSE_MANAGER_TOKEN);
315
- res.headers(responseManager.getHeaders()).status(responseManager.getStatus());
316
- if (res.sent) {
317
- return;
318
- }
319
- if (!payload && responseManager.getBody()) {
320
- res.send(responseManager.getBody());
321
- return res;
322
- }
323
- return {
324
- resultCode: 'OK',
325
- payload,
326
- };
327
- });
328
- }
329
- }, { prefix: baseUrl });
330
- }
331
-
332
- let papis;
333
- try {
334
- // eslint-disable-next-line import/no-extraneous-dependencies
335
- papis = require('@tramvai/cli/lib/external/api').default; // eslint-disable-line import/no-unresolved
336
- }
337
- catch (e) { }
338
- const getFileApi = ({ logger }) => {
339
- const log = logger('papi:fileApi');
340
- const result = [];
341
- eachObj__default["default"](({ default: entry }, path) => {
342
- if (!papi.isPapiMethod(entry)) {
343
- log.error({
344
- path,
345
- entry,
346
- message: `Cannot resolve a papi handler.
347
- Check that you are using file based papi right way by docs https://tramvai.dev/docs/how-to/how-create-papi#automatic-handler-creation
348
- In case you have not added any file papi handler, consider renaming directory ./src/api (by default) to the other name to resolve conflicts with papi, or
349
- change settings serverApiDir in tramvai.json`,
350
- });
351
- throw new Error('Not a papi');
352
- }
353
- const papiParameters = papi.getPapiParameters(entry);
354
- result.push(papi.createPapiMethod({
355
- ...papiParameters,
356
- path: `/${path}`,
357
- }));
358
- }, papis);
359
- return result;
360
- };
361
- const fileApiProvider = {
362
- provide: tokensServer.SERVER_MODULE_PAPI_PUBLIC_ROUTE,
363
- multi: true,
364
- useFactory: getFileApi,
365
- deps: {
366
- logger: tokensCommon.LOGGER_TOKEN,
367
- },
368
- };
369
-
370
- const sharedProviders = [
371
- {
372
- provide: tokensServer.SERVER_MODULE_PAPI_PUBLIC_URL,
373
- useFactory: ({ appInfo }) => {
374
- return `/${appInfo.appName}/papi`;
375
- },
376
- deps: {
377
- appInfo: core.APP_INFO_TOKEN,
378
- },
379
- },
380
- {
381
- provide: tokensServer.SERVER_MODULE_PAPI_PRIVATE_URL,
382
- useFactory: ({ appInfo }) => {
383
- return `/${appInfo.appName}/private/papi`;
384
- },
385
- deps: {
386
- appInfo: core.APP_INFO_TOKEN,
387
- },
388
- },
389
- ];
390
-
391
- const papiExecutorProvider = dippy.provide({
392
- provide: tokensServerPrivate.PAPI_EXECUTOR,
393
- scope: dippy.Scope.REQUEST,
394
- useFactory: ({ di, logger, fastifyRequest, requestManager, responseManager }) => {
395
- var _a;
396
- const papiLog = logger('papi');
397
- const papiOptions = {
398
- requestManager,
399
- responseManager,
400
- params: (_a = fastifyRequest.params) !== null && _a !== void 0 ? _a : {},
401
- cookies: requestManager.getCookies(),
402
- headers: requestManager.getHeaders(),
403
- body: requestManager.getBody(),
404
- parsedUrl: requestManager.getParsedUrl(),
405
- };
406
- return (papi$1) => {
407
- const { handler, deps, method, path } = papi.getPapiParameters(papi$1);
408
- const papiContext = {
409
- deps: di.getOfDeps(deps),
410
- log: papiLog.child(`${method}_${path}`),
411
- };
412
- return handler.call(papiContext, papiOptions);
413
- };
414
- },
415
- deps: {
416
- di: dippy.DI_TOKEN,
417
- logger: tokensCommon.LOGGER_TOKEN,
418
- fastifyRequest: tokensServerPrivate.FASTIFY_REQUEST,
419
- requestManager: tokensCommon.REQUEST_MANAGER_TOKEN,
420
- responseManager: tokensCommon.RESPONSE_MANAGER_TOKEN,
421
- },
422
- });
423
-
424
- let ServerPapiModule = class ServerPapiModule {
425
- };
426
- ServerPapiModule = tslib.__decorate([
427
- core.Module({
428
- providers: [
429
- papiExecutorProvider,
430
- fileApiProvider,
431
- ...sharedProviders,
432
- core.provide({
433
- provide: tokensServerPrivate.WEB_FASTIFY_APP_BEFORE_INIT_TOKEN,
434
- useFactory: ({ di, logger, privateRoutes, publicRoutes, publicBaseUrl, privateBaseUrl }) => (app) => {
435
- if (process.env.NODE_ENV === 'development') {
436
- const papiListRoute = papi.createPapiMethod({
437
- method: 'get',
438
- path: '/papi-list',
439
- async handler() {
440
- return [
441
- ...flatten__default["default"](privateRoutes).map((papi$1) => {
442
- const params = papi.getPapiParameters(papi$1);
443
- return {
444
- path: params.path,
445
- method: params.method,
446
- options: params.options,
447
- type: 'private',
448
- };
449
- }),
450
- ...flatten__default["default"](publicRoutes).map((papi$1) => {
451
- const params = papi.getPapiParameters(papi$1);
452
- return {
453
- path: params.path,
454
- method: params.method,
455
- options: params.options,
456
- type: 'public',
457
- };
458
- }),
459
- ];
460
- },
461
- });
462
- // eslint-disable-next-line no-param-reassign
463
- privateRoutes = privateRoutes
464
- ? [...toArray__default["default"](privateRoutes), papiListRoute]
465
- : [papiListRoute];
466
- }
467
- if (privateRoutes) {
468
- createApi(app, flatten__default["default"](privateRoutes), {
469
- baseUrl: privateBaseUrl,
470
- di,
471
- logger,
472
- });
473
- }
474
- if (publicRoutes) {
475
- createApi(app, flatten__default["default"](publicRoutes), {
476
- baseUrl: publicBaseUrl,
477
- di,
478
- logger,
479
- });
480
- }
481
- },
482
- deps: {
483
- di: core.DI_TOKEN,
484
- logger: tokensCommon.LOGGER_TOKEN,
485
- privateRoutes: {
486
- token: tokensServer.SERVER_MODULE_PAPI_PRIVATE_ROUTE,
487
- optional: true,
488
- multi: true,
489
- },
490
- publicRoutes: {
491
- token: tokensServer.SERVER_MODULE_PAPI_PUBLIC_ROUTE,
492
- optional: true,
493
- multi: true,
494
- },
495
- privateBaseUrl: tokensServer.SERVER_MODULE_PAPI_PRIVATE_URL,
496
- publicBaseUrl: tokensServer.SERVER_MODULE_PAPI_PUBLIC_URL,
497
- },
498
- multi: true,
499
- }),
500
- // необходимо для утилит. Подумать как можно убрать в будующем. Если убрать не будет ломающим изменением
501
- core.provide({
502
- provide: tokensServer.SERVER_MODULE_PAPI_PUBLIC_ROUTE,
503
- multi: true,
504
- useValue: papi.createPapiMethod({
505
- method: 'get',
506
- path: '/version',
507
- async handler() {
508
- return {
509
- version: this.deps.envManager.get('APP_VERSION'),
510
- };
511
- },
512
- deps: {
513
- envManager: tokensCommon.ENV_MANAGER_TOKEN,
514
- },
515
- }),
516
- }),
517
- ],
518
- })
519
- ], ServerPapiModule);
520
-
521
- let BrowserPapiModule = class BrowserPapiModule {
522
- };
523
- BrowserPapiModule = tslib.__decorate([
524
- core.Module({
525
- providers: [...sharedProviders],
526
- })
527
- ], BrowserPapiModule);
528
-
529
- const ONE_YEAR = 365 * 24 * 60 * 60;
530
- let ServerStaticsModule = class ServerStaticsModule {
531
- };
532
- ServerStaticsModule = tslib.__decorate([
533
- core.Module({
534
- providers: [
535
- core.provide({
536
- provide: tokensServerPrivate.WEB_FASTIFY_APP_BEFORE_INIT_TOKEN,
537
- useFactory: ({ options }) => {
538
- const path$1 = (options === null || options === void 0 ? void 0 : options.path) || 'public';
539
- return (instance) => {
540
- instance.register(FastifyStatic__default["default"], {
541
- decorateReply: false,
542
- // for backward compatibility, leaving default prefix.
543
- // without `wildcard: false` property, this middleware has conflicts with express compatibility plugin
544
- prefix: `/`,
545
- // prevent errors by use FastifyStatic only for all defined files in the served folder,
546
- // will not serve the newly added file on the filesystem - https://github.com/fastify/fastify-static#wildcard
547
- wildcard: false,
548
- root: path.resolve(process.cwd(), path$1),
549
- setHeaders: (res) => {
550
- const oneYearForward = new Date(Date.now() + ONE_YEAR * 1000);
551
- res.setHeader('cache-control', `public, max-age=${ONE_YEAR}`);
552
- res.setHeader('expires', oneYearForward.toUTCString());
553
- },
554
- });
555
- };
556
- },
557
- deps: {
558
- options: {
559
- token: tokensServer.SERVER_MODULE_STATICS_OPTIONS,
560
- optional: true,
561
- },
562
- },
563
- multi: true,
564
- }),
565
- ],
566
- })
567
- ], ServerStaticsModule);
568
-
569
- const GRACEFUL_SHUTDOWN_TIMEOUT = 25000;
570
- const GRACEFUL_READINESS_TIMEOUT = 5000;
571
- const noopCheck = () => { };
572
- let ServerGracefulShutdownModule = class ServerGracefulShutdownModule {
573
- };
574
- ServerGracefulShutdownModule = tslib.__decorate([
575
- core.Module({
576
- providers: [
577
- core.provide({
578
- provide: tokensServerPrivate.WEB_FASTIFY_APP_BEFORE_INIT_TOKEN,
579
- multi: true,
580
- useFactory: ({ app, server, logger, commandLineRunner, livenessPath, readinessPath, livenessProbe, readinessProbe, }) => {
581
- const log = logger('server');
582
- return function serverListen() {
583
- terminus.createTerminus(server, app, {
584
- signal: 'SIGTERM',
585
- timeout: GRACEFUL_SHUTDOWN_TIMEOUT,
586
- logger: (msg, error) => {
587
- log.error({
588
- event: 'terminus',
589
- message: msg,
590
- error,
591
- });
592
- },
593
- // https://github.com/godaddy/terminus#how-to-set-terminus-up-with-kubernetes
594
- beforeShutdown: () => {
595
- log.warn({
596
- event: 'terminus-wait',
597
- message: 'wait for other tasks before shutdown',
598
- });
599
- return new Promise((resolve) => setTimeout(resolve, GRACEFUL_READINESS_TIMEOUT));
600
- },
601
- onSignal: () => {
602
- log.warn({
603
- event: 'terminus-run-command',
604
- message: 'run commandLineRunner close line',
605
- });
606
- commandLineRunner.run('server', 'close');
607
- },
608
- onShutdown: () => {
609
- log.warn({
610
- event: 'terminus-exit',
611
- message: 'calling process.exit',
612
- });
613
- process.exit();
614
- },
615
- healthChecks: {
616
- [livenessPath]: livenessProbe || noopCheck,
617
- [readinessPath]: readinessProbe || noopCheck,
618
- },
619
- });
620
- };
621
- },
622
- deps: {
623
- app: tokensServerPrivate.UTILITY_WEB_FASTIFY_APP_TOKEN,
624
- server: tokensServer.SERVER_TOKEN,
625
- logger: tokensCommon.LOGGER_TOKEN,
626
- commandLineRunner: core.COMMAND_LINE_RUNNER_TOKEN,
627
- livenessPath: tokensServer.LIVENESS_PATH_TOKEN,
628
- readinessPath: tokensServer.READINESS_PATH_TOKEN,
629
- readinessProbe: { token: tokensServer.READINESS_PROBE_TOKEN, optional: true },
630
- livenessProbe: { token: tokensServer.LIVENESS_PROBE_TOKEN, optional: true },
631
- },
632
- }),
633
- core.provide({
634
- provide: tokensServer.LIVENESS_PATH_TOKEN,
635
- useValue: '/healthz',
636
- }),
637
- core.provide({
638
- provide: tokensServer.READINESS_PATH_TOKEN,
639
- useValue: '/readyz',
640
- }),
641
- core.provide({
642
- provide: tokensServer.UTILITY_SERVER_PATHS,
643
- useFactory: ({ livenessPath }) => {
644
- return livenessPath;
645
- },
646
- multi: true,
647
- deps: {
648
- livenessPath: tokensServer.LIVENESS_PATH_TOKEN,
649
- },
650
- }),
651
- core.provide({
652
- provide: tokensServer.UTILITY_SERVER_PATHS,
653
- useFactory: ({ readinessPath }) => {
654
- return readinessPath;
655
- },
656
- multi: true,
657
- deps: {
658
- readinessPath: tokensServer.READINESS_PATH_TOKEN,
659
- },
660
- }),
661
- ],
662
- })
663
- ], ServerGracefulShutdownModule);
664
-
665
- class Interceptor {
666
- constructor() {
667
- this.intercepted = false;
668
- this.delay = 0;
669
- }
670
- setIntercept(intercept) {
671
- this.intercepted = intercept;
672
- }
673
- setDelay(delay) {
674
- this.intercepted = true;
675
- this.delay = delay;
676
- }
677
- clear() {
678
- this.intercepted = false;
679
- this.delay = 0;
680
- }
681
- getStatus() {
682
- return {
683
- intercepted: this.intercepted,
684
- delay: this.delay,
685
- };
686
- }
687
- }
688
- const INTERCEPTOR_TOKEN = 'debugRequestsInterceptor';
689
- let DebugHttpRequestsModule = class DebugHttpRequestsModule {
690
- };
691
- DebugHttpRequestsModule = tslib.__decorate([
692
- core.Module({
693
- providers: [
694
- {
695
- provide: INTERCEPTOR_TOKEN,
696
- useClass: Interceptor,
697
- scope: core.Scope.SINGLETON,
698
- },
699
- {
700
- provide: core.commandLineListTokens.init,
701
- multi: true,
702
- useFactory: ({ logger, interceptor }) => {
703
- const log = logger('server:node-debug:request');
704
- return function debugHttp() {
705
- const handler = (request, options, cb) => {
706
- const parsed = typeof options === 'string' ? url.parse(options) : options;
707
- const wasHandled = typeof cb === 'function';
708
- return request(options, cb)
709
- .on('response', (response) => {
710
- interceptor.intercepted &&
711
- monkeypatch__default["default"]({
712
- obj: response,
713
- method: 'emit',
714
- handler: (emit, event, ...args) => {
715
- if (event === 'end') {
716
- setTimeout(() => {
717
- emit(event, ...args);
718
- }, interceptor.delay);
719
- return !!response.listenerCount(event);
720
- }
721
- return emit(event, ...args);
722
- },
723
- });
724
- })
725
- .on('response', (response) => {
726
- // Workaround for res._dump in Node.JS http client
727
- // https://github.com/nodejs/node/blob/20285ad17755187ece16b8a5effeaa87f5407da2/lib/_http_client.js#L421-L427
728
- if (!wasHandled && EventEmitter.EventEmitter.listenerCount(response.req, 'response') === 0) {
729
- response.resume();
730
- }
731
- log.debug(`${response.statusCode}
732
- ${parsed.href || `${parsed.protocol}//${parsed.hostname}${parsed.path}`}
733
- `);
734
- })
735
- .on('error', (error) => {
736
- log.error({
737
- event: 'request-failed',
738
- error,
739
- url: parsed.href || options,
740
- });
741
- });
742
- };
743
- monkeypatch__default["default"]({ obj: http__default["default"], method: 'request', handler });
744
- monkeypatch__default["default"]({ obj: https__default["default"], method: 'request', handler });
745
- };
746
- },
747
- deps: {
748
- logger: tokensCommon.LOGGER_TOKEN,
749
- interceptor: INTERCEPTOR_TOKEN,
750
- },
751
- },
752
- {
753
- provide: tokensServer.SERVER_MODULE_PAPI_PRIVATE_ROUTE,
754
- multi: true,
755
- useFactory: ({ interceptor }) => {
756
- return papi.createPapiMethod({
757
- method: 'post',
758
- path: '/debug-http-request',
759
- async handler({ body }) {
760
- const { delay = 10000 } = body;
761
- if (delay) {
762
- interceptor.setDelay(delay);
763
- }
764
- else {
765
- interceptor.setIntercept(true);
766
- }
767
- return interceptor.getStatus();
768
- },
769
- });
770
- },
771
- deps: {
772
- interceptor: INTERCEPTOR_TOKEN,
773
- },
774
- },
775
- {
776
- provide: tokensServer.SERVER_MODULE_PAPI_PRIVATE_ROUTE,
777
- multi: true,
778
- useFactory: ({ interceptor }) => {
779
- return papi.createPapiMethod({
780
- method: 'delete',
781
- path: '/debug-http-request',
782
- async handler() {
783
- interceptor.clear();
784
- return interceptor.getStatus();
785
- },
786
- });
787
- },
788
- deps: {
789
- interceptor: INTERCEPTOR_TOKEN,
790
- },
791
- },
792
- ],
793
- })
794
- ], DebugHttpRequestsModule);
795
-
796
- const nodeRequire = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require;
797
- const safeNodeRequire = (path) => {
798
- try {
799
- return nodeRequire(path);
800
- }
801
- catch (e) {
802
- return null;
803
- }
804
- };
805
-
806
- let ServerProxyModule = class ServerProxyModule {
807
- };
808
- ServerProxyModule = tslib.__decorate([
809
- core.Module({
810
- providers: [
811
- {
812
- provide: tokensServerPrivate.WEB_FASTIFY_APP_INIT_TOKEN,
813
- useFactory: ({ defaultProxies }) => {
814
- return (app) => {
815
- const proxyConfig = safeNodeRequire(path.resolve(process.cwd(), 'proxy.conf'));
816
- const proxies = defaultProxies !== null && defaultProxies !== void 0 ? defaultProxies : [];
817
- if (!proxyConfig && proxies.length === 0) {
818
- return;
819
- }
820
- if (isArray__default["default"](proxyConfig)) {
821
- proxies.push(...proxyConfig);
822
- }
823
- else if (proxyConfig === null || proxyConfig === void 0 ? void 0 : proxyConfig.target) {
824
- proxies.push(proxyConfig);
825
- }
826
- else if (isObject__default["default"](proxyConfig)) {
827
- eachObj__default["default"]((target, source) => {
828
- const options = typeof target === 'string' ? { target } : target;
829
- proxies.push({ context: source, ...options });
830
- }, proxyConfig);
831
- }
832
- proxies.forEach((proxy) => {
833
- const middleware = httpProxyMiddleware.createProxyMiddleware(proxy.context, {
834
- changeOrigin: true,
835
- onProxyRes: (proxyRes) => {
836
- // eslint-disable-next-line no-param-reassign
837
- proxyRes.headers['x-tramvai-proxied-response'] = '1';
838
- },
839
- ...proxy,
840
- });
841
- app.addHook('onRequest', (req, res, next) => {
842
- middleware(req.raw, res.raw, next);
843
- });
844
- });
845
- };
846
- },
847
- deps: {
848
- defaultProxies: {
849
- token: tokensServer.PROXY_CONFIG_TOKEN,
850
- optional: true,
851
- },
852
- },
853
- multi: true,
854
- },
855
- ],
856
- })
857
- ], ServerProxyModule);
858
-
859
- const RegExp = /^@tramvai/;
860
- const tramvaiDepsFilter = (deps) => {
861
- return filterObj__default["default"]((v, k) => RegExp.test(k), deps);
862
- };
863
-
864
- let packageJson = {};
865
- try {
866
- // eslint-disable-next-line import/no-unresolved
867
- packageJson = require('../../../../package.json');
868
- }
869
- catch (e) {
870
- packageJson = safeNodeRequire(path.resolve(process.cwd(), 'package.json'));
871
- }
872
- let DependenciesVersionModule = class DependenciesVersionModule {
873
- };
874
- DependenciesVersionModule = tslib.__decorate([
875
- core.Module({
876
- providers: [
877
- {
878
- provide: tokensServer.SERVER_MODULE_PAPI_PRIVATE_ROUTE,
879
- multi: true,
880
- useFactory: ({ depsFilter }) => {
881
- const { dependencies = [] } = packageJson !== null && packageJson !== void 0 ? packageJson : {};
882
- return papi.createPapiMethod({
883
- path: '/dependenciesVersion',
884
- method: 'get',
885
- handler: async () => {
886
- return depsFilter(dependencies);
887
- },
888
- });
889
- },
890
- deps: {
891
- depsFilter: tokensServer.DEPENDENCIES_VERSION_FILTER_TOKEN,
892
- },
893
- },
894
- {
895
- provide: tokensServer.DEPENDENCIES_VERSION_FILTER_TOKEN,
896
- useValue: tramvaiDepsFilter,
897
- },
898
- ],
899
- })
900
- ], DependenciesVersionModule);
901
-
902
- const IS_CUSTOM_SERVER_TOKEN = core.createToken('server utility isCustomServer');
903
- let UtilityServerModule = class UtilityServerModule {
904
- };
905
- UtilityServerModule = tslib.__decorate([
906
- core.Module({
907
- providers: [
908
- core.provide({
909
- provide: tokensCommon.ENV_USED_TOKEN,
910
- multi: true,
911
- useValue: [{ key: 'UTILITY_SERVER_PORT', optional: true }],
912
- }),
913
- core.provide({
914
- provide: tokensServer.UTILITY_SERVER_PORT_TOKEN,
915
- scope: core.Scope.SINGLETON,
916
- useFactory: ({ envManager }) => {
917
- return +(envManager.get('UTILITY_SERVER_PORT') || envManager.get('PORT'));
918
- },
919
- deps: {
920
- envManager: tokensCommon.ENV_MANAGER_TOKEN,
921
- },
922
- }),
923
- core.provide({
924
- provide: IS_CUSTOM_SERVER_TOKEN,
925
- scope: core.Scope.SINGLETON,
926
- useFactory: ({ port, envManager }) => {
927
- return +envManager.get('PORT') !== port;
928
- },
929
- deps: {
930
- envManager: tokensCommon.ENV_MANAGER_TOKEN,
931
- port: tokensServer.UTILITY_SERVER_PORT_TOKEN,
932
- },
933
- }),
934
- core.provide({
935
- provide: tokensServerPrivate.UTILITY_SERVER_TOKEN,
936
- scope: core.Scope.SINGLETON,
937
- useFactory: ({ isCustomServer, serverFactory, server }) => {
938
- return isCustomServer ? serverFactory() : server;
939
- },
940
- deps: {
941
- isCustomServer: IS_CUSTOM_SERVER_TOKEN,
942
- server: tokensServer.SERVER_TOKEN,
943
- serverFactory: tokensServerPrivate.SERVER_FACTORY_TOKEN,
944
- },
945
- }),
946
- core.provide({
947
- provide: tokensServerPrivate.UTILITY_WEB_FASTIFY_APP_TOKEN,
948
- scope: core.Scope.SINGLETON,
949
- useFactory: ({ isCustomServer, app, appFactory, server }) => {
950
- return isCustomServer ? appFactory({ server }) : app;
951
- },
952
- deps: {
953
- isCustomServer: IS_CUSTOM_SERVER_TOKEN,
954
- app: tokensServerPrivate.WEB_FASTIFY_APP_TOKEN,
955
- appFactory: tokensServerPrivate.WEB_FASTIFY_APP_FACTORY_TOKEN,
956
- server: tokensServerPrivate.UTILITY_SERVER_TOKEN,
957
- },
958
- }),
959
- core.provide({
960
- provide: core.commandLineListTokens.listen,
961
- multi: true,
962
- scope: core.Scope.SINGLETON,
963
- useFactory: ({ logger, isCustomServer, port, app, server }) => {
964
- return async function utilityServerListen() {
965
- if (!isCustomServer) {
966
- return;
967
- }
968
- const log = logger('server:utility');
969
- await app.ready();
970
- return new Promise((resolve, reject) => {
971
- server.once('error', (error) => {
972
- log.error({ event: 'server-listen-port', error });
973
- reject(error);
974
- });
975
- server.listen(port, () => {
976
- log.warn({ event: 'server-listen-port', message: `Server listen ${port} port` });
977
- resolve();
978
- });
979
- });
980
- };
981
- },
982
- deps: {
983
- logger: tokensCommon.LOGGER_TOKEN,
984
- isCustomServer: IS_CUSTOM_SERVER_TOKEN,
985
- port: tokensServer.UTILITY_SERVER_PORT_TOKEN,
986
- app: tokensServerPrivate.UTILITY_WEB_FASTIFY_APP_TOKEN,
987
- server: tokensServerPrivate.UTILITY_SERVER_TOKEN,
988
- },
989
- }),
990
- ],
991
- })
992
- ], UtilityServerModule);
993
-
994
- let KeepAliveModule = class KeepAliveModule {
995
- };
996
- KeepAliveModule = tslib.__decorate([
997
- core.Module({
998
- providers: [
999
- core.provide({
1000
- provide: tokensCommon.ENV_USED_TOKEN,
1001
- useValue: [
1002
- {
1003
- key: 'NODE_KEEPALIVE_TIMEOUT',
1004
- optional: true,
1005
- validator(keepAliveTimeout) {
1006
- const value = Number(keepAliveTimeout);
1007
- if (Number.isNaN(value)) {
1008
- return 'Env variable NODE_KEEPALIVE_TIMEOUT should be a number';
1009
- }
1010
- if (value < 0) {
1011
- return 'Env variable NODE_KEEPALIVE_TIMEOUT should be greater or equal than 0';
1012
- }
1013
- return true;
1014
- },
1015
- },
1016
- ],
1017
- }),
1018
- core.provide({
1019
- provide: core.commandLineListTokens.init,
1020
- useFactory: ({ server, envManager, }) => () => {
1021
- const externalKeepAliveTimeout = envManager.get('NODE_KEEPALIVE_TIMEOUT');
1022
- if (externalKeepAliveTimeout !== 'undefined') {
1023
- // eslint-disable-next-line no-param-reassign
1024
- server.keepAliveTimeout = Number(externalKeepAliveTimeout);
1025
- }
1026
- },
1027
- multi: true,
1028
- deps: { server: tokensServer.SERVER_TOKEN, envManager: moduleCommon.ENV_MANAGER_TOKEN },
1029
- }),
1030
- ],
1031
- })
1032
- ], KeepAliveModule);
1033
-
1034
- const ServerTimingModule = core.declareModule({
1035
- name: 'ServerTiming',
1036
- providers: [
1037
- core.provide({
1038
- provide: tokensCorePrivate.COMMAND_LINE_EXECUTION_END_TOKEN,
1039
- multi: true,
1040
- useValue: (di, type, status, timingInfo) => {
1041
- var _a;
1042
- if (type === 'server' && status === 'customer') {
1043
- const responseManager = di.get(tokensCommon.RESPONSE_MANAGER_TOKEN);
1044
- const initialHeader = (_a = responseManager.getHeader('Server-Timing')) !== null && _a !== void 0 ? _a : '';
1045
- const entries = [];
1046
- // index for custom sort
1047
- let index = 0;
1048
- for (const line in timingInfo) {
1049
- const info = timingInfo[line];
1050
- entries.push(`line_${index++}_${line};dur=${info.end - info.start}`);
1051
- }
1052
- responseManager.setHeader('Server-Timing', `${initialHeader ? `${initialHeader}, ` : ''}${entries.join(', ')}`);
1053
- }
1054
- },
1055
- }),
1056
- ],
1057
- });
1058
32
 
1059
33
  if (typeof dns.setDefaultResultOrder === 'function') {
1060
34
  dns.setDefaultResultOrder('ipv4first');
@@ -1069,21 +43,21 @@ exports.ServerModule = tslib.__decorate([
1069
43
  imports: [
1070
44
  moduleMetrics.MetricsModule,
1071
45
  moduleCacheWarmup.CacheWarmupModule,
1072
- ServerPapiModule,
1073
- ServerStaticsModule,
1074
- ServerGracefulShutdownModule,
1075
- ServerProxyModule,
1076
- DependenciesVersionModule,
1077
- UtilityServerModule,
1078
- KeepAliveModule,
1079
- ServerTimingModule,
1080
- process.env.NODE_ENV !== 'production' && DebugHttpRequestsModule,
46
+ papi.ServerPapiModule,
47
+ statics.ServerStaticsModule,
48
+ gracefulShutdown.ServerGracefulShutdownModule,
49
+ proxy.ServerProxyModule,
50
+ dependenciesVersion.DependenciesVersionModule,
51
+ utilityServer.UtilityServerModule,
52
+ keepAlive.KeepAliveModule,
53
+ serverTiming.ServerTimingModule,
54
+ process.env.NODE_ENV !== 'production' && debugRequests.DebugHttpRequestsModule,
1081
55
  ].filter(Boolean),
1082
56
  providers: [
1083
57
  core.provide({
1084
58
  provide: tokensServerPrivate.SERVER_FACTORY_TOKEN,
1085
59
  scope: core.Scope.SINGLETON,
1086
- useValue: serverFactory,
60
+ useValue: server.serverFactory,
1087
61
  }),
1088
62
  core.provide({
1089
63
  provide: tokensServer.SERVER_TOKEN,
@@ -1096,7 +70,7 @@ exports.ServerModule = tslib.__decorate([
1096
70
  core.provide({
1097
71
  provide: tokensServerPrivate.WEB_FASTIFY_APP_FACTORY_TOKEN,
1098
72
  scope: core.Scope.SINGLETON,
1099
- useValue: webAppFactory,
73
+ useValue: webApp.webAppFactory,
1100
74
  }),
1101
75
  core.provide({
1102
76
  provide: tokensServerPrivate.WEB_FASTIFY_APP_TOKEN,
@@ -1110,7 +84,7 @@ exports.ServerModule = tslib.__decorate([
1110
84
  {
1111
85
  provide: core.commandLineListTokens.init,
1112
86
  multi: true,
1113
- useFactory: webAppInitCommand,
87
+ useFactory: webApp.webAppInitCommand,
1114
88
  deps: {
1115
89
  app: tokensServerPrivate.WEB_FASTIFY_APP_TOKEN,
1116
90
  logger: tokensCommon.LOGGER_TOKEN,
@@ -1129,7 +103,7 @@ exports.ServerModule = tslib.__decorate([
1129
103
  {
1130
104
  provide: core.commandLineListTokens.listen,
1131
105
  multi: true,
1132
- useFactory: serverListenCommand,
106
+ useFactory: server.serverListenCommand,
1133
107
  deps: {
1134
108
  server: tokensServer.SERVER_TOKEN,
1135
109
  logger: tokensCommon.LOGGER_TOKEN,
@@ -1139,7 +113,7 @@ exports.ServerModule = tslib.__decorate([
1139
113
  {
1140
114
  provide: core.commandLineListTokens.listen,
1141
115
  multi: true,
1142
- useFactory: staticAppCommand,
116
+ useFactory: _static.staticAppCommand,
1143
117
  deps: {
1144
118
  logger: tokensCommon.LOGGER_TOKEN,
1145
119
  envManager: tokensCommon.ENV_MANAGER_TOKEN,
@@ -1169,7 +143,7 @@ exports.ServerModule = tslib.__decorate([
1169
143
  {
1170
144
  provide: tokensServerPrivate.WEB_FASTIFY_APP_INIT_TOKEN,
1171
145
  multi: true,
1172
- useFactory: xHeadersFactory,
146
+ useFactory: xHeaders.xHeadersFactory,
1173
147
  deps: {
1174
148
  app: tokensServerPrivate.WEB_FASTIFY_APP_TOKEN,
1175
149
  envManager: tokensCommon.ENV_MANAGER_TOKEN,