[]): void {
* @param OrigApp The Remix root to wrap
* @param options The options for ErrorBoundary wrapper.
*/
-export function withSentry, R extends React.ComponentType
>(
- OrigApp: R,
- options: {
- wrapWithErrorBoundary?: boolean;
- errorBoundaryOptions?: ErrorBoundaryProps;
- } = {
- // We don't want to wrap application with Sentry's ErrorBoundary by default for Remix v2
- wrapWithErrorBoundary: true,
- errorBoundaryOptions: {},
- },
-): R {
+export function withSentry
, R extends React.ComponentType
>(OrigApp: R): R {
const SentryRoot: React.FC
= (props: P) => {
// Early return when any of the required functions is not available.
if (!_useEffect || !_useLocation || !_useMatches) {
@@ -188,11 +163,6 @@ export function withSentry
, R extends React.Co
isBaseLocation = false;
- if (!isRemixV2(readRemixVersionFromLoader()) && options.wrapWithErrorBoundary) {
- // @ts-expect-error Setting more specific React Component typing for `R` generic above
- // will break advanced type inference done by react router params
- return withErrorBoundary(OrigApp, options.errorBoundaryOptions)(props);
- }
// @ts-expect-error Setting more specific React Component typing for `R` generic above
// will break advanced type inference done by react router params
return ;
diff --git a/packages/remix/src/utils/errors.ts b/packages/remix/src/utils/errors.ts
index 94c1c8755ad4..1921ee2a37f2 100644
--- a/packages/remix/src/utils/errors.ts
+++ b/packages/remix/src/utils/errors.ts
@@ -1,10 +1,14 @@
-import type { AppData, DataFunctionArgs, EntryContext, HandleDocumentRequestFunction } from '@remix-run/node';
+import type {
+ ActionFunctionArgs,
+ EntryContext,
+ HandleDocumentRequestFunction,
+ LoaderFunctionArgs,
+} from '@remix-run/node';
import {
addExceptionMechanism,
captureException,
getClient,
handleCallbackErrors,
- isPrimitive,
logger,
objectify,
winterCGRequestToRequestData,
@@ -22,19 +26,13 @@ import type { DataFunction, RemixRequest } from './vendor/types';
* @param err The error to capture.
* @param name The name of the origin function.
* @param request The request object.
- * @param isRemixV2 Whether the error is from Remix v2 or not. Default is `true`.
*
* @returns A promise that resolves when the exception is captured.
*/
-export async function captureRemixServerException(
- err: unknown,
- name: string,
- request: Request,
- isRemixV2: boolean = true,
-): Promise {
+export async function captureRemixServerException(err: unknown, name: string, request: Request): Promise {
// Skip capturing if the thrown error is not a 5xx response
- // https://remix.run/docs/en/v1/api/conventions#throwing-responses-in-loaders
- if (isRemixV2 && isRouteErrorResponse(err) && err.status < 500) {
+ // https://remix.run/docs/en/main/route/loader#throwing-responses-in-loaders
+ if (isRouteErrorResponse(err) && err.status < 500) {
return;
}
@@ -82,7 +80,6 @@ export async function captureRemixServerException(
*
* @param origDocumentRequestFunction The original `HandleDocumentRequestFunction`.
* @param requestContext The request context.
- * @param isRemixV2 Whether the Remix version is v2 or not.
*
* @returns The wrapped `HandleDocumentRequestFunction`.
*/
@@ -96,7 +93,6 @@ export function errorHandleDocumentRequestFunction(
context: EntryContext;
loadContext?: Record;
},
- isRemixV2: boolean,
): HandleDocumentRequestFunction {
const { request, responseStatusCode, responseHeaders, context, loadContext } = requestContext;
@@ -105,14 +101,6 @@ export function errorHandleDocumentRequestFunction(
return origDocumentRequestFunction.call(this, request, responseStatusCode, responseHeaders, context, loadContext);
},
err => {
- // This exists to capture the server-side rendering errors on Remix v1
- // On Remix v2, we capture SSR errors at `handleError`
- // We also skip primitives here, as we can't dedupe them, and also we don't expect any primitive SSR errors.
- if (!isRemixV2 && !isPrimitive(err)) {
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
- captureRemixServerException(err, 'documentRequest', request, isRemixV2);
- }
-
throw err;
},
);
@@ -125,7 +113,6 @@ export function errorHandleDocumentRequestFunction(
* @param origFn The original `DataFunction`.
* @param name The name of the function.
* @param args The arguments of the function.
- * @param isRemixV2 Whether the Remix version is v2 or not.
* @param span The span to store the form data keys.
*
* @returns The wrapped `DataFunction`.
@@ -134,10 +121,9 @@ export async function errorHandleDataFunction(
this: unknown,
origFn: DataFunction,
name: string,
- args: DataFunctionArgs,
- isRemixV2: boolean,
+ args: ActionFunctionArgs | LoaderFunctionArgs,
span?: Span,
-): Promise {
+): Promise {
return handleCallbackErrors(
async () => {
if (name === 'action' && span) {
@@ -151,12 +137,11 @@ export async function errorHandleDataFunction(
return origFn.call(this, args);
},
err => {
- // On Remix v2, we capture all unexpected errors (except the `Route Error Response`s / Thrown Responses) in `handleError` function.
+ // We capture all unexpected errors (except the `Route Error Response`s / Thrown Responses) in `handleError` function.
// This is both for consistency and also avoid duplicates such as primitives like `string` or `number` being captured twice.
- // Remix v1 does not have a `handleError` function, so we capture all errors here.
- if (isRemixV2 ? isResponse(err) : true) {
+ if (isResponse(err)) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
- captureRemixServerException(err, name, args.request, true);
+ captureRemixServerException(err, name, args.request);
}
throw err;
diff --git a/packages/remix/src/utils/futureFlags.ts b/packages/remix/src/utils/futureFlags.ts
deleted file mode 100644
index 63c9c5dff2ef..000000000000
--- a/packages/remix/src/utils/futureFlags.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { GLOBAL_OBJ } from '@sentry/core';
-
-import type { FutureConfig, ServerBuild } from './vendor/types';
-
-export type EnhancedGlobal = typeof GLOBAL_OBJ & {
- __remixContext?: {
- future?: FutureConfig;
- state?: {
- loaderData?: {
- root?: {
- remixVersion?: number;
- };
- };
- };
- };
-};
-
-/**
- * Get the future flags from the Remix browser context
- *
- * @returns The future flags
- */
-export function getFutureFlagsBrowser(): FutureConfig | undefined {
- const window = GLOBAL_OBJ as EnhancedGlobal;
-
- if (!window.__remixContext) {
- return;
- }
-
- return window.__remixContext.future;
-}
-
-/**
- * Get the future flags from the Remix server build
- *
- * @param build The Remix server build
- *
- * @returns The future flags
- */
-export function getFutureFlagsServer(build: ServerBuild): FutureConfig | undefined {
- return build.future;
-}
-
-/**
- * Learn Remix version from the server build object
- * V2 Server builds have a non-optional `mode` property
- *
- * @returns The major version number
- */
-export function getRemixVersionFromBuild(build: ServerBuild): number {
- if ('mode' in build) {
- return 2;
- }
-
- return 1;
-}
-
-/**
- * Read Remix version from the Remix context on the browser
- *
- * @returns The major version number
- */
-export function readRemixVersionFromLoader(): number | undefined {
- const window = GLOBAL_OBJ as EnhancedGlobal;
-
- return window.__remixContext?.state?.loaderData?.root?.remixVersion;
-}
diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts
index 1d67403209bc..0ea54986f55c 100644
--- a/packages/remix/src/utils/instrumentServer.ts
+++ b/packages/remix/src/utils/instrumentServer.ts
@@ -22,7 +22,6 @@ import {
} from '@sentry/core';
import { DEBUG_BUILD } from './debug-build';
import { captureRemixServerException, errorHandleDataFunction, errorHandleDocumentRequestFunction } from './errors';
-import { getFutureFlagsServer, getRemixVersionFromBuild } from './futureFlags';
import type { RemixOptions } from './remixOptions';
import { createRoutes, getTransactionName } from './utils';
import { extractData, isDeferredData, isResponse, isRouteErrorResponse, json } from './vendor/response';
@@ -33,7 +32,6 @@ import type {
DataFunction,
DataFunctionArgs,
EntryContext,
- FutureConfig,
HandleDocumentRequestFunction,
RemixRequest,
RequestHandler,
@@ -42,8 +40,6 @@ import type {
ServerRouteManifest,
} from './vendor/types';
-let FUTURE_FLAGS: FutureConfig | undefined;
-
const redirectStatusCodes = new Set([301, 302, 303, 307, 308]);
function isRedirectResponse(response: Response): boolean {
return redirectStatusCodes.has(response.status);
@@ -67,7 +63,6 @@ export function sentryHandleError(err: unknown, { request }: DataFunctionArgs):
// We don't want to capture them twice.
// This function is only for capturing unhandled server-side exceptions.
// https://remix.run/docs/en/main/file-conventions/entry.server#thrown-responses
- // https://remix.run/docs/en/v1/api/conventions#throwing-responses-in-loaders
if (isResponse(err) || isRouteErrorResponse(err)) {
return;
}
@@ -99,7 +94,7 @@ export function wrapHandleErrorWithSentry(
};
}
-function makeWrappedDocumentRequestFunction(autoInstrumentRemix?: boolean, remixVersion?: number) {
+function makeWrappedDocumentRequestFunction(autoInstrumentRemix?: boolean) {
return function (origDocumentRequestFunction: HandleDocumentRequestFunction): HandleDocumentRequestFunction {
return async function (
this: unknown,
@@ -117,8 +112,6 @@ function makeWrappedDocumentRequestFunction(autoInstrumentRemix?: boolean, remix
loadContext,
};
- const isRemixV2 = FUTURE_FLAGS?.v2_errorBoundary || remixVersion === 2;
-
if (!autoInstrumentRemix) {
const activeSpan = getActiveSpan();
const rootSpan = activeSpan && getRootSpan(activeSpan);
@@ -139,21 +132,11 @@ function makeWrappedDocumentRequestFunction(autoInstrumentRemix?: boolean, remix
},
},
() => {
- return errorHandleDocumentRequestFunction.call(
- this,
- origDocumentRequestFunction,
- documentRequestContext,
- isRemixV2,
- );
+ return errorHandleDocumentRequestFunction.call(this, origDocumentRequestFunction, documentRequestContext);
},
);
} else {
- return errorHandleDocumentRequestFunction.call(
- this,
- origDocumentRequestFunction,
- documentRequestContext,
- isRemixV2,
- );
+ return errorHandleDocumentRequestFunction.call(this, origDocumentRequestFunction, documentRequestContext);
}
};
};
@@ -163,12 +146,9 @@ function makeWrappedDataFunction(
origFn: DataFunction,
id: string,
name: 'action' | 'loader',
- remixVersion: number,
autoInstrumentRemix?: boolean,
): DataFunction {
return async function (this: unknown, args: DataFunctionArgs): Promise {
- const isRemixV2 = FUTURE_FLAGS?.v2_errorBoundary || remixVersion === 2;
-
if (!autoInstrumentRemix) {
return startSpan(
{
@@ -180,25 +160,25 @@ function makeWrappedDataFunction(
},
},
(span: Span) => {
- return errorHandleDataFunction.call(this, origFn, name, args, isRemixV2, span);
+ return errorHandleDataFunction.call(this, origFn, name, args, span);
},
);
} else {
- return errorHandleDataFunction.call(this, origFn, name, args, isRemixV2);
+ return errorHandleDataFunction.call(this, origFn, name, args);
}
};
}
const makeWrappedAction =
- (id: string, remixVersion: number, autoInstrumentRemix?: boolean) =>
+ (id: string, autoInstrumentRemix?: boolean) =>
(origAction: DataFunction): DataFunction => {
- return makeWrappedDataFunction(origAction, id, 'action', remixVersion, autoInstrumentRemix);
+ return makeWrappedDataFunction(origAction, id, 'action', autoInstrumentRemix);
};
const makeWrappedLoader =
- (id: string, remixVersion: number, autoInstrumentRemix?: boolean) =>
+ (id: string, autoInstrumentRemix?: boolean) =>
(origLoader: DataFunction): DataFunction => {
- return makeWrappedDataFunction(origLoader, id, 'loader', remixVersion, autoInstrumentRemix);
+ return makeWrappedDataFunction(origLoader, id, 'loader', autoInstrumentRemix);
};
function getTraceAndBaggage(): {
@@ -217,7 +197,7 @@ function getTraceAndBaggage(): {
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);
@@ -226,7 +206,6 @@ function makeWrappedRootLoader(remixVersion: number) {
if (isDeferredData(res)) {
res.data['sentryTrace'] = traceAndBaggage.sentryTrace;
res.data['sentryBaggage'] = traceAndBaggage.sentryBaggage;
- res.data['remixVersion'] = remixVersion;
return res;
}
@@ -243,7 +222,7 @@ function makeWrappedRootLoader(remixVersion: number) {
if (typeof data === 'object') {
return json(
- { ...data, ...traceAndBaggage, remixVersion },
+ { ...data, ...traceAndBaggage },
{
headers: res.headers,
statusText: res.statusText,
@@ -257,7 +236,7 @@ function makeWrappedRootLoader(remixVersion: number) {
}
}
- return { ...res, ...traceAndBaggage, remixVersion };
+ return { ...res, ...traceAndBaggage };
};
};
}
@@ -351,7 +330,6 @@ function wrapRequestHandler(
function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolean): ServerBuild {
const routes: ServerRouteManifest = {};
- const remixVersion = getRemixVersionFromBuild(build);
const wrappedEntry = { ...build.entry, module: { ...build.entry.module } };
// Not keeping boolean flags like it's done for `requestHandler` functions,
@@ -360,7 +338,7 @@ function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolea
// We should be able to wrap them, as they may not be wrapped before.
const defaultExport = wrappedEntry.module.default as undefined | WrappedFunction;
if (defaultExport && !defaultExport.__sentry_original__) {
- fill(wrappedEntry.module, 'default', makeWrappedDocumentRequestFunction(autoInstrumentRemix, remixVersion));
+ fill(wrappedEntry.module, 'default', makeWrappedDocumentRequestFunction(autoInstrumentRemix));
}
for (const [id, route] of Object.entries(build.routes)) {
@@ -368,12 +346,12 @@ function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolea
const routeAction = wrappedRoute.module.action as undefined | WrappedFunction;
if (routeAction && !routeAction.__sentry_original__) {
- fill(wrappedRoute.module, 'action', makeWrappedAction(id, remixVersion, autoInstrumentRemix));
+ fill(wrappedRoute.module, 'action', makeWrappedAction(id, autoInstrumentRemix));
}
const routeLoader = wrappedRoute.module.loader as undefined | WrappedFunction;
if (routeLoader && !routeLoader.__sentry_original__) {
- fill(wrappedRoute.module, 'loader', makeWrappedLoader(id, remixVersion, autoInstrumentRemix));
+ fill(wrappedRoute.module, 'loader', makeWrappedLoader(id, autoInstrumentRemix));
}
// Entry module should have a loader function to provide `sentry-trace` and `baggage`
@@ -384,7 +362,7 @@ function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolea
}
// 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;
@@ -409,19 +387,13 @@ export function instrumentBuild(
if (resolvedBuild instanceof Promise) {
return resolvedBuild.then(build => {
- FUTURE_FLAGS = getFutureFlagsServer(build);
-
return instrumentBuildCallback(build, autoInstrumentRemix);
});
} else {
- FUTURE_FLAGS = getFutureFlagsServer(resolvedBuild);
-
return instrumentBuildCallback(resolvedBuild, autoInstrumentRemix);
}
};
} else {
- FUTURE_FLAGS = getFutureFlagsServer(build);
-
return instrumentBuildCallback(build, autoInstrumentRemix);
}
}
diff --git a/packages/remix/src/utils/utils.ts b/packages/remix/src/utils/utils.ts
index 221ae4cf8e6c..295e61673b8b 100644
--- a/packages/remix/src/utils/utils.ts
+++ b/packages/remix/src/utils/utils.ts
@@ -1,4 +1,4 @@
-import type { DataFunctionArgs } from '@remix-run/node';
+import type { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node';
import { logger } from '@sentry/core';
import type { Span, TransactionSource } from '@sentry/core';
import { DEBUG_BUILD } from './debug-build';
@@ -8,7 +8,7 @@ import type { ServerRoute, ServerRouteManifest } from './vendor/types';
/**
*
*/
-export async function storeFormDataKeys(args: DataFunctionArgs, span: Span): Promise {
+export async function storeFormDataKeys(args: LoaderFunctionArgs | ActionFunctionArgs, span: Span): Promise {
try {
// We clone the request for Remix be able to read the FormData later.
const clonedRequest = args.request.clone();
diff --git a/packages/remix/test/integration/app_v2/entry.client.tsx b/packages/remix/test/integration/app/entry.client.tsx
similarity index 58%
rename from packages/remix/test/integration/app_v2/entry.client.tsx
rename to packages/remix/test/integration/app/entry.client.tsx
index bdee1860d03f..7059cf1e27e8 100644
--- a/packages/remix/test/integration/app_v2/entry.client.tsx
+++ b/packages/remix/test/integration/app/entry.client.tsx
@@ -1,7 +1,7 @@
import { RemixBrowser, useLocation, useMatches } from '@remix-run/react';
import * as Sentry from '@sentry/remix';
-import { useEffect } from 'react';
-import { hydrate } from 'react-dom';
+import { StrictMode, startTransition, useEffect } from 'react';
+import { hydrateRoot } from 'react-dom/client';
Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
@@ -15,4 +15,11 @@ Sentry.init({
],
});
-hydrate(, document);
+startTransition(() => {
+ hydrateRoot(
+ document,
+
+
+ ,
+ );
+});
diff --git a/packages/remix/test/integration/app_v2/entry.server.tsx b/packages/remix/test/integration/app/entry.server.tsx
similarity index 82%
rename from packages/remix/test/integration/app_v2/entry.server.tsx
rename to packages/remix/test/integration/app/entry.server.tsx
index 968ec19a5f59..f7ca9d82345a 100644
--- a/packages/remix/test/integration/app_v2/entry.server.tsx
+++ b/packages/remix/test/integration/app/entry.server.tsx
@@ -1,9 +1,14 @@
+import * as Sentry from '@sentry/remix';
+
if (process.env.USE_OTEL !== '1') {
- require('../instrument.server.cjs');
+ Sentry.init({
+ dsn: 'https://public@dsn.ingest.sentry.io/1337',
+ tracesSampleRate: 1,
+ tracePropagationTargets: ['example.org'],
+ autoInstrumentRemix: false,
+ });
}
-import * as Sentry from '@sentry/remix';
-
import type { EntryContext } from '@remix-run/node';
import { RemixServer } from '@remix-run/react';
import { renderToString } from 'react-dom/server';
diff --git a/packages/remix/test/integration/app_v2/root.tsx b/packages/remix/test/integration/app/root.tsx
similarity index 86%
rename from packages/remix/test/integration/app_v2/root.tsx
rename to packages/remix/test/integration/app/root.tsx
index 399136e04089..1b8e5e39e8f5 100644
--- a/packages/remix/test/integration/app_v2/root.tsx
+++ b/packages/remix/test/integration/app/root.tsx
@@ -1,9 +1,9 @@
-import { LoaderFunction, V2_MetaFunction, defer, json, redirect } from '@remix-run/node';
+import { LoaderFunction, MetaFunction, defer, json, redirect } from '@remix-run/node';
import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration, useRouteError } from '@remix-run/react';
-import { V2_ErrorBoundaryComponent } from '@remix-run/react/dist/routeModules';
+import { ErrorBoundaryComponent } from '@remix-run/react/dist/routeModules';
import { captureRemixErrorBoundaryError, withSentry } from '@sentry/remix';
-export const ErrorBoundary: V2_ErrorBoundaryComponent = () => {
+export const ErrorBoundary: ErrorBoundaryComponent = () => {
const error = useRouteError();
captureRemixErrorBoundaryError(error);
@@ -15,7 +15,7 @@ export const ErrorBoundary: V2_ErrorBoundaryComponent = () => {
);
};
-export const meta: V2_MetaFunction = ({ data }) => [
+export const meta: MetaFunction = ({ data }) => [
{ charset: 'utf-8' },
{ title: 'New Remix App' },
{ name: 'viewport', content: 'width=device-width,initial-scale=1' },
diff --git a/packages/remix/test/integration/common/routes/action-json-response.$id.tsx b/packages/remix/test/integration/app/routes/action-json-response.$id.tsx
similarity index 71%
rename from packages/remix/test/integration/common/routes/action-json-response.$id.tsx
rename to packages/remix/test/integration/app/routes/action-json-response.$id.tsx
index 67c89279388c..b9d3d545403a 100644
--- a/packages/remix/test/integration/common/routes/action-json-response.$id.tsx
+++ b/packages/remix/test/integration/app/routes/action-json-response.$id.tsx
@@ -1,7 +1,8 @@
-import { ActionFunction, LoaderFunction, json, redirect } from '@remix-run/node';
+import { ActionFunction, ActionFunctionArgs, json, redirect } from '@remix-run/node';
import { useActionData } from '@remix-run/react';
+import { LoaderFunctionArgs } from '@remix-run/router';
-export const loader: LoaderFunction = async ({ params: { id } }) => {
+export const loader = async ({ params: { id } }: LoaderFunctionArgs) => {
if (id === '-100') {
throw new Error('Unexpected Server Error');
}
@@ -9,7 +10,7 @@ export const loader: LoaderFunction = async ({ params: { id } }) => {
return null;
};
-export const action: ActionFunction = async ({ params: { id } }) => {
+export const action: ActionFunction = async ({ params: { id } }: ActionFunctionArgs) => {
if (id === '-1') {
throw new Error('Unexpected Server Error');
}
@@ -39,7 +40,7 @@ export const action: ActionFunction = async ({ params: { id } }) => {
};
export default function ActionJSONResponse() {
- const data = useActionData();
+ const data = useActionData();
return (
diff --git a/packages/remix/test/integration/common/routes/capture-exception.tsx b/packages/remix/test/integration/app/routes/capture-exception.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/capture-exception.tsx
rename to packages/remix/test/integration/app/routes/capture-exception.tsx
diff --git a/packages/remix/test/integration/common/routes/capture-message.tsx b/packages/remix/test/integration/app/routes/capture-message.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/capture-message.tsx
rename to packages/remix/test/integration/app/routes/capture-message.tsx
diff --git a/packages/remix/test/integration/app_v2/routes/click-error.tsx b/packages/remix/test/integration/app/routes/click-error.tsx
similarity index 100%
rename from packages/remix/test/integration/app_v2/routes/click-error.tsx
rename to packages/remix/test/integration/app/routes/click-error.tsx
diff --git a/packages/remix/test/integration/common/routes/error-boundary-capture.$id.tsx b/packages/remix/test/integration/app/routes/error-boundary-capture.$id.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/error-boundary-capture.$id.tsx
rename to packages/remix/test/integration/app/routes/error-boundary-capture.$id.tsx
diff --git a/packages/remix/test/integration/common/routes/index.tsx b/packages/remix/test/integration/app/routes/index.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/index.tsx
rename to packages/remix/test/integration/app/routes/index.tsx
diff --git a/packages/remix/test/integration/common/routes/loader-defer-response.$id.tsx b/packages/remix/test/integration/app/routes/loader-defer-response.$id.tsx
similarity index 53%
rename from packages/remix/test/integration/common/routes/loader-defer-response.$id.tsx
rename to packages/remix/test/integration/app/routes/loader-defer-response.$id.tsx
index 48e2a55caaf4..777c3325490e 100644
--- a/packages/remix/test/integration/common/routes/loader-defer-response.$id.tsx
+++ b/packages/remix/test/integration/app/routes/loader-defer-response.$id.tsx
@@ -1,16 +1,14 @@
-import { LoaderFunction, defer } from '@remix-run/node';
+import { LoaderFunctionArgs, defer } from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';
-type LoaderData = { id: string };
-
-export const loader: LoaderFunction = async ({ params: { id } }) => {
+export const loader = async ({ params: { id } }: LoaderFunctionArgs) => {
return defer({
id,
});
};
export default function LoaderJSONResponse() {
- const data = useLoaderData
();
+ const data = useLoaderData();
return (
diff --git a/packages/remix/test/integration/common/routes/loader-json-response.$id.tsx b/packages/remix/test/integration/app/routes/loader-json-response.$id.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/loader-json-response.$id.tsx
rename to packages/remix/test/integration/app/routes/loader-json-response.$id.tsx
diff --git a/packages/remix/test/integration/common/routes/loader-throw-response.$id.tsx b/packages/remix/test/integration/app/routes/loader-throw-response.$id.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/loader-throw-response.$id.tsx
rename to packages/remix/test/integration/app/routes/loader-throw-response.$id.tsx
diff --git a/packages/remix/test/integration/common/routes/manual-tracing.$id.tsx b/packages/remix/test/integration/app/routes/manual-tracing.$id.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/manual-tracing.$id.tsx
rename to packages/remix/test/integration/app/routes/manual-tracing.$id.tsx
diff --git a/packages/remix/test/integration/common/routes/scope-bleed.$id.tsx b/packages/remix/test/integration/app/routes/scope-bleed.$id.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/scope-bleed.$id.tsx
rename to packages/remix/test/integration/app/routes/scope-bleed.$id.tsx
diff --git a/packages/remix/test/integration/common/routes/server-side-unexpected-errors.$id.tsx b/packages/remix/test/integration/app/routes/server-side-unexpected-errors.$id.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/server-side-unexpected-errors.$id.tsx
rename to packages/remix/test/integration/app/routes/server-side-unexpected-errors.$id.tsx
diff --git a/packages/remix/test/integration/common/routes/ssr-error.tsx b/packages/remix/test/integration/app/routes/ssr-error.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/ssr-error.tsx
rename to packages/remix/test/integration/app/routes/ssr-error.tsx
diff --git a/packages/remix/test/integration/common/routes/throw-redirect.tsx b/packages/remix/test/integration/app/routes/throw-redirect.tsx
similarity index 100%
rename from packages/remix/test/integration/common/routes/throw-redirect.tsx
rename to packages/remix/test/integration/app/routes/throw-redirect.tsx
diff --git a/packages/remix/test/integration/app_v1/entry.client.tsx b/packages/remix/test/integration/app_v1/entry.client.tsx
deleted file mode 100644
index bdee1860d03f..000000000000
--- a/packages/remix/test/integration/app_v1/entry.client.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { RemixBrowser, useLocation, useMatches } from '@remix-run/react';
-import * as Sentry from '@sentry/remix';
-import { useEffect } from 'react';
-import { hydrate } from 'react-dom';
-
-Sentry.init({
- dsn: 'https://public@dsn.ingest.sentry.io/1337',
- tracesSampleRate: 1,
- integrations: [
- Sentry.browserTracingIntegration({
- useEffect,
- useLocation,
- useMatches,
- }),
- ],
-});
-
-hydrate(
, document);
diff --git a/packages/remix/test/integration/app_v1/entry.server.tsx b/packages/remix/test/integration/app_v1/entry.server.tsx
deleted file mode 100644
index 9ecf5f467588..000000000000
--- a/packages/remix/test/integration/app_v1/entry.server.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-if (process.env.USE_OTEL !== '1') {
- require('../instrument.server.cjs');
-}
-
-import type { EntryContext } from '@remix-run/node';
-import { RemixServer } from '@remix-run/react';
-import { renderToString } from 'react-dom/server';
-
-export default function handleRequest(
- request: Request,
- responseStatusCode: number,
- responseHeaders: Headers,
- remixContext: EntryContext,
-) {
- let markup = renderToString(
);
-
- responseHeaders.set('Content-Type', 'text/html');
-
- return new Response('' + markup, {
- status: responseStatusCode,
- headers: responseHeaders,
- });
-}
diff --git a/packages/remix/test/integration/app_v1/root.tsx b/packages/remix/test/integration/app_v1/root.tsx
deleted file mode 100644
index 51dcb00c4e8f..000000000000
--- a/packages/remix/test/integration/app_v1/root.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import { LoaderFunction, MetaFunction, defer, json, redirect } from '@remix-run/node';
-import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react';
-import { withSentry } from '@sentry/remix';
-
-export const meta: MetaFunction = ({ data }) => ({
- charset: 'utf-8',
- title: 'New Remix App',
- viewport: 'width=device-width,initial-scale=1',
- 'sentry-trace': data.sentryTrace,
- baggage: data.sentryBaggage,
-});
-
-export const loader: LoaderFunction = async ({ request }) => {
- const url = new URL(request.url);
- const type = url.searchParams.get('type');
-
- switch (type) {
- case 'empty':
- return {};
- case 'plain':
- return {
- data_one: [],
- data_two: 'a string',
- };
- case 'json':
- return json({ data_one: [], data_two: 'a string' }, { headers: { 'Cache-Control': 'max-age=300' } });
- case 'defer':
- return defer({ data_one: [], data_two: 'a string' });
- case 'null':
- return null;
- case 'undefined':
- return undefined;
- case 'throwRedirect':
- throw redirect('/?type=plain');
- case 'returnRedirect':
- return redirect('/?type=plain');
- case 'throwRedirectToExternal':
- throw redirect('https://example.com');
- case 'returnRedirectToExternal':
- return redirect('https://example.com');
- default: {
- return {};
- }
- }
-};
-
-function App() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-export default withSentry(App);
diff --git a/packages/remix/test/integration/app_v1/routes/action-json-response/$id.tsx b/packages/remix/test/integration/app_v1/routes/action-json-response/$id.tsx
deleted file mode 100644
index ed034a14c52a..000000000000
--- a/packages/remix/test/integration/app_v1/routes/action-json-response/$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../../common/routes/action-json-response.$id';
-export { default } from '../../../common/routes/action-json-response.$id';
diff --git a/packages/remix/test/integration/app_v1/routes/capture-exception.tsx b/packages/remix/test/integration/app_v1/routes/capture-exception.tsx
deleted file mode 100644
index 1ba745d2e63d..000000000000
--- a/packages/remix/test/integration/app_v1/routes/capture-exception.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/capture-exception';
-export { default } from '../../common/routes/capture-exception';
diff --git a/packages/remix/test/integration/app_v1/routes/capture-message.tsx b/packages/remix/test/integration/app_v1/routes/capture-message.tsx
deleted file mode 100644
index 9dae2318cc14..000000000000
--- a/packages/remix/test/integration/app_v1/routes/capture-message.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/capture-message';
-export { default } from '../../common/routes/capture-message';
diff --git a/packages/remix/test/integration/app_v1/routes/error-boundary-capture/$id.tsx b/packages/remix/test/integration/app_v1/routes/error-boundary-capture/$id.tsx
deleted file mode 100644
index 2c287dfe9696..000000000000
--- a/packages/remix/test/integration/app_v1/routes/error-boundary-capture/$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../../common/routes/error-boundary-capture.$id';
-export { default } from '../../../common/routes/error-boundary-capture.$id';
diff --git a/packages/remix/test/integration/app_v1/routes/index.tsx b/packages/remix/test/integration/app_v1/routes/index.tsx
deleted file mode 100644
index 22c086a4c2cf..000000000000
--- a/packages/remix/test/integration/app_v1/routes/index.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/index';
-export { default } from '../../common/routes/index';
diff --git a/packages/remix/test/integration/app_v1/routes/loader-defer-response/$id.tsx b/packages/remix/test/integration/app_v1/routes/loader-defer-response/$id.tsx
deleted file mode 100644
index f0c19208a85f..000000000000
--- a/packages/remix/test/integration/app_v1/routes/loader-defer-response/$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../../common/routes/loader-defer-response.$id';
-export { default } from '../../../common/routes/loader-defer-response.$id';
diff --git a/packages/remix/test/integration/app_v1/routes/loader-json-response/$id.tsx b/packages/remix/test/integration/app_v1/routes/loader-json-response/$id.tsx
deleted file mode 100644
index ddf33953d77d..000000000000
--- a/packages/remix/test/integration/app_v1/routes/loader-json-response/$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../../common/routes/loader-json-response.$id';
-export { default } from '../../../common/routes/loader-json-response.$id';
diff --git a/packages/remix/test/integration/app_v1/routes/loader-throw-response/$id.tsx b/packages/remix/test/integration/app_v1/routes/loader-throw-response/$id.tsx
deleted file mode 100644
index 0b9850f50287..000000000000
--- a/packages/remix/test/integration/app_v1/routes/loader-throw-response/$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../../common/routes/loader-throw-response.$id';
-export { default } from '../../../common/routes/loader-throw-response.$id';
diff --git a/packages/remix/test/integration/app_v1/routes/manual-tracing/$id.tsx b/packages/remix/test/integration/app_v1/routes/manual-tracing/$id.tsx
deleted file mode 100644
index 9979714818ff..000000000000
--- a/packages/remix/test/integration/app_v1/routes/manual-tracing/$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../../common/routes/manual-tracing.$id';
-export { default } from '../../../common/routes/manual-tracing.$id';
diff --git a/packages/remix/test/integration/app_v1/routes/scope-bleed/$id.tsx b/packages/remix/test/integration/app_v1/routes/scope-bleed/$id.tsx
deleted file mode 100644
index d86864dccb9b..000000000000
--- a/packages/remix/test/integration/app_v1/routes/scope-bleed/$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../../common/routes/scope-bleed.$id';
-export { default } from '../../../common/routes/scope-bleed.$id';
diff --git a/packages/remix/test/integration/app_v1/routes/server-side-unexpected-errors/$id.tsx b/packages/remix/test/integration/app_v1/routes/server-side-unexpected-errors/$id.tsx
deleted file mode 100644
index fc595b18c3b3..000000000000
--- a/packages/remix/test/integration/app_v1/routes/server-side-unexpected-errors/$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../../common/routes/server-side-unexpected-errors.$id';
-export { default } from '../../../common/routes/server-side-unexpected-errors.$id';
diff --git a/packages/remix/test/integration/app_v1/routes/ssr-error.tsx b/packages/remix/test/integration/app_v1/routes/ssr-error.tsx
deleted file mode 100644
index 627f7e126871..000000000000
--- a/packages/remix/test/integration/app_v1/routes/ssr-error.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/ssr-error';
-export { default } from '../../common/routes/ssr-error';
diff --git a/packages/remix/test/integration/app_v1/routes/throw-redirect.tsx b/packages/remix/test/integration/app_v1/routes/throw-redirect.tsx
deleted file mode 100644
index 4425f3432b58..000000000000
--- a/packages/remix/test/integration/app_v1/routes/throw-redirect.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/throw-redirect';
-export { default } from '../../common/routes/throw-redirect';
diff --git a/packages/remix/test/integration/app_v2/routes/action-json-response.$id.tsx b/packages/remix/test/integration/app_v2/routes/action-json-response.$id.tsx
deleted file mode 100644
index 7a00bfb2bfe7..000000000000
--- a/packages/remix/test/integration/app_v2/routes/action-json-response.$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/action-json-response.$id';
-export { default } from '../../common/routes/action-json-response.$id';
diff --git a/packages/remix/test/integration/app_v2/routes/capture-exception.tsx b/packages/remix/test/integration/app_v2/routes/capture-exception.tsx
deleted file mode 100644
index 1ba745d2e63d..000000000000
--- a/packages/remix/test/integration/app_v2/routes/capture-exception.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/capture-exception';
-export { default } from '../../common/routes/capture-exception';
diff --git a/packages/remix/test/integration/app_v2/routes/capture-message.tsx b/packages/remix/test/integration/app_v2/routes/capture-message.tsx
deleted file mode 100644
index 9dae2318cc14..000000000000
--- a/packages/remix/test/integration/app_v2/routes/capture-message.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/capture-message';
-export { default } from '../../common/routes/capture-message';
diff --git a/packages/remix/test/integration/app_v2/routes/error-boundary-capture.$id.tsx b/packages/remix/test/integration/app_v2/routes/error-boundary-capture.$id.tsx
deleted file mode 100644
index 011f92462069..000000000000
--- a/packages/remix/test/integration/app_v2/routes/error-boundary-capture.$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/error-boundary-capture.$id';
-export { default } from '../../common/routes/error-boundary-capture.$id';
diff --git a/packages/remix/test/integration/app_v2/routes/index.tsx b/packages/remix/test/integration/app_v2/routes/index.tsx
deleted file mode 100644
index 22c086a4c2cf..000000000000
--- a/packages/remix/test/integration/app_v2/routes/index.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/index';
-export { default } from '../../common/routes/index';
diff --git a/packages/remix/test/integration/app_v2/routes/loader-defer-response.$id.tsx b/packages/remix/test/integration/app_v2/routes/loader-defer-response.$id.tsx
deleted file mode 100644
index 69499e594ccc..000000000000
--- a/packages/remix/test/integration/app_v2/routes/loader-defer-response.$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/loader-defer-response.$id';
-export { default } from '../../common/routes/loader-defer-response.$id';
diff --git a/packages/remix/test/integration/app_v2/routes/loader-json-response.$id.tsx b/packages/remix/test/integration/app_v2/routes/loader-json-response.$id.tsx
deleted file mode 100644
index 7761875bdb76..000000000000
--- a/packages/remix/test/integration/app_v2/routes/loader-json-response.$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/loader-json-response.$id';
-export { default } from '../../common/routes/loader-json-response.$id';
diff --git a/packages/remix/test/integration/app_v2/routes/loader-throw-response.$id.tsx b/packages/remix/test/integration/app_v2/routes/loader-throw-response.$id.tsx
deleted file mode 100644
index 6b9a6a85cbef..000000000000
--- a/packages/remix/test/integration/app_v2/routes/loader-throw-response.$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/loader-throw-response.$id';
-export { default } from '../../common/routes/loader-throw-response.$id';
diff --git a/packages/remix/test/integration/app_v2/routes/manual-tracing.$id.tsx b/packages/remix/test/integration/app_v2/routes/manual-tracing.$id.tsx
deleted file mode 100644
index a7cfebe4ed46..000000000000
--- a/packages/remix/test/integration/app_v2/routes/manual-tracing.$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/manual-tracing.$id';
-export { default } from '../../common/routes/manual-tracing.$id';
diff --git a/packages/remix/test/integration/app_v2/routes/scope-bleed.$id.tsx b/packages/remix/test/integration/app_v2/routes/scope-bleed.$id.tsx
deleted file mode 100644
index 5ba2376f0339..000000000000
--- a/packages/remix/test/integration/app_v2/routes/scope-bleed.$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/scope-bleed.$id';
-export { default } from '../../common/routes/scope-bleed.$id';
diff --git a/packages/remix/test/integration/app_v2/routes/server-side-unexpected-errors.$id.tsx b/packages/remix/test/integration/app_v2/routes/server-side-unexpected-errors.$id.tsx
deleted file mode 100644
index d9571c68ddd5..000000000000
--- a/packages/remix/test/integration/app_v2/routes/server-side-unexpected-errors.$id.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/server-side-unexpected-errors.$id';
-export { default } from '../../common/routes/server-side-unexpected-errors.$id';
diff --git a/packages/remix/test/integration/app_v2/routes/ssr-error.tsx b/packages/remix/test/integration/app_v2/routes/ssr-error.tsx
deleted file mode 100644
index 627f7e126871..000000000000
--- a/packages/remix/test/integration/app_v2/routes/ssr-error.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/ssr-error';
-export { default } from '../../common/routes/ssr-error';
diff --git a/packages/remix/test/integration/app_v2/routes/throw-redirect.tsx b/packages/remix/test/integration/app_v2/routes/throw-redirect.tsx
deleted file mode 100644
index 4425f3432b58..000000000000
--- a/packages/remix/test/integration/app_v2/routes/throw-redirect.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from '../../common/routes/throw-redirect';
-export { default } from '../../common/routes/throw-redirect';
diff --git a/packages/remix/test/integration/instrument.server.cjs b/packages/remix/test/integration/instrument.server.mjs
similarity index 59%
rename from packages/remix/test/integration/instrument.server.cjs
rename to packages/remix/test/integration/instrument.server.mjs
index d33b155f2d50..3efde8ef19c4 100644
--- a/packages/remix/test/integration/instrument.server.cjs
+++ b/packages/remix/test/integration/instrument.server.mjs
@@ -1,8 +1,8 @@
-const Sentry = require('@sentry/remix');
+import * as Sentry from '@sentry/remix';
Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
tracesSampleRate: 1,
tracePropagationTargets: ['example.org'],
- autoInstrumentRemix: process.env.USE_OTEL === '1',
+ autoInstrumentRemix: true,
});
diff --git a/packages/remix/test/integration/package.json b/packages/remix/test/integration/package.json
index 13d66600bedd..518cee89ec18 100644
--- a/packages/remix/test/integration/package.json
+++ b/packages/remix/test/integration/package.json
@@ -1,24 +1,26 @@
{
"private": true,
"sideEffects": false,
+ "type": "module",
"scripts": {
"build": "remix build",
"dev": "remix dev",
- "start": "remix-serve build"
+ "start": "remix-serve build/index.js",
+ "start:otel": "NODE_OPTIONS='--import=./instrument.server.mjs' remix-serve build/index.js"
},
"dependencies": {
- "@remix-run/express": "1.17.0",
- "@remix-run/node": "1.17.0",
- "@remix-run/react": "1.17.0",
- "@remix-run/serve": "1.17.0",
+ "@remix-run/express": "2.15.2",
+ "@remix-run/node": "2.15.2",
+ "@remix-run/react": "2.15.2",
+ "@remix-run/serve": "2.15.2",
"@sentry/remix": "file:../..",
- "react": "^17.0.2",
- "react-dom": "^17.0.2"
+ "react": "^18",
+ "react-dom": "^18"
},
"devDependencies": {
- "@remix-run/dev": "1.17.0",
- "@types/react": "^17.0.47",
- "@types/react-dom": "^17.0.17",
+ "@remix-run/dev": "2.15.2",
+ "@types/react": "^18",
+ "@types/react-dom": "^18",
"nock": "^13.5.5",
"typescript": "~5.0.0"
},
@@ -32,6 +34,7 @@
"@sentry-internal/replay": "file:../../../replay-internal",
"@sentry-internal/replay-canvas": "file:../../../replay-canvas",
"@sentry-internal/feedback": "file:../../../feedback",
+ "@sentry-internal/browser-integration-tests": "file:../../../../dev-packages/browser-integration-tests",
"@vanilla-extract/css": "1.13.0",
"@vanilla-extract/integration": "6.2.4",
"@types/mime": "^3.0.0",
diff --git a/packages/remix/test/integration/remix.config.js b/packages/remix/test/integration/remix.config.js
index b4c7ac0837b8..e74f084ccbfd 100644
--- a/packages/remix/test/integration/remix.config.js
+++ b/packages/remix/test/integration/remix.config.js
@@ -1,16 +1,7 @@
/** @type {import('@remix-run/dev').AppConfig} */
-const useV2 = process.env.REMIX_VERSION === '2';
-
-module.exports = {
- appDirectory: useV2 ? 'app_v2' : 'app_v1',
+export default {
+ appDirectory: 'app',
assetsBuildDirectory: 'public/build',
serverBuildPath: 'build/index.js',
publicPath: '/build/',
- future: {
- v2_errorBoundary: useV2,
- v2_headers: useV2,
- v2_meta: useV2,
- v2_normalizeFormMethod: useV2,
- v2_routeConvention: useV2,
- },
};
diff --git a/packages/remix/test/integration/test/client/click-error.test.ts b/packages/remix/test/integration/test/client/click-error.test.ts
index f9e895b3a8f2..a6385c0e0963 100644
--- a/packages/remix/test/integration/test/client/click-error.test.ts
+++ b/packages/remix/test/integration/test/client/click-error.test.ts
@@ -2,14 +2,7 @@ import { expect, test } from '@playwright/test';
import { Event } from '@sentry/core';
import { getMultipleSentryEnvelopeRequests } from './utils/helpers';
-const useV2 = process.env.REMIX_VERSION === '2';
-
test('should report a manually captured message on click with the correct stacktrace.', async ({ page }) => {
- if (!useV2) {
- test.skip();
- return;
- }
-
await page.goto('/click-error');
const promise = getMultipleSentryEnvelopeRequests
(page, 2);
diff --git a/packages/remix/test/integration/test/client/errorboundary.test.ts b/packages/remix/test/integration/test/client/errorboundary.test.ts
index c679f736ea8e..dc7f0378184f 100644
--- a/packages/remix/test/integration/test/client/errorboundary.test.ts
+++ b/packages/remix/test/integration/test/client/errorboundary.test.ts
@@ -2,8 +2,6 @@ import { expect, test } from '@playwright/test';
import { Event } from '@sentry/core';
import { getMultipleSentryEnvelopeRequests } from './utils/helpers';
-const useV2 = process.env.REMIX_VERSION === '2';
-
test('should capture React component errors.', async ({ page }) => {
const envelopes = await getMultipleSentryEnvelopeRequests(page, 2, {
url: '/error-boundary-capture/0',
@@ -13,38 +11,20 @@ test('should capture React component errors.', async ({ page }) => {
expect(pageloadEnvelope.contexts?.trace?.op).toBe('pageload');
expect(pageloadEnvelope.type).toBe('transaction');
- expect(pageloadEnvelope.transaction).toBe(
- useV2 ? 'routes/error-boundary-capture.$id' : 'routes/error-boundary-capture/$id',
- );
+ expect(pageloadEnvelope.transaction).toBe('routes/error-boundary-capture.$id');
expect(errorEnvelope.level).toBe('error');
expect(errorEnvelope.sdk?.name).toBe('sentry.javascript.remix');
expect(errorEnvelope.exception?.values).toMatchObject([
- ...(!useV2
- ? [
- {
- type: 'React ErrorBoundary Error',
- value: 'Sentry React Component Error',
- stacktrace: { frames: expect.any(Array) },
- mechanism: { type: 'chained', handled: false },
- },
- ]
- : []),
{
type: 'Error',
value: 'Sentry React Component Error',
stacktrace: { frames: expect.any(Array) },
- // In v2 this error will be marked unhandled, in v1 its handled because of LinkedErrors
- // This should be fine though because the error boundary's error is marked unhandled
- mechanism: { type: useV2 ? 'instrument' : 'generic', handled: !useV2 },
+ mechanism: { type: 'instrument', handled: false },
},
]);
- expect(errorEnvelope.transaction).toBe(
- useV2 ? 'routes/error-boundary-capture.$id' : 'routes/error-boundary-capture/$id',
- );
+ expect(errorEnvelope.transaction).toBe('routes/error-boundary-capture.$id');
- if (useV2) {
- // The error boundary should be rendered
- expect(await page.textContent('#error-header')).toBe('ErrorBoundary Error');
- }
+ // The error boundary should be rendered
+ expect(await page.textContent('#error-header')).toBe('ErrorBoundary Error');
});
diff --git a/packages/remix/test/integration/test/client/manualtracing.test.ts b/packages/remix/test/integration/test/client/manualtracing.test.ts
index 01ae4cf66521..ff2bcac3ec1c 100644
--- a/packages/remix/test/integration/test/client/manualtracing.test.ts
+++ b/packages/remix/test/integration/test/client/manualtracing.test.ts
@@ -2,8 +2,6 @@ import { expect, test } from '@playwright/test';
import { Event } from '@sentry/core';
import { getMultipleSentryEnvelopeRequests } from './utils/helpers';
-const useV2 = process.env.REMIX_VERSION === '2';
-
test('should report a manually created / finished transaction.', async ({ page }) => {
const envelopes = await getMultipleSentryEnvelopeRequests(page, 2, {
url: '/manual-tracing/0',
@@ -19,5 +17,5 @@ test('should report a manually created / finished transaction.', async ({ page }
expect(pageloadEnvelope.contexts?.trace?.op).toBe('pageload');
expect(pageloadEnvelope.type).toBe('transaction');
- expect(pageloadEnvelope.transaction).toBe(useV2 ? 'routes/manual-tracing.$id' : 'routes/manual-tracing/$id');
+ expect(pageloadEnvelope.transaction).toBe('routes/manual-tracing.$id');
});
diff --git a/packages/remix/test/integration/test/client/pageload.test.ts b/packages/remix/test/integration/test/client/pageload.test.ts
index bf45a512fabe..55e97e23635f 100644
--- a/packages/remix/test/integration/test/client/pageload.test.ts
+++ b/packages/remix/test/integration/test/client/pageload.test.ts
@@ -1,5 +1,3 @@
-const useV2 = process.env.REMIX_VERSION === '2';
-
import { expect, test } from '@playwright/test';
import { Event } from '@sentry/core';
import { getFirstSentryEnvelopeRequest } from './utils/helpers';
@@ -10,5 +8,5 @@ test('should add `pageload` transaction on load.', async ({ page }) => {
expect(envelope.contexts?.trace.op).toBe('pageload');
expect(envelope.type).toBe('transaction');
- expect(envelope.transaction).toBe(useV2 ? 'root' : 'routes/index');
+ expect(envelope.transaction).toBe('root');
});
diff --git a/packages/remix/test/integration/test/client/utils/helpers.ts b/packages/remix/test/integration/test/client/utils/helpers.ts
index 37cffb1cd898..56e31cc331c8 100644
--- a/packages/remix/test/integration/test/client/utils/helpers.ts
+++ b/packages/remix/test/integration/test/client/utils/helpers.ts
@@ -1 +1,412 @@
-export * from '@sentry-internal/browser-integration-tests/utils/helpers';
+// Inlined copy from dev-packages/browser-integration-tests/utils/helpers
+
+import type { Page, Request } from '@playwright/test';
+import { parseEnvelope } from '@sentry/core';
+import type {
+ Envelope,
+ EnvelopeItem,
+ EnvelopeItemType,
+ Event,
+ EventEnvelope,
+ EventEnvelopeHeaders,
+ SessionContext,
+ TransactionEvent,
+} from '@sentry/core';
+
+export const envelopeUrlRegex = /\.sentry\.io\/api\/\d+\/envelope\//;
+
+export const envelopeParser = (request: Request | null): unknown[] => {
+ // https://develop.sentry.dev/sdk/envelopes/
+ const envelope = request?.postData() || '';
+
+ // Third row of the envelop is the event payload.
+ return envelope.split('\n').map(line => {
+ try {
+ return JSON.parse(line);
+ } catch (error) {
+ return line;
+ }
+ });
+};
+
+export const envelopeRequestParser = (request: Request | null, envelopeIndex = 2): T => {
+ return envelopeParser(request)[envelopeIndex] as T;
+};
+
+/**
+ * The above envelope parser does not follow the envelope spec...
+ * ...but modifying it to follow the spec breaks a lot of the test which rely on the current indexing behavior.
+ *
+ * This parser is a temporary solution to allow us to test metrics with statsd envelopes.
+ *
+ * Eventually, all the tests should be migrated to use this 'proper' envelope parser!
+ */
+export const properEnvelopeParser = (request: Request | null): EnvelopeItem[] => {
+ // https://develop.sentry.dev/sdk/envelopes/
+ const envelope = request?.postData() || '';
+
+ const [, items] = parseEnvelope(envelope);
+
+ return items;
+};
+
+export type EventAndTraceHeader = [Event, EventEnvelopeHeaders['trace']];
+
+/**
+ * Returns the first event item and `trace` envelope header from an envelope.
+ * This is particularly helpful if you want to test dynamic sampling and trace propagation-related cases.
+ */
+export const eventAndTraceHeaderRequestParser = (request: Request | null): EventAndTraceHeader => {
+ const envelope = properFullEnvelopeParser(request);
+ return getEventAndTraceHeader(envelope);
+};
+
+const properFullEnvelopeParser = (request: Request | null): T => {
+ // https://develop.sentry.dev/sdk/envelopes/
+ const envelope = request?.postData() || '';
+
+ return parseEnvelope(envelope) as T;
+};
+
+function getEventAndTraceHeader(envelope: EventEnvelope): EventAndTraceHeader {
+ const event = envelope[1][0]?.[1] as Event | undefined;
+ const trace = envelope[0]?.trace;
+
+ if (!event || !trace) {
+ throw new Error('Could not get event or trace from envelope');
+ }
+
+ return [event, trace];
+}
+
+export const properEnvelopeRequestParser = (request: Request | null, envelopeIndex = 1): T => {
+ return properEnvelopeParser(request)[0]?.[envelopeIndex] as T;
+};
+
+export const properFullEnvelopeRequestParser = (request: Request | null): T => {
+ // https://develop.sentry.dev/sdk/envelopes/
+ const envelope = request?.postData() || '';
+
+ return parseEnvelope(envelope) as T;
+};
+
+export const envelopeHeaderRequestParser = (request: Request | null): EventEnvelopeHeaders => {
+ // https://develop.sentry.dev/sdk/envelopes/
+ const envelope = request?.postData() || '';
+
+ // First row of the envelop is the event payload.
+ return envelope.split('\n').map(line => JSON.parse(line))[0];
+};
+
+export const getEnvelopeType = (request: Request | null): EnvelopeItemType => {
+ const envelope = request?.postData() || '';
+
+ return (envelope.split('\n').map(line => JSON.parse(line))[1] as Record).type as EnvelopeItemType;
+};
+
+export const countEnvelopes = async (
+ page: Page,
+ options?: {
+ url?: string;
+ timeout?: number;
+ envelopeType: EnvelopeItemType | EnvelopeItemType[];
+ },
+): Promise => {
+ const countPromise = new Promise((resolve, reject) => {
+ let reqCount = 0;
+
+ const requestHandler = (request: Request): void => {
+ if (envelopeUrlRegex.test(request.url())) {
+ try {
+ if (options?.envelopeType) {
+ const envelopeTypeArray = options
+ ? typeof options.envelopeType === 'string'
+ ? [options.envelopeType]
+ : options.envelopeType || (['event'] as EnvelopeItemType[])
+ : (['event'] as EnvelopeItemType[]);
+
+ if (envelopeTypeArray.includes(getEnvelopeType(request))) {
+ reqCount++;
+ }
+ }
+ } catch (e) {
+ reject(e);
+ }
+ }
+ };
+
+ page.on('request', requestHandler);
+
+ setTimeout(() => {
+ page.off('request', requestHandler);
+ resolve(reqCount);
+ }, options?.timeout || 1000);
+ });
+
+ if (options?.url) {
+ await page.goto(options.url);
+ }
+
+ return countPromise;
+};
+
+/**
+ * Run script inside the test environment.
+ * This is useful for throwing errors in the test environment.
+ *
+ * Errors thrown from this function are not guaranteed to be captured by Sentry, especially in Webkit.
+ *
+ * @param {Page} page
+ * @param {{ path?: string; content?: string }} impl
+ * @return {*} {Promise}
+ */
+export async function runScriptInSandbox(
+ page: Page,
+ impl: {
+ path?: string;
+ content?: string;
+ },
+): Promise {
+ try {
+ await page.addScriptTag({ path: impl.path, content: impl.content });
+ } catch (e) {
+ // no-op
+ }
+}
+
+/**
+ * Get Sentry events at the given URL, or the current page.
+ *
+ * @param {Page} page
+ * @param {string} [url]
+ * @return {*} {Promise>}
+ */
+export async function getSentryEvents(page: Page, url?: string): Promise> {
+ if (url) {
+ await page.goto(url);
+ }
+ const eventsHandle = await page.evaluateHandle>('window.events');
+
+ return eventsHandle.jsonValue();
+}
+
+export async function waitForErrorRequestOnUrl(page: Page, url: string): Promise {
+ const [req] = await Promise.all([waitForErrorRequest(page), page.goto(url)]);
+ return req;
+}
+
+export async function waitForTransactionRequestOnUrl(page: Page, url: string): Promise {
+ const [req] = await Promise.all([waitForTransactionRequest(page), page.goto(url)]);
+ return req;
+}
+
+export function waitForErrorRequest(page: Page, callback?: (event: Event) => boolean): Promise {
+ return page.waitForRequest(req => {
+ const postData = req.postData();
+ if (!postData) {
+ return false;
+ }
+
+ try {
+ const event = envelopeRequestParser(req);
+
+ if (event.type) {
+ return false;
+ }
+
+ if (callback) {
+ return callback(event);
+ }
+
+ return true;
+ } catch {
+ return false;
+ }
+ });
+}
+
+export function waitForTransactionRequest(
+ page: Page,
+ callback?: (event: TransactionEvent) => boolean,
+): Promise {
+ return page.waitForRequest(req => {
+ const postData = req.postData();
+ if (!postData) {
+ return false;
+ }
+
+ try {
+ const event = envelopeRequestParser(req);
+
+ if (event.type !== 'transaction') {
+ return false;
+ }
+
+ if (callback) {
+ return callback(event as TransactionEvent);
+ }
+
+ return true;
+ } catch {
+ return false;
+ }
+ });
+}
+
+export async function waitForSession(page: Page): Promise {
+ const req = await page.waitForRequest(req => {
+ const postData = req.postData();
+ if (!postData) {
+ return false;
+ }
+
+ try {
+ const event = envelopeRequestParser(req);
+
+ return typeof event.init === 'boolean' && event.started !== undefined;
+ } catch {
+ return false;
+ }
+ });
+
+ return envelopeRequestParser(req);
+}
+
+/**
+ * We can only test tracing tests in certain bundles/packages:
+ * - NPM (ESM, CJS)
+ * - CDN bundles that contain Tracing
+ *
+ * @returns `true` if we should skip the tracing test
+ */
+export function shouldSkipTracingTest(): boolean {
+ const bundle = process.env.PW_BUNDLE as string | undefined;
+ return bundle != null && !bundle.includes('tracing') && !bundle.includes('esm') && !bundle.includes('cjs');
+}
+
+/**
+ * Today we always run feedback tests, but this can be used to guard this if we ever need to.
+ */
+export function shouldSkipFeedbackTest(): boolean {
+ // We always run these, in bundles the pluggable integration is automatically added
+ return false;
+}
+
+/**
+ * We only test feature flags integrations in certain bundles/packages:
+ * - NPM (ESM, CJS)
+ * - Not CDNs.
+ *
+ * @returns `true` if we should skip the feature flags test
+ */
+export function shouldSkipFeatureFlagsTest(): boolean {
+ const bundle = process.env.PW_BUNDLE as string | undefined;
+ return bundle != null && !bundle.includes('esm') && !bundle.includes('cjs');
+}
+
+/**
+ * Waits until a number of requests matching urlRgx at the given URL arrive.
+ * If the timeout option is configured, this function will abort waiting, even if it hasn't received the configured
+ * amount of requests, and returns all the events received up to that point in time.
+ */
+async function getMultipleRequests(
+ page: Page,
+ count: number,
+ urlRgx: RegExp,
+ requestParser: (req: Request) => T,
+ options?: {
+ url?: string;
+ timeout?: number;
+ envelopeType?: EnvelopeItemType | EnvelopeItemType[];
+ },
+): Promise {
+ const requests: Promise = new Promise((resolve, reject) => {
+ let reqCount = count;
+ const requestData: T[] = [];
+ let timeoutId: NodeJS.Timeout | undefined = undefined;
+
+ function requestHandler(request: Request): void {
+ if (urlRgx.test(request.url())) {
+ try {
+ if (options?.envelopeType) {
+ const envelopeTypeArray = options
+ ? typeof options.envelopeType === 'string'
+ ? [options.envelopeType]
+ : options.envelopeType || (['event'] as EnvelopeItemType[])
+ : (['event'] as EnvelopeItemType[]);
+
+ if (!envelopeTypeArray.includes(getEnvelopeType(request))) {
+ return;
+ }
+ }
+
+ reqCount--;
+ requestData.push(requestParser(request));
+
+ if (reqCount === 0) {
+ if (timeoutId) {
+ clearTimeout(timeoutId);
+ }
+ page.off('request', requestHandler);
+ resolve(requestData);
+ }
+ } catch (err) {
+ reject(err);
+ }
+ }
+ }
+
+ page.on('request', requestHandler);
+
+ if (options?.timeout) {
+ timeoutId = setTimeout(() => {
+ resolve(requestData);
+ }, options.timeout);
+ }
+ });
+
+ if (options?.url) {
+ await page.goto(options.url);
+ }
+
+ return requests;
+}
+
+/**
+ * Wait and get multiple envelope requests at the given URL, or the current page
+ */
+export async function getMultipleSentryEnvelopeRequests(
+ page: Page,
+ count: number,
+ options?: {
+ url?: string;
+ timeout?: number;
+ envelopeType?: EnvelopeItemType | EnvelopeItemType[];
+ },
+ requestParser: (req: Request) => T = envelopeRequestParser as (req: Request) => T,
+): Promise {
+ return getMultipleRequests(page, count, envelopeUrlRegex, requestParser, options) as Promise;
+}
+
+/**
+ * Wait and get the first envelope request at the given URL, or the current page
+ *
+ * @template T
+ * @param {Page} page
+ * @param {string} [url]
+ * @return {*} {Promise}
+ */
+export async function getFirstSentryEnvelopeRequest(
+ page: Page,
+ url?: string,
+ requestParser: (req: Request) => T = envelopeRequestParser as (req: Request) => T,
+): Promise {
+ const reqs = await getMultipleSentryEnvelopeRequests(page, 1, { url }, requestParser);
+
+ const req = reqs[0];
+ if (!req) {
+ throw new Error('No request found');
+ }
+
+ return req;
+}
diff --git a/packages/remix/test/integration/test/server/instrumentation-legacy/action.test.ts b/packages/remix/test/integration/test/server/instrumentation-legacy/action.test.ts
index d9e91088cb8b..c502b801ed81 100644
--- a/packages/remix/test/integration/test/server/instrumentation-legacy/action.test.ts
+++ b/packages/remix/test/integration/test/server/instrumentation-legacy/action.test.ts
@@ -1,8 +1,6 @@
import { describe, it } from 'vitest';
import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers';
-const useV2 = process.env.REMIX_VERSION === '2';
-
describe('Remix API Actions', () => {
it('correctly instruments a parameterized Remix API action', async () => {
const env = await RemixTestEnv.init();
@@ -15,10 +13,10 @@ describe('Remix API Actions', () => {
const transaction = envelope[2]!;
assertSentryTransaction(transaction, {
- transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: `routes/action-json-response.$id`,
spans: [
{
- description: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ description: `routes/action-json-response.$id`,
op: 'function.remix.action',
},
{
@@ -26,11 +24,11 @@ describe('Remix API Actions', () => {
op: 'function.remix.loader',
},
{
- description: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ description: `routes/action-json-response.$id`,
op: 'function.remix.loader',
},
{
- description: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ description: `routes/action-json-response.$id`,
op: 'function.remix.document_request',
},
],
@@ -81,7 +79,7 @@ describe('Remix API Actions', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'action',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
@@ -107,7 +105,7 @@ describe('Remix API Actions', () => {
const [event] = envelopes.filter(envelope => envelope[1]?.type === 'event');
assertSentryTransaction(transaction![2]!, {
- transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: `routes/action-json-response.$id`,
request: {
method: 'POST',
url,
@@ -165,7 +163,7 @@ describe('Remix API Actions', () => {
},
},
},
- transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/action-json-response.$id',
});
assertSentryTransaction(transaction_2![2]!, {
@@ -179,7 +177,7 @@ describe('Remix API Actions', () => {
},
},
},
- transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/action-json-response.$id',
});
assertSentryEvent(event![2]!, {
@@ -192,7 +190,7 @@ describe('Remix API Actions', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'loader',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
@@ -228,7 +226,7 @@ describe('Remix API Actions', () => {
},
},
},
- transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/action-json-response.$id',
});
assertSentryEvent(event![2]!, {
@@ -277,7 +275,7 @@ describe('Remix API Actions', () => {
},
},
},
- transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/action-json-response.$id',
});
assertSentryEvent(event![2]!, {
@@ -326,7 +324,7 @@ describe('Remix API Actions', () => {
},
},
},
- transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/action-json-response.$id',
});
assertSentryEvent(event![2]!, {
@@ -375,7 +373,7 @@ describe('Remix API Actions', () => {
},
},
},
- transaction: `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/action-json-response.$id',
});
assertSentryEvent(event![2]!, {
@@ -424,7 +422,7 @@ describe('Remix API Actions', () => {
},
},
},
- transaction: `routes/server-side-unexpected-errors${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/server-side-unexpected-errors.$id',
});
assertSentryEvent(event![2]!, {
@@ -437,7 +435,7 @@ describe('Remix API Actions', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'action',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
@@ -473,7 +471,7 @@ describe('Remix API Actions', () => {
},
},
},
- transaction: `routes/server-side-unexpected-errors${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/server-side-unexpected-errors.$id',
});
assertSentryEvent(event![2]!, {
@@ -486,7 +484,7 @@ describe('Remix API Actions', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'action',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
diff --git a/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts b/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts
index bf69b5e7e35b..79fb7bb270d3 100644
--- a/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts
+++ b/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts
@@ -2,8 +2,6 @@ import { Event } from '@sentry/core';
import { describe, expect, it } from 'vitest';
import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers';
-const useV2 = process.env.REMIX_VERSION === '2';
-
describe('Remix API Loaders', () => {
it('reports an error thrown from the loader', async () => {
const env = await RemixTestEnv.init();
@@ -35,7 +33,7 @@ describe('Remix API Loaders', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'loader',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
@@ -96,7 +94,7 @@ describe('Remix API Loaders', () => {
const transaction = envelope[2]!;
assertSentryTransaction(transaction, {
- transaction: `routes/loader-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/loader-json-response.$id',
transaction_info: {
source: 'route',
},
@@ -106,11 +104,11 @@ describe('Remix API Loaders', () => {
op: 'function.remix.loader',
},
{
- description: `routes/loader-json-response${useV2 ? '.' : '/'}$id`,
+ description: 'routes/loader-json-response.$id',
op: 'function.remix.loader',
},
{
- description: `routes/loader-json-response${useV2 ? '.' : '/'}$id`,
+ description: 'routes/loader-json-response.$id',
op: 'function.remix.document_request',
},
],
@@ -141,7 +139,7 @@ describe('Remix API Loaders', () => {
},
},
},
- transaction: `routes/loader-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/loader-json-response.$id',
});
assertSentryTransaction(transaction_2![2]!, {
@@ -155,7 +153,7 @@ describe('Remix API Loaders', () => {
},
},
},
- transaction: `routes/loader-json-response${useV2 ? '.' : '/'}$id`,
+ transaction: 'routes/loader-json-response.$id',
});
assertSentryEvent(event![2]!, {
@@ -168,7 +166,7 @@ describe('Remix API Loaders', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'loader',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
@@ -236,39 +234,24 @@ describe('Remix API Loaders', () => {
const transaction = envelope[2]!;
assertSentryTransaction(transaction, {
- transaction: useV2 ? 'routes/loader-defer-response.$id' : 'routes/loader-defer-response/$id',
+ transaction: 'routes/loader-defer-response.$id',
transaction_info: {
source: 'route',
},
- spans: useV2
- ? [
- {
- description: 'root',
- op: 'function.remix.loader',
- },
- {
- description: 'routes/loader-defer-response.$id',
- op: 'function.remix.loader',
- },
- {
- description: 'routes/loader-defer-response.$id',
- op: 'function.remix.document_request',
- },
- ]
- : [
- {
- description: 'root',
- op: 'function.remix.loader',
- },
- {
- description: 'routes/loader-defer-response/$id',
- op: 'function.remix.loader',
- },
- {
- description: 'routes/loader-defer-response/$id',
- op: 'function.remix.document_request',
- },
- ],
+ spans: [
+ {
+ description: 'root',
+ op: 'function.remix.loader',
+ },
+ {
+ description: 'routes/loader-defer-response.$id',
+ op: 'function.remix.loader',
+ },
+ {
+ description: 'routes/loader-defer-response.$id',
+ op: 'function.remix.document_request',
+ },
+ ],
});
});
diff --git a/packages/remix/test/integration/test/server/instrumentation-legacy/ssr.test.ts b/packages/remix/test/integration/test/server/instrumentation-legacy/ssr.test.ts
index 9fafe0a70056..c4ea2503e67f 100644
--- a/packages/remix/test/integration/test/server/instrumentation-legacy/ssr.test.ts
+++ b/packages/remix/test/integration/test/server/instrumentation-legacy/ssr.test.ts
@@ -1,8 +1,6 @@
import { describe, expect, it } from 'vitest';
import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers';
-const useV2 = process.env.REMIX_VERSION === '2';
-
describe('Server Side Rendering', () => {
it('correctly reports a server side rendering error', async () => {
const env = await RemixTestEnv.init();
@@ -19,12 +17,10 @@ describe('Server Side Rendering', () => {
},
},
},
- ...(useV2 && {
- tags: {
- // Testing that the wrapped `handleError` correctly adds tags
- 'remix-test-tag': 'remix-test-value',
- },
- }),
+ tags: {
+ // Testing that the wrapped `handleError` correctly adds tags
+ 'remix-test-tag': 'remix-test-value',
+ },
});
assertSentryEvent(event![2]!, {
@@ -37,7 +33,7 @@ describe('Server Side Rendering', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'documentRequest',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
diff --git a/packages/remix/test/integration/test/server/instrumentation-otel/action.test.ts b/packages/remix/test/integration/test/server/instrumentation-otel/action.test.ts
index f883c4bfeee5..e0a07ac82eae 100644
--- a/packages/remix/test/integration/test/server/instrumentation-otel/action.test.ts
+++ b/packages/remix/test/integration/test/server/instrumentation-otel/action.test.ts
@@ -1,8 +1,6 @@
import { describe, it } from 'vitest';
import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers';
-const useV2 = process.env.REMIX_VERSION === '2';
-
describe('Remix API Actions', () => {
it('correctly instruments a parameterized Remix API action', async () => {
const env = await RemixTestEnv.init();
@@ -22,7 +20,7 @@ describe('Remix API Actions', () => {
data: {
'code.function': 'action',
'sentry.op': 'action.remix',
- 'match.route.id': `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ 'match.route.id': 'routes/action-json-response.$id',
'match.params.id': '123123',
},
},
@@ -30,7 +28,7 @@ describe('Remix API Actions', () => {
data: {
'code.function': 'loader',
'sentry.op': 'loader.remix',
- 'match.route.id': `routes/action-json-response${useV2 ? '.' : '/'}$id`,
+ 'match.route.id': 'routes/action-json-response.$id',
'match.params.id': '123123',
},
},
@@ -89,7 +87,7 @@ describe('Remix API Actions', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'action',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
@@ -197,7 +195,7 @@ describe('Remix API Actions', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'loader',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
@@ -432,7 +430,7 @@ describe('Remix API Actions', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'action',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
@@ -479,7 +477,7 @@ describe('Remix API Actions', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'action',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
diff --git a/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts b/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts
index 93235b33d54d..baec26b3eb67 100644
--- a/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts
+++ b/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts
@@ -2,8 +2,6 @@ import { Event } from '@sentry/core';
import { describe, expect, it } from 'vitest';
import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers';
-const useV2 = process.env.REMIX_VERSION === '2';
-
describe('Remix API Loaders', () => {
it('reports an error thrown from the loader', async () => {
const env = await RemixTestEnv.init();
@@ -34,7 +32,7 @@ describe('Remix API Loaders', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'loader',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
@@ -167,7 +165,7 @@ describe('Remix API Loaders', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'loader',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
@@ -244,7 +242,7 @@ describe('Remix API Loaders', () => {
data: {
'code.function': 'loader',
'sentry.op': 'loader.remix',
- 'match.route.id': `routes/loader-defer-response${useV2 ? '.' : '/'}$id`,
+ 'match.route.id': 'routes/loader-defer-response.$id',
},
},
{
diff --git a/packages/remix/test/integration/test/server/instrumentation-otel/ssr.test.ts b/packages/remix/test/integration/test/server/instrumentation-otel/ssr.test.ts
index f3a5d7e4124f..1b2a97a99b55 100644
--- a/packages/remix/test/integration/test/server/instrumentation-otel/ssr.test.ts
+++ b/packages/remix/test/integration/test/server/instrumentation-otel/ssr.test.ts
@@ -1,8 +1,6 @@
import { describe, expect, it } from 'vitest';
import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers';
-const useV2 = process.env.REMIX_VERSION === '2';
-
describe('Server Side Rendering', () => {
it('correctly reports a server side rendering error', async () => {
const env = await RemixTestEnv.init();
@@ -20,12 +18,10 @@ describe('Server Side Rendering', () => {
},
},
},
- ...(useV2 && {
- tags: {
- // Testing that the wrapped `handleError` correctly adds tags
- 'remix-test-tag': 'remix-test-value',
- },
- }),
+ tags: {
+ // Testing that the wrapped `handleError` correctly adds tags
+ 'remix-test-tag': 'remix-test-value',
+ },
});
assertSentryEvent(event[2], {
@@ -37,7 +33,7 @@ describe('Server Side Rendering', () => {
stacktrace: expect.any(Object),
mechanism: {
data: {
- function: useV2 ? 'remix.server.handleError' : 'documentRequest',
+ function: 'remix.server.handleError',
},
handled: false,
type: 'instrument',
diff --git a/packages/remix/test/integration/test/server/utils/helpers.ts b/packages/remix/test/integration/test/server/utils/helpers.ts
index deec33e06b1e..f273aaffc73a 100644
--- a/packages/remix/test/integration/test/server/utils/helpers.ts
+++ b/packages/remix/test/integration/test/server/utils/helpers.ts
@@ -74,13 +74,13 @@ class TestEnv {
public static async init(testDir: string, serverPath?: string, scenarioPath?: string): Promise {
const defaultServerPath = path.resolve(process.cwd(), 'utils', 'defaults', 'server');
- const [server, url] = await new Promise<[http.Server, string]>(resolve => {
+ const [server, url] = await new Promise<[http.Server, string]>(async resolve => {
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
- const app = require(serverPath || defaultServerPath).default as Express;
+ const { default: app } = (await import(serverPath || defaultServerPath)) as { default: Express };
- app.get('/test', (_req, res) => {
+ app.get('/test', async (_req, res) => {
try {
- require(scenarioPath || `${testDir}/scenario`);
+ await import(scenarioPath || `${testDir}/scenario`);
} finally {
res.status(200).end();
}
@@ -267,10 +267,10 @@ export class RemixTestEnv extends TestEnv {
public static async init(): Promise {
let serverPort;
- const server = await new Promise(resolve => {
+ const server = await new Promise(async resolve => {
const app = express();
- app.all('*', createRequestHandler({ build: require('../../../build') }));
+ app.all('*', createRequestHandler({ build: await import('../../../build') }));
const server = app.listen(0, () => {
serverPort = (server.address() as AddressInfo).port;
diff --git a/packages/remix/test/integration/tsconfig.json b/packages/remix/test/integration/tsconfig.json
index f190b5da307f..1ab42867a9dc 100644
--- a/packages/remix/test/integration/tsconfig.json
+++ b/packages/remix/test/integration/tsconfig.json
@@ -13,7 +13,7 @@
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
- "~/*": ["app_v1/*", "app_v2/*"]
+ "~/*": ["app_v2/*"]
},
"noEmit": true
}
diff --git a/packages/remix/vitest.config.ts b/packages/remix/vitest.config.ts
index 23c2383b9e8b..774227165ee3 100644
--- a/packages/remix/vitest.config.ts
+++ b/packages/remix/vitest.config.ts
@@ -7,7 +7,7 @@ export default defineConfig({
globals: true,
disableConsoleIntercept: true,
silent: false,
- setupFiles: useOtel ? './test/integration/instrument.server.cjs' : undefined,
+ setupFiles: useOtel ? './test/integration/instrument.server.mjs' : undefined,
include: useOtel ? ['**/instrumentation-otel/*.test.ts'] : ['**/instrumentation-legacy/*.test.ts'],
},
});
diff --git a/yarn.lock b/yarn.lock
index 5184b4a37e2a..0cfe279f3561 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2711,7 +2711,7 @@
dependencies:
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
+"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.24.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12"
integrity sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==
@@ -6604,28 +6604,29 @@
resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.0.5.tgz#a6d70ef7a0e71e083ea09b967df0a0ed742bc6ad"
integrity sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==
-"@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==
+"@remix-run/node@^2.15.2":
+ version "2.15.2"
+ resolved "https://registry.yarnpkg.com/@remix-run/node/-/node-2.15.2.tgz#7ea460335b66a06d22e554a84edf09e2b8879a8a"
+ integrity sha512-NS/h5uxje7DYCNgcKqKAiUhf0r2HVnoYUBWLyIIMmCUP1ddWurBP6xTPcWzGhEvV/EvguniYi1wJZ5+X8sonWw==
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/server-runtime" "2.15.2"
+ "@remix-run/web-fetch" "^4.4.2"
"@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"
+ undici "^6.11.1"
-"@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@^2.15.2":
+ version "2.15.2"
+ resolved "https://registry.yarnpkg.com/@remix-run/react/-/react-2.15.2.tgz#4f57434c120e0b7885d8b737c417b67f72a3a042"
+ integrity sha512-NAAMsSgoC/sdOgovUewwRCE/RUm3F+MBxxZKfwu3POCNeHaplY5qGkH/y8PUXvdN1EBG7Z0Ko43dyzCfcEy5PA==
dependencies:
- history "^5.3.0"
- react-router-dom "^6.2.2"
+ "@remix-run/router" "1.21.0"
+ "@remix-run/server-runtime" "2.15.2"
+ react-router "6.28.1"
+ react-router-dom "6.28.1"
+ turbo-stream "2.4.0"
"@remix-run/router@1.21.0":
version "1.21.0"
@@ -6637,57 +6638,59 @@
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.15.0.tgz#461a952c2872dd82c8b2e9b74c4dfaff569123e2"
integrity sha512-HOil5aFtme37dVQTB6M34G95kPM3MMuqSmIRVCC52eKV+Y/tGSqw9P3rWhlAx6A+mz+MoX+XxsGsNJbaI5qCgQ==
-"@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/server-runtime@2.15.2":
+ version "2.15.2"
+ resolved "https://registry.yarnpkg.com/@remix-run/server-runtime/-/server-runtime-2.15.2.tgz#5be945027612c0891748d1788d39fea1ef0ba33c"
+ integrity sha512-OqiPcvEnnU88B8b1LIWHHkQ3Tz2GDAmQ1RihFNQsbrFKpDsQLkw0lJlnfgKA/uHd0CEEacpfV7C9qqJT3V6Z2g==
dependencies:
- "@types/cookie" "^0.4.0"
+ "@remix-run/router" "1.21.0"
+ "@types/cookie" "^0.6.0"
"@web3-storage/multipart-parser" "^1.0.0"
- cookie "^0.4.1"
- jsesc "^3.0.1"
- react-router-dom "^6.2.2"
+ cookie "^0.6.0"
set-cookie-parser "^2.4.8"
source-map "^0.7.3"
+ turbo-stream "2.4.0"
-"@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.4.2":
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/@remix-run/web-fetch/-/web-fetch-4.4.2.tgz#ce7aedef72cc26e15060e8cf84674029f92809b6"
+ integrity sha512-jgKfzA713/4kAW/oZ4bC3MoLWyjModOVDjFPNseVqcJKSafgIscrYL9G50SurEYLswPuoU3HzSbO0jQCMYWHhA==
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.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.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"
@@ -8038,7 +8041,7 @@
dependencies:
"@types/node" "*"
-"@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==
@@ -13368,11 +13371,6 @@ cookie@0.7.1:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9"
integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==
-cookie@^0.4.1:
- version "0.4.2"
- resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
- integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
-
cookie@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
@@ -18760,13 +18758,6 @@ 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:
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b"
- integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==
- dependencies:
- "@babel/runtime" "^7.7.6"
-
hoist-non-react-statics@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
@@ -20840,7 +20831,7 @@ jsesc@^2.5.1:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
-jsesc@^3.0.1, jsesc@^3.0.2:
+jsesc@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e"
integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==
@@ -27098,20 +27089,20 @@ react-is@^18.0.0:
dependencies:
"@remix-run/router" "1.21.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.28.1:
+ version "6.28.1"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.28.1.tgz#b78fe452d2cd31919b80e57047a896bfa1509f8c"
+ integrity sha512-YraE27C/RdjcZwl5UCqF/ffXnZDxpJdk9Q6jw38SZHjXs7NNdpViq2l2c7fO7+4uWaEfcwfGCv3RSg4e1By/fQ==
dependencies:
- history "^5.2.0"
- react-router "6.3.0"
+ "@remix-run/router" "1.21.0"
+ react-router "6.28.1"
-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==
+react-router@6.28.1:
+ version "6.28.1"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.28.1.tgz#f82317ab24eee67d7beb7b304c0378b2b48fa178"
+ integrity sha512-2omQTA3rkMljmrvvo6WtewGdVh45SpL9hGiCI9uUrwGGfNFDIvGK4gYJsKlJoNVi6AQZcopSCballL+QGOm7fA==
dependencies:
- history "^5.2.0"
+ "@remix-run/router" "1.21.0"
react@^18.0.0:
version "18.0.0"
@@ -30754,6 +30745,11 @@ tunnel@^0.0.6:
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
+turbo-stream@2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/turbo-stream/-/turbo-stream-2.4.0.tgz#1e4fca6725e90fa14ac4adb782f2d3759a5695f0"
+ integrity sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==
+
twirp-ts@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/twirp-ts/-/twirp-ts-2.5.0.tgz#b43f09e95868d68ecd5c755ecbb08a7e51388504"
@@ -31053,6 +31049,11 @@ undici@^5.28.4:
dependencies:
"@fastify/busboy" "^2.0.0"
+undici@^6.11.1:
+ version "6.21.0"
+ resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.0.tgz#4b3d3afaef984e07b48e7620c34ed8a285ed4cd4"
+ integrity sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==
+
unenv@^1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.10.0.tgz#c3394a6c6e4cfe68d699f87af456fe3f0db39571"