@sentry/core 10.39.0 → 10.41.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/client.js +1 -0
- package/build/cjs/client.js.map +1 -1
- package/build/cjs/exports.js +4 -2
- package/build/cjs/exports.js.map +1 -1
- package/build/cjs/fetch.js +8 -4
- package/build/cjs/fetch.js.map +1 -1
- package/build/cjs/index.js +3 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/integrations/consola.js.map +1 -1
- package/build/cjs/tracing/ai/mediaStripping.js +135 -0
- package/build/cjs/tracing/ai/mediaStripping.js.map +1 -0
- package/build/cjs/tracing/ai/messageTruncation.js +18 -60
- package/build/cjs/tracing/ai/messageTruncation.js.map +1 -1
- package/build/cjs/tracing/anthropic-ai/index.js +1 -1
- package/build/cjs/tracing/anthropic-ai/index.js.map +1 -1
- package/build/cjs/tracing/google-genai/index.js +1 -1
- package/build/cjs/tracing/google-genai/index.js.map +1 -1
- package/build/cjs/tracing/langgraph/index.js +1 -1
- package/build/cjs/tracing/langgraph/index.js.map +1 -1
- package/build/cjs/tracing/openai/index.js +1 -1
- package/build/cjs/tracing/openai/index.js.map +1 -1
- package/build/cjs/utils/misc.js +7 -0
- package/build/cjs/utils/misc.js.map +1 -1
- package/build/cjs/utils/node-stack-trace.js +11 -2
- package/build/cjs/utils/node-stack-trace.js.map +1 -1
- package/build/cjs/utils/tunnel.js +74 -0
- package/build/cjs/utils/tunnel.js.map +1 -0
- package/build/cjs/utils/version.js +1 -1
- package/build/cjs/utils/version.js.map +1 -1
- package/build/cjs/utils/worldwide.js.map +1 -1
- package/build/esm/client.js +1 -0
- package/build/esm/client.js.map +1 -1
- package/build/esm/exports.js +4 -2
- package/build/esm/exports.js.map +1 -1
- package/build/esm/fetch.js +8 -4
- package/build/esm/fetch.js.map +1 -1
- package/build/esm/index.js +2 -1
- package/build/esm/index.js.map +1 -1
- package/build/esm/integrations/consola.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/tracing/ai/mediaStripping.js +132 -0
- package/build/esm/tracing/ai/mediaStripping.js.map +1 -0
- package/build/esm/tracing/ai/messageTruncation.js +12 -54
- package/build/esm/tracing/ai/messageTruncation.js.map +1 -1
- package/build/esm/tracing/anthropic-ai/index.js +1 -1
- package/build/esm/tracing/anthropic-ai/index.js.map +1 -1
- package/build/esm/tracing/google-genai/index.js +1 -1
- package/build/esm/tracing/google-genai/index.js.map +1 -1
- package/build/esm/tracing/langgraph/index.js +1 -1
- package/build/esm/tracing/langgraph/index.js.map +1 -1
- package/build/esm/tracing/openai/index.js +1 -1
- package/build/esm/tracing/openai/index.js.map +1 -1
- package/build/esm/utils/misc.js +7 -1
- package/build/esm/utils/misc.js.map +1 -1
- package/build/esm/utils/node-stack-trace.js +11 -2
- package/build/esm/utils/node-stack-trace.js.map +1 -1
- package/build/esm/utils/tunnel.js +72 -0
- package/build/esm/utils/tunnel.js.map +1 -0
- package/build/esm/utils/version.js +1 -1
- package/build/esm/utils/version.js.map +1 -1
- package/build/esm/utils/worldwide.js.map +1 -1
- package/build/types/client.d.ts.map +1 -1
- package/build/types/exports.d.ts.map +1 -1
- package/build/types/fetch.d.ts.map +1 -1
- package/build/types/index.d.ts +3 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/integrations/consola.d.ts +8 -1
- package/build/types/integrations/consola.d.ts.map +1 -1
- package/build/types/tracing/ai/mediaStripping.d.ts +40 -0
- package/build/types/tracing/ai/mediaStripping.d.ts.map +1 -0
- package/build/types/tracing/ai/messageTruncation.d.ts.map +1 -1
- package/build/types/types-hoist/replay.d.ts +1 -0
- package/build/types/types-hoist/replay.d.ts.map +1 -1
- package/build/types/utils/misc.d.ts +7 -0
- package/build/types/utils/misc.d.ts.map +1 -1
- package/build/types/utils/node-stack-trace.d.ts.map +1 -1
- package/build/types/utils/tunnel.d.ts +16 -0
- package/build/types/utils/tunnel.d.ts.map +1 -0
- package/build/types/utils/worldwide.d.ts +0 -2
- package/build/types/utils/worldwide.d.ts.map +1 -1
- package/build/types-ts3.8/index.d.ts +3 -1
- package/build/types-ts3.8/integrations/consola.d.ts +8 -1
- package/build/types-ts3.8/tracing/ai/mediaStripping.d.ts +40 -0
- package/build/types-ts3.8/types-hoist/replay.d.ts +4 -0
- package/build/types-ts3.8/utils/misc.d.ts +7 -0
- package/build/types-ts3.8/utils/tunnel.d.ts +16 -0
- package/build/types-ts3.8/utils/worldwide.d.ts +0 -2
- package/package.json +2 -3
package/build/esm/exports.js
CHANGED
|
@@ -6,6 +6,7 @@ import { debug } from './utils/debug-logger.js';
|
|
|
6
6
|
import { isThenable } from './utils/is.js';
|
|
7
7
|
import { uuid4 } from './utils/misc.js';
|
|
8
8
|
import { parseEventHintOrCaptureContext } from './utils/prepareEvent.js';
|
|
9
|
+
import { getCombinedScopeData } from './utils/scopeData.js';
|
|
9
10
|
import { timestampInSeconds } from './utils/time.js';
|
|
10
11
|
import { GLOBAL_OBJ } from './utils/worldwide.js';
|
|
11
12
|
|
|
@@ -260,13 +261,14 @@ function addEventProcessor(callback) {
|
|
|
260
261
|
*/
|
|
261
262
|
function startSession(context) {
|
|
262
263
|
const isolationScope = getIsolationScope();
|
|
263
|
-
|
|
264
|
+
|
|
265
|
+
const { user } = getCombinedScopeData(isolationScope, getCurrentScope());
|
|
264
266
|
|
|
265
267
|
// Will fetch userAgent if called from browser sdk
|
|
266
268
|
const { userAgent } = GLOBAL_OBJ.navigator || {};
|
|
267
269
|
|
|
268
270
|
const session = makeSession({
|
|
269
|
-
user
|
|
271
|
+
user,
|
|
270
272
|
...(userAgent && { userAgent }),
|
|
271
273
|
...context,
|
|
272
274
|
});
|
package/build/esm/exports.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exports.js","sources":["../../src/exports.ts"],"sourcesContent":["import { getClient, getCurrentScope, getIsolationScope, withIsolationScope } from './currentScopes';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { CaptureContext } from './scope';\nimport { closeSession, makeSession, updateSession } from './session';\nimport { startNewTrace } from './tracing/trace';\nimport type { CheckIn, FinishedCheckIn, MonitorConfig } from './types-hoist/checkin';\nimport type { Event, EventHint } from './types-hoist/event';\nimport type { EventProcessor } from './types-hoist/eventprocessor';\nimport type { Extra, Extras } from './types-hoist/extra';\nimport type { Primitive } from './types-hoist/misc';\nimport type { Session, SessionContext } from './types-hoist/session';\nimport type { SeverityLevel } from './types-hoist/severity';\nimport type { User } from './types-hoist/user';\nimport { debug } from './utils/debug-logger';\nimport { isThenable } from './utils/is';\nimport { uuid4 } from './utils/misc';\nimport type { ExclusiveEventHintOrCaptureContext } from './utils/prepareEvent';\nimport { parseEventHintOrCaptureContext } from './utils/prepareEvent';\nimport { timestampInSeconds } from './utils/time';\nimport { GLOBAL_OBJ } from './utils/worldwide';\n\n/**\n * Captures an exception event and sends it to Sentry.\n *\n * @param exception The exception to capture.\n * @param hint Optional additional data to attach to the Sentry event.\n * @returns the id of the captured Sentry event.\n */\nexport function captureException(exception: unknown, hint?: ExclusiveEventHintOrCaptureContext): string {\n return getCurrentScope().captureException(exception, parseEventHintOrCaptureContext(hint));\n}\n\n/**\n * Captures a message event and sends it to Sentry.\n *\n * @param message The message to send to Sentry.\n * @param captureContext Define the level of the message or pass in additional data to attach to the message.\n * @returns the id of the captured message.\n */\nexport function captureMessage(message: string, captureContext?: CaptureContext | SeverityLevel): string {\n // This is necessary to provide explicit scopes upgrade, without changing the original\n // arity of the `captureMessage(message, level)` method.\n const level = typeof captureContext === 'string' ? captureContext : undefined;\n const hint = typeof captureContext !== 'string' ? { captureContext } : undefined;\n return getCurrentScope().captureMessage(message, level, hint);\n}\n\n/**\n * Captures a manually created event and sends it to Sentry.\n *\n * @param event The event to send to Sentry.\n * @param hint Optional additional data to attach to the Sentry event.\n * @returns the id of the captured event.\n */\nexport function captureEvent(event: Event, hint?: EventHint): string {\n return getCurrentScope().captureEvent(event, hint);\n}\n\n/**\n * Sets context data with the given name.\n * @param name of the context\n * @param context Any kind of data. This data will be normalized.\n */\nexport function setContext(name: string, context: { [key: string]: unknown } | null): void {\n getIsolationScope().setContext(name, context);\n}\n\n/**\n * Set an object that will be merged sent as extra data with the event.\n * @param extras Extras object to merge into current context.\n */\nexport function setExtras(extras: Extras): void {\n getIsolationScope().setExtras(extras);\n}\n\n/**\n * Set key:value that will be sent as extra data with the event.\n * @param key String of extra\n * @param extra Any kind of data. This data will be normalized.\n */\nexport function setExtra(key: string, extra: Extra): void {\n getIsolationScope().setExtra(key, extra);\n}\n\n/**\n * Set an object that will be merged sent as tags data with the event.\n * @param tags Tags context object to merge into current context.\n */\nexport function setTags(tags: { [key: string]: Primitive }): void {\n getIsolationScope().setTags(tags);\n}\n\n/**\n * Set key:value that will be sent as tags data with the event.\n *\n * Can also be used to unset a tag, by passing `undefined`.\n *\n * @param key String key of tag\n * @param value Value of tag\n */\nexport function setTag(key: string, value: Primitive): void {\n getIsolationScope().setTag(key, value);\n}\n\n/**\n * Updates user context information for future events.\n *\n * @param user User context object to be set in the current context. Pass `null` to unset the user.\n */\nexport function setUser(user: User | null): void {\n getIsolationScope().setUser(user);\n}\n\n/**\n * Sets the conversation ID for the current isolation scope.\n *\n * @param conversationId The conversation ID to set. Pass `null` or `undefined` to unset the conversation ID.\n */\nexport function setConversationId(conversationId: string | null | undefined): void {\n getIsolationScope().setConversationId(conversationId);\n}\n\n/**\n * The last error event id of the isolation scope.\n *\n * Warning: This function really returns the last recorded error event id on the current\n * isolation scope. If you call this function after handling a certain error and another error\n * is captured in between, the last one is returned instead of the one you might expect.\n * Also, ids of events that were never sent to Sentry (for example because\n * they were dropped in `beforeSend`) could be returned.\n *\n * @returns The last event id of the isolation scope.\n */\nexport function lastEventId(): string | undefined {\n return getIsolationScope().lastEventId();\n}\n\n/**\n * Create a cron monitor check in and send it to Sentry.\n *\n * @param checkIn An object that describes a check in.\n * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want\n * to create a monitor automatically when sending a check in.\n */\nexport function captureCheckIn(checkIn: CheckIn, upsertMonitorConfig?: MonitorConfig): string {\n const scope = getCurrentScope();\n const client = getClient();\n if (!client) {\n DEBUG_BUILD && debug.warn('Cannot capture check-in. No client defined.');\n } else if (!client.captureCheckIn) {\n DEBUG_BUILD && debug.warn('Cannot capture check-in. Client does not support sending check-ins.');\n } else {\n return client.captureCheckIn(checkIn, upsertMonitorConfig, scope);\n }\n\n return uuid4();\n}\n\n/**\n * Wraps a callback with a cron monitor check in. The check in will be sent to Sentry when the callback finishes.\n *\n * @param monitorSlug The distinct slug of the monitor.\n * @param callback Callback to be monitored\n * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want\n * to create a monitor automatically when sending a check in.\n */\nexport function withMonitor<T>(\n monitorSlug: CheckIn['monitorSlug'],\n callback: () => T,\n upsertMonitorConfig?: MonitorConfig,\n): T {\n function runCallback(): T {\n const checkInId = captureCheckIn({ monitorSlug, status: 'in_progress' }, upsertMonitorConfig);\n const now = timestampInSeconds();\n\n function finishCheckIn(status: FinishedCheckIn['status']): void {\n captureCheckIn({ monitorSlug, status, checkInId, duration: timestampInSeconds() - now });\n }\n // Default behavior without isolateTrace\n let maybePromiseResult: T;\n try {\n maybePromiseResult = callback();\n } catch (e) {\n finishCheckIn('error');\n throw e;\n }\n\n if (isThenable(maybePromiseResult)) {\n return maybePromiseResult.then(\n r => {\n finishCheckIn('ok');\n return r;\n },\n e => {\n finishCheckIn('error');\n throw e;\n },\n ) as T;\n }\n finishCheckIn('ok');\n\n return maybePromiseResult;\n }\n\n return withIsolationScope(() => (upsertMonitorConfig?.isolateTrace ? startNewTrace(runCallback) : runCallback()));\n}\n\n/**\n * Call `flush()` on the current client, if there is one. See {@link Client.flush}.\n *\n * @param timeout Maximum time in ms the client should wait to flush its event queue. Omitting this parameter will cause\n * the client to wait until all events are sent before resolving the promise.\n * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it\n * doesn't (or if there's no client defined).\n */\nexport async function flush(timeout?: number): Promise<boolean> {\n const client = getClient();\n if (client) {\n return client.flush(timeout);\n }\n DEBUG_BUILD && debug.warn('Cannot flush events. No client defined.');\n return Promise.resolve(false);\n}\n\n/**\n * Call `close()` on the current client, if there is one. See {@link Client.close}.\n *\n * @param timeout Maximum time in ms the client should wait to flush its event queue before shutting down. Omitting this\n * parameter will cause the client to wait until all events are sent before disabling itself.\n * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it\n * doesn't (or if there's no client defined).\n */\nexport async function close(timeout?: number): Promise<boolean> {\n const client = getClient();\n if (client) {\n return client.close(timeout);\n }\n DEBUG_BUILD && debug.warn('Cannot flush events and disable SDK. No client defined.');\n return Promise.resolve(false);\n}\n\n/**\n * Returns true if Sentry has been properly initialized.\n */\nexport function isInitialized(): boolean {\n return !!getClient();\n}\n\n/** If the SDK is initialized & enabled. */\nexport function isEnabled(): boolean {\n const client = getClient();\n return client?.getOptions().enabled !== false && !!client?.getTransport();\n}\n\n/**\n * Add an event processor.\n * This will be added to the current isolation scope, ensuring any event that is processed in the current execution\n * context will have the processor applied.\n */\nexport function addEventProcessor(callback: EventProcessor): void {\n getIsolationScope().addEventProcessor(callback);\n}\n\n/**\n * Start a session on the current isolation scope.\n *\n * @param context (optional) additional properties to be applied to the returned session object\n *\n * @returns the new active session\n */\nexport function startSession(context?: SessionContext): Session {\n const isolationScope = getIsolationScope();\n const currentScope = getCurrentScope();\n\n // Will fetch userAgent if called from browser sdk\n const { userAgent } = GLOBAL_OBJ.navigator || {};\n\n const session = makeSession({\n user: currentScope.getUser() || isolationScope.getUser(),\n ...(userAgent && { userAgent }),\n ...context,\n });\n\n // End existing session if there's one\n const currentSession = isolationScope.getSession();\n if (currentSession?.status === 'ok') {\n updateSession(currentSession, { status: 'exited' });\n }\n\n endSession();\n\n // Afterwards we set the new session on the scope\n isolationScope.setSession(session);\n\n return session;\n}\n\n/**\n * End the session on the current isolation scope.\n */\nexport function endSession(): void {\n const isolationScope = getIsolationScope();\n const currentScope = getCurrentScope();\n\n const session = currentScope.getSession() || isolationScope.getSession();\n if (session) {\n closeSession(session);\n }\n _sendSessionUpdate();\n\n // the session is over; take it off of the scope\n isolationScope.setSession();\n}\n\n/**\n * Sends the current Session on the scope\n */\nfunction _sendSessionUpdate(): void {\n const isolationScope = getIsolationScope();\n const client = getClient();\n const session = isolationScope.getSession();\n if (session && client) {\n client.captureSession(session);\n }\n}\n\n/**\n * Sends the current session on the scope to Sentry\n *\n * @param end If set the session will be marked as exited and removed from the scope.\n * Defaults to `false`.\n */\nexport function captureSession(end: boolean = false): void {\n // both send the update and pull the session from the scope\n if (end) {\n endSession();\n return;\n }\n\n // only send the update\n _sendSessionUpdate();\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAqBA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAC,SAAS,EAAW,IAAI,EAA+C;AACxG,EAAE,OAAO,eAAe,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,8BAA8B,CAAC,IAAI,CAAC,CAAC;AAC5F;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,cAAc,CAAC,OAAO,EAAU,cAAc,EAA2C;AACzG;AACA;AACA,EAAE,MAAM,KAAA,GAAQ,OAAO,cAAA,KAAmB,QAAA,GAAW,cAAA,GAAiB,SAAS;AAC/E,EAAE,MAAM,IAAA,GAAO,OAAO,cAAA,KAAmB,QAAA,GAAW,EAAE,cAAA,EAAe,GAAI,SAAS;AAClF,EAAE,OAAO,eAAe,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,YAAY,CAAC,KAAK,EAAS,IAAI,EAAsB;AACrE,EAAE,OAAO,eAAe,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC;AACpD;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,UAAU,CAAC,IAAI,EAAU,OAAO,EAA2C;AAC3F,EAAE,iBAAiB,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;AAC/C;;AAEA;AACA;AACA;AACA;AACO,SAAS,SAAS,CAAC,MAAM,EAAgB;AAChD,EAAE,iBAAiB,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;AACvC;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,QAAQ,CAAC,GAAG,EAAU,KAAK,EAAe;AAC1D,EAAE,iBAAiB,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;AAC1C;;AAEA;AACA;AACA;AACA;AACO,SAAS,OAAO,CAAC,IAAI,EAAsC;AAClE,EAAE,iBAAiB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;AACnC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,MAAM,CAAC,GAAG,EAAU,KAAK,EAAmB;AAC5D,EAAE,iBAAiB,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,OAAO,CAAC,IAAI,EAAqB;AACjD,EAAE,iBAAiB,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;AACnC;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,cAAc,EAAmC;AACnF,EAAE,iBAAiB,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;AACvD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW,GAAuB;AAClD,EAAE,OAAO,iBAAiB,EAAE,CAAC,WAAW,EAAE;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,cAAc,CAAC,OAAO,EAAW,mBAAmB,EAA0B;AAC9F,EAAE,MAAM,KAAA,GAAQ,eAAe,EAAE;AACjC,EAAE,MAAM,MAAA,GAAS,SAAS,EAAE;AAC5B,EAAE,IAAI,CAAC,MAAM,EAAE;AACf,IAAI,eAAe,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC;AAC5E,EAAE,CAAA,MAAO,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE;AACrC,IAAI,eAAe,KAAK,CAAC,IAAI,CAAC,qEAAqE,CAAC;AACpG,EAAE,OAAO;AACT,IAAI,OAAO,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,CAAC;AACrE,EAAE;;AAEF,EAAE,OAAO,KAAK,EAAE;AAChB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW;AAC3B,EAAE,WAAW;AACb,EAAE,QAAQ;AACV,EAAE,mBAAmB;AACrB,EAAK;AACL,EAAE,SAAS,WAAW,GAAM;AAC5B,IAAI,MAAM,SAAA,GAAY,cAAc,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,aAAA,EAAe,EAAE,mBAAmB,CAAC;AACjG,IAAI,MAAM,GAAA,GAAM,kBAAkB,EAAE;;AAEpC,IAAI,SAAS,aAAa,CAAC,MAAM,EAAmC;AACpE,MAAM,cAAc,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,kBAAkB,KAAK,GAAA,EAAK,CAAC;AAC9F,IAAI;AACJ;AACA,IAAI,IAAI,kBAAkB;AAC1B,IAAI,IAAI;AACR,MAAM,kBAAA,GAAqB,QAAQ,EAAE;AACrC,IAAI,CAAA,CAAE,OAAO,CAAC,EAAE;AAChB,MAAM,aAAa,CAAC,OAAO,CAAC;AAC5B,MAAM,MAAM,CAAC;AACb,IAAI;;AAEJ,IAAI,IAAI,UAAU,CAAC,kBAAkB,CAAC,EAAE;AACxC,MAAM,OAAO,kBAAkB,CAAC,IAAI;AACpC,QAAQ,KAAK;AACb,UAAU,aAAa,CAAC,IAAI,CAAC;AAC7B,UAAU,OAAO,CAAC;AAClB,QAAQ,CAAC;AACT,QAAQ,KAAK;AACb,UAAU,aAAa,CAAC,OAAO,CAAC;AAChC,UAAU,MAAM,CAAC;AACjB,QAAQ,CAAC;AACT,OAAM;AACN,IAAI;AACJ,IAAI,aAAa,CAAC,IAAI,CAAC;;AAEvB,IAAI,OAAO,kBAAkB;AAC7B,EAAE;;AAEF,EAAE,OAAO,kBAAkB,CAAC,OAAO,mBAAmB,EAAE,YAAA,GAAe,aAAa,CAAC,WAAW,CAAA,GAAI,WAAW,EAAE,CAAC,CAAC;AACnH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,KAAK,CAAC,OAAO,EAA6B;AAChE,EAAE,MAAM,MAAA,GAAS,SAAS,EAAE;AAC5B,EAAE,IAAI,MAAM,EAAE;AACd,IAAI,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;AAChC,EAAE;AACF,EAAE,eAAe,KAAK,CAAC,IAAI,CAAC,yCAAyC,CAAC;AACtE,EAAE,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,KAAK,CAAC,OAAO,EAA6B;AAChE,EAAE,MAAM,MAAA,GAAS,SAAS,EAAE;AAC5B,EAAE,IAAI,MAAM,EAAE;AACd,IAAI,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;AAChC,EAAE;AACF,EAAE,eAAe,KAAK,CAAC,IAAI,CAAC,yDAAyD,CAAC;AACtF,EAAE,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;AAC/B;;AAEA;AACA;AACA;AACO,SAAS,aAAa,GAAY;AACzC,EAAE,OAAO,CAAC,CAAC,SAAS,EAAE;AACtB;;AAEA;AACO,SAAS,SAAS,GAAY;AACrC,EAAE,MAAM,MAAA,GAAS,SAAS,EAAE;AAC5B,EAAE,OAAO,MAAM,EAAE,UAAU,EAAE,CAAC,OAAA,KAAY,KAAA,IAAS,CAAC,CAAC,MAAM,EAAE,YAAY,EAAE;AAC3E;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,QAAQ,EAAwB;AAClE,EAAE,iBAAiB,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC;AACjD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,YAAY,CAAC,OAAO,EAA4B;AAChE,EAAE,MAAM,cAAA,GAAiB,iBAAiB,EAAE;AAC5C,EAAE,MAAM,YAAA,GAAe,eAAe,EAAE;;AAExC;AACA,EAAE,MAAM,EAAE,SAAA,EAAU,GAAI,UAAU,CAAC,SAAA,IAAa,EAAE;;AAElD,EAAE,MAAM,OAAA,GAAU,WAAW,CAAC;AAC9B,IAAI,IAAI,EAAE,YAAY,CAAC,OAAO,EAAC,IAAK,cAAc,CAAC,OAAO,EAAE;AAC5D,IAAI,IAAI,SAAA,IAAa,EAAE,SAAA,EAAW,CAAC;AACnC,IAAI,GAAG,OAAO;AACd,GAAG,CAAC;;AAEJ;AACA,EAAE,MAAM,cAAA,GAAiB,cAAc,CAAC,UAAU,EAAE;AACpD,EAAE,IAAI,cAAc,EAAE,MAAA,KAAW,IAAI,EAAE;AACvC,IAAI,aAAa,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,QAAA,EAAU,CAAC;AACvD,EAAE;;AAEF,EAAE,UAAU,EAAE;;AAEd;AACA,EAAE,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC;;AAEpC,EAAE,OAAO,OAAO;AAChB;;AAEA;AACA;AACA;AACO,SAAS,UAAU,GAAS;AACnC,EAAE,MAAM,cAAA,GAAiB,iBAAiB,EAAE;AAC5C,EAAE,MAAM,YAAA,GAAe,eAAe,EAAE;;AAExC,EAAE,MAAM,OAAA,GAAU,YAAY,CAAC,UAAU,EAAC,IAAK,cAAc,CAAC,UAAU,EAAE;AAC1E,EAAE,IAAI,OAAO,EAAE;AACf,IAAI,YAAY,CAAC,OAAO,CAAC;AACzB,EAAE;AACF,EAAE,kBAAkB,EAAE;;AAEtB;AACA,EAAE,cAAc,CAAC,UAAU,EAAE;AAC7B;;AAEA;AACA;AACA;AACA,SAAS,kBAAkB,GAAS;AACpC,EAAE,MAAM,cAAA,GAAiB,iBAAiB,EAAE;AAC5C,EAAE,MAAM,MAAA,GAAS,SAAS,EAAE;AAC5B,EAAE,MAAM,OAAA,GAAU,cAAc,CAAC,UAAU,EAAE;AAC7C,EAAE,IAAI,OAAA,IAAW,MAAM,EAAE;AACzB,IAAI,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC;AAClC,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,cAAc,CAAC,GAAG,GAAY,KAAK,EAAQ;AAC3D;AACA,EAAE,IAAI,GAAG,EAAE;AACX,IAAI,UAAU,EAAE;AAChB,IAAI;AACJ,EAAE;;AAEF;AACA,EAAE,kBAAkB,EAAE;AACtB;;;;"}
|
|
1
|
+
{"version":3,"file":"exports.js","sources":["../../src/exports.ts"],"sourcesContent":["import { getClient, getCurrentScope, getIsolationScope, withIsolationScope } from './currentScopes';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { CaptureContext } from './scope';\nimport { closeSession, makeSession, updateSession } from './session';\nimport { startNewTrace } from './tracing/trace';\nimport type { CheckIn, FinishedCheckIn, MonitorConfig } from './types-hoist/checkin';\nimport type { Event, EventHint } from './types-hoist/event';\nimport type { EventProcessor } from './types-hoist/eventprocessor';\nimport type { Extra, Extras } from './types-hoist/extra';\nimport type { Primitive } from './types-hoist/misc';\nimport type { Session, SessionContext } from './types-hoist/session';\nimport type { SeverityLevel } from './types-hoist/severity';\nimport type { User } from './types-hoist/user';\nimport { debug } from './utils/debug-logger';\nimport { isThenable } from './utils/is';\nimport { uuid4 } from './utils/misc';\nimport type { ExclusiveEventHintOrCaptureContext } from './utils/prepareEvent';\nimport { parseEventHintOrCaptureContext } from './utils/prepareEvent';\nimport { getCombinedScopeData } from './utils/scopeData';\nimport { timestampInSeconds } from './utils/time';\nimport { GLOBAL_OBJ } from './utils/worldwide';\n\n/**\n * Captures an exception event and sends it to Sentry.\n *\n * @param exception The exception to capture.\n * @param hint Optional additional data to attach to the Sentry event.\n * @returns the id of the captured Sentry event.\n */\nexport function captureException(exception: unknown, hint?: ExclusiveEventHintOrCaptureContext): string {\n return getCurrentScope().captureException(exception, parseEventHintOrCaptureContext(hint));\n}\n\n/**\n * Captures a message event and sends it to Sentry.\n *\n * @param message The message to send to Sentry.\n * @param captureContext Define the level of the message or pass in additional data to attach to the message.\n * @returns the id of the captured message.\n */\nexport function captureMessage(message: string, captureContext?: CaptureContext | SeverityLevel): string {\n // This is necessary to provide explicit scopes upgrade, without changing the original\n // arity of the `captureMessage(message, level)` method.\n const level = typeof captureContext === 'string' ? captureContext : undefined;\n const hint = typeof captureContext !== 'string' ? { captureContext } : undefined;\n return getCurrentScope().captureMessage(message, level, hint);\n}\n\n/**\n * Captures a manually created event and sends it to Sentry.\n *\n * @param event The event to send to Sentry.\n * @param hint Optional additional data to attach to the Sentry event.\n * @returns the id of the captured event.\n */\nexport function captureEvent(event: Event, hint?: EventHint): string {\n return getCurrentScope().captureEvent(event, hint);\n}\n\n/**\n * Sets context data with the given name.\n * @param name of the context\n * @param context Any kind of data. This data will be normalized.\n */\nexport function setContext(name: string, context: { [key: string]: unknown } | null): void {\n getIsolationScope().setContext(name, context);\n}\n\n/**\n * Set an object that will be merged sent as extra data with the event.\n * @param extras Extras object to merge into current context.\n */\nexport function setExtras(extras: Extras): void {\n getIsolationScope().setExtras(extras);\n}\n\n/**\n * Set key:value that will be sent as extra data with the event.\n * @param key String of extra\n * @param extra Any kind of data. This data will be normalized.\n */\nexport function setExtra(key: string, extra: Extra): void {\n getIsolationScope().setExtra(key, extra);\n}\n\n/**\n * Set an object that will be merged sent as tags data with the event.\n * @param tags Tags context object to merge into current context.\n */\nexport function setTags(tags: { [key: string]: Primitive }): void {\n getIsolationScope().setTags(tags);\n}\n\n/**\n * Set key:value that will be sent as tags data with the event.\n *\n * Can also be used to unset a tag, by passing `undefined`.\n *\n * @param key String key of tag\n * @param value Value of tag\n */\nexport function setTag(key: string, value: Primitive): void {\n getIsolationScope().setTag(key, value);\n}\n\n/**\n * Updates user context information for future events.\n *\n * @param user User context object to be set in the current context. Pass `null` to unset the user.\n */\nexport function setUser(user: User | null): void {\n getIsolationScope().setUser(user);\n}\n\n/**\n * Sets the conversation ID for the current isolation scope.\n *\n * @param conversationId The conversation ID to set. Pass `null` or `undefined` to unset the conversation ID.\n */\nexport function setConversationId(conversationId: string | null | undefined): void {\n getIsolationScope().setConversationId(conversationId);\n}\n\n/**\n * The last error event id of the isolation scope.\n *\n * Warning: This function really returns the last recorded error event id on the current\n * isolation scope. If you call this function after handling a certain error and another error\n * is captured in between, the last one is returned instead of the one you might expect.\n * Also, ids of events that were never sent to Sentry (for example because\n * they were dropped in `beforeSend`) could be returned.\n *\n * @returns The last event id of the isolation scope.\n */\nexport function lastEventId(): string | undefined {\n return getIsolationScope().lastEventId();\n}\n\n/**\n * Create a cron monitor check in and send it to Sentry.\n *\n * @param checkIn An object that describes a check in.\n * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want\n * to create a monitor automatically when sending a check in.\n */\nexport function captureCheckIn(checkIn: CheckIn, upsertMonitorConfig?: MonitorConfig): string {\n const scope = getCurrentScope();\n const client = getClient();\n if (!client) {\n DEBUG_BUILD && debug.warn('Cannot capture check-in. No client defined.');\n } else if (!client.captureCheckIn) {\n DEBUG_BUILD && debug.warn('Cannot capture check-in. Client does not support sending check-ins.');\n } else {\n return client.captureCheckIn(checkIn, upsertMonitorConfig, scope);\n }\n\n return uuid4();\n}\n\n/**\n * Wraps a callback with a cron monitor check in. The check in will be sent to Sentry when the callback finishes.\n *\n * @param monitorSlug The distinct slug of the monitor.\n * @param callback Callback to be monitored\n * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want\n * to create a monitor automatically when sending a check in.\n */\nexport function withMonitor<T>(\n monitorSlug: CheckIn['monitorSlug'],\n callback: () => T,\n upsertMonitorConfig?: MonitorConfig,\n): T {\n function runCallback(): T {\n const checkInId = captureCheckIn({ monitorSlug, status: 'in_progress' }, upsertMonitorConfig);\n const now = timestampInSeconds();\n\n function finishCheckIn(status: FinishedCheckIn['status']): void {\n captureCheckIn({ monitorSlug, status, checkInId, duration: timestampInSeconds() - now });\n }\n // Default behavior without isolateTrace\n let maybePromiseResult: T;\n try {\n maybePromiseResult = callback();\n } catch (e) {\n finishCheckIn('error');\n throw e;\n }\n\n if (isThenable(maybePromiseResult)) {\n return maybePromiseResult.then(\n r => {\n finishCheckIn('ok');\n return r;\n },\n e => {\n finishCheckIn('error');\n throw e;\n },\n ) as T;\n }\n finishCheckIn('ok');\n\n return maybePromiseResult;\n }\n\n return withIsolationScope(() => (upsertMonitorConfig?.isolateTrace ? startNewTrace(runCallback) : runCallback()));\n}\n\n/**\n * Call `flush()` on the current client, if there is one. See {@link Client.flush}.\n *\n * @param timeout Maximum time in ms the client should wait to flush its event queue. Omitting this parameter will cause\n * the client to wait until all events are sent before resolving the promise.\n * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it\n * doesn't (or if there's no client defined).\n */\nexport async function flush(timeout?: number): Promise<boolean> {\n const client = getClient();\n if (client) {\n return client.flush(timeout);\n }\n DEBUG_BUILD && debug.warn('Cannot flush events. No client defined.');\n return Promise.resolve(false);\n}\n\n/**\n * Call `close()` on the current client, if there is one. See {@link Client.close}.\n *\n * @param timeout Maximum time in ms the client should wait to flush its event queue before shutting down. Omitting this\n * parameter will cause the client to wait until all events are sent before disabling itself.\n * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it\n * doesn't (or if there's no client defined).\n */\nexport async function close(timeout?: number): Promise<boolean> {\n const client = getClient();\n if (client) {\n return client.close(timeout);\n }\n DEBUG_BUILD && debug.warn('Cannot flush events and disable SDK. No client defined.');\n return Promise.resolve(false);\n}\n\n/**\n * Returns true if Sentry has been properly initialized.\n */\nexport function isInitialized(): boolean {\n return !!getClient();\n}\n\n/** If the SDK is initialized & enabled. */\nexport function isEnabled(): boolean {\n const client = getClient();\n return client?.getOptions().enabled !== false && !!client?.getTransport();\n}\n\n/**\n * Add an event processor.\n * This will be added to the current isolation scope, ensuring any event that is processed in the current execution\n * context will have the processor applied.\n */\nexport function addEventProcessor(callback: EventProcessor): void {\n getIsolationScope().addEventProcessor(callback);\n}\n\n/**\n * Start a session on the current isolation scope.\n *\n * @param context (optional) additional properties to be applied to the returned session object\n *\n * @returns the new active session\n */\nexport function startSession(context?: SessionContext): Session {\n const isolationScope = getIsolationScope();\n\n const { user } = getCombinedScopeData(isolationScope, getCurrentScope());\n\n // Will fetch userAgent if called from browser sdk\n const { userAgent } = GLOBAL_OBJ.navigator || {};\n\n const session = makeSession({\n user,\n ...(userAgent && { userAgent }),\n ...context,\n });\n\n // End existing session if there's one\n const currentSession = isolationScope.getSession();\n if (currentSession?.status === 'ok') {\n updateSession(currentSession, { status: 'exited' });\n }\n\n endSession();\n\n // Afterwards we set the new session on the scope\n isolationScope.setSession(session);\n\n return session;\n}\n\n/**\n * End the session on the current isolation scope.\n */\nexport function endSession(): void {\n const isolationScope = getIsolationScope();\n const currentScope = getCurrentScope();\n\n const session = currentScope.getSession() || isolationScope.getSession();\n if (session) {\n closeSession(session);\n }\n _sendSessionUpdate();\n\n // the session is over; take it off of the scope\n isolationScope.setSession();\n}\n\n/**\n * Sends the current Session on the scope\n */\nfunction _sendSessionUpdate(): void {\n const isolationScope = getIsolationScope();\n const client = getClient();\n const session = isolationScope.getSession();\n if (session && client) {\n client.captureSession(session);\n }\n}\n\n/**\n * Sends the current session on the scope to Sentry\n *\n * @param end If set the session will be marked as exited and removed from the scope.\n * Defaults to `false`.\n */\nexport function captureSession(end: boolean = false): void {\n // both send the update and pull the session from the scope\n if (end) {\n endSession();\n return;\n }\n\n // only send the update\n _sendSessionUpdate();\n}\n"],"names":[],"mappings":"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"}
|
package/build/esm/fetch.js
CHANGED
|
@@ -30,19 +30,23 @@ function instrumentFetchRequest(
|
|
|
30
30
|
|
|
31
31
|
const shouldCreateSpanResult = hasSpansEnabled() && shouldCreateSpan(url);
|
|
32
32
|
|
|
33
|
-
if (handlerData.endTimestamp
|
|
33
|
+
if (handlerData.endTimestamp) {
|
|
34
34
|
const spanId = handlerData.fetchData.__span;
|
|
35
35
|
if (!spanId) return;
|
|
36
36
|
|
|
37
37
|
const span = spans[spanId];
|
|
38
|
-
if (span) {
|
|
39
|
-
endSpan(span, handlerData);
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
if (span) {
|
|
40
|
+
// Only end the span and call hooks if we're actually recording
|
|
41
|
+
if (shouldCreateSpanResult) {
|
|
42
|
+
endSpan(span, handlerData);
|
|
43
|
+
_callOnRequestSpanEnd(span, handlerData, spanOriginOrOptions);
|
|
44
|
+
}
|
|
42
45
|
|
|
43
46
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
44
47
|
delete spans[spanId];
|
|
45
48
|
}
|
|
49
|
+
|
|
46
50
|
return undefined;
|
|
47
51
|
}
|
|
48
52
|
|
package/build/esm/fetch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sources":["../../src/fetch.ts"],"sourcesContent":["import { getClient } from './currentScopes';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from './semanticAttributes';\nimport { setHttpStatus, SPAN_STATUS_ERROR, startInactiveSpan } from './tracing';\nimport { SentryNonRecordingSpan } from './tracing/sentryNonRecordingSpan';\nimport type { FetchBreadcrumbHint } from './types-hoist/breadcrumb';\nimport type { HandlerDataFetch } from './types-hoist/instrument';\nimport type { ResponseHookInfo } from './types-hoist/request';\nimport type { Span, SpanAttributes, SpanOrigin } from './types-hoist/span';\nimport { SENTRY_BAGGAGE_KEY_PREFIX } from './utils/baggage';\nimport { hasSpansEnabled } from './utils/hasSpansEnabled';\nimport { isInstanceOf, isRequest } from './utils/is';\nimport { getActiveSpan } from './utils/spanUtils';\nimport { getTraceData } from './utils/traceData';\nimport {\n getSanitizedUrlStringFromUrlObject,\n isURLObjectRelative,\n parseStringToURLObject,\n stripDataUrlContent,\n} from './utils/url';\n\ntype PolymorphicRequestHeaders =\n | Record<string, string | undefined>\n | Array<[string, string]>\n // the below is not precisely the Header type used in Request, but it'll pass duck-typing\n | {\n append: (key: string, value: string) => void;\n get: (key: string) => string | null | undefined;\n };\n\ninterface InstrumentFetchRequestOptions {\n spanOrigin?: SpanOrigin;\n propagateTraceparent?: boolean;\n onRequestSpanEnd?: (span: Span, responseInformation: ResponseHookInfo) => void;\n}\n\n/**\n * Create and track fetch request spans for usage in combination with `addFetchInstrumentationHandler`.\n *\n * @deprecated pass an options object instead of the spanOrigin parameter\n *\n * @returns Span if a span was created, otherwise void.\n */\nexport function instrumentFetchRequest(\n handlerData: HandlerDataFetch,\n shouldCreateSpan: (url: string) => boolean,\n shouldAttachHeaders: (url: string) => boolean,\n spans: Record<string, Span>,\n spanOrigin: SpanOrigin,\n): Span | undefined;\n/**\n * Create and track fetch request spans for usage in combination with `addFetchInstrumentationHandler`.\n *\n * @returns Span if a span was created, otherwise void.\n */\nexport function instrumentFetchRequest(\n handlerData: HandlerDataFetch,\n shouldCreateSpan: (url: string) => boolean,\n shouldAttachHeaders: (url: string) => boolean,\n spans: Record<string, Span>,\n // eslint-disable-next-line @typescript-eslint/unified-signatures -- needed because the other overload is deprecated\n instrumentFetchRequestOptions: InstrumentFetchRequestOptions,\n): Span | undefined;\n\n/**\n * Create and track fetch request spans for usage in combination with `addFetchInstrumentationHandler`.\n *\n * @returns Span if a span was created, otherwise void.\n */\nexport function instrumentFetchRequest(\n handlerData: HandlerDataFetch,\n shouldCreateSpan: (url: string) => boolean,\n shouldAttachHeaders: (url: string) => boolean,\n spans: Record<string, Span>,\n spanOriginOrOptions?: SpanOrigin | InstrumentFetchRequestOptions,\n): Span | undefined {\n if (!handlerData.fetchData) {\n return undefined;\n }\n\n const { method, url } = handlerData.fetchData;\n\n const shouldCreateSpanResult = hasSpansEnabled() && shouldCreateSpan(url);\n\n if (handlerData.endTimestamp && shouldCreateSpanResult) {\n const spanId = handlerData.fetchData.__span;\n if (!spanId) return;\n\n const span = spans[spanId];\n if (span) {\n endSpan(span, handlerData);\n\n _callOnRequestSpanEnd(span, handlerData, spanOriginOrOptions);\n\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete spans[spanId];\n }\n return undefined;\n }\n\n // Backwards-compatible with the old signature. Needed to introduce the combined optional parameter\n // to avoid API breakage for anyone calling this function with the optional spanOrigin parameter\n // TODO (v11): remove this backwards-compatible code and only accept the options parameter\n const { spanOrigin = 'auto.http.browser', propagateTraceparent = false } =\n typeof spanOriginOrOptions === 'object' ? spanOriginOrOptions : { spanOrigin: spanOriginOrOptions };\n\n const hasParent = !!getActiveSpan();\n\n const span =\n shouldCreateSpanResult && hasParent\n ? startInactiveSpan(getSpanStartOptions(url, method, spanOrigin))\n : new SentryNonRecordingSpan();\n\n handlerData.fetchData.__span = span.spanContext().spanId;\n spans[span.spanContext().spanId] = span;\n\n if (shouldAttachHeaders(handlerData.fetchData.url)) {\n const request: string | Request = handlerData.args[0];\n\n // Shallow clone the options object to avoid mutating the original user-provided object\n // Examples: users re-using same options object for multiple fetch calls, frozen objects\n const options: { [key: string]: unknown } = { ...(handlerData.args[1] || {}) };\n\n const headers = _addTracingHeadersToFetchRequest(\n request,\n options,\n // If performance is disabled (TWP) or there's no active root span (pageload/navigation/interaction),\n // we do not want to use the span as base for the trace headers,\n // which means that the headers will be generated from the scope and the sampling decision is deferred\n hasSpansEnabled() && hasParent ? span : undefined,\n propagateTraceparent,\n );\n if (headers) {\n // Ensure this is actually set, if no options have been passed previously\n handlerData.args[1] = options;\n options.headers = headers;\n }\n }\n\n const client = getClient();\n\n if (client) {\n const fetchHint = {\n input: handlerData.args,\n response: handlerData.response,\n startTimestamp: handlerData.startTimestamp,\n endTimestamp: handlerData.endTimestamp,\n } satisfies FetchBreadcrumbHint;\n\n client.emit('beforeOutgoingRequestSpan', span, fetchHint);\n }\n\n return span;\n}\n\n/**\n * Calls the onRequestSpanEnd callback if it is defined.\n */\nexport function _callOnRequestSpanEnd(\n span: Span,\n handlerData: HandlerDataFetch,\n spanOriginOrOptions?: SpanOrigin | InstrumentFetchRequestOptions,\n): void {\n const onRequestSpanEnd =\n typeof spanOriginOrOptions === 'object' && spanOriginOrOptions !== null\n ? spanOriginOrOptions.onRequestSpanEnd\n : undefined;\n\n onRequestSpanEnd?.(span, {\n headers: handlerData.response?.headers,\n error: handlerData.error,\n });\n}\n\n/**\n * Adds sentry-trace and baggage headers to the various forms of fetch headers.\n * exported only for testing purposes\n *\n * When we determine if we should add a baggage header, there are 3 cases:\n * 1. No previous baggage header -> add baggage\n * 2. Previous baggage header has no sentry baggage values -> add our baggage\n * 3. Previous baggage header has sentry baggage values -> do nothing (might have been added manually by users)\n */\n// eslint-disable-next-line complexity -- yup it's this complicated :(\nexport function _addTracingHeadersToFetchRequest(\n request: string | Request,\n fetchOptionsObj: {\n headers?:\n | {\n [key: string]: string[] | string | undefined;\n }\n | PolymorphicRequestHeaders;\n },\n span?: Span,\n propagateTraceparent?: boolean,\n): PolymorphicRequestHeaders | undefined {\n const traceHeaders = getTraceData({ span, propagateTraceparent });\n const sentryTrace = traceHeaders['sentry-trace'];\n const baggage = traceHeaders.baggage;\n const traceparent = traceHeaders.traceparent;\n\n // Nothing to do, when we return undefined here, the original headers will be used\n if (!sentryTrace) {\n return undefined;\n }\n\n const originalHeaders = fetchOptionsObj.headers || (isRequest(request) ? request.headers : undefined);\n\n if (!originalHeaders) {\n return { ...traceHeaders };\n } else if (isHeaders(originalHeaders)) {\n const newHeaders = new Headers(originalHeaders);\n\n // We don't want to override manually added sentry headers\n if (!newHeaders.get('sentry-trace')) {\n newHeaders.set('sentry-trace', sentryTrace);\n }\n\n if (propagateTraceparent && traceparent && !newHeaders.get('traceparent')) {\n newHeaders.set('traceparent', traceparent);\n }\n\n if (baggage) {\n const prevBaggageHeader = newHeaders.get('baggage');\n\n if (!prevBaggageHeader) {\n newHeaders.set('baggage', baggage);\n } else if (!baggageHeaderHasSentryBaggageValues(prevBaggageHeader)) {\n newHeaders.set('baggage', `${prevBaggageHeader},${baggage}`);\n }\n }\n\n return newHeaders;\n } else if (Array.isArray(originalHeaders)) {\n const newHeaders = [...originalHeaders];\n\n if (!originalHeaders.find(header => header[0] === 'sentry-trace')) {\n newHeaders.push(['sentry-trace', sentryTrace]);\n }\n\n if (propagateTraceparent && traceparent && !originalHeaders.find(header => header[0] === 'traceparent')) {\n newHeaders.push(['traceparent', traceparent]);\n }\n\n const prevBaggageHeaderWithSentryValues = originalHeaders.find(\n header => header[0] === 'baggage' && baggageHeaderHasSentryBaggageValues(header[1]),\n );\n\n if (baggage && !prevBaggageHeaderWithSentryValues) {\n // If there are multiple entries with the same key, the browser will merge the values into a single request header.\n // Its therefore safe to simply push a \"baggage\" entry, even though there might already be another baggage header.\n newHeaders.push(['baggage', baggage]);\n }\n\n return newHeaders as PolymorphicRequestHeaders;\n } else {\n const existingSentryTraceHeader = 'sentry-trace' in originalHeaders ? originalHeaders['sentry-trace'] : undefined;\n const existingTraceparentHeader = 'traceparent' in originalHeaders ? originalHeaders.traceparent : undefined;\n const existingBaggageHeader = 'baggage' in originalHeaders ? originalHeaders.baggage : undefined;\n\n const newBaggageHeaders: string[] = existingBaggageHeader\n ? Array.isArray(existingBaggageHeader)\n ? [...existingBaggageHeader]\n : [existingBaggageHeader]\n : [];\n\n const prevBaggageHeaderWithSentryValues =\n existingBaggageHeader &&\n (Array.isArray(existingBaggageHeader)\n ? existingBaggageHeader.find(headerItem => baggageHeaderHasSentryBaggageValues(headerItem))\n : baggageHeaderHasSentryBaggageValues(existingBaggageHeader));\n\n if (baggage && !prevBaggageHeaderWithSentryValues) {\n newBaggageHeaders.push(baggage);\n }\n\n const newHeaders: {\n 'sentry-trace': string;\n baggage: string | undefined;\n traceparent?: string;\n } = {\n ...originalHeaders,\n 'sentry-trace': (existingSentryTraceHeader as string | undefined) ?? sentryTrace,\n baggage: newBaggageHeaders.length > 0 ? newBaggageHeaders.join(',') : undefined,\n };\n\n if (propagateTraceparent && traceparent && !existingTraceparentHeader) {\n newHeaders.traceparent = traceparent;\n }\n\n return newHeaders;\n }\n}\n\nfunction endSpan(span: Span, handlerData: HandlerDataFetch): void {\n if (handlerData.response) {\n setHttpStatus(span, handlerData.response.status);\n\n const contentLength = handlerData.response?.headers?.get('content-length');\n\n if (contentLength) {\n const contentLengthNum = parseInt(contentLength);\n if (contentLengthNum > 0) {\n span.setAttribute('http.response_content_length', contentLengthNum);\n }\n }\n } else if (handlerData.error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n span.end();\n}\n\nfunction baggageHeaderHasSentryBaggageValues(baggageHeader: string): boolean {\n return baggageHeader.split(',').some(baggageEntry => baggageEntry.trim().startsWith(SENTRY_BAGGAGE_KEY_PREFIX));\n}\n\nfunction isHeaders(headers: unknown): headers is Headers {\n return typeof Headers !== 'undefined' && isInstanceOf(headers, Headers);\n}\n\nfunction getSpanStartOptions(\n url: string,\n method: string,\n spanOrigin: SpanOrigin,\n): Parameters<typeof startInactiveSpan>[0] {\n // Data URLs need special handling because parseStringToURLObject treats them as \"relative\"\n // (no \"://\"), causing getSanitizedUrlStringFromUrlObject to return just the pathname\n // without the \"data:\" prefix, making later stripDataUrlContent calls ineffective.\n // So for data URLs, we strip the content first and use that directly.\n if (url.startsWith('data:')) {\n const sanitizedUrl = stripDataUrlContent(url);\n return {\n name: `${method} ${sanitizedUrl}`,\n attributes: getFetchSpanAttributes(url, undefined, method, spanOrigin),\n };\n }\n\n const parsedUrl = parseStringToURLObject(url);\n const sanitizedUrl = parsedUrl ? getSanitizedUrlStringFromUrlObject(parsedUrl) : url;\n return {\n name: `${method} ${sanitizedUrl}`,\n attributes: getFetchSpanAttributes(url, parsedUrl, method, spanOrigin),\n };\n}\n\nfunction getFetchSpanAttributes(\n url: string,\n parsedUrl: ReturnType<typeof parseStringToURLObject>,\n method: string,\n spanOrigin: SpanOrigin,\n): SpanAttributes {\n const attributes: SpanAttributes = {\n url: stripDataUrlContent(url),\n type: 'fetch',\n 'http.method': method,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanOrigin,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',\n };\n if (parsedUrl) {\n if (!isURLObjectRelative(parsedUrl)) {\n attributes['http.url'] = stripDataUrlContent(parsedUrl.href);\n attributes['server.address'] = parsedUrl.host;\n }\n if (parsedUrl.search) {\n attributes['http.query'] = parsedUrl.search;\n }\n if (parsedUrl.hash) {\n attributes['http.fragment'] = parsedUrl.hash;\n }\n }\n return attributes;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fetch.js","sources":["../../src/fetch.ts"],"sourcesContent":["import { getClient } from './currentScopes';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from './semanticAttributes';\nimport { setHttpStatus, SPAN_STATUS_ERROR, startInactiveSpan } from './tracing';\nimport { SentryNonRecordingSpan } from './tracing/sentryNonRecordingSpan';\nimport type { FetchBreadcrumbHint } from './types-hoist/breadcrumb';\nimport type { HandlerDataFetch } from './types-hoist/instrument';\nimport type { ResponseHookInfo } from './types-hoist/request';\nimport type { Span, SpanAttributes, SpanOrigin } from './types-hoist/span';\nimport { SENTRY_BAGGAGE_KEY_PREFIX } from './utils/baggage';\nimport { hasSpansEnabled } from './utils/hasSpansEnabled';\nimport { isInstanceOf, isRequest } from './utils/is';\nimport { getActiveSpan } from './utils/spanUtils';\nimport { getTraceData } from './utils/traceData';\nimport {\n getSanitizedUrlStringFromUrlObject,\n isURLObjectRelative,\n parseStringToURLObject,\n stripDataUrlContent,\n} from './utils/url';\n\ntype PolymorphicRequestHeaders =\n | Record<string, string | undefined>\n | Array<[string, string]>\n // the below is not precisely the Header type used in Request, but it'll pass duck-typing\n | {\n append: (key: string, value: string) => void;\n get: (key: string) => string | null | undefined;\n };\n\ninterface InstrumentFetchRequestOptions {\n spanOrigin?: SpanOrigin;\n propagateTraceparent?: boolean;\n onRequestSpanEnd?: (span: Span, responseInformation: ResponseHookInfo) => void;\n}\n\n/**\n * Create and track fetch request spans for usage in combination with `addFetchInstrumentationHandler`.\n *\n * @deprecated pass an options object instead of the spanOrigin parameter\n *\n * @returns Span if a span was created, otherwise void.\n */\nexport function instrumentFetchRequest(\n handlerData: HandlerDataFetch,\n shouldCreateSpan: (url: string) => boolean,\n shouldAttachHeaders: (url: string) => boolean,\n spans: Record<string, Span>,\n spanOrigin: SpanOrigin,\n): Span | undefined;\n/**\n * Create and track fetch request spans for usage in combination with `addFetchInstrumentationHandler`.\n *\n * @returns Span if a span was created, otherwise void.\n */\nexport function instrumentFetchRequest(\n handlerData: HandlerDataFetch,\n shouldCreateSpan: (url: string) => boolean,\n shouldAttachHeaders: (url: string) => boolean,\n spans: Record<string, Span>,\n // eslint-disable-next-line @typescript-eslint/unified-signatures -- needed because the other overload is deprecated\n instrumentFetchRequestOptions: InstrumentFetchRequestOptions,\n): Span | undefined;\n\n/**\n * Create and track fetch request spans for usage in combination with `addFetchInstrumentationHandler`.\n *\n * @returns Span if a span was created, otherwise void.\n */\nexport function instrumentFetchRequest(\n handlerData: HandlerDataFetch,\n shouldCreateSpan: (url: string) => boolean,\n shouldAttachHeaders: (url: string) => boolean,\n spans: Record<string, Span>,\n spanOriginOrOptions?: SpanOrigin | InstrumentFetchRequestOptions,\n): Span | undefined {\n if (!handlerData.fetchData) {\n return undefined;\n }\n\n const { method, url } = handlerData.fetchData;\n\n const shouldCreateSpanResult = hasSpansEnabled() && shouldCreateSpan(url);\n\n if (handlerData.endTimestamp) {\n const spanId = handlerData.fetchData.__span;\n if (!spanId) return;\n\n const span = spans[spanId];\n\n if (span) {\n // Only end the span and call hooks if we're actually recording\n if (shouldCreateSpanResult) {\n endSpan(span, handlerData);\n _callOnRequestSpanEnd(span, handlerData, spanOriginOrOptions);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete spans[spanId];\n }\n\n return undefined;\n }\n\n // Backwards-compatible with the old signature. Needed to introduce the combined optional parameter\n // to avoid API breakage for anyone calling this function with the optional spanOrigin parameter\n // TODO (v11): remove this backwards-compatible code and only accept the options parameter\n const { spanOrigin = 'auto.http.browser', propagateTraceparent = false } =\n typeof spanOriginOrOptions === 'object' ? spanOriginOrOptions : { spanOrigin: spanOriginOrOptions };\n\n const hasParent = !!getActiveSpan();\n\n const span =\n shouldCreateSpanResult && hasParent\n ? startInactiveSpan(getSpanStartOptions(url, method, spanOrigin))\n : new SentryNonRecordingSpan();\n\n handlerData.fetchData.__span = span.spanContext().spanId;\n spans[span.spanContext().spanId] = span;\n\n if (shouldAttachHeaders(handlerData.fetchData.url)) {\n const request: string | Request = handlerData.args[0];\n\n // Shallow clone the options object to avoid mutating the original user-provided object\n // Examples: users re-using same options object for multiple fetch calls, frozen objects\n const options: { [key: string]: unknown } = { ...(handlerData.args[1] || {}) };\n\n const headers = _addTracingHeadersToFetchRequest(\n request,\n options,\n // If performance is disabled (TWP) or there's no active root span (pageload/navigation/interaction),\n // we do not want to use the span as base for the trace headers,\n // which means that the headers will be generated from the scope and the sampling decision is deferred\n hasSpansEnabled() && hasParent ? span : undefined,\n propagateTraceparent,\n );\n if (headers) {\n // Ensure this is actually set, if no options have been passed previously\n handlerData.args[1] = options;\n options.headers = headers;\n }\n }\n\n const client = getClient();\n\n if (client) {\n const fetchHint = {\n input: handlerData.args,\n response: handlerData.response,\n startTimestamp: handlerData.startTimestamp,\n endTimestamp: handlerData.endTimestamp,\n } satisfies FetchBreadcrumbHint;\n\n client.emit('beforeOutgoingRequestSpan', span, fetchHint);\n }\n\n return span;\n}\n\n/**\n * Calls the onRequestSpanEnd callback if it is defined.\n */\nexport function _callOnRequestSpanEnd(\n span: Span,\n handlerData: HandlerDataFetch,\n spanOriginOrOptions?: SpanOrigin | InstrumentFetchRequestOptions,\n): void {\n const onRequestSpanEnd =\n typeof spanOriginOrOptions === 'object' && spanOriginOrOptions !== null\n ? spanOriginOrOptions.onRequestSpanEnd\n : undefined;\n\n onRequestSpanEnd?.(span, {\n headers: handlerData.response?.headers,\n error: handlerData.error,\n });\n}\n\n/**\n * Adds sentry-trace and baggage headers to the various forms of fetch headers.\n * exported only for testing purposes\n *\n * When we determine if we should add a baggage header, there are 3 cases:\n * 1. No previous baggage header -> add baggage\n * 2. Previous baggage header has no sentry baggage values -> add our baggage\n * 3. Previous baggage header has sentry baggage values -> do nothing (might have been added manually by users)\n */\n// eslint-disable-next-line complexity -- yup it's this complicated :(\nexport function _addTracingHeadersToFetchRequest(\n request: string | Request,\n fetchOptionsObj: {\n headers?:\n | {\n [key: string]: string[] | string | undefined;\n }\n | PolymorphicRequestHeaders;\n },\n span?: Span,\n propagateTraceparent?: boolean,\n): PolymorphicRequestHeaders | undefined {\n const traceHeaders = getTraceData({ span, propagateTraceparent });\n const sentryTrace = traceHeaders['sentry-trace'];\n const baggage = traceHeaders.baggage;\n const traceparent = traceHeaders.traceparent;\n\n // Nothing to do, when we return undefined here, the original headers will be used\n if (!sentryTrace) {\n return undefined;\n }\n\n const originalHeaders = fetchOptionsObj.headers || (isRequest(request) ? request.headers : undefined);\n\n if (!originalHeaders) {\n return { ...traceHeaders };\n } else if (isHeaders(originalHeaders)) {\n const newHeaders = new Headers(originalHeaders);\n\n // We don't want to override manually added sentry headers\n if (!newHeaders.get('sentry-trace')) {\n newHeaders.set('sentry-trace', sentryTrace);\n }\n\n if (propagateTraceparent && traceparent && !newHeaders.get('traceparent')) {\n newHeaders.set('traceparent', traceparent);\n }\n\n if (baggage) {\n const prevBaggageHeader = newHeaders.get('baggage');\n\n if (!prevBaggageHeader) {\n newHeaders.set('baggage', baggage);\n } else if (!baggageHeaderHasSentryBaggageValues(prevBaggageHeader)) {\n newHeaders.set('baggage', `${prevBaggageHeader},${baggage}`);\n }\n }\n\n return newHeaders;\n } else if (Array.isArray(originalHeaders)) {\n const newHeaders = [...originalHeaders];\n\n if (!originalHeaders.find(header => header[0] === 'sentry-trace')) {\n newHeaders.push(['sentry-trace', sentryTrace]);\n }\n\n if (propagateTraceparent && traceparent && !originalHeaders.find(header => header[0] === 'traceparent')) {\n newHeaders.push(['traceparent', traceparent]);\n }\n\n const prevBaggageHeaderWithSentryValues = originalHeaders.find(\n header => header[0] === 'baggage' && baggageHeaderHasSentryBaggageValues(header[1]),\n );\n\n if (baggage && !prevBaggageHeaderWithSentryValues) {\n // If there are multiple entries with the same key, the browser will merge the values into a single request header.\n // Its therefore safe to simply push a \"baggage\" entry, even though there might already be another baggage header.\n newHeaders.push(['baggage', baggage]);\n }\n\n return newHeaders as PolymorphicRequestHeaders;\n } else {\n const existingSentryTraceHeader = 'sentry-trace' in originalHeaders ? originalHeaders['sentry-trace'] : undefined;\n const existingTraceparentHeader = 'traceparent' in originalHeaders ? originalHeaders.traceparent : undefined;\n const existingBaggageHeader = 'baggage' in originalHeaders ? originalHeaders.baggage : undefined;\n\n const newBaggageHeaders: string[] = existingBaggageHeader\n ? Array.isArray(existingBaggageHeader)\n ? [...existingBaggageHeader]\n : [existingBaggageHeader]\n : [];\n\n const prevBaggageHeaderWithSentryValues =\n existingBaggageHeader &&\n (Array.isArray(existingBaggageHeader)\n ? existingBaggageHeader.find(headerItem => baggageHeaderHasSentryBaggageValues(headerItem))\n : baggageHeaderHasSentryBaggageValues(existingBaggageHeader));\n\n if (baggage && !prevBaggageHeaderWithSentryValues) {\n newBaggageHeaders.push(baggage);\n }\n\n const newHeaders: {\n 'sentry-trace': string;\n baggage: string | undefined;\n traceparent?: string;\n } = {\n ...originalHeaders,\n 'sentry-trace': (existingSentryTraceHeader as string | undefined) ?? sentryTrace,\n baggage: newBaggageHeaders.length > 0 ? newBaggageHeaders.join(',') : undefined,\n };\n\n if (propagateTraceparent && traceparent && !existingTraceparentHeader) {\n newHeaders.traceparent = traceparent;\n }\n\n return newHeaders;\n }\n}\n\nfunction endSpan(span: Span, handlerData: HandlerDataFetch): void {\n if (handlerData.response) {\n setHttpStatus(span, handlerData.response.status);\n\n const contentLength = handlerData.response?.headers?.get('content-length');\n\n if (contentLength) {\n const contentLengthNum = parseInt(contentLength);\n if (contentLengthNum > 0) {\n span.setAttribute('http.response_content_length', contentLengthNum);\n }\n }\n } else if (handlerData.error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n span.end();\n}\n\nfunction baggageHeaderHasSentryBaggageValues(baggageHeader: string): boolean {\n return baggageHeader.split(',').some(baggageEntry => baggageEntry.trim().startsWith(SENTRY_BAGGAGE_KEY_PREFIX));\n}\n\nfunction isHeaders(headers: unknown): headers is Headers {\n return typeof Headers !== 'undefined' && isInstanceOf(headers, Headers);\n}\n\nfunction getSpanStartOptions(\n url: string,\n method: string,\n spanOrigin: SpanOrigin,\n): Parameters<typeof startInactiveSpan>[0] {\n // Data URLs need special handling because parseStringToURLObject treats them as \"relative\"\n // (no \"://\"), causing getSanitizedUrlStringFromUrlObject to return just the pathname\n // without the \"data:\" prefix, making later stripDataUrlContent calls ineffective.\n // So for data URLs, we strip the content first and use that directly.\n if (url.startsWith('data:')) {\n const sanitizedUrl = stripDataUrlContent(url);\n return {\n name: `${method} ${sanitizedUrl}`,\n attributes: getFetchSpanAttributes(url, undefined, method, spanOrigin),\n };\n }\n\n const parsedUrl = parseStringToURLObject(url);\n const sanitizedUrl = parsedUrl ? getSanitizedUrlStringFromUrlObject(parsedUrl) : url;\n return {\n name: `${method} ${sanitizedUrl}`,\n attributes: getFetchSpanAttributes(url, parsedUrl, method, spanOrigin),\n };\n}\n\nfunction getFetchSpanAttributes(\n url: string,\n parsedUrl: ReturnType<typeof parseStringToURLObject>,\n method: string,\n spanOrigin: SpanOrigin,\n): SpanAttributes {\n const attributes: SpanAttributes = {\n url: stripDataUrlContent(url),\n type: 'fetch',\n 'http.method': method,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanOrigin,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',\n };\n if (parsedUrl) {\n if (!isURLObjectRelative(parsedUrl)) {\n attributes['http.url'] = stripDataUrlContent(parsedUrl.href);\n attributes['server.address'] = parsedUrl.host;\n }\n if (parsedUrl.search) {\n attributes['http.query'] = parsedUrl.search;\n }\n if (parsedUrl.hash) {\n attributes['http.fragment'] = parsedUrl.hash;\n }\n }\n return attributes;\n}\n"],"names":[],"mappings":"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"}
|
package/build/esm/index.js
CHANGED
|
@@ -36,6 +36,7 @@ export { hasSpansEnabled } from './utils/hasSpansEnabled.js';
|
|
|
36
36
|
export { isSentryRequestUrl } from './utils/isSentryRequestUrl.js';
|
|
37
37
|
export { handleCallbackErrors } from './utils/handleCallbackErrors.js';
|
|
38
38
|
export { fmt, parameterize } from './utils/parameterize.js';
|
|
39
|
+
export { handleTunnelRequest } from './utils/tunnel.js';
|
|
39
40
|
export { addAutoIpAddressToSession, addAutoIpAddressToUser } from './utils/ipAddress.js';
|
|
40
41
|
export { addChildSpanToSpan, convertSpanLinksForEnvelope, getActiveSpan, getRootSpan, getSpanDescendants, getStatusMessage, spanIsSampled, spanTimeInputToSeconds, spanToJSON, spanToTraceContext, spanToTraceHeader, updateSpanName } from './utils/spanUtils.js';
|
|
41
42
|
export { _setSpanForScope as _INTERNAL_setSpanForScope } from './utils/spanOnScope.js';
|
|
@@ -104,7 +105,7 @@ export { addHandler, maybeInstrument, resetInstrumentationHandlers, triggerHandl
|
|
|
104
105
|
export { isDOMError, isDOMException, isElement, isError, isErrorEvent, isEvent, isInstanceOf, isParameterizedString, isPlainObject, isPrimitive, isRegExp, isString, isSyntheticEvent, isThenable, isVueViewModel } from './utils/is.js';
|
|
105
106
|
export { isBrowser } from './utils/isBrowser.js';
|
|
106
107
|
export { CONSOLE_LEVELS, consoleSandbox, debug, originalConsoleMethods } from './utils/debug-logger.js';
|
|
107
|
-
export { addContextToFrame, addExceptionMechanism, addExceptionTypeValue, checkOrSetAlreadyCaught, getEventDescription, parseSemver, uuid4 } from './utils/misc.js';
|
|
108
|
+
export { addContextToFrame, addExceptionMechanism, addExceptionTypeValue, checkOrSetAlreadyCaught, getEventDescription, isAlreadyCaptured, parseSemver, uuid4 } from './utils/misc.js';
|
|
108
109
|
export { isNodeEnv, loadModule } from './utils/node.js';
|
|
109
110
|
export { normalize, normalizeToSize, normalizeUrlToBase } from './utils/normalize.js';
|
|
110
111
|
export { addNonEnumerableProperty, convertToPlainObject, dropUndefinedKeys, extractExceptionKeysForMessage, fill, getOriginalFunction, markFunctionWrapped, objectify } from './utils/object.js';
|
package/build/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consola.js","sources":["../../../src/integrations/consola.ts"],"sourcesContent":["import type { Client } from '../client';\nimport { getClient } from '../currentScopes';\nimport { _INTERNAL_captureLog } from '../logs/internal';\nimport { formatConsoleArgs } from '../logs/utils';\nimport type { LogSeverityLevel } from '../types-hoist/log';\n\n/**\n * Options for the Sentry Consola reporter.\n */\ninterface ConsolaReporterOptions {\n /**\n * Use this option to filter which levels should be captured. By default, all levels are captured.\n *\n * @example\n * ```ts\n * const sentryReporter = Sentry.createConsolaReporter({\n * // Only capture error and warn logs\n * levels: ['error', 'warn'],\n * });\n * consola.addReporter(sentryReporter);\n * ```\n */\n levels?: Array<LogSeverityLevel>;\n\n /**\n * Optionally provide a specific Sentry client instance to use for capturing logs.\n * If not provided, the current client will be retrieved using `getClient()`.\n *\n * This is useful when you want to use specific client options for log normalization\n * or when working with multiple client instances.\n *\n * @example\n * ```ts\n * const sentryReporter = Sentry.createConsolaReporter({\n * client: myCustomClient,\n * });\n * ```\n */\n client?: Client;\n}\n\nexport interface ConsolaReporter {\n log: (logObj: ConsolaLogObject) => void;\n}\n\n/**\n * Represents a log object that Consola reporters receive.\n *\n * This interface matches the structure of log objects passed to Consola reporters.\n * See: https://github.com/unjs/consola#custom-reporters\n *\n * @example\n * ```ts\n * const reporter = {\n * log(logObj: ConsolaLogObject) {\n * console.log(`[${logObj.type}] ${logObj.message || logObj.args?.join(' ')}`);\n * }\n * };\n * consola.addReporter(reporter);\n * ```\n */\nexport interface ConsolaLogObject {\n /**\n * Allows additional custom properties to be set on the log object.\n * These properties will be captured as log attributes with a 'consola.' prefix.\n *\n * @example\n * ```ts\n * const reporter = Sentry.createConsolaReporter();\n * reporter.log({\n * type: 'info',\n * message: 'User action',\n * userId: 123,\n * sessionId: 'abc-123'\n * });\n * // Will create attributes: consola.userId and consola.sessionId\n * ```\n */\n [key: string]: unknown;\n\n /**\n * The numeric log level (0-5) or null.\n *\n * Consola log levels:\n * - 0: Fatal and Error\n * - 1: Warnings\n * - 2: Normal logs\n * - 3: Informational logs, success, fail, ready, start, box, ...\n * - 4: Debug logs\n * - 5: Trace logs\n * - null: Some special types like 'verbose'\n *\n * See: https://github.com/unjs/consola/blob/main/README.md#log-level\n */\n level?: number | null;\n\n /**\n * The log type/method name (e.g., 'error', 'warn', 'info', 'debug', 'trace', 'success', 'fail', etc.).\n *\n * Consola built-in types include:\n * - Standard: silent, fatal, error, warn, log, info, success, fail, ready, start, box, debug, trace, verbose\n * - Custom types can also be defined\n *\n * See: https://github.com/unjs/consola/blob/main/README.md#log-types\n */\n type?: string;\n\n /**\n * An optional tag/scope for the log entry.\n *\n * Tags are created using `consola.withTag('scope')` and help categorize logs.\n *\n * @example\n * ```ts\n * const scopedLogger = consola.withTag('auth');\n * scopedLogger.info('User logged in'); // tag will be 'auth'\n * ```\n *\n * See: https://github.com/unjs/consola/blob/main/README.md#withtagtag\n */\n tag?: string;\n\n /**\n * The raw arguments passed to the log method.\n *\n * When `message` is not provided, these args are typically formatted into the final message.\n *\n * @example\n * ```ts\n * consola.info('Hello', 'world', { user: 'john' });\n * // args = ['Hello', 'world', { user: 'john' }]\n * ```\n */\n args?: unknown[];\n\n /**\n * The timestamp when the log was created.\n *\n * This is automatically set by Consola when the log is created.\n */\n date?: Date;\n\n /**\n * The formatted log message.\n *\n * When provided, this is the final formatted message. When not provided,\n * the message should be constructed from the `args` array.\n */\n message?: string;\n}\n\nconst DEFAULT_CAPTURED_LEVELS: Array<LogSeverityLevel> = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n\n/**\n * Creates a new Sentry reporter for Consola that forwards logs to Sentry. Requires the `enableLogs` option to be enabled.\n *\n * **Note: This integration supports Consola v3.x only.** The reporter interface and log object structure\n * may differ in other versions of Consola.\n *\n * @param options - Configuration options for the reporter.\n * @returns A Consola reporter that can be added to consola instances.\n *\n * @example\n * ```ts\n * import * as Sentry from '@sentry/node';\n * import { consola } from 'consola';\n *\n * Sentry.init({\n * enableLogs: true,\n * });\n *\n * const sentryReporter = Sentry.createConsolaReporter({\n * // Optional: filter levels to capture\n * levels: ['error', 'warn', 'info'],\n * });\n *\n * consola.addReporter(sentryReporter);\n *\n * // Now consola logs will be captured by Sentry\n * consola.info('This will be sent to Sentry');\n * consola.error('This error will also be sent to Sentry');\n * ```\n */\nexport function createConsolaReporter(options: ConsolaReporterOptions = {}): ConsolaReporter {\n const levels = new Set(options.levels ?? DEFAULT_CAPTURED_LEVELS);\n const providedClient = options.client;\n\n return {\n log(logObj: ConsolaLogObject) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { type, level, message: consolaMessage, args, tag, date: _date, ...attributes } = logObj;\n\n // Get client - use provided client or current client\n const client = providedClient || getClient();\n if (!client) {\n return;\n }\n\n // Determine the log severity level\n const logSeverityLevel = getLogSeverityLevel(type, level);\n\n // Early exit if this level should not be captured\n if (!levels.has(logSeverityLevel)) {\n return;\n }\n\n const { normalizeDepth = 3, normalizeMaxBreadth = 1_000 } = client.getOptions();\n\n // Format the log message using the same approach as consola's basic reporter\n const messageParts = [];\n if (consolaMessage) {\n messageParts.push(consolaMessage);\n }\n if (args && args.length > 0) {\n messageParts.push(formatConsoleArgs(args, normalizeDepth, normalizeMaxBreadth));\n }\n const message = messageParts.join(' ');\n\n // Build attributes\n attributes['sentry.origin'] = 'auto.log.consola';\n\n if (tag) {\n attributes['consola.tag'] = tag;\n }\n\n if (type) {\n attributes['consola.type'] = type;\n }\n\n // Only add level if it's a valid number (not null/undefined)\n if (level != null && typeof level === 'number') {\n attributes['consola.level'] = level;\n }\n\n _INTERNAL_captureLog({\n level: logSeverityLevel,\n message,\n attributes,\n });\n },\n };\n}\n\n// Mapping from consola log types to Sentry log severity levels\nconst CONSOLA_TYPE_TO_LOG_SEVERITY_LEVEL_MAP: Record<string, LogSeverityLevel> = {\n // Consola built-in types\n silent: 'trace',\n fatal: 'fatal',\n error: 'error',\n warn: 'warn',\n log: 'info',\n info: 'info',\n success: 'info',\n fail: 'error',\n ready: 'info',\n start: 'info',\n box: 'info',\n debug: 'debug',\n trace: 'trace',\n verbose: 'debug',\n // Custom types that might exist\n critical: 'fatal',\n notice: 'info',\n};\n\n// Mapping from consola log levels (numbers) to Sentry log severity levels\nconst CONSOLA_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP: Record<number, LogSeverityLevel> = {\n 0: 'fatal', // Fatal and Error\n 1: 'warn', // Warnings\n 2: 'info', // Normal logs\n 3: 'info', // Informational logs, success, fail, ready, start, ...\n 4: 'debug', // Debug logs\n 5: 'trace', // Trace logs\n};\n\n/**\n * Determines the log severity level from Consola type and level.\n *\n * @param type - The Consola log type (e.g., 'error', 'warn', 'info')\n * @param level - The Consola numeric log level (0-5) or null for some types like 'verbose'\n * @returns The corresponding Sentry log severity level\n */\nfunction getLogSeverityLevel(type?: string, level?: number | null): LogSeverityLevel {\n // Handle special case for verbose logs (level can be null with infinite level in Consola)\n if (type === 'verbose') {\n return 'debug';\n }\n\n // Handle silent logs - these should be at trace level\n if (type === 'silent') {\n return 'trace';\n }\n\n // First try to map by type (more specific)\n if (type) {\n const mappedLevel = CONSOLA_TYPE_TO_LOG_SEVERITY_LEVEL_MAP[type];\n if (mappedLevel) {\n return mappedLevel;\n }\n }\n\n // Fallback to level mapping (handle null level)\n if (typeof level === 'number') {\n const mappedLevel = CONSOLA_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP[level];\n if (mappedLevel) {\n return mappedLevel;\n }\n }\n\n // Default fallback\n return 'info';\n}\n"],"names":[],"mappings":";;;;AAMA;AACA;AACA;;AA+IA,MAAM,uBAAuB,GAA4B,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC;;AAE7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,qBAAqB,CAAC,OAAO,GAA2B,EAAE,EAAmB;AAC7F,EAAE,MAAM,MAAA,GAAS,IAAI,GAAG,CAAC,OAAO,CAAC,MAAA,IAAU,uBAAuB,CAAC;AACnE,EAAE,MAAM,cAAA,GAAiB,OAAO,CAAC,MAAM;;AAEvC,EAAE,OAAO;AACT,IAAI,GAAG,CAAC,MAAM,EAAoB;AAClC;AACA,MAAM,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,UAAA,EAAW,GAAI,MAAM;;AAEpG;AACA,MAAM,MAAM,MAAA,GAAS,kBAAkB,SAAS,EAAE;AAClD,MAAM,IAAI,CAAC,MAAM,EAAE;AACnB,QAAQ;AACR,MAAM;;AAEN;AACA,MAAM,MAAM,mBAAmB,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC;;AAE/D;AACA,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE;AACzC,QAAQ;AACR,MAAM;;AAEN,MAAM,MAAM,EAAE,cAAA,GAAiB,CAAC,EAAE,mBAAA,GAAsB,IAAA,KAAU,MAAM,CAAC,UAAU,EAAE;;AAErF;AACA,MAAM,MAAM,YAAA,GAAe,EAAE;AAC7B,MAAM,IAAI,cAAc,EAAE;AAC1B,QAAQ,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC;AACzC,MAAM;AACN,MAAM,IAAI,IAAA,IAAQ,IAAI,CAAC,MAAA,GAAS,CAAC,EAAE;AACnC,QAAQ,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,mBAAmB,CAAC,CAAC;AACvF,MAAM;AACN,MAAM,MAAM,UAAU,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;;AAE5C;AACA,MAAM,UAAU,CAAC,eAAe,CAAA,GAAI,kBAAkB;;AAEtD,MAAM,IAAI,GAAG,EAAE;AACf,QAAQ,UAAU,CAAC,aAAa,CAAA,GAAI,GAAG;AACvC,MAAM;;AAEN,MAAM,IAAI,IAAI,EAAE;AAChB,QAAQ,UAAU,CAAC,cAAc,CAAA,GAAI,IAAI;AACzC,MAAM;;AAEN;AACA,MAAM,IAAI,KAAA,IAAS,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAQ,EAAE;AACtD,QAAQ,UAAU,CAAC,eAAe,CAAA,GAAI,KAAK;AAC3C,MAAM;;AAEN,MAAM,oBAAoB,CAAC;AAC3B,QAAQ,KAAK,EAAE,gBAAgB;AAC/B,QAAQ,OAAO;AACf,QAAQ,UAAU;AAClB,OAAO,CAAC;AACR,IAAI,CAAC;AACL,GAAG;AACH;;AAEA;AACA,MAAM,sCAAsC,GAAqC;AACjF;AACA,EAAE,MAAM,EAAE,OAAO;AACjB,EAAE,KAAK,EAAE,OAAO;AAChB,EAAE,KAAK,EAAE,OAAO;AAChB,EAAE,IAAI,EAAE,MAAM;AACd,EAAE,GAAG,EAAE,MAAM;AACb,EAAE,IAAI,EAAE,MAAM;AACd,EAAE,OAAO,EAAE,MAAM;AACjB,EAAE,IAAI,EAAE,OAAO;AACf,EAAE,KAAK,EAAE,MAAM;AACf,EAAE,KAAK,EAAE,MAAM;AACf,EAAE,GAAG,EAAE,MAAM;AACb,EAAE,KAAK,EAAE,OAAO;AAChB,EAAE,KAAK,EAAE,OAAO;AAChB,EAAE,OAAO,EAAE,OAAO;AAClB;AACA,EAAE,QAAQ,EAAE,OAAO;AACnB,EAAE,MAAM,EAAE,MAAM;AAChB,CAAC;;AAED;AACA,MAAM,uCAAuC,GAAqC;AAClF,EAAE,CAAC,EAAE,OAAO;AACZ,EAAE,CAAC,EAAE,MAAM;AACX,EAAE,CAAC,EAAE,MAAM;AACX,EAAE,CAAC,EAAE,MAAM;AACX,EAAE,CAAC,EAAE,OAAO;AACZ,EAAE,CAAC,EAAE,OAAO;AACZ,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,mBAAmB,CAAC,IAAI,EAAW,KAAK,EAAoC;AACrF;AACA,EAAE,IAAI,IAAA,KAAS,SAAS,EAAE;AAC1B,IAAI,OAAO,OAAO;AAClB,EAAE;;AAEF;AACA,EAAE,IAAI,IAAA,KAAS,QAAQ,EAAE;AACzB,IAAI,OAAO,OAAO;AAClB,EAAE;;AAEF;AACA,EAAE,IAAI,IAAI,EAAE;AACZ,IAAI,MAAM,WAAA,GAAc,sCAAsC,CAAC,IAAI,CAAC;AACpE,IAAI,IAAI,WAAW,EAAE;AACrB,MAAM,OAAO,WAAW;AACxB,IAAI;AACJ,EAAE;;AAEF;AACA,EAAE,IAAI,OAAO,KAAA,KAAU,QAAQ,EAAE;AACjC,IAAI,MAAM,WAAA,GAAc,uCAAuC,CAAC,KAAK,CAAC;AACtE,IAAI,IAAI,WAAW,EAAE;AACrB,MAAM,OAAO,WAAW;AACxB,IAAI;AACJ,EAAE;;AAEF;AACA,EAAE,OAAO,MAAM;AACf;;;;"}
|
|
1
|
+
{"version":3,"file":"consola.js","sources":["../../../src/integrations/consola.ts"],"sourcesContent":["import type { Client } from '../client';\nimport { getClient } from '../currentScopes';\nimport { _INTERNAL_captureLog } from '../logs/internal';\nimport { formatConsoleArgs } from '../logs/utils';\nimport type { LogSeverityLevel } from '../types-hoist/log';\n\n/**\n * Options for the Sentry Consola reporter.\n */\ninterface ConsolaReporterOptions {\n /**\n * Use this option to filter which levels should be captured. By default, all levels are captured.\n *\n * @example\n * ```ts\n * const sentryReporter = Sentry.createConsolaReporter({\n * // Only capture error and warn logs\n * levels: ['error', 'warn'],\n * });\n * consola.addReporter(sentryReporter);\n * ```\n */\n levels?: Array<LogSeverityLevel>;\n\n /**\n * Optionally provide a specific Sentry client instance to use for capturing logs.\n * If not provided, the current client will be retrieved using `getClient()`.\n *\n * This is useful when you want to use specific client options for log normalization\n * or when working with multiple client instances.\n *\n * @example\n * ```ts\n * const sentryReporter = Sentry.createConsolaReporter({\n * client: myCustomClient,\n * });\n * ```\n */\n client?: Client;\n}\n\nexport interface ConsolaReporter {\n log: (logObj: ConsolaLogObject) => void;\n}\n\n/**\n * Represents a log object that Consola reporters receive.\n *\n * This interface matches the structure of log objects passed to Consola reporters.\n * See: https://github.com/unjs/consola#custom-reporters\n *\n * @example\n * ```ts\n * const reporter = {\n * log(logObj: ConsolaLogObject) {\n * console.log(`[${logObj.type}] ${logObj.message || logObj.args?.join(' ')}`);\n * }\n * };\n * consola.addReporter(reporter);\n * ```\n */\nexport interface ConsolaLogObject {\n /**\n * Allows additional custom properties to be set on the log object.\n * These properties will be captured as log attributes with a 'consola.' prefix.\n *\n * @example\n * ```ts\n * const reporter = Sentry.createConsolaReporter();\n * reporter.log({\n * type: 'info',\n * message: 'User action',\n * userId: 123,\n * sessionId: 'abc-123'\n * });\n * // Will create attributes: consola.userId and consola.sessionId\n * ```\n */\n [key: string]: unknown;\n\n /**\n * The numeric log level (0-5) or null.\n *\n * Consola log levels:\n * - 0: Fatal and Error\n * - 1: Warnings\n * - 2: Normal logs\n * - 3: Informational logs, success, fail, ready, start, box, ...\n * - 4: Debug logs\n * - 5: Trace logs\n * - null: Some special types like 'verbose'\n *\n * See: https://github.com/unjs/consola/blob/main/README.md#log-level\n */\n level?: number | null;\n\n /**\n * The log type/method name (e.g., 'error', 'warn', 'info', 'debug', 'trace', 'success', 'fail', etc.).\n *\n * Consola built-in types include:\n * - Standard: silent, fatal, error, warn, log, info, success, fail, ready, start, box, debug, trace, verbose\n * - Custom types can also be defined\n *\n * See: https://github.com/unjs/consola/blob/main/README.md#log-types\n */\n type?: string;\n\n /**\n * An optional tag/scope for the log entry.\n *\n * Tags are created using `consola.withTag('scope')` and help categorize logs.\n *\n * @example\n * ```ts\n * const scopedLogger = consola.withTag('auth');\n * scopedLogger.info('User logged in'); // tag will be 'auth'\n * ```\n *\n * See: https://github.com/unjs/consola/blob/main/README.md#withtagtag\n */\n tag?: string;\n\n /**\n * The raw arguments passed to the log method.\n *\n * These args are typically formatted into the final `message`. In Consola reporters, `message` is not provided.\n *\n * @example\n * ```ts\n * consola.info('Hello', 'world', { user: 'john' });\n * // args = ['Hello', 'world', { user: 'john' }]\n * ```\n *\n * @example\n * ```ts\n * // `message` is a reserved property in Consola\n * consola.log({ message: 'Hello' });\n * // args = ['Hello']\n * ```\n */\n args?: unknown[];\n\n /**\n * The timestamp when the log was created.\n *\n * This is automatically set by Consola when the log is created.\n */\n date?: Date;\n\n /**\n * The formatted log message.\n *\n * When provided, this is the final formatted message. When not provided,\n * the message should be constructed from the `args` array.\n */\n message?: string;\n}\n\nconst DEFAULT_CAPTURED_LEVELS: Array<LogSeverityLevel> = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n\n/**\n * Creates a new Sentry reporter for Consola that forwards logs to Sentry. Requires the `enableLogs` option to be enabled.\n *\n * **Note: This integration supports Consola v3.x only.** The reporter interface and log object structure\n * may differ in other versions of Consola.\n *\n * @param options - Configuration options for the reporter.\n * @returns A Consola reporter that can be added to consola instances.\n *\n * @example\n * ```ts\n * import * as Sentry from '@sentry/node';\n * import { consola } from 'consola';\n *\n * Sentry.init({\n * enableLogs: true,\n * });\n *\n * const sentryReporter = Sentry.createConsolaReporter({\n * // Optional: filter levels to capture\n * levels: ['error', 'warn', 'info'],\n * });\n *\n * consola.addReporter(sentryReporter);\n *\n * // Now consola logs will be captured by Sentry\n * consola.info('This will be sent to Sentry');\n * consola.error('This error will also be sent to Sentry');\n * ```\n */\nexport function createConsolaReporter(options: ConsolaReporterOptions = {}): ConsolaReporter {\n const levels = new Set(options.levels ?? DEFAULT_CAPTURED_LEVELS);\n const providedClient = options.client;\n\n return {\n log(logObj: ConsolaLogObject) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { type, level, message: consolaMessage, args, tag, date: _date, ...attributes } = logObj;\n\n // Get client - use provided client or current client\n const client = providedClient || getClient();\n if (!client) {\n return;\n }\n\n // Determine the log severity level\n const logSeverityLevel = getLogSeverityLevel(type, level);\n\n // Early exit if this level should not be captured\n if (!levels.has(logSeverityLevel)) {\n return;\n }\n\n const { normalizeDepth = 3, normalizeMaxBreadth = 1_000 } = client.getOptions();\n\n // Format the log message using the same approach as consola's basic reporter\n const messageParts = [];\n if (consolaMessage) {\n messageParts.push(consolaMessage);\n }\n if (args && args.length > 0) {\n messageParts.push(formatConsoleArgs(args, normalizeDepth, normalizeMaxBreadth));\n }\n const message = messageParts.join(' ');\n\n // Build attributes\n attributes['sentry.origin'] = 'auto.log.consola';\n\n if (tag) {\n attributes['consola.tag'] = tag;\n }\n\n if (type) {\n attributes['consola.type'] = type;\n }\n\n // Only add level if it's a valid number (not null/undefined)\n if (level != null && typeof level === 'number') {\n attributes['consola.level'] = level;\n }\n\n _INTERNAL_captureLog({\n level: logSeverityLevel,\n message,\n attributes,\n });\n },\n };\n}\n\n// Mapping from consola log types to Sentry log severity levels\nconst CONSOLA_TYPE_TO_LOG_SEVERITY_LEVEL_MAP: Record<string, LogSeverityLevel> = {\n // Consola built-in types\n silent: 'trace',\n fatal: 'fatal',\n error: 'error',\n warn: 'warn',\n log: 'info',\n info: 'info',\n success: 'info',\n fail: 'error',\n ready: 'info',\n start: 'info',\n box: 'info',\n debug: 'debug',\n trace: 'trace',\n verbose: 'debug',\n // Custom types that might exist\n critical: 'fatal',\n notice: 'info',\n};\n\n// Mapping from consola log levels (numbers) to Sentry log severity levels\nconst CONSOLA_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP: Record<number, LogSeverityLevel> = {\n 0: 'fatal', // Fatal and Error\n 1: 'warn', // Warnings\n 2: 'info', // Normal logs\n 3: 'info', // Informational logs, success, fail, ready, start, ...\n 4: 'debug', // Debug logs\n 5: 'trace', // Trace logs\n};\n\n/**\n * Determines the log severity level from Consola type and level.\n *\n * @param type - The Consola log type (e.g., 'error', 'warn', 'info')\n * @param level - The Consola numeric log level (0-5) or null for some types like 'verbose'\n * @returns The corresponding Sentry log severity level\n */\nfunction getLogSeverityLevel(type?: string, level?: number | null): LogSeverityLevel {\n // Handle special case for verbose logs (level can be null with infinite level in Consola)\n if (type === 'verbose') {\n return 'debug';\n }\n\n // Handle silent logs - these should be at trace level\n if (type === 'silent') {\n return 'trace';\n }\n\n // First try to map by type (more specific)\n if (type) {\n const mappedLevel = CONSOLA_TYPE_TO_LOG_SEVERITY_LEVEL_MAP[type];\n if (mappedLevel) {\n return mappedLevel;\n }\n }\n\n // Fallback to level mapping (handle null level)\n if (typeof level === 'number') {\n const mappedLevel = CONSOLA_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP[level];\n if (mappedLevel) {\n return mappedLevel;\n }\n }\n\n // Default fallback\n return 'info';\n}\n"],"names":[],"mappings":"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"}
|
package/build/esm/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"10.
|
|
1
|
+
{"type":"module","version":"10.41.0-beta.0","sideEffects":false}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline media content source, with a potentially very large base64
|
|
3
|
+
* blob or data: uri.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Check if a content part is an OpenAI/Anthropic media source
|
|
8
|
+
*/
|
|
9
|
+
function isContentMedia(part) {
|
|
10
|
+
if (!part || typeof part !== 'object') return false;
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
isContentMediaSource(part) ||
|
|
14
|
+
hasInlineData(part) ||
|
|
15
|
+
hasImageUrl(part) ||
|
|
16
|
+
hasInputAudio(part) ||
|
|
17
|
+
hasFileData(part) ||
|
|
18
|
+
hasMediaTypeData(part) ||
|
|
19
|
+
hasBlobOrBase64Type(part) ||
|
|
20
|
+
hasB64Json(part) ||
|
|
21
|
+
hasImageGenerationResult(part) ||
|
|
22
|
+
hasDataUri(part)
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function hasImageUrl(part) {
|
|
27
|
+
if (!('image_url' in part)) return false;
|
|
28
|
+
if (typeof part.image_url === 'string') return part.image_url.startsWith('data:');
|
|
29
|
+
return hasNestedImageUrl(part);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function hasNestedImageUrl(part) {
|
|
33
|
+
return (
|
|
34
|
+
'image_url' in part &&
|
|
35
|
+
!!part.image_url &&
|
|
36
|
+
typeof part.image_url === 'object' &&
|
|
37
|
+
'url' in part.image_url &&
|
|
38
|
+
typeof part.image_url.url === 'string' &&
|
|
39
|
+
part.image_url.url.startsWith('data:')
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isContentMediaSource(part) {
|
|
44
|
+
return 'type' in part && typeof part.type === 'string' && 'source' in part && isContentMedia(part.source);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function hasInlineData(part) {
|
|
48
|
+
return (
|
|
49
|
+
'inlineData' in part &&
|
|
50
|
+
!!part.inlineData &&
|
|
51
|
+
typeof part.inlineData === 'object' &&
|
|
52
|
+
'data' in part.inlineData &&
|
|
53
|
+
typeof part.inlineData.data === 'string'
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function hasInputAudio(part) {
|
|
58
|
+
return (
|
|
59
|
+
'type' in part &&
|
|
60
|
+
part.type === 'input_audio' &&
|
|
61
|
+
'input_audio' in part &&
|
|
62
|
+
!!part.input_audio &&
|
|
63
|
+
typeof part.input_audio === 'object' &&
|
|
64
|
+
'data' in part.input_audio &&
|
|
65
|
+
typeof part.input_audio.data === 'string'
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function hasFileData(part) {
|
|
70
|
+
return (
|
|
71
|
+
'type' in part &&
|
|
72
|
+
part.type === 'file' &&
|
|
73
|
+
'file' in part &&
|
|
74
|
+
!!part.file &&
|
|
75
|
+
typeof part.file === 'object' &&
|
|
76
|
+
'file_data' in part.file &&
|
|
77
|
+
typeof part.file.file_data === 'string'
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function hasMediaTypeData(part) {
|
|
82
|
+
return 'media_type' in part && typeof part.media_type === 'string' && 'data' in part;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function hasBlobOrBase64Type(part) {
|
|
86
|
+
return 'type' in part && (part.type === 'blob' || part.type === 'base64');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function hasB64Json(part) {
|
|
90
|
+
return 'b64_json' in part;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function hasImageGenerationResult(part) {
|
|
94
|
+
return 'type' in part && 'result' in part && part.type === 'image_generation';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function hasDataUri(part) {
|
|
98
|
+
return 'uri' in part && typeof part.uri === 'string' && part.uri.startsWith('data:');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const REMOVED_STRING = '[Blob substitute]';
|
|
102
|
+
|
|
103
|
+
const MEDIA_FIELDS = ['image_url', 'data', 'content', 'b64_json', 'result', 'uri'] ;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Replace inline binary data in a single media content part with a placeholder.
|
|
107
|
+
*/
|
|
108
|
+
function stripInlineMediaFromSingleMessage(part) {
|
|
109
|
+
const strip = { ...part };
|
|
110
|
+
if (isContentMedia(strip.source)) {
|
|
111
|
+
strip.source = stripInlineMediaFromSingleMessage(strip.source);
|
|
112
|
+
}
|
|
113
|
+
if (hasInlineData(part)) {
|
|
114
|
+
strip.inlineData = { ...part.inlineData, data: REMOVED_STRING };
|
|
115
|
+
}
|
|
116
|
+
if (hasNestedImageUrl(part)) {
|
|
117
|
+
strip.image_url = { ...part.image_url, url: REMOVED_STRING };
|
|
118
|
+
}
|
|
119
|
+
if (hasInputAudio(part)) {
|
|
120
|
+
strip.input_audio = { ...part.input_audio, data: REMOVED_STRING };
|
|
121
|
+
}
|
|
122
|
+
if (hasFileData(part)) {
|
|
123
|
+
strip.file = { ...part.file, file_data: REMOVED_STRING };
|
|
124
|
+
}
|
|
125
|
+
for (const field of MEDIA_FIELDS) {
|
|
126
|
+
if (typeof strip[field] === 'string') strip[field] = REMOVED_STRING;
|
|
127
|
+
}
|
|
128
|
+
return strip;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export { isContentMedia, stripInlineMediaFromSingleMessage };
|
|
132
|
+
//# sourceMappingURL=mediaStripping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mediaStripping.js","sources":["../../../../src/tracing/ai/mediaStripping.ts"],"sourcesContent":["/**\n * Inline media content source, with a potentially very large base64\n * blob or data: uri.\n */\nexport type ContentMedia = Record<string, unknown> &\n (\n | {\n media_type: string;\n data: string;\n }\n | {\n image_url: `data:${string}`;\n }\n | {\n image_url: { url: `data:${string}` };\n }\n | {\n type: 'blob' | 'base64';\n content: string;\n }\n | {\n b64_json: string;\n }\n | {\n uri: `data:${string}`;\n }\n | {\n type: 'input_audio';\n input_audio: { data: string };\n }\n | {\n type: 'file';\n file: { file_data?: string };\n }\n );\n\n/**\n * Check if a content part is an OpenAI/Anthropic media source\n */\nexport function isContentMedia(part: unknown): part is ContentMedia {\n if (!part || typeof part !== 'object') return false;\n\n return (\n isContentMediaSource(part) ||\n hasInlineData(part) ||\n hasImageUrl(part) ||\n hasInputAudio(part) ||\n hasFileData(part) ||\n hasMediaTypeData(part) ||\n hasBlobOrBase64Type(part) ||\n hasB64Json(part) ||\n hasImageGenerationResult(part) ||\n hasDataUri(part)\n );\n}\n\nfunction hasImageUrl(part: NonNullable<unknown>): boolean {\n if (!('image_url' in part)) return false;\n if (typeof part.image_url === 'string') return part.image_url.startsWith('data:');\n return hasNestedImageUrl(part);\n}\n\nfunction hasNestedImageUrl(part: NonNullable<unknown>): part is { image_url: { url: string } } {\n return (\n 'image_url' in part &&\n !!part.image_url &&\n typeof part.image_url === 'object' &&\n 'url' in part.image_url &&\n typeof part.image_url.url === 'string' &&\n part.image_url.url.startsWith('data:')\n );\n}\n\nfunction isContentMediaSource(part: NonNullable<unknown>): boolean {\n return 'type' in part && typeof part.type === 'string' && 'source' in part && isContentMedia(part.source);\n}\n\nfunction hasInlineData(part: NonNullable<unknown>): part is { inlineData: { data?: string } } {\n return (\n 'inlineData' in part &&\n !!part.inlineData &&\n typeof part.inlineData === 'object' &&\n 'data' in part.inlineData &&\n typeof part.inlineData.data === 'string'\n );\n}\n\nfunction hasInputAudio(part: NonNullable<unknown>): part is { type: 'input_audio'; input_audio: { data: string } } {\n return (\n 'type' in part &&\n part.type === 'input_audio' &&\n 'input_audio' in part &&\n !!part.input_audio &&\n typeof part.input_audio === 'object' &&\n 'data' in part.input_audio &&\n typeof part.input_audio.data === 'string'\n );\n}\n\nfunction hasFileData(part: NonNullable<unknown>): part is { type: 'file'; file: { file_data: string } } {\n return (\n 'type' in part &&\n part.type === 'file' &&\n 'file' in part &&\n !!part.file &&\n typeof part.file === 'object' &&\n 'file_data' in part.file &&\n typeof part.file.file_data === 'string'\n );\n}\n\nfunction hasMediaTypeData(part: NonNullable<unknown>): part is { media_type: string; data: string } {\n return 'media_type' in part && typeof part.media_type === 'string' && 'data' in part;\n}\n\nfunction hasBlobOrBase64Type(part: NonNullable<unknown>): part is { type: 'blob' | 'base64'; content: string } {\n return 'type' in part && (part.type === 'blob' || part.type === 'base64');\n}\n\nfunction hasB64Json(part: NonNullable<unknown>): part is { b64_json: string } {\n return 'b64_json' in part;\n}\n\nfunction hasImageGenerationResult(part: NonNullable<unknown>): part is { type: 'image_generation'; result: string } {\n return 'type' in part && 'result' in part && part.type === 'image_generation';\n}\n\nfunction hasDataUri(part: NonNullable<unknown>): part is { uri: string } {\n return 'uri' in part && typeof part.uri === 'string' && part.uri.startsWith('data:');\n}\n\nconst REMOVED_STRING = '[Blob substitute]';\n\nconst MEDIA_FIELDS = ['image_url', 'data', 'content', 'b64_json', 'result', 'uri'] as const;\n\n/**\n * Replace inline binary data in a single media content part with a placeholder.\n */\nexport function stripInlineMediaFromSingleMessage(part: ContentMedia): ContentMedia {\n const strip = { ...part };\n if (isContentMedia(strip.source)) {\n strip.source = stripInlineMediaFromSingleMessage(strip.source);\n }\n if (hasInlineData(part)) {\n strip.inlineData = { ...part.inlineData, data: REMOVED_STRING };\n }\n if (hasNestedImageUrl(part)) {\n strip.image_url = { ...part.image_url, url: REMOVED_STRING };\n }\n if (hasInputAudio(part)) {\n strip.input_audio = { ...part.input_audio, data: REMOVED_STRING };\n }\n if (hasFileData(part)) {\n strip.file = { ...part.file, file_data: REMOVED_STRING };\n }\n for (const field of MEDIA_FIELDS) {\n if (typeof strip[field] === 'string') strip[field] = REMOVED_STRING;\n }\n return strip;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isContentMedia, stripInlineMediaFromSingleMessage } from './mediaStripping.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Default maximum size in bytes for GenAI messages.
|
|
3
5
|
* Messages exceeding this limit will be truncated.
|
|
@@ -23,12 +25,12 @@ const jsonBytes = (value) => {
|
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
|
-
* Truncate a string to fit within maxBytes when encoded as UTF-8.
|
|
28
|
+
* Truncate a string to fit within maxBytes (inclusive) when encoded as UTF-8.
|
|
27
29
|
* Uses binary search for efficiency with multi-byte characters.
|
|
28
30
|
*
|
|
29
31
|
* @param text - The string to truncate
|
|
30
|
-
* @param maxBytes - Maximum byte length (UTF-8 encoded)
|
|
31
|
-
* @returns Truncated string
|
|
32
|
+
* @param maxBytes - Maximum byte length (inclusive, UTF-8 encoded)
|
|
33
|
+
* @returns Truncated string whose UTF-8 byte length is at most maxBytes
|
|
32
34
|
*/
|
|
33
35
|
function truncateTextByBytes(text, maxBytes) {
|
|
34
36
|
if (utf8Bytes(text) <= maxBytes) {
|
|
@@ -102,36 +104,6 @@ function isContentArrayMessage(message) {
|
|
|
102
104
|
return message !== null && typeof message === 'object' && 'content' in message && Array.isArray(message.content);
|
|
103
105
|
}
|
|
104
106
|
|
|
105
|
-
/**
|
|
106
|
-
* Check if a content part is an OpenAI/Anthropic media source
|
|
107
|
-
*/
|
|
108
|
-
function isContentMedia(part) {
|
|
109
|
-
if (!part || typeof part !== 'object') return false;
|
|
110
|
-
|
|
111
|
-
return (
|
|
112
|
-
isContentMediaSource(part) ||
|
|
113
|
-
hasInlineData(part) ||
|
|
114
|
-
('media_type' in part && typeof part.media_type === 'string' && 'data' in part) ||
|
|
115
|
-
('image_url' in part && typeof part.image_url === 'string' && part.image_url.startsWith('data:')) ||
|
|
116
|
-
('type' in part && (part.type === 'blob' || part.type === 'base64')) ||
|
|
117
|
-
'b64_json' in part ||
|
|
118
|
-
('type' in part && 'result' in part && part.type === 'image_generation') ||
|
|
119
|
-
('uri' in part && typeof part.uri === 'string' && part.uri.startsWith('data:'))
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
function isContentMediaSource(part) {
|
|
123
|
-
return 'type' in part && typeof part.type === 'string' && 'source' in part && isContentMedia(part.source);
|
|
124
|
-
}
|
|
125
|
-
function hasInlineData(part) {
|
|
126
|
-
return (
|
|
127
|
-
'inlineData' in part &&
|
|
128
|
-
!!part.inlineData &&
|
|
129
|
-
typeof part.inlineData === 'object' &&
|
|
130
|
-
'data' in part.inlineData &&
|
|
131
|
-
typeof part.inlineData.data === 'string'
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
107
|
/**
|
|
136
108
|
* Check if a message has the Google GenAI parts format.
|
|
137
109
|
*/
|
|
@@ -256,25 +228,6 @@ function truncateSingleMessage(message, maxBytes) {
|
|
|
256
228
|
return [];
|
|
257
229
|
}
|
|
258
230
|
|
|
259
|
-
const REMOVED_STRING = '[Filtered]';
|
|
260
|
-
|
|
261
|
-
const MEDIA_FIELDS = ['image_url', 'data', 'content', 'b64_json', 'result', 'uri'] ;
|
|
262
|
-
|
|
263
|
-
function stripInlineMediaFromSingleMessage(part) {
|
|
264
|
-
const strip = { ...part };
|
|
265
|
-
if (isContentMedia(strip.source)) {
|
|
266
|
-
strip.source = stripInlineMediaFromSingleMessage(strip.source);
|
|
267
|
-
}
|
|
268
|
-
// google genai inline data blob objects
|
|
269
|
-
if (hasInlineData(part)) {
|
|
270
|
-
strip.inlineData = { ...part.inlineData, data: REMOVED_STRING };
|
|
271
|
-
}
|
|
272
|
-
for (const field of MEDIA_FIELDS) {
|
|
273
|
-
if (typeof strip[field] === 'string') strip[field] = REMOVED_STRING;
|
|
274
|
-
}
|
|
275
|
-
return strip;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
231
|
/**
|
|
279
232
|
* Strip the inline media from message arrays.
|
|
280
233
|
*
|
|
@@ -339,6 +292,11 @@ function truncateMessagesByBytes(messages, maxBytes) {
|
|
|
339
292
|
return messages;
|
|
340
293
|
}
|
|
341
294
|
|
|
295
|
+
// The result is always a single-element array that callers wrap with
|
|
296
|
+
// JSON.stringify([message]), so subtract the 2-byte array wrapper ("[" and "]")
|
|
297
|
+
// to ensure the final serialized value stays under the limit.
|
|
298
|
+
const effectiveMaxBytes = maxBytes - 2;
|
|
299
|
+
|
|
342
300
|
// Always keep only the last message
|
|
343
301
|
const lastMessage = messages[messages.length - 1];
|
|
344
302
|
|
|
@@ -348,12 +306,12 @@ function truncateMessagesByBytes(messages, maxBytes) {
|
|
|
348
306
|
|
|
349
307
|
// Check if it fits
|
|
350
308
|
const messageBytes = jsonBytes(strippedMessage);
|
|
351
|
-
if (messageBytes <=
|
|
309
|
+
if (messageBytes <= effectiveMaxBytes) {
|
|
352
310
|
return stripped;
|
|
353
311
|
}
|
|
354
312
|
|
|
355
313
|
// Truncate the single message if needed
|
|
356
|
-
return truncateSingleMessage(strippedMessage,
|
|
314
|
+
return truncateSingleMessage(strippedMessage, effectiveMaxBytes);
|
|
357
315
|
}
|
|
358
316
|
|
|
359
317
|
/**
|