diff --git a/package.json b/package.json index f8a49fe..f866fab 100644 --- a/package.json +++ b/package.json @@ -141,29 +141,11 @@ "import": "./dist/esm/preset/node/index.js", "default": "./dist/esm/preset/node/index.js" }, - "./preset/node/node/providers": { - "types": "./dist/types/preset/node/node/providers/index.d.ts", - "require": "./dist/cjs/preset/node/node/providers/index.js", - "import": "./dist/esm/preset/node/node/providers/index.js", - "default": "./dist/esm/preset/node/node/providers/index.js" - }, - "./preset/node/node/utils": { - "types": "./dist/types/preset/node/node/utils/index.d.ts", - "require": "./dist/cjs/preset/node/node/utils/index.js", - "import": "./dist/esm/preset/node/node/utils/index.js", - "default": "./dist/esm/preset/node/node/utils/index.js" - }, - "./preset/node/handler/providers": { - "types": "./dist/types/preset/node/handler/providers/index.d.ts", - "require": "./dist/cjs/preset/node/handler/providers/index.js", - "import": "./dist/esm/preset/node/handler/providers/index.js", - "default": "./dist/esm/preset/node/handler/providers/index.js" - }, - "./preset/node/handler/utils": { - "types": "./dist/types/preset/node/handler/utils/index.d.ts", - "require": "./dist/cjs/preset/node/handler/utils/index.js", - "import": "./dist/esm/preset/node/handler/utils/index.js", - "default": "./dist/esm/preset/node/handler/utils/index.js" + "./preset/node-handler": { + "types": "./dist/types/preset/node-handler/index.d.ts", + "require": "./dist/cjs/preset/node-handler/index.js", + "import": "./dist/esm/preset/node-handler/index.js", + "default": "./dist/esm/preset/node-handler/index.js" }, "./preset/bun": { "types": "./dist/types/preset/bun/index.d.ts", @@ -270,17 +252,8 @@ "preset/node": [ "./dist/types/preset/node/index.d.ts" ], - "preset/node/node/providers": [ - "./dist/types/preset/node/node/providers/index.d.ts" - ], - "preset/node/node/utils": [ - "./dist/types/preset/node/node/utils/index.d.ts" - ], - "preset/node/handler/providers": [ - "./dist/types/preset/node/handler/providers/index.d.ts" - ], - "preset/node/handler/utils": [ - "./dist/types/preset/node/handler/utils/index.d.ts" + "preset/node-handler": [ + "./dist/types/preset/node-handler/index.d.ts" ], "preset/bun": [ "./dist/types/preset/bun/index.d.ts" diff --git a/src/preset/bun-handler/index.ts b/src/preset/bun-handler/index.ts index c722bec..679b0d0 100644 --- a/src/preset/bun-handler/index.ts +++ b/src/preset/bun-handler/index.ts @@ -7,8 +7,8 @@ import { provideFetch, provideReduxMiddlewareSaga, } from '../isomorphic/providers'; -import { providePageRender } from '../node/handler/providers'; -import { SpecificExtras } from '../node/handler/utils'; +import { providePageRender } from '../node-handler/providers'; +import { SpecificExtras } from '../node-handler/utils'; import { HandlerProviders } from './providers'; /** diff --git a/src/preset/bun-handler/providers/index.tsx b/src/preset/bun-handler/providers/index.tsx index 3560a59..7bcdc96 100644 --- a/src/preset/bun-handler/providers/index.tsx +++ b/src/preset/bun-handler/providers/index.tsx @@ -2,7 +2,7 @@ import { renderToString } from 'react-dom/server'; import { Resolve } from '../../../di'; import { KnownToken } from '../../../tokens'; -import { HelmetContext, RegularHelmet } from '../../node/handler/utils'; +import { HelmetContext, RegularHelmet } from '../../node-handler/utils'; import { CookieStore, Middleware, diff --git a/src/preset/bun/index.ts b/src/preset/bun/index.ts index ec41e64..04514a9 100644 --- a/src/preset/bun/index.ts +++ b/src/preset/bun/index.ts @@ -2,7 +2,7 @@ import { createPreset } from '../../di'; import { KnownToken } from '../../tokens'; import { PresetTuner } from '../isomorphic'; import { provideBaseConfig } from '../isomorphic/providers'; -import { provideKnownHttpApiHosts, provideSsrBridgeServerSide } from '../node/node/providers'; +import { provideKnownHttpApiHosts, provideSsrBridgeServerSide } from '../node/providers'; import { BunProviders } from './providers'; /** diff --git a/src/preset/bun/providers/index.ts b/src/preset/bun/providers/index.ts index 347489c..66bf320 100644 --- a/src/preset/bun/providers/index.ts +++ b/src/preset/bun/providers/index.ts @@ -4,7 +4,7 @@ import { KnownToken } from '../../../tokens'; import { ConfigSource, createConfigSource } from '../../../config'; import { Logger, createLogger } from '../../../log'; import { Handler, Middleware } from '../../../http'; -import { providePinoHandler } from '../../node/node/providers'; +import { providePinoHandler } from '../../node/providers'; import { route, router } from '@krutoo/fetch-tools'; import { getCurrentHub, init, runWithAsyncContext } from '@sentry/bun'; import { createSentryHandler } from '../../../log/handler/sentry'; diff --git a/src/preset/node/handler/index.ts b/src/preset/node-handler/index.ts similarity index 90% rename from src/preset/node/handler/index.ts rename to src/preset/node-handler/index.ts index d105ee1..35c9b55 100644 --- a/src/preset/node/handler/index.ts +++ b/src/preset/node-handler/index.ts @@ -1,11 +1,11 @@ -import { Preset, createPreset } from '../../../di'; -import { KnownToken } from '../../../tokens'; +import { Preset, createPreset } from '../../di'; +import { KnownToken } from '../../tokens'; import { provideReduxMiddlewareSaga, provideFetch, provideAbortController, -} from '../../isomorphic/providers'; -import { PresetTuner } from '../../isomorphic/types'; +} from '../isomorphic/providers'; +import { PresetTuner } from '../isomorphic/types'; import { provideAxiosMiddleware, provideAxiosLogHandler, @@ -59,5 +59,3 @@ export function PresetHandler(customize?: PresetTuner): Preset { return preset; } - -export { HandlerProvider } from './utils'; diff --git a/src/preset/node/handler/providers/index.tsx b/src/preset/node-handler/providers/index.tsx similarity index 93% rename from src/preset/node/handler/providers/index.tsx rename to src/preset/node-handler/providers/index.tsx index 8e03576..4e4b1dd 100644 --- a/src/preset/node/handler/providers/index.tsx +++ b/src/preset/node-handler/providers/index.tsx @@ -6,27 +6,27 @@ import { cookie, createCookieStore, defaultHeaders, -} from '../../../../http'; -import type { Resolve } from '../../../../di'; -import { KnownToken } from '../../../../tokens'; +} from '../../../http'; +import type { Resolve } from '../../../di'; +import { KnownToken } from '../../../tokens'; import { getForwardedHeaders as getForwardedHeadersExpress, axiosTracingMiddleware, } from '../../node/utils/http-client'; import type { Middleware as AxiosMiddleware } from 'middleware-axios'; -import { AxiosLogging } from '../../../isomorphic/utils/axios-logging'; -import { FetchLogging } from '../../../isomorphic/utils/fetch-logging'; -import { HttpStatus } from '../../../isomorphic/utils/http-status'; -import { getFetchLogging } from '../../../isomorphic/utils/get-fetch-logging'; -import { getFetchErrorLogging } from '../../../isomorphic/utils/get-fetch-error-logging'; -import { getFetchExtraAborting } from '../../../isomorphic/utils/get-fetch-extra-aborting'; -import { LogMiddlewareHandlerInit, cookieMiddleware, logMiddleware } from '../../../../utils/axios'; -import { PAGE_HANDLER_EVENT_TYPE } from '../../../server/constants'; -import type { ConventionalJson } from '../../../isomorphic/types'; +import { AxiosLogging } from '../../isomorphic/utils/axios-logging'; +import { FetchLogging } from '../../isomorphic/utils/fetch-logging'; +import { HttpStatus } from '../../isomorphic/utils/http-status'; +import { getFetchLogging } from '../../isomorphic/utils/get-fetch-logging'; +import { getFetchErrorLogging } from '../../isomorphic/utils/get-fetch-error-logging'; +import { getFetchExtraAborting } from '../../isomorphic/utils/get-fetch-extra-aborting'; +import { LogMiddlewareHandlerInit, cookieMiddleware, logMiddleware } from '../../../utils/axios'; +import { PAGE_HANDLER_EVENT_TYPE } from '../../server/constants'; +import type { ConventionalJson } from '../../isomorphic/types'; import { Fragment } from 'react'; import { HelmetContext, RegularHelmet, getPageResponseFormat } from '../utils'; import { renderToString } from 'react-dom/server'; -import { getFetchTracing } from '../../../server/utils/get-fetch-tracing'; +import { getFetchTracing } from '../../server/utils/get-fetch-tracing'; /** * Провайдер главной функции обработчика входящего http-запроса. diff --git a/src/preset/node/handler/utils/index.tsx b/src/preset/node-handler/utils/index.tsx similarity index 72% rename from src/preset/node/handler/utils/index.tsx rename to src/preset/node-handler/utils/index.tsx index 4db4819..0aa3dee 100644 --- a/src/preset/node/handler/utils/index.tsx +++ b/src/preset/node-handler/utils/index.tsx @@ -1,9 +1,10 @@ import { ReactNode, createContext, useContext } from 'react'; -import { PageAssets } from '../../../isomorphic/types'; -import { Handler, Request } from 'express'; -import { Application, CURRENT_APP, Resolve } from '../../../../di'; -import { KnownToken } from '../../../../tokens'; +import { PageAssets } from '../../isomorphic/types'; +import express from 'express'; +/** + * @todo Перенести в preset/server. + */ export const HelmetContext = createContext<{ title?: string; assets?: PageAssets }>({}); const resetCSS = ` @@ -21,6 +22,7 @@ body { * Выведет html, head и body. * @param props Свойства. * @return Элемент. + * @todo Перенести в preset/server. */ export function RegularHelmet({ children }: { children?: ReactNode }) { const { title, assets } = useContext(HelmetContext); @@ -52,6 +54,7 @@ export function RegularHelmet({ children }: { children?: ReactNode }) { /** * Специфичные для наших микросервисов дополнительные данные ответа. + * @todo Перенести в preset/server. */ export class SpecificExtras { private _meta: any; @@ -80,7 +83,7 @@ export class SpecificExtras { * @param req Запрос. * @return Формат. */ -export function getPageResponseFormat(req: Request): 'html' | 'json' { +export function getPageResponseFormat(req: express.Request): 'html' | 'json' { let result: 'html' | 'json' = 'html'; if ((req.header('accept') || '').toLowerCase().includes('application/json')) { @@ -89,22 +92,3 @@ export function getPageResponseFormat(req: Request): 'html' | 'json' { return result; } - -/** - * Возвращает express-handler, создающий дочернее di-приложение при запросе. - * @param getApp Должна вернуть di-приложения запроса. - * @return Обработчик. - */ -export function HandlerProvider(getApp: () => Application) { - return (resolve: Resolve): Handler => { - const parent = resolve(CURRENT_APP); - - return (req, res, next) => { - const app = getApp(); - - app.attach(parent); - app.bind(KnownToken.ExpressHandler.context).toValue({ req, res, next }); - app.get(KnownToken.ExpressHandler.main)(); - }; - }; -} diff --git a/src/preset/node/index.ts b/src/preset/node/index.ts index 1fd5b24..bc212da 100644 --- a/src/preset/node/index.ts +++ b/src/preset/node/index.ts @@ -1,3 +1,79 @@ -export type { ExpressHandlerContext } from './types'; -export { PresetNode } from './node'; -export { PresetHandler, HandlerProvider } from './handler'; +import { KnownToken } from '../../tokens'; +import { provideAxiosFactory, provideBaseConfig, provideFetch } from '../isomorphic/providers'; +import { Preset, createPreset } from '../../di'; +import { PresetTuner } from '../isomorphic/types'; +import { healthCheck } from '../../utils/express/handler/health-check'; +import { + provideConfigSource, + provideExpressErrorMiddleware, + provideExpressFactory, + provideExpressLogMiddleware, + provideExpressMetricsMiddleware, + provideExpressRequestMiddleware, + provideExpressTracingMiddleware, + provideKnownHttpApiHosts, + provideLogger, + provideMetricsHttpApp, + provideSpanExporter, + provideSsrBridgeServerSide, + provideTracer, + provideTracerProvider, + provideTracerProviderResource, +} from './providers'; + +/** + * Возвращает preset с зависимостями по умолчанию для frontend-микросервисов на Node.js. + * @param customize Получит функцию с помощью которой можно переопределить предустановленные провайдеры. + * @return Preset. + */ +export function PresetNode(customize?: PresetTuner): Preset { + // ВАЖНО: используем .set() вместо аргумента defaults функции createPreset из-за скорости + const preset = createPreset(); + + // config + preset.set(KnownToken.Config.source, provideConfigSource); + preset.set(KnownToken.Config.base, provideBaseConfig); + + // log + preset.set(KnownToken.logger, provideLogger); + + // tracing + preset.set(KnownToken.Tracing.tracer, provideTracer); + preset.set(KnownToken.Tracing.spanExporter, provideSpanExporter); + preset.set(KnownToken.Tracing.tracerProvider, provideTracerProvider); + preset.set(KnownToken.Tracing.tracerProviderResource, provideTracerProviderResource); + + // metrics + preset.set(KnownToken.Metrics.httpApp, provideMetricsHttpApp); + + // fetch + preset.set(KnownToken.Http.fetch, provideFetch); + preset.set(KnownToken.Http.Fetch.middleware, () => []); + + // axios + preset.set(KnownToken.Axios.factory, provideAxiosFactory); + preset.set(KnownToken.Axios.middleware, () => []); + + // express + preset.set(KnownToken.Express.factory, provideExpressFactory); + preset.set(KnownToken.Express.Handlers.healthCheck, healthCheck); + preset.set(KnownToken.Express.Middleware.request, provideExpressRequestMiddleware); + preset.set(KnownToken.Express.Middleware.log, provideExpressLogMiddleware); + preset.set(KnownToken.Express.Middleware.metrics, provideExpressMetricsMiddleware); + preset.set(KnownToken.Express.Middleware.tracing, provideExpressTracingMiddleware); + preset.set(KnownToken.Express.Middleware.error, provideExpressErrorMiddleware); + + // http api + preset.set(KnownToken.Http.Api.knownHosts, provideKnownHttpApiHosts); + + // ssr bridge + preset.set(KnownToken.SsrBridge.serverSide, provideSsrBridgeServerSide); + + if (customize) { + customize({ override: preset.set.bind(preset) }); + } + + return preset; +} + +export { HandlerProvider } from './utils/handler-provider'; diff --git a/src/preset/node/node/index.ts b/src/preset/node/node/index.ts deleted file mode 100644 index 2940fba..0000000 --- a/src/preset/node/node/index.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { KnownToken } from '../../../tokens'; -import { provideAxiosFactory, provideBaseConfig, provideFetch } from '../../isomorphic/providers'; -import { Preset, createPreset } from '../../../di'; -import { PresetTuner } from '../../isomorphic/types'; -import { healthCheck } from '../../../utils/express/handler/health-check'; -import { - provideConfigSource, - provideExpressErrorMiddleware, - provideExpressFactory, - provideExpressLogMiddleware, - provideExpressMetricsMiddleware, - provideExpressRequestMiddleware, - provideExpressTracingMiddleware, - provideKnownHttpApiHosts, - provideLogger, - provideMetricsHttpApp, - provideSpanExporter, - provideSsrBridgeServerSide, - provideTracer, - provideTracerProvider, - provideTracerProviderResource, -} from './providers'; - -/** - * Возвращает preset с зависимостями по умолчанию для frontend-микросервисов на Node.js. - * @param customize Получит функцию с помощью которой можно переопределить предустановленные провайдеры. - * @return Preset. - */ -export function PresetNode(customize?: PresetTuner): Preset { - // ВАЖНО: используем .set() вместо аргумента defaults функции createPreset из-за скорости - const preset = createPreset(); - - // config - preset.set(KnownToken.Config.source, provideConfigSource); - preset.set(KnownToken.Config.base, provideBaseConfig); - - // log - preset.set(KnownToken.logger, provideLogger); - - // tracing - preset.set(KnownToken.Tracing.tracer, provideTracer); - preset.set(KnownToken.Tracing.spanExporter, provideSpanExporter); - preset.set(KnownToken.Tracing.tracerProvider, provideTracerProvider); - preset.set(KnownToken.Tracing.tracerProviderResource, provideTracerProviderResource); - - // metrics - preset.set(KnownToken.Metrics.httpApp, provideMetricsHttpApp); - - // fetch - preset.set(KnownToken.Http.fetch, provideFetch); - preset.set(KnownToken.Http.Fetch.middleware, () => []); - - // axios - preset.set(KnownToken.Axios.factory, provideAxiosFactory); - preset.set(KnownToken.Axios.middleware, () => []); - - // express - preset.set(KnownToken.Express.factory, provideExpressFactory); - preset.set(KnownToken.Express.Handlers.healthCheck, healthCheck); - preset.set(KnownToken.Express.Middleware.request, provideExpressRequestMiddleware); - preset.set(KnownToken.Express.Middleware.log, provideExpressLogMiddleware); - preset.set(KnownToken.Express.Middleware.metrics, provideExpressMetricsMiddleware); - preset.set(KnownToken.Express.Middleware.tracing, provideExpressTracingMiddleware); - preset.set(KnownToken.Express.Middleware.error, provideExpressErrorMiddleware); - - // http api - preset.set(KnownToken.Http.Api.knownHosts, provideKnownHttpApiHosts); - - // ssr bridge - preset.set(KnownToken.SsrBridge.serverSide, provideSsrBridgeServerSide); - - if (customize) { - customize({ override: preset.set.bind(preset) }); - } - - return preset; -} diff --git a/src/preset/node/node/providers/index.ts b/src/preset/node/providers/index.ts similarity index 95% rename from src/preset/node/node/providers/index.ts rename to src/preset/node/providers/index.ts index 27deb11..b776fe5 100644 --- a/src/preset/node/node/providers/index.ts +++ b/src/preset/node/providers/index.ts @@ -1,15 +1,15 @@ -import type { ConventionalFluentInfo, Logger, LogHandler } from '../../../../log/types'; -import { BridgeServerSide, SsrBridge } from '../../../../utils/ssr'; -import { ConfigSource, createConfigSource } from '../../../../config'; -import { createLogger } from '../../../../log'; -import { createPinoHandler } from '../../../../log/handler/pino'; -import { createSentryHandler } from '../../../../log/handler/sentry'; -import { HttpApiHostPool } from '../../../isomorphic/utils/http-api-host-pool'; -import { KnownToken } from '../../../../tokens'; -import { Resolve } from '../../../../di'; -import { KnownHttpApiKey } from '../../../isomorphic/types'; -import { toMilliseconds } from '../../../../utils'; -import { PAGE_HANDLER_EVENT_TYPE } from '../../../server/constants'; +import type { ConventionalFluentInfo, Logger, LogHandler } from '../../../log/types'; +import { BridgeServerSide, SsrBridge } from '../../../utils/ssr'; +import { ConfigSource, createConfigSource } from '../../../config'; +import { createLogger } from '../../../log'; +import { createPinoHandler } from '../../../log/handler/pino'; +import { createSentryHandler } from '../../../log/handler/sentry'; +import { HttpApiHostPool } from '../../isomorphic/utils/http-api-host-pool'; +import { KnownToken } from '../../../tokens'; +import { Resolve } from '../../../di'; +import { KnownHttpApiKey } from '../../isomorphic/types'; +import { toMilliseconds } from '../../../utils'; +import { PAGE_HANDLER_EVENT_TYPE } from '../../server/constants'; import { getClientIp } from '../utils/http-server'; // Node.js specific packages diff --git a/src/preset/node/utils/handler-provider.ts b/src/preset/node/utils/handler-provider.ts new file mode 100644 index 0000000..d4b5ab1 --- /dev/null +++ b/src/preset/node/utils/handler-provider.ts @@ -0,0 +1,22 @@ +import type express from 'express'; +import { KnownToken } from '../../../tokens'; +import { CURRENT_APP, type Application, type Provider, type Resolve } from '../../../di'; + +/** + * Возвращает express-handler, создающий дочернее di-приложение при запросе. + * @param getApp Должна вернуть di-приложения запроса. + * @return Обработчик. + */ +export function HandlerProvider(getApp: () => Application): Provider { + return (resolve: Resolve): express.Handler => { + const parent = resolve(CURRENT_APP); + + return (req, res, next) => { + const app = getApp(); + + app.attach(parent); + app.bind(KnownToken.ExpressHandler.context).toValue({ req, res, next }); + app.get(KnownToken.ExpressHandler.main)(); + }; + }; +} diff --git a/src/preset/node/node/utils/http-client/__test__/index.test.ts b/src/preset/node/utils/http-client/__test__/index.test.ts similarity index 99% rename from src/preset/node/node/utils/http-client/__test__/index.test.ts rename to src/preset/node/utils/http-client/__test__/index.test.ts index e404ccc..b7a2c00 100644 --- a/src/preset/node/node/utils/http-client/__test__/index.test.ts +++ b/src/preset/node/utils/http-client/__test__/index.test.ts @@ -2,7 +2,7 @@ import { Context } from '@opentelemetry/api'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; import { Span, Tracer } from '@opentelemetry/sdk-trace-base'; import { axiosTracingMiddleware, getRequestInfo, getForwardedHeaders } from '..'; -import { BaseConfig } from '../../../../../../config'; +import { BaseConfig } from '../../../../../config'; import express from 'express'; describe('axiosTracingMiddleware', () => { diff --git a/src/preset/node/node/utils/http-client/index.ts b/src/preset/node/utils/http-client/index.ts similarity index 94% rename from src/preset/node/node/utils/http-client/index.ts rename to src/preset/node/utils/http-client/index.ts index ff4d8c6..218498c 100644 --- a/src/preset/node/node/utils/http-client/index.ts +++ b/src/preset/node/utils/http-client/index.ts @@ -3,10 +3,10 @@ import type { Middleware } from 'middleware-axios'; import type express from 'express'; import { Context, Tracer, SpanStatusCode } from '@opentelemetry/api'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; -import { BaseConfig } from '../../../../../config'; +import { BaseConfig } from '../../../../config'; import { getClientIp } from '../http-server'; -import { displayUrl } from '../../../../isomorphic/utils/display-url'; -import { hideFirstId } from '../../../../isomorphic/utils/hide-first-id'; +import { displayUrl } from '../../../isomorphic/utils/display-url'; +import { hideFirstId } from '../../../isomorphic/utils/hide-first-id'; /** * Возвращает новый middleware для трассировки исходящих запросов. diff --git a/src/preset/node/node/utils/http-server/index.ts b/src/preset/node/utils/http-server/index.ts similarity index 100% rename from src/preset/node/node/utils/http-server/index.ts rename to src/preset/node/utils/http-server/index.ts diff --git a/src/preset/node/node/utils/index.ts b/src/preset/node/utils/index.ts similarity index 100% rename from src/preset/node/node/utils/index.ts rename to src/preset/node/utils/index.ts diff --git a/src/tokens.ts b/src/tokens.ts index 0042613..7861fb7 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -14,7 +14,7 @@ import type { Resource } from '@opentelemetry/resources'; import type { ElementType, ReactNode } from 'react'; import type { KnownHttpApiKey, PageAssets } from './preset/isomorphic/types'; import type { ExpressHandlerContext } from './preset/node/types'; -import type { SpecificExtras } from './preset/node/handler/utils'; +import type { SpecificExtras } from './preset/node-handler/utils'; import type { CreateAxiosDefaults } from 'axios'; import type { AxiosInstanceWrapper, Middleware as AxiosMiddleware } from 'middleware-axios'; import type { CookieStore, Handler, LogHandler, LogHandlerFactory, Middleware } from './http';