From 1155dd6999d2b07152114c6805ae563f96ac0806 Mon Sep 17 00:00:00 2001 From: krutoo Date: Tue, 12 Mar 2024 14:42:16 +0500 Subject: [PATCH 1/2] #38 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - добавлены комменты с кодом проброса кук из входящих ответов (patch) --- src/preset/bun-handler/providers/index.tsx | 17 +++++++++++++++ .../node-handler/providers/cookie-store.ts | 21 +++---------------- .../node-handler/providers/handler-main.tsx | 10 +++++++++ 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/preset/bun-handler/providers/index.tsx b/src/preset/bun-handler/providers/index.tsx index 9398c18..66646dc 100644 --- a/src/preset/bun-handler/providers/index.tsx +++ b/src/preset/bun-handler/providers/index.tsx @@ -35,6 +35,13 @@ export const HandlerProviders = { const abortController = resolve(KnownToken.Http.Fetch.abortController); const context = resolve(KnownToken.Http.Handler.context); + // @todo https://github.com/sima-land/isomorph/issues/69 + // const cookieStore = resolve(KnownToken.Http.Fetch.cookieStore); + // const forwardedSetCookie: string[] = []; + // const unsubscribeCookieStore = cookieStore.subscribe(setCookieList => { + // forwardedSetCookie.push(...setCookieList); + // }); + const getAssets = typeof assetsInit === 'function' ? assetsInit : () => assetsInit; const elementToString = (element: JSX.Element) => { @@ -137,6 +144,16 @@ export const HandlerProviders = { }; const enhancer = applyMiddleware( + // @todo https://github.com/sima-land/isomorph/issues/69 + // async (request, next) => { + // const response = await next(request); + // for (const item of forwardedSetCookie) { + // response.headers.append('set-cookie', item); + // } + // unsubscribeCookieStore(); + // return response; + // }, + // ВАЖНО: прерываем исходящие в рамках обработчика http-запросы async (request, next) => { const response = await next(request); diff --git a/src/preset/node-handler/providers/cookie-store.ts b/src/preset/node-handler/providers/cookie-store.ts index b444e1a..18256cb 100644 --- a/src/preset/node-handler/providers/cookie-store.ts +++ b/src/preset/node-handler/providers/cookie-store.ts @@ -1,5 +1,5 @@ -import { createCookieStore } from '../../../http'; import type { Resolve } from '../../../di'; +import { CookieStore, createCookieStore } from '../../../http'; import { KnownToken } from '../../../tokens'; /** @@ -7,23 +7,8 @@ import { KnownToken } from '../../../tokens'; * @param resolve Функция для получения зависимости по токену. * @return Хранилище cookie. */ -export function provideCookieStore(resolve: Resolve) { +export function provideCookieStore(resolve: Resolve): CookieStore { const context = resolve(KnownToken.ExpressHandler.context); - const store = createCookieStore(context.req.header('cookie')); - - // @todo - // store.subscribe(setCookieList => { - // for (const setCookie of setCookieList) { - // const parsed = parseSetCookieHeader(setCookie); - - // if (!parsed) { - // return; - // } - - // context.res.cookie(parsed.name, parsed.value, parsed.attrs); - // } - // }); - - return store; + return createCookieStore(context.req.header('cookie')); } diff --git a/src/preset/node-handler/providers/handler-main.tsx b/src/preset/node-handler/providers/handler-main.tsx index 1cf6731..37f254f 100644 --- a/src/preset/node-handler/providers/handler-main.tsx +++ b/src/preset/node-handler/providers/handler-main.tsx @@ -37,6 +37,16 @@ export function provideHandlerMain(resolve: Resolve): VoidFunction { return result; }; + // @todo https://github.com/sima-land/isomorph/issues/69 + // const cookieStore = resolve(KnownToken.Http.Fetch.cookieStore); + // cookieStore.subscribe(setCookieList => { + // for (const setCookie of setCookieList) { + // const parsed = parseSetCookieHeader(setCookie); + + // parsed && res.cookie(parsed.name, parsed.value, parsed.attrs); + // } + // }); + return async () => { try { const assets = await getAssets(); From 782b8bb16b7496e3b811aa599aaa749d86a7b6c6 Mon Sep 17 00:00:00 2001 From: krutoo Date: Tue, 12 Mar 2024 14:48:18 +0500 Subject: [PATCH 2/2] #38 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - preset/web: модуль провайдеров разбит на отдельные модули по провайдерам (patch) --- src/preset/web/index.ts | 16 +-- src/preset/web/providers/axios-middleware.ts | 15 ++ src/preset/web/providers/config-source.ts | 14 ++ src/preset/web/providers/fetch-middleware.ts | 16 +++ src/preset/web/providers/index.ts | 130 ------------------ .../web/providers/known-http-api-hosts.ts | 24 ++++ src/preset/web/providers/logger.ts | 55 ++++++++ .../web/providers/ssr-bridge-client-side.ts | 14 ++ 8 files changed, 145 insertions(+), 139 deletions(-) create mode 100644 src/preset/web/providers/axios-middleware.ts create mode 100644 src/preset/web/providers/config-source.ts create mode 100644 src/preset/web/providers/fetch-middleware.ts delete mode 100644 src/preset/web/providers/index.ts create mode 100644 src/preset/web/providers/known-http-api-hosts.ts create mode 100644 src/preset/web/providers/logger.ts create mode 100644 src/preset/web/providers/ssr-bridge-client-side.ts diff --git a/src/preset/web/index.ts b/src/preset/web/index.ts index c615489..0f0bfa7 100644 --- a/src/preset/web/index.ts +++ b/src/preset/web/index.ts @@ -8,14 +8,12 @@ import { provideAxiosLogHandler, provideReduxMiddlewareSaga, } from '../isomorphic/providers'; -import { - provideConfigSource, - provideLogger, - provideKnownHttpApiHosts, - provideFetchMiddleware, - provideAxiosMiddleware, - provideBridgeClientSide, -} from './providers'; +import { provideConfigSource } from './providers/config-source'; +import { provideLogger } from './providers/logger'; +import { provideKnownHttpApiHosts } from './providers/known-http-api-hosts'; +import { provideFetchMiddleware } from './providers/fetch-middleware'; +import { provideAxiosMiddleware } from './providers/axios-middleware'; +import { provideSsrBridgeClientSide } from './providers/ssr-bridge-client-side'; /** * Возвращает preset с зависимостями для frontend-микросервисов в браузере. @@ -33,7 +31,7 @@ export function PresetWeb(customize?: PresetTuner): Preset { preset.set(KnownToken.Axios.factory, provideAxiosFactory); preset.set(KnownToken.Axios.middleware, provideAxiosMiddleware); preset.set(KnownToken.Axios.Middleware.Log.handler, provideAxiosLogHandler); - preset.set(KnownToken.SsrBridge.clientSide, provideBridgeClientSide); + preset.set(KnownToken.SsrBridge.clientSide, provideSsrBridgeClientSide); preset.set(KnownToken.Http.Api.knownHosts, provideKnownHttpApiHosts); preset.set(KnownToken.Http.fetch, provideFetch); preset.set(KnownToken.Http.Fetch.middleware, provideFetchMiddleware); diff --git a/src/preset/web/providers/axios-middleware.ts b/src/preset/web/providers/axios-middleware.ts new file mode 100644 index 0000000..0aa2128 --- /dev/null +++ b/src/preset/web/providers/axios-middleware.ts @@ -0,0 +1,15 @@ +import { Resolve } from '../../../di'; +import { KnownToken } from '../../../tokens'; +import { HttpStatus } from '../../isomorphic/utils/http-status'; +import { logMiddleware } from '../../../utils/axios'; + +/** + * Провайдер фабрики http-клиентов. + * @param resolve Функция для получения зависимости по токену. + * @return Фабрика. + */ +export function provideAxiosMiddleware(resolve: Resolve) { + const logHandler = resolve(KnownToken.Axios.Middleware.Log.handler); + + return [HttpStatus.axiosMiddleware(), logMiddleware(logHandler)]; +} diff --git a/src/preset/web/providers/config-source.ts b/src/preset/web/providers/config-source.ts new file mode 100644 index 0000000..c34dc15 --- /dev/null +++ b/src/preset/web/providers/config-source.ts @@ -0,0 +1,14 @@ +import { ConfigSource, createConfigSource } from '../../../config'; + +/** + * Провайдер источника конфигурации. + * @return Источник конфигурации. + */ +export function provideConfigSource(): ConfigSource { + // ВАЖНО: по умолчанию рассчитываем на process.env который предоставляется сборщиком (например webpack) + if (typeof process !== 'undefined' && process.env) { + return createConfigSource(process.env); + } + + return createConfigSource({}); +} diff --git a/src/preset/web/providers/fetch-middleware.ts b/src/preset/web/providers/fetch-middleware.ts new file mode 100644 index 0000000..0c01804 --- /dev/null +++ b/src/preset/web/providers/fetch-middleware.ts @@ -0,0 +1,16 @@ +import { Resolve } from '../../../di'; +import { KnownToken } from '../../../tokens'; +import { FetchLogging } from '../../isomorphic/utils/fetch-logging'; +import { log } from '../../../http'; + +/** + * Провайдер промежуточных слоев для fetch. + * @param resolve Функция для получения зависимости по токену. + * @return Фабрика. + */ +export function provideFetchMiddleware(resolve: Resolve) { + const logger = resolve(KnownToken.logger); + + // ВАЖНО: если появятся еще промежуточные слои - не забыть разделить логирование на 2 части (ошибки и данные) + return [log(new FetchLogging(logger))]; +} diff --git a/src/preset/web/providers/index.ts b/src/preset/web/providers/index.ts deleted file mode 100644 index f5bb996..0000000 --- a/src/preset/web/providers/index.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { - BrowserClient, - Hub, - defaultIntegrations, - defaultStackParser, - makeFetchTransport, -} from '@sentry/browser'; -import { ConfigSource, createConfigSource } from '../../../config'; -import { Resolve } from '../../../di'; -import { Logger, createLogger } from '../../../log'; -import { KnownToken } from '../../../tokens'; -import { createSentryHandler } from '../../../log/handler/sentry'; -import { BridgeClientSide, SsrBridge } from '../../../utils/ssr'; -import { KnownHttpApiKey } from '../../isomorphic/types'; -import { FetchLogging } from '../../isomorphic/utils/fetch-logging'; -import { HttpApiHostPool } from '../../isomorphic/utils/http-api-host-pool'; -import { HttpStatus } from '../../isomorphic/utils/http-status'; -import { logMiddleware } from '../../../utils/axios'; -import { log } from '../../../http'; - -/** - * Провайдер источника конфигурации. - * @return Источник конфигурации. - */ -export function provideConfigSource(): ConfigSource { - // ВАЖНО: по умолчанию рассчитываем на process.env который предоставляется сборщиком (например webpack) - if (typeof process !== 'undefined' && process.env) { - return createConfigSource(process.env); - } - - return createConfigSource({}); -} - -/** - * Провайдер Logger'а. - * @param resolve Функция для получения зависимости по токену. - * @return Logger. - */ -export function provideLogger(resolve: Resolve): Logger { - const source = resolve(KnownToken.Config.source); - const config = resolve(KnownToken.Config.base); - - const client = new BrowserClient({ - transport: makeFetchTransport, - stackParser: defaultStackParser, - dsn: source.require('PUBLIC_SENTRY_DSN'), - release: source.require('SENTRY_RELEASE'), - environment: source.require('PUBLIC_SENTRY_ENVIRONMENT'), - integrations: [...defaultIntegrations], - }); - - const hub = new Hub(client); - - hub.setTag('url', window.location.href); - - const logger = createLogger(); - - logger.subscribe(createSentryHandler(hub)); - - if (config.env === 'development') { - logger.subscribe(event => { - switch (event.type) { - case 'debug': - // eslint-disable-next-line no-console - console.debug(event.data); - break; - case 'error': - // eslint-disable-next-line no-console - console.error(event.data); - break; - } - }); - } - - return logger; -} - -/** - * Провайдер клиентской части "моста" для передачи данных между сервером и клиентом. - * @param resolve Функция для получения зависимости по токену. - * @return Клиентская часть "моста". - */ -export function provideBridgeClientSide(resolve: Resolve): BridgeClientSide { - const config = resolve(KnownToken.Config.base); - - return SsrBridge.resolve(config.appName); -} - -/** - * Провайдер известных http-хостов. - * @param resolve Функция для получения зависимости по токену. - * @return Пул известных http-хостов. - */ -export function provideKnownHttpApiHosts(resolve: Resolve): HttpApiHostPool { - const source = resolve(KnownToken.Config.source); - - return new HttpApiHostPool( - { - ilium: 'PUBLIC_API_URL_ILIUM', - simaV3: 'PUBLIC_API_URL_SIMALAND_V3', - simaV4: 'PUBLIC_API_URL_SIMALAND_V4', - simaV6: 'PUBLIC_API_URL_SIMALAND_V6', - chponkiV2: 'PUBLIC_API_URL_CHPONKI_V2', - }, - source, - ); -} - -/** - * Провайдер промежуточных слоев для fetch. - * @param resolve Функция для получения зависимости по токену. - * @return Фабрика. - */ -export function provideFetchMiddleware(resolve: Resolve) { - const logger = resolve(KnownToken.logger); - - // ВАЖНО: если появятся еще промежуточные слои - не забыть разделить логирование на 2 части (ошибки и данные) - return [log(new FetchLogging(logger))]; -} - -/** - * Провайдер фабрики http-клиентов. - * @param resolve Функция для получения зависимости по токену. - * @return Фабрика. - */ -export function provideAxiosMiddleware(resolve: Resolve) { - const logHandler = resolve(KnownToken.Axios.Middleware.Log.handler); - - return [HttpStatus.axiosMiddleware(), logMiddleware(logHandler)]; -} diff --git a/src/preset/web/providers/known-http-api-hosts.ts b/src/preset/web/providers/known-http-api-hosts.ts new file mode 100644 index 0000000..f49804c --- /dev/null +++ b/src/preset/web/providers/known-http-api-hosts.ts @@ -0,0 +1,24 @@ +import { Resolve } from '../../../di'; +import { KnownToken } from '../../../tokens'; +import { KnownHttpApiKey } from '../../isomorphic/types'; +import { HttpApiHostPool } from '../../isomorphic/utils/http-api-host-pool'; + +/** + * Провайдер известных http-хостов. + * @param resolve Функция для получения зависимости по токену. + * @return Пул известных http-хостов. + */ +export function provideKnownHttpApiHosts(resolve: Resolve): HttpApiHostPool { + const source = resolve(KnownToken.Config.source); + + return new HttpApiHostPool( + { + ilium: 'PUBLIC_API_URL_ILIUM', + simaV3: 'PUBLIC_API_URL_SIMALAND_V3', + simaV4: 'PUBLIC_API_URL_SIMALAND_V4', + simaV6: 'PUBLIC_API_URL_SIMALAND_V6', + chponkiV2: 'PUBLIC_API_URL_CHPONKI_V2', + }, + source, + ); +} diff --git a/src/preset/web/providers/logger.ts b/src/preset/web/providers/logger.ts new file mode 100644 index 0000000..4f26177 --- /dev/null +++ b/src/preset/web/providers/logger.ts @@ -0,0 +1,55 @@ +import { + BrowserClient, + Hub, + defaultIntegrations, + defaultStackParser, + makeFetchTransport, +} from '@sentry/browser'; +import { Resolve } from '../../../di'; +import { Logger, createLogger } from '../../../log'; +import { KnownToken } from '../../../tokens'; +import { createSentryHandler } from '../../../log/handler/sentry'; + +/** + * Провайдер Logger'а. + * @param resolve Функция для получения зависимости по токену. + * @return Logger. + */ +export function provideLogger(resolve: Resolve): Logger { + const source = resolve(KnownToken.Config.source); + const config = resolve(KnownToken.Config.base); + + const client = new BrowserClient({ + transport: makeFetchTransport, + stackParser: defaultStackParser, + dsn: source.require('PUBLIC_SENTRY_DSN'), + release: source.require('SENTRY_RELEASE'), + environment: source.require('PUBLIC_SENTRY_ENVIRONMENT'), + integrations: [...defaultIntegrations], + }); + + const hub = new Hub(client); + + hub.setTag('url', window.location.href); + + const logger = createLogger(); + + logger.subscribe(createSentryHandler(hub)); + + if (config.env === 'development') { + logger.subscribe(event => { + switch (event.type) { + case 'debug': + // eslint-disable-next-line no-console + console.debug(event.data); + break; + case 'error': + // eslint-disable-next-line no-console + console.error(event.data); + break; + } + }); + } + + return logger; +} diff --git a/src/preset/web/providers/ssr-bridge-client-side.ts b/src/preset/web/providers/ssr-bridge-client-side.ts new file mode 100644 index 0000000..4c26280 --- /dev/null +++ b/src/preset/web/providers/ssr-bridge-client-side.ts @@ -0,0 +1,14 @@ +import { Resolve } from '../../../di'; +import { KnownToken } from '../../../tokens'; +import { BridgeClientSide, SsrBridge } from '../../../utils/ssr'; + +/** + * Провайдер клиентской части "моста" для передачи данных между сервером и клиентом. + * @param resolve Функция для получения зависимости по токену. + * @return Клиентская часть "моста". + */ +export function provideSsrBridgeClientSide(resolve: Resolve): BridgeClientSide { + const config = resolve(KnownToken.Config.base); + + return SsrBridge.resolve(config.appName); +}