diff --git a/packages/remix/package.json b/packages/remix/package.json
index b6c1afcd3c4f..dc3794f77495 100644
--- a/packages/remix/package.json
+++ b/packages/remix/package.json
@@ -34,12 +34,13 @@
"@sentry/types": "7.73.0",
"@sentry/utils": "7.73.0",
"glob": "^10.3.4",
+ "is-ip": "^3.1.0",
"tslib": "^2.4.1 || ^1.9.3",
"yargs": "^17.6.0"
},
"devDependencies": {
- "@remix-run/node": "^1.4.3",
- "@remix-run/react": "^1.4.3",
+ "@remix-run/node": "^1.19.3",
+ "@remix-run/react": "^1.19.3",
"@types/express": "^4.17.14"
},
"peerDependencies": {
@@ -86,6 +87,8 @@
},
"sideEffects": [
"./esm/index.server.js",
- "./src/index.server.ts"
+ "./src/index.server.ts",
+ "./src/index.worker.ts",
+ "./esm/index.worker.js"
]
}
diff --git a/packages/remix/rollup.npm.config.js b/packages/remix/rollup.npm.config.js
index dc51f24c7bb2..f8ed9410309b 100644
--- a/packages/remix/rollup.npm.config.js
+++ b/packages/remix/rollup.npm.config.js
@@ -2,7 +2,7 @@ import { makeBaseNPMConfig, makeNPMConfigVariants } from '../../rollup/index.js'
export default makeNPMConfigVariants(
makeBaseNPMConfig({
- entrypoints: ['src/index.server.ts', 'src/index.client.tsx'],
+ entrypoints: ['src/index.server.ts', 'src/index.client.tsx', 'src/index.worker.ts'],
packageSpecificConfig: {
external: ['react-router', 'react-router-dom'],
output: {
diff --git a/packages/remix/src/client/errors.tsx b/packages/remix/src/client/errors.tsx
index 6732ed5cdc91..8182666612a2 100644
--- a/packages/remix/src/client/errors.tsx
+++ b/packages/remix/src/client/errors.tsx
@@ -1,5 +1,5 @@
import { captureException, withScope } from '@sentry/core';
-import { addExceptionMechanism, isNodeEnv, isString } from '@sentry/utils';
+import { addExceptionMechanism, isBrowser, isString } from '@sentry/utils';
import { isRouteErrorResponse } from '../utils/vendor/response';
@@ -11,7 +11,7 @@ import { isRouteErrorResponse } from '../utils/vendor/response';
*/
export function captureRemixErrorBoundaryError(error: unknown): string | undefined {
let eventId: string | undefined;
- const isClientSideRuntimeError = !isNodeEnv() && error instanceof Error;
+ const isClientSideRuntimeError = isBrowser() && error instanceof Error;
const isRemixErrorResponse = isRouteErrorResponse(error);
// Server-side errors apart from `ErrorResponse`s also appear here without their stacktraces.
// So, we only capture:
diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx
index 97c455a80a94..9895f1bd8e17 100644
--- a/packages/remix/src/client/performance.tsx
+++ b/packages/remix/src/client/performance.tsx
@@ -1,7 +1,7 @@
import type { ErrorBoundaryProps } from '@sentry/react';
import { WINDOW, withErrorBoundary } from '@sentry/react';
import type { Transaction, TransactionContext } from '@sentry/types';
-import { isNodeEnv, logger } from '@sentry/utils';
+import { isBrowser, logger } from '@sentry/utils';
import * as React from 'react';
import { getFutureFlagsBrowser, readRemixVersionFromLoader } from '../utils/futureFlags';
@@ -109,7 +109,7 @@ export function withSentry
, R extends React.Co
// Early return when any of the required functions is not available.
if (!_useEffect || !_useLocation || !_useMatches || !_customStartTransaction) {
__DEBUG_BUILD__ &&
- !isNodeEnv() &&
+ isBrowser() &&
logger.warn('Remix SDK was unable to wrap your root because of one or more missing parameters.');
// @ts-expect-error Setting more specific React Component typing for `R` generic above
diff --git a/packages/remix/src/index.client.tsx b/packages/remix/src/index.client.tsx
index 64951a3f10cd..a817450c2615 100644
--- a/packages/remix/src/index.client.tsx
+++ b/packages/remix/src/index.client.tsx
@@ -1,11 +1,28 @@
/* eslint-disable import/export */
-import { configureScope, init as reactInit } from '@sentry/react';
+import { init as reactInit } from '@sentry/react';
import { buildMetadata } from './utils/metadata';
import type { RemixOptions } from './utils/remixOptions';
export { remixRouterInstrumentation, withSentry } from './client/performance';
export { captureRemixErrorBoundaryError } from './client/errors';
export * from '@sentry/react';
+import type { ServerRuntimeClientOptions } from '@sentry/core';
+import {
+ configureScope,
+ getCurrentHub,
+ getIntegrationsToSetup,
+ initAndBind,
+ ServerRuntimeClient,
+ startTransaction,
+} from '@sentry/core';
+import { createStackParser, logger, nodeStackLineParser, stackParserFromStackParserOptions } from '@sentry/utils';
+
+import { makeEdgeTransport } from './worker/transport';
+
+export { captureRemixServerException } from './utils/instrumentServer';
+export { ErrorBoundary, withErrorBoundary } from '@sentry/react';
+// export { wrapExpressCreateRequestHandler } from './utils/serverAdapters/express';
+export { wrapWorkerCreateRequestHandler } from './utils/serverAdapters/worker';
export function init(options: RemixOptions): void {
buildMetadata(options, ['remix', 'react']);
@@ -17,3 +34,41 @@ export function init(options: RemixOptions): void {
scope.setTag('runtime', 'browser');
});
}
+
+const nodeStackParser = createStackParser(nodeStackLineParser());
+
+function sdkAlreadyInitialized(): boolean {
+ const hub = getCurrentHub();
+ return !!hub.getClient();
+}
+
+/** Initializes Sentry Remix SDK on Node. */
+export function workerInit(options: RemixOptions): void {
+ buildMetadata(options, ['remix', 'node']);
+
+ if (sdkAlreadyInitialized()) {
+ __DEBUG_BUILD__ && logger.log('SDK already initialized');
+
+ return;
+ }
+
+ const clientOptions: ServerRuntimeClientOptions = {
+ ...options,
+ stackParser: stackParserFromStackParserOptions(options.stackParser || nodeStackParser),
+ integrations: getIntegrationsToSetup(options),
+ transport: options.transport || makeEdgeTransport,
+ };
+
+ initAndBind(ServerRuntimeClient, clientOptions);
+
+ configureScope(scope => {
+ scope.setTag('runtime', 'worker');
+ });
+
+ const transaction = startTransaction({
+ name: 'remix-main',
+ op: 'init',
+ });
+
+ transaction.finish();
+}
diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts
index 53757b4a89f4..43b2ca6b6daa 100644
--- a/packages/remix/src/index.server.ts
+++ b/packages/remix/src/index.server.ts
@@ -60,6 +60,7 @@ export { ErrorBoundary, withErrorBoundary } from '@sentry/react';
export { remixRouterInstrumentation, withSentry } from './client/performance';
export { captureRemixErrorBoundaryError } from './client/errors';
export { wrapExpressCreateRequestHandler } from './utils/serverAdapters/express';
+export { wrapWorkerCreateRequestHandler } from './utils/serverAdapters/worker';
function sdkAlreadyInitialized(): boolean {
const hub = getCurrentHub();
diff --git a/packages/remix/src/index.worker.ts b/packages/remix/src/index.worker.ts
new file mode 100644
index 000000000000..619afd2afe14
--- /dev/null
+++ b/packages/remix/src/index.worker.ts
@@ -0,0 +1,46 @@
+import type { ServerRuntimeClientOptions } from '@sentry/core';
+import { configureScope, getCurrentHub, getIntegrationsToSetup, initAndBind, ServerRuntimeClient } from '@sentry/core';
+import { createStackParser, logger, nodeStackLineParser, stackParserFromStackParserOptions } from '@sentry/utils';
+
+import { instrumentServer } from './utils/instrumentServer';
+import { buildMetadata } from './utils/metadata';
+import type { RemixOptions } from './utils/remixOptions';
+import { makeEdgeTransport } from './worker/transport';
+
+export { captureRemixServerException } from './utils/instrumentServer';
+export { ErrorBoundary, withErrorBoundary } from '@sentry/react';
+export { remixRouterInstrumentation, withSentry } from './client/performance';
+export { captureRemixErrorBoundaryError } from './client/errors';
+export { wrapExpressCreateRequestHandler } from './utils/serverAdapters/express';
+
+const nodeStackParser = createStackParser(nodeStackLineParser());
+
+function sdkAlreadyInitialized(): boolean {
+ const hub = getCurrentHub();
+ return !!hub.getClient();
+}
+
+/** Initializes Sentry Remix SDK on Node. */
+export function init(options: RemixOptions): void {
+ buildMetadata(options, ['remix', 'node']);
+
+ if (sdkAlreadyInitialized()) {
+ __DEBUG_BUILD__ && logger.log('SDK already initialized');
+
+ return;
+ }
+
+ const clientOptions: ServerRuntimeClientOptions = {
+ ...options,
+ stackParser: stackParserFromStackParserOptions(options.stackParser || nodeStackParser),
+ integrations: getIntegrationsToSetup(options),
+ transport: options.transport || makeEdgeTransport,
+ };
+
+ initAndBind(ServerRuntimeClient, clientOptions);
+ instrumentServer();
+
+ configureScope(scope => {
+ scope.setTag('runtime', 'worker');
+ });
+}
diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts
index a80e795fb9a6..590ef96ca932 100644
--- a/packages/remix/src/utils/instrumentServer.ts
+++ b/packages/remix/src/utils/instrumentServer.ts
@@ -1,13 +1,18 @@
/* eslint-disable max-lines */
-import { getActiveTransaction, hasTracingEnabled, runWithAsyncContext } from '@sentry/core';
-import type { Hub } from '@sentry/node';
-import { captureException, getCurrentHub } from '@sentry/node';
+import type { Hub } from '@sentry/core';
+import {
+ captureException,
+ getActiveTransaction,
+ getCurrentHub,
+ hasTracingEnabled,
+ runWithAsyncContext,
+} from '@sentry/core';
import type { Transaction, TransactionSource, WrappedFunction } from '@sentry/types';
import {
addExceptionMechanism,
dynamicSamplingContextToSentryBaggageHeader,
fill,
- isNodeEnv,
+ isBrowser,
loadModule,
logger,
tracingContextFromHeaders,
@@ -236,7 +241,7 @@ function getTraceAndBaggage(): { sentryTrace?: string; sentryBaggage?: string }
const transaction = getActiveTransaction();
const currentScope = getCurrentHub().getScope();
- if (isNodeEnv() && hasTracingEnabled()) {
+ if (!isBrowser() && hasTracingEnabled()) {
const span = currentScope.getSpan();
if (span && transaction) {
@@ -252,18 +257,17 @@ function getTraceAndBaggage(): { sentryTrace?: string; sentryBaggage?: string }
return {};
}
-function makeWrappedRootLoader(remixVersion: number) {
+function makeWrappedRootLoader() {
return function (origLoader: DataFunction): DataFunction {
return async function (this: unknown, args: DataFunctionArgs): Promise {
const res = await origLoader.call(this, args);
const traceAndBaggage = getTraceAndBaggage();
if (isDeferredData(res)) {
- return {
- ...res.data,
- ...traceAndBaggage,
- remixVersion,
- };
+ res.data['sentryTrace'] = traceAndBaggage.sentryTrace;
+ res.data['sentryBaggage'] = traceAndBaggage.sentryBaggage;
+
+ return res;
}
if (isResponse(res)) {
@@ -279,7 +283,7 @@ function makeWrappedRootLoader(remixVersion: number) {
if (typeof data === 'object') {
return json(
- { ...data, ...traceAndBaggage, remixVersion },
+ { ...data, ...traceAndBaggage },
{ headers: res.headers, statusText: res.statusText, status: res.status },
);
} else {
@@ -290,7 +294,7 @@ function makeWrappedRootLoader(remixVersion: number) {
}
}
- return { ...res, ...traceAndBaggage, remixVersion };
+ return { ...res, ...traceAndBaggage };
};
};
}
@@ -462,7 +466,7 @@ export function instrumentBuild(build: ServerBuild): ServerBuild {
}
// We want to wrap the root loader regardless of whether it's already wrapped before.
- fill(wrappedRoute.module, 'loader', makeWrappedRootLoader(remixVersion));
+ fill(wrappedRoute.module, 'loader', makeWrappedRootLoader());
}
routes[id] = wrappedRoute;
diff --git a/packages/remix/src/utils/serverAdapters/worker.ts b/packages/remix/src/utils/serverAdapters/worker.ts
new file mode 100644
index 000000000000..88832183f36e
--- /dev/null
+++ b/packages/remix/src/utils/serverAdapters/worker.ts
@@ -0,0 +1,83 @@
+import { getCurrentHub, hasTracingEnabled } from '@sentry/core';
+import { isString, logger } from '@sentry/utils';
+
+import {
+ createRoutes,
+ getTransactionName,
+ instrumentBuild,
+ isRequestHandlerWrapped,
+ startRequestHandlerTransaction,
+} from '../instrumentServer';
+import type { ReactRouterDomPkg, ServerBuild } from '../vendor/types';
+
+type WorkerRequestHandler = (request: Request) => Promise;
+export type WorkerCreateRequestHandler = (this: unknown, options: any) => WorkerRequestHandler;
+type WorkerRequestHandlerOptions = {
+ build: ServerBuild;
+ mode?: string;
+ poweredByHeader?: boolean;
+ getLoadContext?: (request: Request) => Promise | unknown;
+};
+
+let pkg: ReactRouterDomPkg;
+
+function wrapWorkerRequestHandler(origRequestHandler: WorkerRequestHandler, build: ServerBuild): WorkerRequestHandler {
+ const routes = createRoutes(build.routes);
+
+ // If the core request handler is already wrapped, don't wrap Express handler which uses it.
+ if (isRequestHandlerWrapped) {
+ return origRequestHandler;
+ }
+
+ return async function (this: unknown, request: Request): Promise {
+ if (!pkg) {
+ try {
+ pkg = await import('react-router-dom');
+ } finally {
+ if (!pkg) {
+ __DEBUG_BUILD__ && logger.error('Could not find `react-router-dom` package.');
+ }
+ }
+ }
+
+ const hub = getCurrentHub();
+ const options = hub.getClient()?.getOptions();
+ const scope = hub.getScope();
+
+ scope.setSDKProcessingMetadata({ request });
+
+ if (!options || !hasTracingEnabled(options) || !request.url || !request.method) {
+ return origRequestHandler.call(this, request);
+ }
+
+ const url = new URL(request.url);
+ const [name, source] = getTransactionName(routes, url, pkg);
+ startRequestHandlerTransaction(hub, name, source, {
+ headers: {
+ 'sentry-trace':
+ (request.headers && isString(request.headers.get('sentry-trace')) && request.headers.get('sentry-trace')) ||
+ '',
+ baggage: (request.headers && isString(request.headers.get('baggage')) && request.headers.get('baggage')) || '',
+ },
+ method: request.method,
+ });
+
+ return origRequestHandler.call(this, request);
+ };
+}
+
+/**
+ * Instruments `createRequestHandler` from `@remix-run/express`
+ */
+export function wrapWorkerCreateRequestHandler(
+ origCreateRequestHandler: WorkerCreateRequestHandler,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+): (options: any) => WorkerRequestHandler {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ return function (this: unknown, options: any): WorkerRequestHandler {
+ const newBuild = instrumentBuild((options as WorkerRequestHandlerOptions).build);
+ const requestHandler = origCreateRequestHandler.call(this, { ...options, build: newBuild });
+
+ return wrapWorkerRequestHandler(requestHandler, newBuild);
+ };
+}
diff --git a/packages/remix/src/utils/vendor/getIpAddress.ts b/packages/remix/src/utils/vendor/getIpAddress.ts
index d63e31779aac..52fef0db1f7f 100644
--- a/packages/remix/src/utils/vendor/getIpAddress.ts
+++ b/packages/remix/src/utils/vendor/getIpAddress.ts
@@ -23,8 +23,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
-import { isIP } from 'net';
-
+import isIP from 'is-ip';
/**
* Get the IP address of the client sending a request.
*
diff --git a/packages/remix/src/utils/vendor/types.ts b/packages/remix/src/utils/vendor/types.ts
index faaa7e5f6f60..da5c2a19b595 100644
--- a/packages/remix/src/utils/vendor/types.ts
+++ b/packages/remix/src/utils/vendor/types.ts
@@ -202,7 +202,7 @@ export interface DataFunction {
}
export interface ReactRouterDomPkg {
- matchRoutes: (routes: ServerRoute[], pathname: string) => RouteMatch[] | null;
+ matchRoutes: (routes: any[], pathname: string) => RouteMatch[] | null;
}
// Taken from Remix Implementation
diff --git a/packages/remix/src/worker/transport.ts b/packages/remix/src/worker/transport.ts
new file mode 100644
index 000000000000..a479425f96e6
--- /dev/null
+++ b/packages/remix/src/worker/transport.ts
@@ -0,0 +1,103 @@
+import { createTransport } from '@sentry/core';
+import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/types';
+import { SentryError } from '@sentry/utils';
+
+export interface VercelEdgeTransportOptions extends BaseTransportOptions {
+ /** Fetch API init parameters. */
+ fetchOptions?: RequestInit;
+ /** Custom headers for the transport. */
+ headers?: { [key: string]: string };
+}
+
+const DEFAULT_TRANSPORT_BUFFER_SIZE = 30;
+
+/**
+ * This is a modified promise buffer that collects tasks until drain is called.
+ * We need this in the edge runtime because edge function invocations may not share I/O objects, like fetch requests
+ * and responses, and the normal PromiseBuffer inherently buffers stuff inbetween incoming requests.
+ *
+ * A limitation we need to be aware of is that DEFAULT_TRANSPORT_BUFFER_SIZE is the maximum amount of payloads the
+ * SDK can send for a given edge function invocation.
+ */
+export class IsolatedPromiseBuffer {
+ // We just have this field because the promise buffer interface requires it.
+ // If we ever remove it from the interface we should also remove it here.
+ public $: Array>;
+
+ private _taskProducers: (() => PromiseLike)[];
+
+ private readonly _bufferSize: number;
+
+ public constructor(_bufferSize = DEFAULT_TRANSPORT_BUFFER_SIZE) {
+ this.$ = [];
+ this._taskProducers = [];
+ this._bufferSize = _bufferSize;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public add(taskProducer: () => PromiseLike): PromiseLike {
+ if (this._taskProducers.length >= this._bufferSize) {
+ return Promise.reject(new SentryError('Not adding Promise because buffer limit was reached.'));
+ }
+
+ this._taskProducers.push(taskProducer);
+ return Promise.resolve();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public drain(timeout?: number): PromiseLike {
+ const oldTaskProducers = [...this._taskProducers];
+ this._taskProducers = [];
+
+ return new Promise(resolve => {
+ const timer = setTimeout(() => {
+ if (timeout && timeout > 0) {
+ resolve(false);
+ }
+ }, timeout);
+
+ void Promise.all(
+ oldTaskProducers.map(taskProducer =>
+ taskProducer().then(null, () => {
+ // catch all failed requests
+ }),
+ ),
+ ).then(() => {
+ // resolve to true if all fetch requests settled
+ clearTimeout(timer);
+ resolve(true);
+ });
+ });
+ }
+}
+
+/**
+ * Creates a Transport that uses the Edge Runtimes native fetch API to send events to Sentry.
+ */
+export function makeEdgeTransport(options: VercelEdgeTransportOptions): Transport {
+ function makeRequest(request: TransportRequest): PromiseLike {
+ const requestOptions: RequestInit = {
+ body: request.body,
+ method: 'POST',
+ referrerPolicy: 'origin',
+ headers: options.headers,
+ ...options.fetchOptions,
+ };
+
+ return fetch(options.url, requestOptions).then(response => {
+ return {
+ statusCode: response.status,
+ headers: {
+ 'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),
+ 'retry-after': response.headers.get('Retry-After'),
+ },
+ };
+ });
+ }
+
+ return createTransport(options, makeRequest, new IsolatedPromiseBuffer(options.bufferSize));
+}
diff --git a/packages/replay/jest.setup.ts b/packages/replay/jest.setup.ts
index b44298a751e1..1b6424bb7c93 100644
--- a/packages/replay/jest.setup.ts
+++ b/packages/replay/jest.setup.ts
@@ -10,8 +10,9 @@ import type { ReplayContainer, Session } from './src/types';
type MockTransport = jest.MockedFunction;
-jest.mock('./src/util/isBrowser', () => {
+jest.mock('@sentry/utils', () => {
return {
+ ...jest.requireActual('@sentry/utils'),
isBrowser: () => true,
};
});
diff --git a/packages/replay/src/integration.ts b/packages/replay/src/integration.ts
index 753fd62d5660..6522e4dd1c6f 100644
--- a/packages/replay/src/integration.ts
+++ b/packages/replay/src/integration.ts
@@ -1,6 +1,6 @@
import { getCurrentHub } from '@sentry/core';
import type { BrowserClientReplayOptions, Integration } from '@sentry/types';
-import { dropUndefinedKeys } from '@sentry/utils';
+import { dropUndefinedKeys, isBrowser } from '@sentry/utils';
import {
DEFAULT_FLUSH_MAX_DELAY,
@@ -12,7 +12,6 @@ import {
import { ReplayContainer } from './replay';
import type { RecordingOptions, ReplayConfiguration, ReplayPluginOptions, SendBufferedReplayOptions } from './types';
import { getPrivacyOptions } from './util/getPrivacyOptions';
-import { isBrowser } from './util/isBrowser';
import { maskAttribute } from './util/maskAttribute';
const MEDIA_SELECTORS =
diff --git a/packages/replay/src/util/isBrowser.ts b/packages/replay/src/util/isBrowser.ts
deleted file mode 100644
index 6a64317ba3fa..000000000000
--- a/packages/replay/src/util/isBrowser.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { isNodeEnv } from '@sentry/utils';
-
-/**
- * Returns true if we are in the browser.
- */
-export function isBrowser(): boolean {
- // eslint-disable-next-line no-restricted-globals
- return typeof window !== 'undefined' && (!isNodeEnv() || isElectronNodeRenderer());
-}
-
-type ElectronProcess = { type?: string };
-
-// Electron renderers with nodeIntegration enabled are detected as Node.js so we specifically test for them
-function isElectronNodeRenderer(): boolean {
- return typeof process !== 'undefined' && (process as ElectronProcess).type === 'renderer';
-}
diff --git a/packages/utils/src/node.ts b/packages/utils/src/node.ts
index 33bece5ef62f..1c5097617cb9 100644
--- a/packages/utils/src/node.ts
+++ b/packages/utils/src/node.ts
@@ -19,6 +19,21 @@ export function isNodeEnv(): boolean {
);
}
+/**
+ * Returns true if we are in the browser.
+ */
+export function isBrowser(): boolean {
+ // eslint-disable-next-line no-restricted-globals
+ return typeof window !== 'undefined' && (!isNodeEnv() || isElectronNodeRenderer());
+}
+
+type ElectronProcess = { type?: string };
+
+// Electron renderers with nodeIntegration enabled are detected as Node.js so we specifically test for them
+function isElectronNodeRenderer(): boolean {
+ return typeof process !== 'undefined' && (process as ElectronProcess).type === 'renderer';
+}
+
/**
* Requires a module which is protected against bundler minification.
*
@@ -49,6 +64,7 @@ export function loadModule(moduleName: string): T | undefined {
try {
mod = dynamicRequire(module, moduleName);
} catch (e) {
+ console.warn(`Cannot load instrumentation module '${moduleName}': ${e}`);
// no-empty
}
@@ -56,6 +72,7 @@ export function loadModule(moduleName: string): T | undefined {
const { cwd } = dynamicRequire(module, 'process');
mod = dynamicRequire(module, `${cwd()}/node_modules/${moduleName}`) as T;
} catch (e) {
+ console.warn(`Cannot load instrumentation module '${moduleName}': ${e}`);
// no-empty
}
diff --git a/yarn.lock b/yarn.lock
index d52033c73e40..adacf99f05a2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4699,85 +4699,91 @@
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
-"@remix-run/node@^1.4.3":
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/@remix-run/node/-/node-1.5.1.tgz#1c367d4035baaef8f0ea66962a826456d62f0030"
- integrity sha512-yl4bd1nl7MiJp4tI3+4ygObeMU3txM4Uo09IdHLRa4NMdBQnacUJ47kqCahny01MerC2JL2d9NPjdVPwRCRZvQ==
- dependencies:
- "@remix-run/server-runtime" "1.5.1"
- "@remix-run/web-fetch" "^4.1.3"
- "@remix-run/web-file" "^3.0.2"
- "@remix-run/web-stream" "^1.0.3"
+"@remix-run/node@^1.19.3":
+ version "1.19.3"
+ resolved "https://registry.yarnpkg.com/@remix-run/node/-/node-1.19.3.tgz#d27e2f742fc45379525cb3fca466a883ca06d6c9"
+ integrity sha512-z5qrVL65xLXIUpU4mkR4MKlMeKARLepgHAk4W5YY3IBXOreRqOGUC70POViYmY7x38c2Ia1NwqL80H+0h7jbMw==
+ dependencies:
+ "@remix-run/server-runtime" "1.19.3"
+ "@remix-run/web-fetch" "^4.3.6"
+ "@remix-run/web-file" "^3.0.3"
+ "@remix-run/web-stream" "^1.0.4"
"@web3-storage/multipart-parser" "^1.0.0"
abort-controller "^3.0.0"
cookie-signature "^1.1.0"
source-map-support "^0.5.21"
stream-slice "^0.1.2"
-"@remix-run/react@^1.4.3":
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/@remix-run/react/-/react-1.5.1.tgz#372e5e80f3f10a638b0567c4e03307dfb0a28dc0"
- integrity sha512-p4t6tC/WyPeLW7DO4g7ZSyH9EpWO37c4wD2np3rDwtv3WtsTZ70bU/+NOWE9nv74mH8i1C50eJ3/OR+8Ll8UbA==
+"@remix-run/react@^1.19.3":
+ version "1.19.3"
+ resolved "https://registry.yarnpkg.com/@remix-run/react/-/react-1.19.3.tgz#00efcc583bf05b434566e56381d51df86575d8b0"
+ integrity sha512-iP37MZ+oG1n4kv4rX77pKT/knra51lNwKo5tinPPF0SuNJhF3+XjWo5nwEjvisKTXLZ/OHeicinhgX2JHHdDvA==
dependencies:
- history "^5.3.0"
- react-router-dom "^6.2.2"
+ "@remix-run/router" "1.7.2"
+ react-router-dom "6.14.2"
"@remix-run/router@1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.0.2.tgz#1c17eadb2fa77f80a796ad5ea9bf108e6993ef06"
integrity sha512-GRSOFhJzjGN+d4sKHTMSvNeUPoZiDHWmRnXfzaxrqe7dE/Nzlc8BiMSJdLDESZlndM7jIUrZ/F4yWqVYlI0rwQ==
-"@remix-run/server-runtime@1.5.1":
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/@remix-run/server-runtime/-/server-runtime-1.5.1.tgz#5272b01e6dce109dc10bd68447ceae2d039315b2"
- integrity sha512-FQbCCdW+qzE3wpoCwUKdwcL8yZVYNPiyHS9JS/6r6qmd/yvZfbj44E48wEQ6trbWE2TUiEh/EQqNMyrZWEs4bw==
+"@remix-run/router@1.7.2":
+ version "1.7.2"
+ resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.7.2.tgz#cba1cf0a04bc04cb66027c51fa600e9cbc388bc8"
+ integrity sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==
+
+"@remix-run/server-runtime@1.19.3":
+ version "1.19.3"
+ resolved "https://registry.yarnpkg.com/@remix-run/server-runtime/-/server-runtime-1.19.3.tgz#206b55337c266c5bc254878f8ff3cd5677cc60fb"
+ integrity sha512-KzQ+htUsKqpBgKE2tWo7kIIGy3MyHP58Io/itUPvV+weDjApwr9tQr9PZDPA3yAY6rAzLax7BU0NMSYCXWFY5A==
dependencies:
- "@types/cookie" "^0.4.0"
+ "@remix-run/router" "1.7.2"
+ "@types/cookie" "^0.4.1"
"@web3-storage/multipart-parser" "^1.0.0"
cookie "^0.4.1"
- jsesc "^3.0.1"
- react-router-dom "^6.2.2"
set-cookie-parser "^2.4.8"
source-map "^0.7.3"
-"@remix-run/web-blob@^3.0.3", "@remix-run/web-blob@^3.0.4":
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/@remix-run/web-blob/-/web-blob-3.0.4.tgz#99c67b9d0fb641bd0c07d267fd218ae5aa4ae5ed"
- integrity sha512-AfegzZvSSDc+LwnXV+SwROTrDtoLiPxeFW+jxgvtDAnkuCX1rrzmVJ6CzqZ1Ai0bVfmJadkG5GxtAfYclpPmgw==
+"@remix-run/web-blob@^3.1.0":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@remix-run/web-blob/-/web-blob-3.1.0.tgz#e0c669934c1eb6028960047e57a13ed38bbfb434"
+ integrity sha512-owGzFLbqPH9PlKb8KvpNJ0NO74HWE2euAn61eEiyCXX/oteoVzTVSN8mpLgDjaxBf2btj5/nUllSUgpyd6IH6g==
dependencies:
- "@remix-run/web-stream" "^1.0.0"
+ "@remix-run/web-stream" "^1.1.0"
web-encoding "1.1.5"
-"@remix-run/web-fetch@^4.1.3":
- version "4.1.3"
- resolved "https://registry.yarnpkg.com/@remix-run/web-fetch/-/web-fetch-4.1.3.tgz#8ad3077c1b5bd9fe2a8813d0ad3c84970a495c04"
- integrity sha512-D3KXAEkzhR248mu7wCHReQrMrIo3Y9pDDa7TrlISnsOEvqkfWkJJF+PQWmOIKpOSHAhDg7TCb2tzvW8lc/MfHw==
+"@remix-run/web-fetch@^4.3.6":
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/@remix-run/web-fetch/-/web-fetch-4.4.1.tgz#1ea34e6f1c660a52e7582007917a552f0efdc58b"
+ integrity sha512-xMceEGn2kvfeWS91nHSOhEQHPGgjFnmDVpWFZrbWPVdiTByMZIn421/tdSF6Kd1RsNsY+5Iwt3JFEKZHAcMQHw==
dependencies:
- "@remix-run/web-blob" "^3.0.4"
- "@remix-run/web-form-data" "^3.0.2"
- "@remix-run/web-stream" "^1.0.3"
+ "@remix-run/web-blob" "^3.1.0"
+ "@remix-run/web-file" "^3.1.0"
+ "@remix-run/web-form-data" "^3.1.0"
+ "@remix-run/web-stream" "^1.1.0"
"@web3-storage/multipart-parser" "^1.0.0"
+ abort-controller "^3.0.0"
data-uri-to-buffer "^3.0.1"
mrmime "^1.0.0"
-"@remix-run/web-file@^3.0.2":
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/@remix-run/web-file/-/web-file-3.0.2.tgz#1a6cc0900a1310ede4bc96abad77ac6eb27a2131"
- integrity sha512-eFC93Onh/rZ5kUNpCQersmBtxedGpaXK2/gsUl49BYSGK/DvuPu3l06vmquEDdcPaEuXcsdGP0L7zrmUqrqo4A==
+"@remix-run/web-file@^3.0.3", "@remix-run/web-file@^3.1.0":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@remix-run/web-file/-/web-file-3.1.0.tgz#07219021a2910e90231bc30ca1ce693d0e9d3825"
+ integrity sha512-dW2MNGwoiEYhlspOAXFBasmLeYshyAyhIdrlXBi06Duex5tDr3ut2LFKVj7tyHLmn8nnNwFf1BjNbkQpygC2aQ==
dependencies:
- "@remix-run/web-blob" "^3.0.3"
+ "@remix-run/web-blob" "^3.1.0"
-"@remix-run/web-form-data@^3.0.2":
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/@remix-run/web-form-data/-/web-form-data-3.0.2.tgz#733a4c8f8176523b7b60a8bd0dc6704fd4d498f3"
- integrity sha512-F8tm3iB1sPxMpysK6Js7lV3gvLfTNKGmIW38t/e6dtPEB5L1WdbRG1cmLyhsonFc7rT1x1JKdz+2jCtoSdnIUw==
+"@remix-run/web-form-data@^3.1.0":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@remix-run/web-form-data/-/web-form-data-3.1.0.tgz#47f9ad8ce8bf1c39ed83eab31e53967fe8e3df6a"
+ integrity sha512-NdeohLMdrb+pHxMQ/Geuzdp0eqPbea+Ieo8M8Jx2lGC6TBHsgHzYcBvr0LyPdPVycNRDEpWpiDdCOdCryo3f9A==
dependencies:
web-encoding "1.1.5"
-"@remix-run/web-stream@^1.0.0", "@remix-run/web-stream@^1.0.3":
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/@remix-run/web-stream/-/web-stream-1.0.3.tgz#3284a6a45675d1455c4d9c8f31b89225c9006438"
- integrity sha512-wlezlJaA5NF6SsNMiwQnnAW6tnPzQ5I8qk0Y0pSohm0eHKa2FQ1QhEKLVVcDDu02TmkfHgnux0igNfeYhDOXiA==
+"@remix-run/web-stream@^1.0.4", "@remix-run/web-stream@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@remix-run/web-stream/-/web-stream-1.1.0.tgz#b93a8f806c2c22204930837c44d81fdedfde079f"
+ integrity sha512-KRJtwrjRV5Bb+pM7zxcTJkhIqWWSy+MYsIxHK+0m5atcznsf15YwUBWHWulZerV2+vvHH1Lp1DD7pw6qKW8SgA==
dependencies:
web-streams-polyfill "^3.1.1"
@@ -5459,7 +5465,7 @@
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.5.2.tgz#9bf9d62c838c85a07c92fdf2334c2c14fd9c59a9"
integrity sha512-DBpRoJGKJZn7RY92dPrgoMew8xCWc2P71beqsjyhEI/Ds9mOyVmBwtekyfhpwFIVt1WrxTonFifiOZ62V8CnNA==
-"@types/cookie@^0.4.0", "@types/cookie@^0.4.1":
+"@types/cookie@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d"
integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==
@@ -16520,7 +16526,7 @@ history@^4.6.0, history@^4.9.0:
tiny-warning "^1.0.0"
value-equal "^1.0.1"
-history@^5.2.0, history@^5.3.0:
+history@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b"
integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==
@@ -17265,6 +17271,11 @@ ip-regex@^2.1.0:
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
+ip-regex@^4.0.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5"
+ integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==
+
ip@1.1.5, ip@^1.1.0, ip@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
@@ -17566,6 +17577,13 @@ is-interactive@^2.0.0:
resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-2.0.0.tgz#40c57614593826da1100ade6059778d597f16e90"
integrity sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==
+is-ip@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8"
+ integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==
+ dependencies:
+ ip-regex "^4.0.0"
+
is-lambda@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5"
@@ -18713,11 +18731,6 @@ jsesc@^2.5.1:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
-jsesc@^3.0.1:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e"
- integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==
-
jsesc@~0.3.x:
version "0.3.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.3.0.tgz#1bf5ee63b4539fe2e26d0c1e99c240b97a457972"
@@ -25438,21 +25451,27 @@ react-refresh@0.8.3:
dependencies:
"@remix-run/router" "1.0.2"
-"react-router-6@npm:react-router@6.3.0", react-router@6.3.0:
- name react-router-6
+"react-router-6@npm:react-router@6.3.0":
version "6.3.0"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557"
integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==
dependencies:
history "^5.2.0"
-react-router-dom@^6.2.2:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.3.0.tgz#a0216da813454e521905b5fa55e0e5176123f43d"
- integrity sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==
+react-router-dom@6.14.2:
+ version "6.14.2"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.14.2.tgz#88f520118b91aa60233bd08dbd3fdcaea3a68488"
+ integrity sha512-5pWX0jdKR48XFZBuJqHosX3AAHjRAzygouMTyimnBPOLdY3WjzUSKhus2FVMihUFWzeLebDgr4r8UeQFAct7Bg==
dependencies:
- history "^5.2.0"
- react-router "6.3.0"
+ "@remix-run/router" "1.7.2"
+ react-router "6.14.2"
+
+react-router@6.14.2:
+ version "6.14.2"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.14.2.tgz#1f60994d8c369de7b8ba7a78d8f7ec23df76b300"
+ integrity sha512-09Zss2dE2z+T1D03IheqAFtK4UzQyX8nFPWx6jkwdYzGLXd5ie06A6ezS2fO6zJfEb/SpG6UocN2O1hfD+2urQ==
+ dependencies:
+ "@remix-run/router" "1.7.2"
react@^18.0.0:
version "18.0.0"