@stainlessdev/xray-emitter 0.1.0-branch.pedro-effect-ts.e7d6f7b → 0.1.0-dev.2c5bc4c
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.
- package/dist/effect.cjs +6 -3
- package/dist/effect.cjs.map +1 -1
- package/dist/effect.js +7 -4
- package/dist/effect.js.map +1 -1
- package/package.json +1 -1
package/dist/effect.cjs
CHANGED
|
@@ -103,11 +103,12 @@ function createEffectMiddleware(xray, options) {
|
|
|
103
103
|
return response;
|
|
104
104
|
}
|
|
105
105
|
const error = _effect.Cause.squash(exit.cause);
|
|
106
|
+
const [errorResponse] = yield* _platform.HttpServerError.causeResponse(exit.cause);
|
|
106
107
|
const log = xray.endRequest(
|
|
107
108
|
ctx,
|
|
108
109
|
{
|
|
109
|
-
statusCode:
|
|
110
|
-
headers:
|
|
110
|
+
statusCode: errorResponse.status,
|
|
111
|
+
headers: effectHeadersToRecord(errorResponse.headers),
|
|
111
112
|
body: void 0,
|
|
112
113
|
endTimeMs: Date.now()
|
|
113
114
|
},
|
|
@@ -131,7 +132,9 @@ function createEffectMiddleware(xray, options) {
|
|
|
131
132
|
"warn",
|
|
132
133
|
xray.config.logLevel,
|
|
133
134
|
"xray: onResponse failed",
|
|
134
|
-
{
|
|
135
|
+
{
|
|
136
|
+
error: errInner instanceof Error ? errInner.message : String(errInner)
|
|
137
|
+
}
|
|
135
138
|
);
|
|
136
139
|
}
|
|
137
140
|
}
|
package/dist/effect.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/xray-emitter-js/xray-emitter-js/dist/effect.cjs","../src/effect/effect.ts"],"names":["createEmitter","log"],"mappings":"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","file":"/home/runner/work/xray-emitter-js/xray-emitter-js/dist/effect.cjs","sourcesContent":[null,"import { Cause, Effect, Exit, Option } from 'effect';\nimport { Headers, HttpApp, HttpRouter, HttpServerRequest } from '@effect/platform';\nimport type {\n CaptureConfig,\n NormalizedRequest,\n RedactionConfig,\n RequestLog,\n XrayContext,\n XrayEmitter,\n XrayRuntimeConfig,\n} from '../core/index';\nimport { createEmitter as createFetchEmitter } from '../fetch/fetch';\nimport {\n bindContextToObject,\n getXrayContextFromObject,\n logWithLevel,\n makeCapturedBody,\n setCaptureOverride,\n setContextRequestId,\n setContextRoute,\n setRedactionOverride,\n} from '../core/internal';\n\nexport { createEmitter as createCoreEmitter } from '../fetch/fetch';\nexport type {\n CaptureConfig,\n RedactionConfig,\n RequestLog,\n XrayConfig,\n XrayContext,\n XrayEmitter,\n XrayRuntimeConfig,\n} from '../core/index';\n\nexport interface WrapOptions {\n route?: string;\n requestId?: string;\n capture?: Partial<CaptureConfig>;\n redaction?: Partial<RedactionConfig>;\n onRequest?: (ctx: XrayContext) => void;\n onResponse?: (ctx: XrayContext, log: RequestLog) => void;\n onError?: (ctx: XrayContext, err: unknown) => void;\n}\n\ntype EffectMiddleware = <E, R>(httpApp: HttpApp.Default<E, R>) => HttpApp.Default<E, R>;\n\ntype EffectEmitter = EffectMiddleware & {\n flush: XrayEmitter['flush'];\n shutdown: XrayEmitter['shutdown'];\n};\n\nexport function createEmitter(config: XrayRuntimeConfig, options?: WrapOptions): EffectEmitter {\n const emitter = createFetchEmitter(config);\n const middleware = createEffectMiddleware(emitter, options) as EffectEmitter;\n middleware.flush = emitter.flush;\n middleware.shutdown = emitter.shutdown;\n return middleware;\n}\n\nexport function createEffectMiddleware(xray: XrayEmitter, options?: WrapOptions): EffectMiddleware {\n return (<E, R>(httpApp: HttpApp.Default<E, R>): HttpApp.Default<E, R> =>\n Effect.gen(function* () {\n const request = yield* HttpServerRequest.HttpServerRequest;\n\n const headers = effectHeadersToRecord(request.headers);\n const url = buildFullUrl(request.originalUrl, headers);\n\n // Try to read the route pattern from HttpRouter.RouteContext (available\n // when the middleware is applied via HttpRouter.use).\n const routeCtxOption = yield* Effect.serviceOption(HttpRouter.RouteContext);\n const route = Option.isSome(routeCtxOption)\n ? String(routeCtxOption.value.route.path)\n : options?.route;\n\n // Capture request body if configured.\n const captureReqBody = xray.config.capture.requestBody;\n let requestBody: NormalizedRequest['body'];\n if (captureReqBody && captureReqBody !== 'none') {\n const textResult = yield* Effect.either(request.text);\n if (textResult._tag === 'Right') {\n const bytes = new TextEncoder().encode(textResult.right);\n const maxBytes = xray.config.capture.maxBodyBytes;\n const truncated = bytes.length > maxBytes;\n const slice = truncated ? bytes.slice(0, maxBytes) : bytes;\n requestBody = makeCapturedBody(slice, bytes.length, truncated, captureReqBody);\n }\n }\n\n const normalizedRequest: NormalizedRequest = {\n method: request.method,\n url,\n route,\n headers,\n body: requestBody,\n requestId: options?.requestId,\n remoteAddress:\n request.remoteAddress._tag === 'Some' ? request.remoteAddress.value : undefined,\n startTimeMs: Date.now(),\n };\n\n const ctx = xray.startRequest(normalizedRequest);\n bindContextToObject(request, ctx);\n\n if (options?.requestId) {\n setContextRequestId(ctx, options.requestId);\n }\n if (route) {\n setContextRoute(ctx, route);\n }\n if (options?.capture) {\n setCaptureOverride(ctx, options.capture);\n }\n if (options?.redaction) {\n setRedactionOverride(ctx, options.redaction);\n }\n\n if (options?.onRequest) {\n try {\n options.onRequest(ctx);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onRequest failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const exit = yield* Effect.exit(httpApp);\n\n if (Exit.isSuccess(exit)) {\n const response = exit.value;\n const responseHeaders = effectHeadersToRecord(response.headers);\n\n const log = xray.endRequest(ctx, {\n statusCode: response.status,\n headers: responseHeaders,\n body: captureResponseBody(xray, response),\n endTimeMs: Date.now(),\n });\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (err) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n { error: err instanceof Error ? err.message : String(err) },\n );\n }\n }\n\n return response;\n }\n\n const error = Cause.squash(exit.cause);\n const log = xray.endRequest(\n ctx,\n {\n statusCode: undefined,\n headers: undefined,\n body: undefined,\n endTimeMs: Date.now(),\n },\n error,\n );\n\n if (options?.onError) {\n try {\n options.onError(ctx, error);\n } catch (errInner) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n });\n }\n }\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (errInner) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n { error: errInner instanceof Error ? errInner.message : String(errInner) },\n );\n }\n }\n\n return yield* Effect.failCause(exit.cause);\n })) as EffectMiddleware;\n}\n\n/**\n * Retrieve the XrayContext bound to a request object.\n */\nexport function getXrayContext(\n request: HttpServerRequest.HttpServerRequest,\n): XrayContext | undefined {\n return getXrayContextFromObject(request);\n}\n\n/**\n * Effect that retrieves the XrayContext from the current HttpServerRequest in scope.\n */\nexport const currentXrayContext: Effect.Effect<\n XrayContext | undefined,\n never,\n HttpServerRequest.HttpServerRequest\n> = Effect.map(HttpServerRequest.HttpServerRequest, (request) => getXrayContextFromObject(request));\n\nfunction effectHeadersToRecord(headers: Headers.Headers): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (typeof value === 'string') {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction buildFullUrl(url: string, headers: Record<string, string | string[]>): string {\n if (url.startsWith('http://') || url.startsWith('https://')) {\n return url;\n }\n const host = headers['host'];\n if (!host || typeof host !== 'string') {\n return url;\n }\n return `http://${host}${url}`;\n}\n\nfunction captureResponseBody(\n xray: XrayEmitter,\n response: { body: { _tag: string; body?: unknown; contentLength?: number } },\n): ReturnType<typeof makeCapturedBody> {\n const mode = xray.config.capture.responseBody;\n if (!mode || mode === 'none') return undefined;\n\n const body = response.body;\n if (body._tag === 'Uint8Array' && body.body instanceof Uint8Array) {\n const maxBytes = xray.config.capture.maxBodyBytes;\n const truncated = body.body.length > maxBytes;\n const slice = truncated ? body.body.slice(0, maxBytes) : body.body;\n return makeCapturedBody(slice, body.body.length, truncated, mode);\n }\n return undefined;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/xray-emitter-js/xray-emitter-js/dist/effect.cjs","../src/effect/effect.ts"],"names":["createEmitter","log"],"mappings":"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","file":"/home/runner/work/xray-emitter-js/xray-emitter-js/dist/effect.cjs","sourcesContent":[null,"import { Cause, Effect, Exit, Option } from 'effect';\nimport { Headers, HttpApp, HttpRouter, HttpServerError, HttpServerRequest } from '@effect/platform';\nimport type {\n CaptureConfig,\n NormalizedRequest,\n RedactionConfig,\n RequestLog,\n XrayContext,\n XrayEmitter,\n XrayRuntimeConfig,\n} from '../core/index';\nimport { createEmitter as createFetchEmitter } from '../fetch/fetch';\nimport {\n bindContextToObject,\n getXrayContextFromObject,\n logWithLevel,\n makeCapturedBody,\n setCaptureOverride,\n setContextRequestId,\n setContextRoute,\n setRedactionOverride,\n} from '../core/internal';\n\nexport { createEmitter as createCoreEmitter } from '../fetch/fetch';\nexport type {\n CaptureConfig,\n RedactionConfig,\n RequestLog,\n XrayConfig,\n XrayContext,\n XrayEmitter,\n XrayRuntimeConfig,\n} from '../core/index';\n\nexport interface WrapOptions {\n route?: string;\n requestId?: string;\n capture?: Partial<CaptureConfig>;\n redaction?: Partial<RedactionConfig>;\n onRequest?: (ctx: XrayContext) => void;\n onResponse?: (ctx: XrayContext, log: RequestLog) => void;\n onError?: (ctx: XrayContext, err: unknown) => void;\n}\n\ntype EffectMiddleware = <E, R>(httpApp: HttpApp.Default<E, R>) => HttpApp.Default<E, R>;\n\ntype EffectEmitter = EffectMiddleware & {\n flush: XrayEmitter['flush'];\n shutdown: XrayEmitter['shutdown'];\n};\n\nexport function createEmitter(config: XrayRuntimeConfig, options?: WrapOptions): EffectEmitter {\n const emitter = createFetchEmitter(config);\n const middleware = createEffectMiddleware(emitter, options) as EffectEmitter;\n middleware.flush = emitter.flush;\n middleware.shutdown = emitter.shutdown;\n return middleware;\n}\n\nexport function createEffectMiddleware(xray: XrayEmitter, options?: WrapOptions): EffectMiddleware {\n return (<E, R>(httpApp: HttpApp.Default<E, R>): HttpApp.Default<E, R> =>\n Effect.gen(function* () {\n const request = yield* HttpServerRequest.HttpServerRequest;\n\n const headers = effectHeadersToRecord(request.headers);\n const url = buildFullUrl(request.originalUrl, headers);\n\n // Try to read the route pattern from HttpRouter.RouteContext (available\n // when the middleware is applied via HttpRouter.use).\n const routeCtxOption = yield* Effect.serviceOption(HttpRouter.RouteContext);\n const route = Option.isSome(routeCtxOption)\n ? String(routeCtxOption.value.route.path)\n : options?.route;\n\n // Capture request body if configured.\n const captureReqBody = xray.config.capture.requestBody;\n let requestBody: NormalizedRequest['body'];\n if (captureReqBody && captureReqBody !== 'none') {\n const textResult = yield* Effect.either(request.text);\n if (textResult._tag === 'Right') {\n const bytes = new TextEncoder().encode(textResult.right);\n const maxBytes = xray.config.capture.maxBodyBytes;\n const truncated = bytes.length > maxBytes;\n const slice = truncated ? bytes.slice(0, maxBytes) : bytes;\n requestBody = makeCapturedBody(slice, bytes.length, truncated, captureReqBody);\n }\n }\n\n const normalizedRequest: NormalizedRequest = {\n method: request.method,\n url,\n route,\n headers,\n body: requestBody,\n requestId: options?.requestId,\n remoteAddress:\n request.remoteAddress._tag === 'Some' ? request.remoteAddress.value : undefined,\n startTimeMs: Date.now(),\n };\n\n const ctx = xray.startRequest(normalizedRequest);\n bindContextToObject(request, ctx);\n\n if (options?.requestId) {\n setContextRequestId(ctx, options.requestId);\n }\n if (route) {\n setContextRoute(ctx, route);\n }\n if (options?.capture) {\n setCaptureOverride(ctx, options.capture);\n }\n if (options?.redaction) {\n setRedactionOverride(ctx, options.redaction);\n }\n\n if (options?.onRequest) {\n try {\n options.onRequest(ctx);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onRequest failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const exit = yield* Effect.exit(httpApp);\n\n if (Exit.isSuccess(exit)) {\n const response = exit.value;\n const responseHeaders = effectHeadersToRecord(response.headers);\n\n const log = xray.endRequest(ctx, {\n statusCode: response.status,\n headers: responseHeaders,\n body: captureResponseBody(xray, response),\n endTimeMs: Date.now(),\n });\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (err) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n { error: err instanceof Error ? err.message : String(err) },\n );\n }\n }\n\n return response;\n }\n\n const error = Cause.squash(exit.cause);\n\n // Resolve the HTTP response that the platform would send for this error\n // (e.g. 404 for RouteNotFound, 500 for unhandled). This mirrors what\n // HttpApp.toWebHandler does internally via causeResponse.\n const [errorResponse] = yield* HttpServerError.causeResponse(exit.cause);\n\n const log = xray.endRequest(\n ctx,\n {\n statusCode: errorResponse.status,\n headers: effectHeadersToRecord(errorResponse.headers),\n body: undefined,\n endTimeMs: Date.now(),\n },\n error,\n );\n\n if (options?.onError) {\n try {\n options.onError(ctx, error);\n } catch (errInner) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n });\n }\n }\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (errInner) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n },\n );\n }\n }\n\n return yield* Effect.failCause(exit.cause);\n })) as EffectMiddleware;\n}\n\n/**\n * Retrieve the XrayContext bound to a request object.\n */\nexport function getXrayContext(\n request: HttpServerRequest.HttpServerRequest,\n): XrayContext | undefined {\n return getXrayContextFromObject(request);\n}\n\n/**\n * Effect that retrieves the XrayContext from the current HttpServerRequest in scope.\n */\nexport const currentXrayContext: Effect.Effect<\n XrayContext | undefined,\n never,\n HttpServerRequest.HttpServerRequest\n> = Effect.map(HttpServerRequest.HttpServerRequest, (request) => getXrayContextFromObject(request));\n\nfunction effectHeadersToRecord(headers: Headers.Headers): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (typeof value === 'string') {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction buildFullUrl(url: string, headers: Record<string, string | string[]>): string {\n if (url.startsWith('http://') || url.startsWith('https://')) {\n return url;\n }\n const host = headers['host'];\n if (!host || typeof host !== 'string') {\n return url;\n }\n return `http://${host}${url}`;\n}\n\nfunction captureResponseBody(\n xray: XrayEmitter,\n response: { body: { _tag: string; body?: unknown; contentLength?: number } },\n): ReturnType<typeof makeCapturedBody> {\n const mode = xray.config.capture.responseBody;\n if (!mode || mode === 'none') return undefined;\n\n const body = response.body;\n if (body._tag === 'Uint8Array' && body.body instanceof Uint8Array) {\n const maxBytes = xray.config.capture.maxBodyBytes;\n const truncated = body.body.length > maxBytes;\n const slice = truncated ? body.body.slice(0, maxBytes) : body.body;\n return makeCapturedBody(slice, body.body.length, truncated, mode);\n }\n return undefined;\n}\n"]}
|
package/dist/effect.js
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
|
|
18
18
|
// src/effect/effect.ts
|
|
19
19
|
import { Cause, Effect, Exit, Option } from "effect";
|
|
20
|
-
import { HttpRouter, HttpServerRequest } from "@effect/platform";
|
|
20
|
+
import { HttpRouter, HttpServerError, HttpServerRequest } from "@effect/platform";
|
|
21
21
|
function createEmitter2(config, options) {
|
|
22
22
|
const emitter = createEmitter(config);
|
|
23
23
|
const middleware = createEffectMiddleware(emitter, options);
|
|
@@ -103,11 +103,12 @@ function createEffectMiddleware(xray, options) {
|
|
|
103
103
|
return response;
|
|
104
104
|
}
|
|
105
105
|
const error = Cause.squash(exit.cause);
|
|
106
|
+
const [errorResponse] = yield* HttpServerError.causeResponse(exit.cause);
|
|
106
107
|
const log = xray.endRequest(
|
|
107
108
|
ctx,
|
|
108
109
|
{
|
|
109
|
-
statusCode:
|
|
110
|
-
headers:
|
|
110
|
+
statusCode: errorResponse.status,
|
|
111
|
+
headers: effectHeadersToRecord(errorResponse.headers),
|
|
111
112
|
body: void 0,
|
|
112
113
|
endTimeMs: Date.now()
|
|
113
114
|
},
|
|
@@ -131,7 +132,9 @@ function createEffectMiddleware(xray, options) {
|
|
|
131
132
|
"warn",
|
|
132
133
|
xray.config.logLevel,
|
|
133
134
|
"xray: onResponse failed",
|
|
134
|
-
{
|
|
135
|
+
{
|
|
136
|
+
error: errInner instanceof Error ? errInner.message : String(errInner)
|
|
137
|
+
}
|
|
135
138
|
);
|
|
136
139
|
}
|
|
137
140
|
}
|
package/dist/effect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/effect/effect.ts"],"sourcesContent":["import { Cause, Effect, Exit, Option } from 'effect';\nimport { Headers, HttpApp, HttpRouter, HttpServerRequest } from '@effect/platform';\nimport type {\n CaptureConfig,\n NormalizedRequest,\n RedactionConfig,\n RequestLog,\n XrayContext,\n XrayEmitter,\n XrayRuntimeConfig,\n} from '../core/index';\nimport { createEmitter as createFetchEmitter } from '../fetch/fetch';\nimport {\n bindContextToObject,\n getXrayContextFromObject,\n logWithLevel,\n makeCapturedBody,\n setCaptureOverride,\n setContextRequestId,\n setContextRoute,\n setRedactionOverride,\n} from '../core/internal';\n\nexport { createEmitter as createCoreEmitter } from '../fetch/fetch';\nexport type {\n CaptureConfig,\n RedactionConfig,\n RequestLog,\n XrayConfig,\n XrayContext,\n XrayEmitter,\n XrayRuntimeConfig,\n} from '../core/index';\n\nexport interface WrapOptions {\n route?: string;\n requestId?: string;\n capture?: Partial<CaptureConfig>;\n redaction?: Partial<RedactionConfig>;\n onRequest?: (ctx: XrayContext) => void;\n onResponse?: (ctx: XrayContext, log: RequestLog) => void;\n onError?: (ctx: XrayContext, err: unknown) => void;\n}\n\ntype EffectMiddleware = <E, R>(httpApp: HttpApp.Default<E, R>) => HttpApp.Default<E, R>;\n\ntype EffectEmitter = EffectMiddleware & {\n flush: XrayEmitter['flush'];\n shutdown: XrayEmitter['shutdown'];\n};\n\nexport function createEmitter(config: XrayRuntimeConfig, options?: WrapOptions): EffectEmitter {\n const emitter = createFetchEmitter(config);\n const middleware = createEffectMiddleware(emitter, options) as EffectEmitter;\n middleware.flush = emitter.flush;\n middleware.shutdown = emitter.shutdown;\n return middleware;\n}\n\nexport function createEffectMiddleware(xray: XrayEmitter, options?: WrapOptions): EffectMiddleware {\n return (<E, R>(httpApp: HttpApp.Default<E, R>): HttpApp.Default<E, R> =>\n Effect.gen(function* () {\n const request = yield* HttpServerRequest.HttpServerRequest;\n\n const headers = effectHeadersToRecord(request.headers);\n const url = buildFullUrl(request.originalUrl, headers);\n\n // Try to read the route pattern from HttpRouter.RouteContext (available\n // when the middleware is applied via HttpRouter.use).\n const routeCtxOption = yield* Effect.serviceOption(HttpRouter.RouteContext);\n const route = Option.isSome(routeCtxOption)\n ? String(routeCtxOption.value.route.path)\n : options?.route;\n\n // Capture request body if configured.\n const captureReqBody = xray.config.capture.requestBody;\n let requestBody: NormalizedRequest['body'];\n if (captureReqBody && captureReqBody !== 'none') {\n const textResult = yield* Effect.either(request.text);\n if (textResult._tag === 'Right') {\n const bytes = new TextEncoder().encode(textResult.right);\n const maxBytes = xray.config.capture.maxBodyBytes;\n const truncated = bytes.length > maxBytes;\n const slice = truncated ? bytes.slice(0, maxBytes) : bytes;\n requestBody = makeCapturedBody(slice, bytes.length, truncated, captureReqBody);\n }\n }\n\n const normalizedRequest: NormalizedRequest = {\n method: request.method,\n url,\n route,\n headers,\n body: requestBody,\n requestId: options?.requestId,\n remoteAddress:\n request.remoteAddress._tag === 'Some' ? request.remoteAddress.value : undefined,\n startTimeMs: Date.now(),\n };\n\n const ctx = xray.startRequest(normalizedRequest);\n bindContextToObject(request, ctx);\n\n if (options?.requestId) {\n setContextRequestId(ctx, options.requestId);\n }\n if (route) {\n setContextRoute(ctx, route);\n }\n if (options?.capture) {\n setCaptureOverride(ctx, options.capture);\n }\n if (options?.redaction) {\n setRedactionOverride(ctx, options.redaction);\n }\n\n if (options?.onRequest) {\n try {\n options.onRequest(ctx);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onRequest failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const exit = yield* Effect.exit(httpApp);\n\n if (Exit.isSuccess(exit)) {\n const response = exit.value;\n const responseHeaders = effectHeadersToRecord(response.headers);\n\n const log = xray.endRequest(ctx, {\n statusCode: response.status,\n headers: responseHeaders,\n body: captureResponseBody(xray, response),\n endTimeMs: Date.now(),\n });\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (err) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n { error: err instanceof Error ? err.message : String(err) },\n );\n }\n }\n\n return response;\n }\n\n const error = Cause.squash(exit.cause);\n const log = xray.endRequest(\n ctx,\n {\n statusCode: undefined,\n headers: undefined,\n body: undefined,\n endTimeMs: Date.now(),\n },\n error,\n );\n\n if (options?.onError) {\n try {\n options.onError(ctx, error);\n } catch (errInner) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n });\n }\n }\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (errInner) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n { error: errInner instanceof Error ? errInner.message : String(errInner) },\n );\n }\n }\n\n return yield* Effect.failCause(exit.cause);\n })) as EffectMiddleware;\n}\n\n/**\n * Retrieve the XrayContext bound to a request object.\n */\nexport function getXrayContext(\n request: HttpServerRequest.HttpServerRequest,\n): XrayContext | undefined {\n return getXrayContextFromObject(request);\n}\n\n/**\n * Effect that retrieves the XrayContext from the current HttpServerRequest in scope.\n */\nexport const currentXrayContext: Effect.Effect<\n XrayContext | undefined,\n never,\n HttpServerRequest.HttpServerRequest\n> = Effect.map(HttpServerRequest.HttpServerRequest, (request) => getXrayContextFromObject(request));\n\nfunction effectHeadersToRecord(headers: Headers.Headers): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (typeof value === 'string') {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction buildFullUrl(url: string, headers: Record<string, string | string[]>): string {\n if (url.startsWith('http://') || url.startsWith('https://')) {\n return url;\n }\n const host = headers['host'];\n if (!host || typeof host !== 'string') {\n return url;\n }\n return `http://${host}${url}`;\n}\n\nfunction captureResponseBody(\n xray: XrayEmitter,\n response: { body: { _tag: string; body?: unknown; contentLength?: number } },\n): ReturnType<typeof makeCapturedBody> {\n const mode = xray.config.capture.responseBody;\n if (!mode || mode === 'none') return undefined;\n\n const body = response.body;\n if (body._tag === 'Uint8Array' && body.body instanceof Uint8Array) {\n const maxBytes = xray.config.capture.maxBodyBytes;\n const truncated = body.body.length > maxBytes;\n const slice = truncated ? body.body.slice(0, maxBytes) : body.body;\n return makeCapturedBody(slice, body.body.length, truncated, mode);\n }\n return undefined;\n}\n"],"mappings":"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","names":["createEmitter","log"]}
|
|
1
|
+
{"version":3,"sources":["../src/effect/effect.ts"],"sourcesContent":["import { Cause, Effect, Exit, Option } from 'effect';\nimport { Headers, HttpApp, HttpRouter, HttpServerError, HttpServerRequest } from '@effect/platform';\nimport type {\n CaptureConfig,\n NormalizedRequest,\n RedactionConfig,\n RequestLog,\n XrayContext,\n XrayEmitter,\n XrayRuntimeConfig,\n} from '../core/index';\nimport { createEmitter as createFetchEmitter } from '../fetch/fetch';\nimport {\n bindContextToObject,\n getXrayContextFromObject,\n logWithLevel,\n makeCapturedBody,\n setCaptureOverride,\n setContextRequestId,\n setContextRoute,\n setRedactionOverride,\n} from '../core/internal';\n\nexport { createEmitter as createCoreEmitter } from '../fetch/fetch';\nexport type {\n CaptureConfig,\n RedactionConfig,\n RequestLog,\n XrayConfig,\n XrayContext,\n XrayEmitter,\n XrayRuntimeConfig,\n} from '../core/index';\n\nexport interface WrapOptions {\n route?: string;\n requestId?: string;\n capture?: Partial<CaptureConfig>;\n redaction?: Partial<RedactionConfig>;\n onRequest?: (ctx: XrayContext) => void;\n onResponse?: (ctx: XrayContext, log: RequestLog) => void;\n onError?: (ctx: XrayContext, err: unknown) => void;\n}\n\ntype EffectMiddleware = <E, R>(httpApp: HttpApp.Default<E, R>) => HttpApp.Default<E, R>;\n\ntype EffectEmitter = EffectMiddleware & {\n flush: XrayEmitter['flush'];\n shutdown: XrayEmitter['shutdown'];\n};\n\nexport function createEmitter(config: XrayRuntimeConfig, options?: WrapOptions): EffectEmitter {\n const emitter = createFetchEmitter(config);\n const middleware = createEffectMiddleware(emitter, options) as EffectEmitter;\n middleware.flush = emitter.flush;\n middleware.shutdown = emitter.shutdown;\n return middleware;\n}\n\nexport function createEffectMiddleware(xray: XrayEmitter, options?: WrapOptions): EffectMiddleware {\n return (<E, R>(httpApp: HttpApp.Default<E, R>): HttpApp.Default<E, R> =>\n Effect.gen(function* () {\n const request = yield* HttpServerRequest.HttpServerRequest;\n\n const headers = effectHeadersToRecord(request.headers);\n const url = buildFullUrl(request.originalUrl, headers);\n\n // Try to read the route pattern from HttpRouter.RouteContext (available\n // when the middleware is applied via HttpRouter.use).\n const routeCtxOption = yield* Effect.serviceOption(HttpRouter.RouteContext);\n const route = Option.isSome(routeCtxOption)\n ? String(routeCtxOption.value.route.path)\n : options?.route;\n\n // Capture request body if configured.\n const captureReqBody = xray.config.capture.requestBody;\n let requestBody: NormalizedRequest['body'];\n if (captureReqBody && captureReqBody !== 'none') {\n const textResult = yield* Effect.either(request.text);\n if (textResult._tag === 'Right') {\n const bytes = new TextEncoder().encode(textResult.right);\n const maxBytes = xray.config.capture.maxBodyBytes;\n const truncated = bytes.length > maxBytes;\n const slice = truncated ? bytes.slice(0, maxBytes) : bytes;\n requestBody = makeCapturedBody(slice, bytes.length, truncated, captureReqBody);\n }\n }\n\n const normalizedRequest: NormalizedRequest = {\n method: request.method,\n url,\n route,\n headers,\n body: requestBody,\n requestId: options?.requestId,\n remoteAddress:\n request.remoteAddress._tag === 'Some' ? request.remoteAddress.value : undefined,\n startTimeMs: Date.now(),\n };\n\n const ctx = xray.startRequest(normalizedRequest);\n bindContextToObject(request, ctx);\n\n if (options?.requestId) {\n setContextRequestId(ctx, options.requestId);\n }\n if (route) {\n setContextRoute(ctx, route);\n }\n if (options?.capture) {\n setCaptureOverride(ctx, options.capture);\n }\n if (options?.redaction) {\n setRedactionOverride(ctx, options.redaction);\n }\n\n if (options?.onRequest) {\n try {\n options.onRequest(ctx);\n } catch (err) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onRequest failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const exit = yield* Effect.exit(httpApp);\n\n if (Exit.isSuccess(exit)) {\n const response = exit.value;\n const responseHeaders = effectHeadersToRecord(response.headers);\n\n const log = xray.endRequest(ctx, {\n statusCode: response.status,\n headers: responseHeaders,\n body: captureResponseBody(xray, response),\n endTimeMs: Date.now(),\n });\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (err) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n { error: err instanceof Error ? err.message : String(err) },\n );\n }\n }\n\n return response;\n }\n\n const error = Cause.squash(exit.cause);\n\n // Resolve the HTTP response that the platform would send for this error\n // (e.g. 404 for RouteNotFound, 500 for unhandled). This mirrors what\n // HttpApp.toWebHandler does internally via causeResponse.\n const [errorResponse] = yield* HttpServerError.causeResponse(exit.cause);\n\n const log = xray.endRequest(\n ctx,\n {\n statusCode: errorResponse.status,\n headers: effectHeadersToRecord(errorResponse.headers),\n body: undefined,\n endTimeMs: Date.now(),\n },\n error,\n );\n\n if (options?.onError) {\n try {\n options.onError(ctx, error);\n } catch (errInner) {\n logWithLevel(xray.config.logger, 'warn', xray.config.logLevel, 'xray: onError failed', {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n });\n }\n }\n\n if (options?.onResponse) {\n try {\n options.onResponse(ctx, log);\n } catch (errInner) {\n logWithLevel(\n xray.config.logger,\n 'warn',\n xray.config.logLevel,\n 'xray: onResponse failed',\n {\n error: errInner instanceof Error ? errInner.message : String(errInner),\n },\n );\n }\n }\n\n return yield* Effect.failCause(exit.cause);\n })) as EffectMiddleware;\n}\n\n/**\n * Retrieve the XrayContext bound to a request object.\n */\nexport function getXrayContext(\n request: HttpServerRequest.HttpServerRequest,\n): XrayContext | undefined {\n return getXrayContextFromObject(request);\n}\n\n/**\n * Effect that retrieves the XrayContext from the current HttpServerRequest in scope.\n */\nexport const currentXrayContext: Effect.Effect<\n XrayContext | undefined,\n never,\n HttpServerRequest.HttpServerRequest\n> = Effect.map(HttpServerRequest.HttpServerRequest, (request) => getXrayContextFromObject(request));\n\nfunction effectHeadersToRecord(headers: Headers.Headers): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (typeof value === 'string') {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction buildFullUrl(url: string, headers: Record<string, string | string[]>): string {\n if (url.startsWith('http://') || url.startsWith('https://')) {\n return url;\n }\n const host = headers['host'];\n if (!host || typeof host !== 'string') {\n return url;\n }\n return `http://${host}${url}`;\n}\n\nfunction captureResponseBody(\n xray: XrayEmitter,\n response: { body: { _tag: string; body?: unknown; contentLength?: number } },\n): ReturnType<typeof makeCapturedBody> {\n const mode = xray.config.capture.responseBody;\n if (!mode || mode === 'none') return undefined;\n\n const body = response.body;\n if (body._tag === 'Uint8Array' && body.body instanceof Uint8Array) {\n const maxBytes = xray.config.capture.maxBodyBytes;\n const truncated = body.body.length > maxBytes;\n const slice = truncated ? body.body.slice(0, maxBytes) : body.body;\n return makeCapturedBody(slice, body.body.length, truncated, mode);\n }\n return undefined;\n}\n"],"mappings":"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","names":["createEmitter","log"]}
|