@tramvai/module-server 1.84.0 → 1.89.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,9 @@
1
- import type express from 'express';
1
+ import type { FastifyInstance } from 'fastify';
2
2
  import type { LOGGER_TOKEN } from '@tramvai/module-common';
3
- export declare const routerErrorHandler: (app: express.Application) => void;
4
- export declare const errorHandler: (app: express.Application, { log, }: {
3
+ import type { WEB_FASTIFY_APP_AFTER_ERROR_TOKEN, WEB_FASTIFY_APP_BEFORE_ERROR_TOKEN, WEB_FASTIFY_APP_PROCESS_ERROR_TOKEN } from '@tramvai/tokens-server-private';
4
+ export declare const errorHandler: (app: FastifyInstance, { log, beforeError, processError, afterError, }: {
5
5
  log: ReturnType<typeof LOGGER_TOKEN>;
6
+ beforeError: typeof WEB_FASTIFY_APP_BEFORE_ERROR_TOKEN;
7
+ processError: typeof WEB_FASTIFY_APP_PROCESS_ERROR_TOKEN;
8
+ afterError: typeof WEB_FASTIFY_APP_AFTER_ERROR_TOKEN;
6
9
  }) => void;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Fork of https://github.com/fastify/fastify-express
3
+ */
4
+ /// <reference types="node" />
5
+ import express from 'express';
6
+ import type { FastifyPluginCallback } from 'fastify';
7
+ declare module 'fastify' {
8
+ interface FastifyInstance {
9
+ /**
10
+ * Express middleware function
11
+ */
12
+ use: express.Application['use'];
13
+ /**
14
+ * Express application instance
15
+ */
16
+ express: express.Application;
17
+ }
18
+ }
19
+ interface Options {
20
+ express: {
21
+ instance: express.Application;
22
+ };
23
+ }
24
+ export declare const fastifyExpressCompatibility: FastifyPluginCallback<Options, import("http").Server>;
25
+ export {};
@@ -1,11 +1,9 @@
1
1
  /// <reference types="node" />
2
2
  import http from 'http';
3
- import type { SERVER_TOKEN, WEB_APP_TOKEN } from '@tramvai/tokens-server';
3
+ import type { SERVER_TOKEN } from '@tramvai/tokens-server';
4
4
  import type { LOGGER_TOKEN } from '@tramvai/tokens-common';
5
5
  import type { ENV_MANAGER_TOKEN } from '@tramvai/module-environment';
6
- export declare const serverFactory: ({ webApp }: {
7
- webApp: typeof WEB_APP_TOKEN;
8
- }) => http.Server;
6
+ export declare const serverFactory: () => http.Server;
9
7
  export declare const serverListenCommand: ({ server, logger, envManager, }: {
10
8
  server: typeof SERVER_TOKEN;
11
9
  logger: typeof LOGGER_TOKEN;
@@ -1,13 +1,29 @@
1
- import type { LOGGER_TOKEN } from '@tramvai/module-common';
1
+ /// <reference types="node" />
2
+ import type { LOGGER_TOKEN } from '@tramvai/tokens-common';
2
3
  import type { COMMAND_LINE_RUNNER_TOKEN } from '@tramvai/core';
3
- import type { WEB_APP_TOKEN, WEB_APP_BEFORE_INIT_TOKEN, WEB_APP_INIT_TOKEN, WEB_APP_AFTER_INIT_TOKEN, WEB_APP_LIMITER_TOKEN } from '@tramvai/tokens-server';
4
- export declare const webAppFactory: () => import("express-serve-static-core").Express;
5
- export declare const webAppInitCommand: ({ app, logger, commandLineRunner, beforeInit, init, afterInit, limiterRequest, }: {
6
- app: typeof WEB_APP_TOKEN;
4
+ import type { WEB_APP_TOKEN, WEB_APP_BEFORE_INIT_TOKEN, WEB_APP_INIT_TOKEN, WEB_APP_AFTER_INIT_TOKEN, WEB_APP_LIMITER_TOKEN, SERVER_TOKEN } from '@tramvai/tokens-server';
5
+ import type { WEB_FASTIFY_APP_TOKEN, WEB_FASTIFY_APP_AFTER_INIT_TOKEN, WEB_FASTIFY_APP_BEFORE_INIT_TOKEN, WEB_FASTIFY_APP_INIT_TOKEN, WEB_FASTIFY_APP_LIMITER_TOKEN, WEB_FASTIFY_APP_BEFORE_ERROR_TOKEN, WEB_FASTIFY_APP_AFTER_ERROR_TOKEN, WEB_FASTIFY_APP_PROCESS_ERROR_TOKEN } from '@tramvai/tokens-server-private';
6
+ export declare const webAppFactory: ({ server, expressApp, }: {
7
+ server: typeof SERVER_TOKEN;
8
+ expressApp: typeof WEB_APP_TOKEN;
9
+ }) => import("fastify").FastifyInstance<import("http").Server, import("http").IncomingMessage, import("http").ServerResponse, import("fastify").FastifyLoggerInstance> & PromiseLike<import("fastify").FastifyInstance<import("http").Server, import("http").IncomingMessage, import("http").ServerResponse, import("fastify").FastifyLoggerInstance>>;
10
+ export declare const webAppExpressFactory: ({ webApp }: {
11
+ webApp: typeof WEB_FASTIFY_APP_TOKEN;
12
+ }) => import("express-serve-static-core").Express;
13
+ export declare const webAppInitCommand: ({ app, expressApp, logger, commandLineRunner, beforeInit, init, afterInit, limiterRequest, expressBeforeInit, expressInit, expressAfterInit, expressLimiterRequest, beforeError, processError, afterError, }: {
14
+ app: typeof WEB_FASTIFY_APP_TOKEN;
15
+ expressApp: typeof WEB_APP_TOKEN;
7
16
  logger: typeof LOGGER_TOKEN;
8
17
  commandLineRunner: typeof COMMAND_LINE_RUNNER_TOKEN;
9
- beforeInit: typeof WEB_APP_BEFORE_INIT_TOKEN;
10
- init: typeof WEB_APP_INIT_TOKEN;
11
- afterInit: typeof WEB_APP_AFTER_INIT_TOKEN;
12
- limiterRequest: typeof WEB_APP_LIMITER_TOKEN;
18
+ beforeInit: typeof WEB_FASTIFY_APP_BEFORE_INIT_TOKEN;
19
+ init: typeof WEB_FASTIFY_APP_INIT_TOKEN;
20
+ afterInit: typeof WEB_FASTIFY_APP_AFTER_INIT_TOKEN;
21
+ limiterRequest: typeof WEB_FASTIFY_APP_LIMITER_TOKEN;
22
+ expressBeforeInit: typeof WEB_APP_BEFORE_INIT_TOKEN;
23
+ expressInit: typeof WEB_APP_INIT_TOKEN;
24
+ expressAfterInit: typeof WEB_APP_AFTER_INIT_TOKEN;
25
+ expressLimiterRequest: typeof WEB_APP_LIMITER_TOKEN;
26
+ beforeError: typeof WEB_FASTIFY_APP_BEFORE_ERROR_TOKEN;
27
+ processError: typeof WEB_FASTIFY_APP_PROCESS_ERROR_TOKEN;
28
+ afterError: typeof WEB_FASTIFY_APP_AFTER_ERROR_TOKEN;
13
29
  }) => () => Promise<void>;
package/lib/server.es.js CHANGED
@@ -2,14 +2,20 @@ import { __decorate } from 'tslib';
2
2
  import { Scope, APP_INFO_TOKEN, Module, provide, DI_TOKEN, COMMAND_LINE_RUNNER_TOKEN, commandLineListTokens } from '@tramvai/core';
3
3
  import { SERVER_MODULE_PAPI_PUBLIC_ROUTE, SERVER_MODULE_PAPI_PUBLIC_URL, SERVER_MODULE_PAPI_PRIVATE_URL, WEB_APP_BEFORE_INIT_TOKEN, WEB_APP_TOKEN, SERVER_MODULE_PAPI_PRIVATE_ROUTE, SERVER_MODULE_STATICS_OPTIONS, SERVER_TOKEN, READINESS_PROBE_TOKEN, LIVENESS_PROBE_TOKEN, SPECIAL_SERVER_PATHS, PROXY_CONFIG_TOKEN, DEPENDENCIES_VERSION_FILTER_TOKEN, WEB_APP_INIT_TOKEN, WEB_APP_AFTER_INIT_TOKEN, WEB_APP_LIMITER_TOKEN } from '@tramvai/tokens-server';
4
4
  export * from '@tramvai/tokens-server';
5
- import { REQUEST, RESPONSE, RESPONSE_MANAGER_TOKEN, LOGGER_TOKEN as LOGGER_TOKEN$1, ENV_MANAGER_TOKEN as ENV_MANAGER_TOKEN$1, ENV_USED_TOKEN } from '@tramvai/module-common';
5
+ import { WEB_FASTIFY_APP_BEFORE_INIT_TOKEN, WEB_FASTIFY_APP_TOKEN, WEB_FASTIFY_APP_INIT_TOKEN, WEB_FASTIFY_APP_AFTER_INIT_TOKEN, WEB_FASTIFY_APP_LIMITER_TOKEN, WEB_FASTIFY_APP_BEFORE_ERROR_TOKEN, WEB_FASTIFY_APP_PROCESS_ERROR_TOKEN, WEB_FASTIFY_APP_AFTER_ERROR_TOKEN } from '@tramvai/tokens-server-private';
6
+ import { REQUEST, RESPONSE, FASTIFY_REQUEST, FASTIFY_RESPONSE, RESPONSE_MANAGER_TOKEN, LOGGER_TOKEN, ENV_MANAGER_TOKEN, ENV_USED_TOKEN } from '@tramvai/tokens-common';
6
7
  import { MetricsModule } from '@tramvai/module-metrics';
7
8
  import { CacheWarmupModule } from '@tramvai/module-cache-warmup';
8
9
  import http from 'http';
10
+ import fastify from 'fastify';
9
11
  import express from 'express';
10
12
  import cookieParser from 'cookie-parser';
11
13
  import bodyParser from 'body-parser';
12
- import finalhandler from 'finalhandler';
14
+ import { fastifyCookie } from 'fastify-cookie';
15
+ import fastifyFormBody from 'fastify-formbody';
16
+ import fp from 'fastify-plugin';
17
+ import symbols from 'fastify/lib/symbols';
18
+ import isNil from '@tinkoff/utils/is/nil';
13
19
  import { isRedirectFoundError, isNotFoundError, isHttpError } from '@tinkoff/errors';
14
20
  import zlib from 'zlib';
15
21
  import compression from 'compression';
@@ -17,11 +23,10 @@ import os from 'os';
17
23
  import filterObj from '@tinkoff/utils/object/filter';
18
24
  import flatten from '@tinkoff/utils/array/flatten';
19
25
  import toArray from '@tinkoff/utils/array/toArray';
20
- import { REQUEST as REQUEST$1, RESPONSE as RESPONSE$1, LOGGER_TOKEN, ENV_MANAGER_TOKEN } from '@tramvai/tokens-common';
21
26
  import { create, middlewares, getPapiParameters, createPapiMethod } from '@tramvai/papi';
22
27
  import { createChildContainer } from '@tinkoff/dippy';
23
28
  import eachObj from '@tinkoff/utils/object/each';
24
- import { createTerminus } from '@tinkoff/express-terminus';
29
+ import { createTerminus } from '@tinkoff/terminus';
25
30
  import { parse } from '@tinkoff/url';
26
31
  import { EventEmitter } from 'events';
27
32
  import monkeypatch from '@tinkoff/monkeypatch';
@@ -31,10 +36,8 @@ import isObject from '@tinkoff/utils/is/object';
31
36
  import { resolve } from 'path';
32
37
  import { createProxyMiddleware } from 'http-proxy-middleware';
33
38
 
34
- const serverFactory = ({ webApp }) => {
35
- const server = http.createServer();
36
- server.on('request', webApp);
37
- return server;
39
+ const serverFactory = () => {
40
+ return http.createServer();
38
41
  };
39
42
  const serverListenCommand = ({ server, logger, envManager, }) => {
40
43
  const log = logger('server');
@@ -47,88 +50,220 @@ const serverListenCommand = ({ server, logger, envManager, }) => {
47
50
  };
48
51
  };
49
52
 
50
- const routerErrorHandler = (app) => {
51
- app.use((err, req, res, next) => {
52
- if (isRedirectFoundError(err)) {
53
- res.setHeader('cache-control', 'no-cache, no-store, must-revalidate');
54
- return res.redirect(err.httpStatus || 307, err.nextUrl);
53
+ /**
54
+ * Fork of https://github.com/fastify/fastify-express
55
+ */
56
+ const kMiddlewares = Symbol('fastify-express-middlewares');
57
+ const expressPlugin = (fastify, options, next) => {
58
+ var _a, _b;
59
+ fastify.decorate('use', use);
60
+ // eslint-disable-next-line no-param-reassign
61
+ fastify[kMiddlewares] = [];
62
+ fastify.decorate('express', (_b = (_a = options.express) === null || _a === void 0 ? void 0 : _a.instance) !== null && _b !== void 0 ? _b : express());
63
+ fastify.express.disable('x-powered-by');
64
+ fastify
65
+ .addHook('onRequest', enhanceRequest)
66
+ .addHook('onRequest', runConnect)
67
+ .addHook('onRegister', onRegister);
68
+ function use(path, fn) {
69
+ if (typeof path === 'string') {
70
+ const prefix = this[symbols.kRoutePrefix];
71
+ // eslint-disable-next-line no-param-reassign
72
+ path = prefix + (path === '/' && prefix.length > 0 ? '' : path);
55
73
  }
56
- if (isNotFoundError(err)) {
57
- return res.status(404).end();
74
+ this[kMiddlewares].push([path, fn]);
75
+ if (fn == null) {
76
+ this.express.use(path);
58
77
  }
59
- next(err);
60
- });
78
+ else {
79
+ this.express.use(path, fn);
80
+ }
81
+ return this;
82
+ }
83
+ function enhanceRequest(req, reply, next) {
84
+ req.raw.originalUrl = req.raw.url;
85
+ req.raw.id = req.id;
86
+ req.raw.hostname = req.hostname;
87
+ req.raw.ip = req.ip;
88
+ req.raw.ips = req.ips;
89
+ req.raw.log = req.log;
90
+ // eslint-disable-next-line no-param-reassign
91
+ reply.raw.log = req.log;
92
+ const originalProtocol = req.raw.protocol;
93
+ // Make it lazy as it does a bit of work
94
+ Object.defineProperty(req.raw, 'protocol', {
95
+ get() {
96
+ // added in Fastify@3.5, so handle it missing
97
+ return req.protocol || originalProtocol;
98
+ },
99
+ });
100
+ next();
101
+ }
102
+ function runConnect(req, reply, next) {
103
+ if (this[kMiddlewares].length > 0) {
104
+ for (const [headerName, headerValue] of Object.entries(reply.getHeaders())) {
105
+ reply.raw.setHeader(headerName, headerValue);
106
+ }
107
+ this.express(req.raw, reply.raw, next);
108
+ }
109
+ else {
110
+ next();
111
+ }
112
+ }
113
+ function onRegister(instance) {
114
+ const middlewares = instance[kMiddlewares].slice();
115
+ // eslint-disable-next-line no-param-reassign
116
+ instance[kMiddlewares] = [];
117
+ instance.decorate('express', express());
118
+ instance.express.disable('x-powered-by');
119
+ instance.decorate('use', use);
120
+ for (const middleware of middlewares) {
121
+ instance.use(...middleware);
122
+ }
123
+ }
124
+ next();
61
125
  };
62
- const errorHandler = (app, { log, }) => {
63
- app.use(async (err, req, res, next) => {
126
+ const fastifyExpressCompatibility = fp(expressPlugin, {
127
+ fastify: '>=3.0.0',
128
+ name: 'fastify-express',
129
+ });
130
+
131
+ const errorHandler = (app, { log, beforeError, processError, afterError, }) => {
132
+ app.setErrorHandler(async (error, request, reply) => {
133
+ const runHandlers = async (handlers) => {
134
+ if (handlers) {
135
+ for (const handler of handlers) {
136
+ const result = await handler(error, request, reply);
137
+ if (result) {
138
+ return result;
139
+ }
140
+ }
141
+ }
142
+ };
64
143
  const requestInfo = {
65
- ip: req.ip,
66
- requestId: req.headers['x-request-id'],
67
- url: req.url,
144
+ ip: request.ip,
145
+ requestId: request.headers['x-request-id'],
146
+ url: request.url,
68
147
  };
69
- if (isHttpError(err)) {
70
- if (err.httpStatus >= 500) {
71
- log.error({ event: 'send-server-error', error: err, requestInfo });
148
+ const beforeErrorResult = await runHandlers(beforeError);
149
+ if (!isNil(beforeErrorResult)) {
150
+ return beforeErrorResult;
151
+ }
152
+ if (isRedirectFoundError(error)) {
153
+ reply.header('cache-control', 'no-cache, no-store, must-revalidate');
154
+ reply.redirect(error.httpStatus || 307, error.nextUrl);
155
+ return;
156
+ }
157
+ if (isNotFoundError(error)) {
158
+ reply.status(404);
159
+ return '';
160
+ }
161
+ const processErrorResult = await runHandlers(processError);
162
+ if (!isNil(processErrorResult)) {
163
+ return processErrorResult;
164
+ }
165
+ if (isHttpError(error)) {
166
+ if (error.httpStatus >= 500) {
167
+ log.error({ event: 'send-server-error', error, requestInfo });
72
168
  }
73
- return res.status(err.httpStatus).end();
169
+ reply.status(error.httpStatus);
170
+ return '';
171
+ }
172
+ log.error({ event: 'send-server-error', error, requestInfo });
173
+ const afterErrorResult = await runHandlers(afterError);
174
+ if (!isNil(afterErrorResult)) {
175
+ return afterErrorResult;
74
176
  }
75
- log.error({ event: 'send-server-error', error: err, requestInfo });
76
- finalhandler(req, res)(err);
177
+ throw error;
77
178
  });
78
179
  };
79
180
 
80
- const webAppFactory = () => {
181
+ const webAppFactory = ({ server, expressApp, }) => {
182
+ const app = fastify({
183
+ serverFactory: (handler) => {
184
+ server.on('request', handler);
185
+ return server;
186
+ },
187
+ });
188
+ return app;
189
+ };
190
+ const webAppExpressFactory = ({ webApp }) => {
81
191
  const app = express();
82
192
  app.disable('etag');
83
193
  app.disable('x-powered-by');
84
194
  return app;
85
195
  };
86
- const webAppInitCommand = ({ app, logger, commandLineRunner, beforeInit, init, afterInit, limiterRequest, }) => {
196
+ const webAppInitCommand = ({ app, expressApp, logger, commandLineRunner, beforeInit, init, afterInit, limiterRequest, expressBeforeInit, expressInit, expressAfterInit, expressLimiterRequest, beforeError, processError, afterError, }) => {
87
197
  const log = logger('server:webapp');
88
- const runHandlers = (handlers) => {
89
- if (handlers) {
90
- return Promise.all(handlers.map((handler) => handler(app)));
91
- }
198
+ const runHandlers = (handlers, expressHandlers) => {
199
+ return Promise.all([
200
+ handlers && Promise.all(handlers.map((handler) => handler(app))),
201
+ expressHandlers && Promise.all(expressHandlers.map((handler) => handler(expressApp))),
202
+ ]);
92
203
  };
93
204
  return async function webAppInit() {
94
- await runHandlers(beforeInit);
95
- await runHandlers(limiterRequest);
96
- app.use(bodyParser.urlencoded({
205
+ errorHandler(app, { log, beforeError, processError, afterError });
206
+ await app.register(fastifyExpressCompatibility, {
207
+ express: {
208
+ instance: expressApp,
209
+ },
210
+ });
211
+ await runHandlers(beforeInit, expressBeforeInit);
212
+ await runHandlers(limiterRequest, expressLimiterRequest);
213
+ await app.register(fastifyCookie);
214
+ await app.register(fastifyFormBody);
215
+ expressApp.use(bodyParser.urlencoded({
97
216
  limit: '2mb',
98
217
  extended: false,
99
218
  }), cookieParser());
100
- await runHandlers(init);
101
- app.use(async (req, res, next) => {
219
+ await runHandlers(init, expressInit);
220
+ // force express to execute to update server's request and response instances
221
+ app.use((req, res, next) => {
222
+ next();
223
+ });
224
+ app.all('*', async (request, reply) => {
102
225
  try {
103
226
  log.debug({
104
227
  event: 'start:request',
105
228
  message: 'Клиент зашел на страницу',
106
- url: req.url,
229
+ url: request.url,
107
230
  });
108
231
  const di = await commandLineRunner.run('server', 'customer', [
109
232
  {
110
233
  provide: REQUEST,
111
234
  scope: Scope.REQUEST,
112
- useValue: req,
235
+ useValue: request.raw,
113
236
  },
114
237
  {
115
238
  provide: RESPONSE,
116
239
  scope: Scope.REQUEST,
117
- useValue: res,
240
+ useValue: reply.raw,
241
+ },
242
+ // TODO: перевести использование на новые
243
+ // TODO: добавить для papi
244
+ {
245
+ provide: FASTIFY_REQUEST,
246
+ scope: Scope.REQUEST,
247
+ useValue: request,
248
+ },
249
+ {
250
+ provide: FASTIFY_RESPONSE,
251
+ scope: Scope.REQUEST,
252
+ useValue: reply,
118
253
  },
119
254
  ]);
120
255
  const responseManager = di.get(RESPONSE_MANAGER_TOKEN);
121
- if (res.writableEnded) {
256
+ if (reply.sent) {
122
257
  log.debug({
123
258
  event: 'response-ended',
124
259
  message: 'Response was already ended.',
125
- url: req.url,
260
+ url: request.url,
126
261
  });
127
262
  }
128
263
  else {
129
- res
130
- .set('content-type', 'text/html')
131
- .set(responseManager.getHeaders())
264
+ reply
265
+ .header('content-type', 'text/html')
266
+ .headers(responseManager.getHeaders())
132
267
  .status(responseManager.getStatus())
133
268
  .send(responseManager.getBody());
134
269
  }
@@ -136,16 +271,15 @@ const webAppInitCommand = ({ app, logger, commandLineRunner, beforeInit, init, a
136
271
  catch (err) {
137
272
  if (err.di) {
138
273
  const responseManager = err.di.get(RESPONSE_MANAGER_TOKEN);
139
- if (responseManager && !res.writableEnded) {
140
- res.set(responseManager.getHeaders());
274
+ if (responseManager && !reply.sent) {
275
+ reply.headers(responseManager.getHeaders());
141
276
  }
142
277
  }
143
- next(err);
278
+ throw err;
144
279
  }
145
280
  });
146
- routerErrorHandler(app);
147
- await runHandlers(afterInit);
148
- errorHandler(app, { log });
281
+ await runHandlers(afterInit, expressAfterInit);
282
+ await app.ready();
149
283
  };
150
284
  };
151
285
 
@@ -213,11 +347,11 @@ function createApi(papiList, { di, logger }) {
213
347
  var _a;
214
348
  const childDI = createChildContainer(di);
215
349
  childDI.register({
216
- provide: REQUEST$1,
350
+ provide: REQUEST,
217
351
  useValue: req,
218
352
  });
219
353
  childDI.register({
220
- provide: RESPONSE$1,
354
+ provide: RESPONSE,
221
355
  useValue: res,
222
356
  });
223
357
  return { ...rootDeps, ...childDI.getOfDeps((_a = papi.deps) !== null && _a !== void 0 ? _a : {}), req, res };
@@ -235,10 +369,20 @@ try {
235
369
  Api = require('@tramvai/cli/lib/external/api').default; // eslint-disable-line import/no-unresolved
236
370
  }
237
371
  catch (e) { }
238
- const getFileApi = () => {
372
+ const getFileApi = ({ logger }) => {
373
+ const log = logger('papi:fileApi');
239
374
  const result = [];
240
375
  eachObj((v, k) => {
241
376
  const handler = (v.handler || v.default);
377
+ if (!handler) {
378
+ log.error({
379
+ message: `Cannot resolve a papi handler.
380
+ Check that you are using file based papi right way by docs https://tramvai.dev/docs/how-to/how-create-papi#automatic-handler-creation
381
+ 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
382
+ change settings application.commands.build.options.serverApiDir in tramvai.json`,
383
+ });
384
+ throw new Error('Not a papi');
385
+ }
242
386
  const papiParameters = getPapiParameters(handler);
243
387
  result.push(createPapiMethod({
244
388
  ...v,
@@ -252,7 +396,10 @@ const getFileApi = () => {
252
396
  const fileApiProvider = {
253
397
  provide: SERVER_MODULE_PAPI_PUBLIC_ROUTE,
254
398
  multi: true,
255
- useValue: getFileApi(),
399
+ useFactory: getFileApi,
400
+ deps: {
401
+ logger: LOGGER_TOKEN,
402
+ },
256
403
  };
257
404
 
258
405
  const sharedProviders = [
@@ -425,9 +572,9 @@ ServerGracefulShutdownModule = __decorate([
425
572
  Module({
426
573
  providers: [
427
574
  {
428
- provide: WEB_APP_BEFORE_INIT_TOKEN,
575
+ provide: WEB_FASTIFY_APP_BEFORE_INIT_TOKEN,
429
576
  multi: true,
430
- useFactory: ({ server, app, logger, commandLineRunner, livenessProbe, readinessProbe, }) => {
577
+ useFactory: ({ app, server, logger, commandLineRunner, livenessProbe, readinessProbe, }) => {
431
578
  const log = logger('server');
432
579
  return function serverListen() {
433
580
  createTerminus(server, app, {
@@ -470,8 +617,8 @@ ServerGracefulShutdownModule = __decorate([
470
617
  };
471
618
  },
472
619
  deps: {
620
+ app: WEB_FASTIFY_APP_TOKEN,
473
621
  server: SERVER_TOKEN,
474
- app: WEB_APP_TOKEN,
475
622
  logger: LOGGER_TOKEN,
476
623
  commandLineRunner: COMMAND_LINE_RUNNER_TOKEN,
477
624
  readinessProbe: { token: READINESS_PROBE_TOKEN, optional: true },
@@ -737,31 +884,48 @@ ServerModule = __decorate([
737
884
  process.env.NODE_ENV !== 'production' && DebugHttpRequestsModule,
738
885
  ].filter(Boolean),
739
886
  providers: [
740
- {
741
- provide: WEB_APP_TOKEN,
887
+ provide({
888
+ provide: SERVER_TOKEN,
742
889
  scope: Scope.SINGLETON,
890
+ useFactory: serverFactory,
891
+ }),
892
+ provide({
893
+ provide: WEB_FASTIFY_APP_TOKEN,
743
894
  useFactory: webAppFactory,
744
- },
895
+ scope: Scope.SINGLETON,
896
+ deps: {
897
+ server: SERVER_TOKEN,
898
+ },
899
+ }),
900
+ provide({
901
+ // BACKWARD: provide the express app as before
902
+ provide: WEB_APP_TOKEN,
903
+ scope: Scope.SINGLETON,
904
+ useFactory: webAppExpressFactory,
905
+ deps: {
906
+ webApp: WEB_FASTIFY_APP_TOKEN,
907
+ },
908
+ }),
745
909
  {
746
910
  provide: commandLineListTokens.init,
747
911
  multi: true,
748
912
  useFactory: webAppInitCommand,
749
913
  deps: {
750
- app: WEB_APP_TOKEN,
751
- logger: LOGGER_TOKEN$1,
914
+ app: WEB_FASTIFY_APP_TOKEN,
915
+ expressApp: WEB_APP_TOKEN,
916
+ logger: LOGGER_TOKEN,
752
917
  commandLineRunner: COMMAND_LINE_RUNNER_TOKEN,
753
- beforeInit: { token: WEB_APP_BEFORE_INIT_TOKEN, optional: true },
754
- init: { token: WEB_APP_INIT_TOKEN, optional: true },
755
- afterInit: { token: WEB_APP_AFTER_INIT_TOKEN, optional: true },
756
- limiterRequest: { token: WEB_APP_LIMITER_TOKEN, optional: true },
757
- },
758
- },
759
- {
760
- provide: SERVER_TOKEN,
761
- scope: Scope.SINGLETON,
762
- useFactory: serverFactory,
763
- deps: {
764
- webApp: WEB_APP_TOKEN,
918
+ beforeInit: { token: WEB_FASTIFY_APP_BEFORE_INIT_TOKEN, optional: true },
919
+ init: { token: WEB_FASTIFY_APP_INIT_TOKEN, optional: true },
920
+ afterInit: { token: WEB_FASTIFY_APP_AFTER_INIT_TOKEN, optional: true },
921
+ limiterRequest: { token: WEB_FASTIFY_APP_LIMITER_TOKEN, optional: true },
922
+ expressBeforeInit: { token: WEB_APP_BEFORE_INIT_TOKEN, optional: true },
923
+ expressInit: { token: WEB_APP_INIT_TOKEN, optional: true },
924
+ expressAfterInit: { token: WEB_APP_AFTER_INIT_TOKEN, optional: true },
925
+ expressLimiterRequest: { token: WEB_APP_LIMITER_TOKEN, optional: true },
926
+ beforeError: { token: WEB_FASTIFY_APP_BEFORE_ERROR_TOKEN, optional: true },
927
+ processError: { token: WEB_FASTIFY_APP_PROCESS_ERROR_TOKEN, optional: true },
928
+ afterError: { token: WEB_FASTIFY_APP_AFTER_ERROR_TOKEN, optional: true },
765
929
  },
766
930
  },
767
931
  {
@@ -770,8 +934,8 @@ ServerModule = __decorate([
770
934
  useFactory: serverListenCommand,
771
935
  deps: {
772
936
  server: SERVER_TOKEN,
773
- logger: LOGGER_TOKEN$1,
774
- envManager: ENV_MANAGER_TOKEN$1,
937
+ logger: LOGGER_TOKEN,
938
+ envManager: ENV_MANAGER_TOKEN,
775
939
  },
776
940
  },
777
941
  {
@@ -779,8 +943,8 @@ ServerModule = __decorate([
779
943
  multi: true,
780
944
  useFactory: staticAppCommand,
781
945
  deps: {
782
- logger: LOGGER_TOKEN$1,
783
- envManager: ENV_MANAGER_TOKEN$1,
946
+ logger: LOGGER_TOKEN,
947
+ envManager: ENV_MANAGER_TOKEN,
784
948
  appInfo: APP_INFO_TOKEN,
785
949
  },
786
950
  },
@@ -810,7 +974,7 @@ ServerModule = __decorate([
810
974
  useFactory: xHeadersFactory,
811
975
  deps: {
812
976
  app: WEB_APP_TOKEN,
813
- envManager: ENV_MANAGER_TOKEN$1,
977
+ envManager: ENV_MANAGER_TOKEN,
814
978
  appInfo: APP_INFO_TOKEN,
815
979
  },
816
980
  },
package/lib/server.js CHANGED
@@ -5,14 +5,20 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var tslib = require('tslib');
6
6
  var core = require('@tramvai/core');
7
7
  var tokensServer = require('@tramvai/tokens-server');
8
- var moduleCommon = require('@tramvai/module-common');
8
+ var tokensServerPrivate = require('@tramvai/tokens-server-private');
9
+ var tokensCommon = require('@tramvai/tokens-common');
9
10
  var moduleMetrics = require('@tramvai/module-metrics');
10
11
  var moduleCacheWarmup = require('@tramvai/module-cache-warmup');
11
12
  var http = require('http');
13
+ var fastify = require('fastify');
12
14
  var express = require('express');
13
15
  var cookieParser = require('cookie-parser');
14
16
  var bodyParser = require('body-parser');
15
- var finalhandler = require('finalhandler');
17
+ var fastifyCookie = require('fastify-cookie');
18
+ var fastifyFormBody = require('fastify-formbody');
19
+ var fp = require('fastify-plugin');
20
+ var symbols = require('fastify/lib/symbols');
21
+ var isNil = require('@tinkoff/utils/is/nil');
16
22
  var errors = require('@tinkoff/errors');
17
23
  var zlib = require('zlib');
18
24
  var compression = require('compression');
@@ -20,11 +26,10 @@ var os = require('os');
20
26
  var filterObj = require('@tinkoff/utils/object/filter');
21
27
  var flatten = require('@tinkoff/utils/array/flatten');
22
28
  var toArray = require('@tinkoff/utils/array/toArray');
23
- var tokensCommon = require('@tramvai/tokens-common');
24
29
  var papi = require('@tramvai/papi');
25
30
  var dippy = require('@tinkoff/dippy');
26
31
  var eachObj = require('@tinkoff/utils/object/each');
27
- var expressTerminus = require('@tinkoff/express-terminus');
32
+ var terminus = require('@tinkoff/terminus');
28
33
  var url = require('@tinkoff/url');
29
34
  var events = require('events');
30
35
  var monkeypatch = require('@tinkoff/monkeypatch');
@@ -37,10 +42,14 @@ var httpProxyMiddleware = require('http-proxy-middleware');
37
42
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
38
43
 
39
44
  var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
45
+ var fastify__default = /*#__PURE__*/_interopDefaultLegacy(fastify);
40
46
  var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
41
47
  var cookieParser__default = /*#__PURE__*/_interopDefaultLegacy(cookieParser);
42
48
  var bodyParser__default = /*#__PURE__*/_interopDefaultLegacy(bodyParser);
43
- var finalhandler__default = /*#__PURE__*/_interopDefaultLegacy(finalhandler);
49
+ var fastifyFormBody__default = /*#__PURE__*/_interopDefaultLegacy(fastifyFormBody);
50
+ var fp__default = /*#__PURE__*/_interopDefaultLegacy(fp);
51
+ var symbols__default = /*#__PURE__*/_interopDefaultLegacy(symbols);
52
+ var isNil__default = /*#__PURE__*/_interopDefaultLegacy(isNil);
44
53
  var zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib);
45
54
  var compression__default = /*#__PURE__*/_interopDefaultLegacy(compression);
46
55
  var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
@@ -53,10 +62,8 @@ var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
53
62
  var isArray__default = /*#__PURE__*/_interopDefaultLegacy(isArray);
54
63
  var isObject__default = /*#__PURE__*/_interopDefaultLegacy(isObject);
55
64
 
56
- const serverFactory = ({ webApp }) => {
57
- const server = http__default["default"].createServer();
58
- server.on('request', webApp);
59
- return server;
65
+ const serverFactory = () => {
66
+ return http__default["default"].createServer();
60
67
  };
61
68
  const serverListenCommand = ({ server, logger, envManager, }) => {
62
69
  const log = logger('server');
@@ -69,105 +76,236 @@ const serverListenCommand = ({ server, logger, envManager, }) => {
69
76
  };
70
77
  };
71
78
 
72
- const routerErrorHandler = (app) => {
73
- app.use((err, req, res, next) => {
74
- if (errors.isRedirectFoundError(err)) {
75
- res.setHeader('cache-control', 'no-cache, no-store, must-revalidate');
76
- return res.redirect(err.httpStatus || 307, err.nextUrl);
79
+ /**
80
+ * Fork of https://github.com/fastify/fastify-express
81
+ */
82
+ const kMiddlewares = Symbol('fastify-express-middlewares');
83
+ const expressPlugin = (fastify, options, next) => {
84
+ var _a, _b;
85
+ fastify.decorate('use', use);
86
+ // eslint-disable-next-line no-param-reassign
87
+ fastify[kMiddlewares] = [];
88
+ fastify.decorate('express', (_b = (_a = options.express) === null || _a === void 0 ? void 0 : _a.instance) !== null && _b !== void 0 ? _b : express__default["default"]());
89
+ fastify.express.disable('x-powered-by');
90
+ fastify
91
+ .addHook('onRequest', enhanceRequest)
92
+ .addHook('onRequest', runConnect)
93
+ .addHook('onRegister', onRegister);
94
+ function use(path, fn) {
95
+ if (typeof path === 'string') {
96
+ const prefix = this[symbols__default["default"].kRoutePrefix];
97
+ // eslint-disable-next-line no-param-reassign
98
+ path = prefix + (path === '/' && prefix.length > 0 ? '' : path);
77
99
  }
78
- if (errors.isNotFoundError(err)) {
79
- return res.status(404).end();
100
+ this[kMiddlewares].push([path, fn]);
101
+ if (fn == null) {
102
+ this.express.use(path);
80
103
  }
81
- next(err);
82
- });
104
+ else {
105
+ this.express.use(path, fn);
106
+ }
107
+ return this;
108
+ }
109
+ function enhanceRequest(req, reply, next) {
110
+ req.raw.originalUrl = req.raw.url;
111
+ req.raw.id = req.id;
112
+ req.raw.hostname = req.hostname;
113
+ req.raw.ip = req.ip;
114
+ req.raw.ips = req.ips;
115
+ req.raw.log = req.log;
116
+ // eslint-disable-next-line no-param-reassign
117
+ reply.raw.log = req.log;
118
+ const originalProtocol = req.raw.protocol;
119
+ // Make it lazy as it does a bit of work
120
+ Object.defineProperty(req.raw, 'protocol', {
121
+ get() {
122
+ // added in Fastify@3.5, so handle it missing
123
+ return req.protocol || originalProtocol;
124
+ },
125
+ });
126
+ next();
127
+ }
128
+ function runConnect(req, reply, next) {
129
+ if (this[kMiddlewares].length > 0) {
130
+ for (const [headerName, headerValue] of Object.entries(reply.getHeaders())) {
131
+ reply.raw.setHeader(headerName, headerValue);
132
+ }
133
+ this.express(req.raw, reply.raw, next);
134
+ }
135
+ else {
136
+ next();
137
+ }
138
+ }
139
+ function onRegister(instance) {
140
+ const middlewares = instance[kMiddlewares].slice();
141
+ // eslint-disable-next-line no-param-reassign
142
+ instance[kMiddlewares] = [];
143
+ instance.decorate('express', express__default["default"]());
144
+ instance.express.disable('x-powered-by');
145
+ instance.decorate('use', use);
146
+ for (const middleware of middlewares) {
147
+ instance.use(...middleware);
148
+ }
149
+ }
150
+ next();
83
151
  };
84
- const errorHandler = (app, { log, }) => {
85
- app.use(async (err, req, res, next) => {
152
+ const fastifyExpressCompatibility = fp__default["default"](expressPlugin, {
153
+ fastify: '>=3.0.0',
154
+ name: 'fastify-express',
155
+ });
156
+
157
+ const errorHandler = (app, { log, beforeError, processError, afterError, }) => {
158
+ app.setErrorHandler(async (error, request, reply) => {
159
+ const runHandlers = async (handlers) => {
160
+ if (handlers) {
161
+ for (const handler of handlers) {
162
+ const result = await handler(error, request, reply);
163
+ if (result) {
164
+ return result;
165
+ }
166
+ }
167
+ }
168
+ };
86
169
  const requestInfo = {
87
- ip: req.ip,
88
- requestId: req.headers['x-request-id'],
89
- url: req.url,
170
+ ip: request.ip,
171
+ requestId: request.headers['x-request-id'],
172
+ url: request.url,
90
173
  };
91
- if (errors.isHttpError(err)) {
92
- if (err.httpStatus >= 500) {
93
- log.error({ event: 'send-server-error', error: err, requestInfo });
174
+ const beforeErrorResult = await runHandlers(beforeError);
175
+ if (!isNil__default["default"](beforeErrorResult)) {
176
+ return beforeErrorResult;
177
+ }
178
+ if (errors.isRedirectFoundError(error)) {
179
+ reply.header('cache-control', 'no-cache, no-store, must-revalidate');
180
+ reply.redirect(error.httpStatus || 307, error.nextUrl);
181
+ return;
182
+ }
183
+ if (errors.isNotFoundError(error)) {
184
+ reply.status(404);
185
+ return '';
186
+ }
187
+ const processErrorResult = await runHandlers(processError);
188
+ if (!isNil__default["default"](processErrorResult)) {
189
+ return processErrorResult;
190
+ }
191
+ if (errors.isHttpError(error)) {
192
+ if (error.httpStatus >= 500) {
193
+ log.error({ event: 'send-server-error', error, requestInfo });
94
194
  }
95
- return res.status(err.httpStatus).end();
195
+ reply.status(error.httpStatus);
196
+ return '';
197
+ }
198
+ log.error({ event: 'send-server-error', error, requestInfo });
199
+ const afterErrorResult = await runHandlers(afterError);
200
+ if (!isNil__default["default"](afterErrorResult)) {
201
+ return afterErrorResult;
96
202
  }
97
- log.error({ event: 'send-server-error', error: err, requestInfo });
98
- finalhandler__default["default"](req, res)(err);
203
+ throw error;
99
204
  });
100
205
  };
101
206
 
102
- const webAppFactory = () => {
207
+ const webAppFactory = ({ server, expressApp, }) => {
208
+ const app = fastify__default["default"]({
209
+ serverFactory: (handler) => {
210
+ server.on('request', handler);
211
+ return server;
212
+ },
213
+ });
214
+ return app;
215
+ };
216
+ const webAppExpressFactory = ({ webApp }) => {
103
217
  const app = express__default["default"]();
104
218
  app.disable('etag');
105
219
  app.disable('x-powered-by');
106
220
  return app;
107
221
  };
108
- const webAppInitCommand = ({ app, logger, commandLineRunner, beforeInit, init, afterInit, limiterRequest, }) => {
222
+ const webAppInitCommand = ({ app, expressApp, logger, commandLineRunner, beforeInit, init, afterInit, limiterRequest, expressBeforeInit, expressInit, expressAfterInit, expressLimiterRequest, beforeError, processError, afterError, }) => {
109
223
  const log = logger('server:webapp');
110
- const runHandlers = (handlers) => {
111
- if (handlers) {
112
- return Promise.all(handlers.map((handler) => handler(app)));
113
- }
224
+ const runHandlers = (handlers, expressHandlers) => {
225
+ return Promise.all([
226
+ handlers && Promise.all(handlers.map((handler) => handler(app))),
227
+ expressHandlers && Promise.all(expressHandlers.map((handler) => handler(expressApp))),
228
+ ]);
114
229
  };
115
230
  return async function webAppInit() {
116
- await runHandlers(beforeInit);
117
- await runHandlers(limiterRequest);
118
- app.use(bodyParser__default["default"].urlencoded({
231
+ errorHandler(app, { log, beforeError, processError, afterError });
232
+ await app.register(fastifyExpressCompatibility, {
233
+ express: {
234
+ instance: expressApp,
235
+ },
236
+ });
237
+ await runHandlers(beforeInit, expressBeforeInit);
238
+ await runHandlers(limiterRequest, expressLimiterRequest);
239
+ await app.register(fastifyCookie.fastifyCookie);
240
+ await app.register(fastifyFormBody__default["default"]);
241
+ expressApp.use(bodyParser__default["default"].urlencoded({
119
242
  limit: '2mb',
120
243
  extended: false,
121
244
  }), cookieParser__default["default"]());
122
- await runHandlers(init);
123
- app.use(async (req, res, next) => {
245
+ await runHandlers(init, expressInit);
246
+ // force express to execute to update server's request and response instances
247
+ app.use((req, res, next) => {
248
+ next();
249
+ });
250
+ app.all('*', async (request, reply) => {
124
251
  try {
125
252
  log.debug({
126
253
  event: 'start:request',
127
254
  message: 'Клиент зашел на страницу',
128
- url: req.url,
255
+ url: request.url,
129
256
  });
130
257
  const di = await commandLineRunner.run('server', 'customer', [
131
258
  {
132
- provide: moduleCommon.REQUEST,
259
+ provide: tokensCommon.REQUEST,
133
260
  scope: core.Scope.REQUEST,
134
- useValue: req,
261
+ useValue: request.raw,
135
262
  },
136
263
  {
137
- provide: moduleCommon.RESPONSE,
264
+ provide: tokensCommon.RESPONSE,
138
265
  scope: core.Scope.REQUEST,
139
- useValue: res,
266
+ useValue: reply.raw,
267
+ },
268
+ // TODO: перевести использование на новые
269
+ // TODO: добавить для papi
270
+ {
271
+ provide: tokensCommon.FASTIFY_REQUEST,
272
+ scope: core.Scope.REQUEST,
273
+ useValue: request,
274
+ },
275
+ {
276
+ provide: tokensCommon.FASTIFY_RESPONSE,
277
+ scope: core.Scope.REQUEST,
278
+ useValue: reply,
140
279
  },
141
280
  ]);
142
- const responseManager = di.get(moduleCommon.RESPONSE_MANAGER_TOKEN);
143
- if (res.writableEnded) {
281
+ const responseManager = di.get(tokensCommon.RESPONSE_MANAGER_TOKEN);
282
+ if (reply.sent) {
144
283
  log.debug({
145
284
  event: 'response-ended',
146
285
  message: 'Response was already ended.',
147
- url: req.url,
286
+ url: request.url,
148
287
  });
149
288
  }
150
289
  else {
151
- res
152
- .set('content-type', 'text/html')
153
- .set(responseManager.getHeaders())
290
+ reply
291
+ .header('content-type', 'text/html')
292
+ .headers(responseManager.getHeaders())
154
293
  .status(responseManager.getStatus())
155
294
  .send(responseManager.getBody());
156
295
  }
157
296
  }
158
297
  catch (err) {
159
298
  if (err.di) {
160
- const responseManager = err.di.get(moduleCommon.RESPONSE_MANAGER_TOKEN);
161
- if (responseManager && !res.writableEnded) {
162
- res.set(responseManager.getHeaders());
299
+ const responseManager = err.di.get(tokensCommon.RESPONSE_MANAGER_TOKEN);
300
+ if (responseManager && !reply.sent) {
301
+ reply.headers(responseManager.getHeaders());
163
302
  }
164
303
  }
165
- next(err);
304
+ throw err;
166
305
  }
167
306
  });
168
- routerErrorHandler(app);
169
- await runHandlers(afterInit);
170
- errorHandler(app, { log });
307
+ await runHandlers(afterInit, expressAfterInit);
308
+ await app.ready();
171
309
  };
172
310
  };
173
311
 
@@ -257,10 +395,20 @@ try {
257
395
  Api = require('@tramvai/cli/lib/external/api').default; // eslint-disable-line import/no-unresolved
258
396
  }
259
397
  catch (e) { }
260
- const getFileApi = () => {
398
+ const getFileApi = ({ logger }) => {
399
+ const log = logger('papi:fileApi');
261
400
  const result = [];
262
401
  eachObj__default["default"]((v, k) => {
263
402
  const handler = (v.handler || v.default);
403
+ if (!handler) {
404
+ log.error({
405
+ message: `Cannot resolve a papi handler.
406
+ Check that you are using file based papi right way by docs https://tramvai.dev/docs/how-to/how-create-papi#automatic-handler-creation
407
+ 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
408
+ change settings application.commands.build.options.serverApiDir in tramvai.json`,
409
+ });
410
+ throw new Error('Not a papi');
411
+ }
264
412
  const papiParameters = papi.getPapiParameters(handler);
265
413
  result.push(papi.createPapiMethod({
266
414
  ...v,
@@ -274,7 +422,10 @@ const getFileApi = () => {
274
422
  const fileApiProvider = {
275
423
  provide: tokensServer.SERVER_MODULE_PAPI_PUBLIC_ROUTE,
276
424
  multi: true,
277
- useValue: getFileApi(),
425
+ useFactory: getFileApi,
426
+ deps: {
427
+ logger: tokensCommon.LOGGER_TOKEN,
428
+ },
278
429
  };
279
430
 
280
431
  const sharedProviders = [
@@ -447,12 +598,12 @@ ServerGracefulShutdownModule = tslib.__decorate([
447
598
  core.Module({
448
599
  providers: [
449
600
  {
450
- provide: tokensServer.WEB_APP_BEFORE_INIT_TOKEN,
601
+ provide: tokensServerPrivate.WEB_FASTIFY_APP_BEFORE_INIT_TOKEN,
451
602
  multi: true,
452
- useFactory: ({ server, app, logger, commandLineRunner, livenessProbe, readinessProbe, }) => {
603
+ useFactory: ({ app, server, logger, commandLineRunner, livenessProbe, readinessProbe, }) => {
453
604
  const log = logger('server');
454
605
  return function serverListen() {
455
- expressTerminus.createTerminus(server, app, {
606
+ terminus.createTerminus(server, app, {
456
607
  signal: 'SIGTERM',
457
608
  timeout: GRACEFUL_SHUTDOWN_TIMEOUT,
458
609
  logger: (msg, error) => {
@@ -492,8 +643,8 @@ ServerGracefulShutdownModule = tslib.__decorate([
492
643
  };
493
644
  },
494
645
  deps: {
646
+ app: tokensServerPrivate.WEB_FASTIFY_APP_TOKEN,
495
647
  server: tokensServer.SERVER_TOKEN,
496
- app: tokensServer.WEB_APP_TOKEN,
497
648
  logger: tokensCommon.LOGGER_TOKEN,
498
649
  commandLineRunner: core.COMMAND_LINE_RUNNER_TOKEN,
499
650
  readinessProbe: { token: tokensServer.READINESS_PROBE_TOKEN, optional: true },
@@ -759,31 +910,48 @@ exports.ServerModule = tslib.__decorate([
759
910
  process.env.NODE_ENV !== 'production' && DebugHttpRequestsModule,
760
911
  ].filter(Boolean),
761
912
  providers: [
762
- {
763
- provide: tokensServer.WEB_APP_TOKEN,
913
+ core.provide({
914
+ provide: tokensServer.SERVER_TOKEN,
764
915
  scope: core.Scope.SINGLETON,
916
+ useFactory: serverFactory,
917
+ }),
918
+ core.provide({
919
+ provide: tokensServerPrivate.WEB_FASTIFY_APP_TOKEN,
765
920
  useFactory: webAppFactory,
766
- },
921
+ scope: core.Scope.SINGLETON,
922
+ deps: {
923
+ server: tokensServer.SERVER_TOKEN,
924
+ },
925
+ }),
926
+ core.provide({
927
+ // BACKWARD: provide the express app as before
928
+ provide: tokensServer.WEB_APP_TOKEN,
929
+ scope: core.Scope.SINGLETON,
930
+ useFactory: webAppExpressFactory,
931
+ deps: {
932
+ webApp: tokensServerPrivate.WEB_FASTIFY_APP_TOKEN,
933
+ },
934
+ }),
767
935
  {
768
936
  provide: core.commandLineListTokens.init,
769
937
  multi: true,
770
938
  useFactory: webAppInitCommand,
771
939
  deps: {
772
- app: tokensServer.WEB_APP_TOKEN,
773
- logger: moduleCommon.LOGGER_TOKEN,
940
+ app: tokensServerPrivate.WEB_FASTIFY_APP_TOKEN,
941
+ expressApp: tokensServer.WEB_APP_TOKEN,
942
+ logger: tokensCommon.LOGGER_TOKEN,
774
943
  commandLineRunner: core.COMMAND_LINE_RUNNER_TOKEN,
775
- beforeInit: { token: tokensServer.WEB_APP_BEFORE_INIT_TOKEN, optional: true },
776
- init: { token: tokensServer.WEB_APP_INIT_TOKEN, optional: true },
777
- afterInit: { token: tokensServer.WEB_APP_AFTER_INIT_TOKEN, optional: true },
778
- limiterRequest: { token: tokensServer.WEB_APP_LIMITER_TOKEN, optional: true },
779
- },
780
- },
781
- {
782
- provide: tokensServer.SERVER_TOKEN,
783
- scope: core.Scope.SINGLETON,
784
- useFactory: serverFactory,
785
- deps: {
786
- webApp: tokensServer.WEB_APP_TOKEN,
944
+ beforeInit: { token: tokensServerPrivate.WEB_FASTIFY_APP_BEFORE_INIT_TOKEN, optional: true },
945
+ init: { token: tokensServerPrivate.WEB_FASTIFY_APP_INIT_TOKEN, optional: true },
946
+ afterInit: { token: tokensServerPrivate.WEB_FASTIFY_APP_AFTER_INIT_TOKEN, optional: true },
947
+ limiterRequest: { token: tokensServerPrivate.WEB_FASTIFY_APP_LIMITER_TOKEN, optional: true },
948
+ expressBeforeInit: { token: tokensServer.WEB_APP_BEFORE_INIT_TOKEN, optional: true },
949
+ expressInit: { token: tokensServer.WEB_APP_INIT_TOKEN, optional: true },
950
+ expressAfterInit: { token: tokensServer.WEB_APP_AFTER_INIT_TOKEN, optional: true },
951
+ expressLimiterRequest: { token: tokensServer.WEB_APP_LIMITER_TOKEN, optional: true },
952
+ beforeError: { token: tokensServerPrivate.WEB_FASTIFY_APP_BEFORE_ERROR_TOKEN, optional: true },
953
+ processError: { token: tokensServerPrivate.WEB_FASTIFY_APP_PROCESS_ERROR_TOKEN, optional: true },
954
+ afterError: { token: tokensServerPrivate.WEB_FASTIFY_APP_AFTER_ERROR_TOKEN, optional: true },
787
955
  },
788
956
  },
789
957
  {
@@ -792,8 +960,8 @@ exports.ServerModule = tslib.__decorate([
792
960
  useFactory: serverListenCommand,
793
961
  deps: {
794
962
  server: tokensServer.SERVER_TOKEN,
795
- logger: moduleCommon.LOGGER_TOKEN,
796
- envManager: moduleCommon.ENV_MANAGER_TOKEN,
963
+ logger: tokensCommon.LOGGER_TOKEN,
964
+ envManager: tokensCommon.ENV_MANAGER_TOKEN,
797
965
  },
798
966
  },
799
967
  {
@@ -801,13 +969,13 @@ exports.ServerModule = tslib.__decorate([
801
969
  multi: true,
802
970
  useFactory: staticAppCommand,
803
971
  deps: {
804
- logger: moduleCommon.LOGGER_TOKEN,
805
- envManager: moduleCommon.ENV_MANAGER_TOKEN,
972
+ logger: tokensCommon.LOGGER_TOKEN,
973
+ envManager: tokensCommon.ENV_MANAGER_TOKEN,
806
974
  appInfo: core.APP_INFO_TOKEN,
807
975
  },
808
976
  },
809
977
  {
810
- provide: moduleCommon.ENV_USED_TOKEN,
978
+ provide: tokensCommon.ENV_USED_TOKEN,
811
979
  multi: true,
812
980
  useValue: [
813
981
  { key: 'DEV_STATIC', optional: true, dehydrate: false },
@@ -832,7 +1000,7 @@ exports.ServerModule = tslib.__decorate([
832
1000
  useFactory: xHeadersFactory,
833
1001
  deps: {
834
1002
  app: tokensServer.WEB_APP_TOKEN,
835
- envManager: moduleCommon.ENV_MANAGER_TOKEN,
1003
+ envManager: tokensCommon.ENV_MANAGER_TOKEN,
836
1004
  appInfo: core.APP_INFO_TOKEN,
837
1005
  },
838
1006
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tramvai/module-server",
3
- "version": "1.84.0",
3
+ "version": "1.89.1",
4
4
  "description": "",
5
5
  "browser": "lib/browser.js",
6
6
  "main": "lib/server.js",
@@ -20,34 +20,37 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@tinkoff/errors": "0.2.20",
23
- "@tinkoff/express-terminus": "0.1.13",
23
+ "@tinkoff/terminus": "0.0.1",
24
24
  "@tinkoff/monkeypatch": "1.3.3",
25
25
  "@tinkoff/url": "0.7.37",
26
- "@tramvai/module-cache-warmup": "1.84.0",
27
- "@tramvai/module-metrics": "1.84.0",
28
- "@tramvai/papi": "1.84.0",
29
- "@tramvai/tokens-server": "1.84.0",
26
+ "@tramvai/module-cache-warmup": "1.89.1",
27
+ "@tramvai/module-metrics": "1.89.1",
28
+ "@tramvai/papi": "1.89.1",
29
+ "@tramvai/tokens-server": "1.89.1",
30
+ "@tramvai/tokens-server-private": "1.89.1",
30
31
  "body-parser": "^1.19.0",
31
32
  "compression": "^1.7.4",
32
33
  "cookie-parser": "^1.4.3",
33
34
  "express": "^4.17.1",
34
- "finalhandler": "^1.1.2",
35
+ "fastify": "^3.27.4",
36
+ "fastify-cookie": "^5.6.0",
37
+ "fastify-formbody": "^5.2.0",
38
+ "fastify-plugin": "^3.0.1",
35
39
  "http-proxy-middleware": "^2.0.2"
36
40
  },
37
41
  "peerDependencies": {
38
- "@tinkoff/utils": "^2.1.2",
39
- "@tramvai/cli": "1.84.0",
40
- "@tramvai/core": "1.84.0",
41
- "@tramvai/module-common": "1.84.0",
42
- "@tramvai/module-environment": "1.84.0",
43
- "@tramvai/tokens-common": "1.84.0",
44
42
  "@tinkoff/dippy": "0.7.39",
43
+ "@tinkoff/utils": "^2.1.2",
44
+ "@tramvai/cli": "1.89.1",
45
+ "@tramvai/core": "1.89.1",
46
+ "@tramvai/module-common": "1.89.1",
47
+ "@tramvai/module-environment": "1.89.1",
48
+ "@tramvai/tokens-common": "1.89.1",
45
49
  "tslib": "^2.0.3"
46
50
  },
47
51
  "devDependencies": {
48
52
  "@types/compression": "^1.7.0",
49
53
  "@types/express": "^4.17.9",
50
- "@types/finalhandler": "^1.1.0",
51
54
  "@types/http-proxy-middleware": "^0.19.3"
52
55
  },
53
56
  "module": "lib/server.es.js",