From 47d00ddbf2e345b581bee7e04c76c664c5f213b1 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Wed, 2 Nov 2022 13:16:27 -0400 Subject: [PATCH 01/36] feat: testing helpers Co-authored-by: James Restall Signed-off-by: Logan McAnsh --- package.json | 1 + packages/remix-testing/create-remix-stub.tsx | 317 +++++++++++++++++++ packages/remix-testing/index.ts | 1 + packages/remix-testing/package.json | 41 +++ packages/remix-testing/rollup.config.js | 80 +++++ packages/remix-testing/tsconfig.json | 20 ++ scripts/publish.js | 1 + scripts/utils.js | 2 +- tsconfig.json | 1 + yarn.lock | 31 ++ 10 files changed, 494 insertions(+), 1 deletion(-) create mode 100644 packages/remix-testing/create-remix-stub.tsx create mode 100644 packages/remix-testing/index.ts create mode 100644 packages/remix-testing/package.json create mode 100644 packages/remix-testing/rollup.config.js create mode 100644 packages/remix-testing/tsconfig.json diff --git a/package.json b/package.json index f7dc676e39b..846da155e70 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "packages/remix-react", "packages/remix-serve", "packages/remix-server-runtime", + "packages/remix-testing", "packages/remix-vercel" ], "scripts": { diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx new file mode 100644 index 00000000000..3ae9140e8fa --- /dev/null +++ b/packages/remix-testing/create-remix-stub.tsx @@ -0,0 +1,317 @@ +import * as React from "react"; +import { + unstable_createStaticHandler as createStaticHandler, + matchRoutes, +} from "@remix-run/router"; +import { createMemoryHistory } from "history"; +import { RemixEntry } from "@remix-run/react/dist/components"; +import type { MemoryHistory, Update } from "history"; +import type { ShouldReloadFunction } from "@remix-run/react"; +import type { + ErrorBoundaryComponent, + LinksFunction, + MetaFunction, +} from "@remix-run/server-runtime"; +import { json } from "@remix-run/server-runtime"; +import type { + InitialEntry, + StaticHandler, + LoaderFunction, + ActionFunction, + Location, +} from "@remix-run/router"; +import type { AssetsManifest, EntryContext } from "@remix-run/react/dist/entry"; +import type { RouteData } from "@remix-run/react/dist/routeData"; +import type { + CatchBoundaryComponent, + RouteModules, +} from "@remix-run/react/dist/routeModules"; +import type { EntryRoute, RouteManifest } from "@remix-run/react/dist/routes"; +import type { AgnosticRouteMatch } from "@remix-run/router/dist/utils"; + +/** + * Base RouteObject with common props shared by all types of mock routes + */ +type BaseMockRouteObject = { + id?: string; + caseSensitive?: boolean; + path?: string; + element?: React.ReactNode | null; + loader?: LoaderFunction; + action?: ActionFunction; + links?: LinksFunction; + meta?: MetaFunction; + handle?: any; + CatchBoundary?: CatchBoundaryComponent; + ErrorBoundary?: ErrorBoundaryComponent; + unstable_shouldReload?: ShouldReloadFunction; +}; + +/** + * Index routes must not have children + */ +export declare type MockIndexRouteObject = BaseMockRouteObject & { + children?: undefined; + index: true; +}; + +/** + * Non-index routes may have children, but cannot have index + */ +export declare type MockNonIndexRouteObject = BaseMockRouteObject & { + children?: MockRouteObject[]; + index?: false; +}; + +/** + * A route object represents a logical route, with (optionally) its child + * routes organized in a tree-like structure. + */ +export declare type MockRouteObject = + | MockIndexRouteObject + | MockNonIndexRouteObject; + +type RemixStubOptions = { + /** + * The initial entries in the history stack. This allows you to start a test with + * multiple locations already in the history stack (for testing a back navigation, etc.) + * The test will default to the last entry in initialEntries if no initialIndex is provided. + * e.g. initialEntries-(["/home", "/about", "/contact"]} + */ + initialEntries?: InitialEntry[]; + + /** + * Used to set the route's initial loader data. + * e.g. initialLoaderData={("/contact": {locale: "en-US" }} + */ + initialLoaderData?: RouteData; + + /** + * Used to set the route's initial action data. + * e.g. initialActionData={("/login": { errors: { email: "invalid email" } }} + */ + initialActionData?: RouteData; + + /** + * The initial index in the history stack to render. This allows you to start a test at a specific entry. + * It defaults to the last entry in initialEntries. + * e.g. + * initialEntries: ["/", "/events/123"] + * initialIndex: 1 // start at "/events/123" + */ + initialIndex?: number; +}; + +export function createRemixStub(routes: MockRouteObject[]) { + // Setup request handler to handle requests to the mock routes + let { dataRoutes, queryRoute } = createStaticHandler(routes); + return function RemixStub({ + initialEntries = ["/"], + initialLoaderData = {}, + initialActionData, + initialIndex, + }: RemixStubOptions) { + let historyRef = React.useRef(); + if (historyRef.current == null) { + historyRef.current = createMemoryHistory({ + initialEntries: initialEntries, + initialIndex: initialIndex, + }); + } + + let history = historyRef.current; + let [state, dispatch] = React.useReducer( + (_: Update, update: Update) => update, + { + action: history.action, + location: history.location, + } + ); + + React.useLayoutEffect(() => history.listen(dispatch), [history]); + + // Convert path based ids in user supplied initial loader/action data to data route ids + let loaderData = convertRouteData(dataRoutes, initialLoaderData); + let actionData = convertRouteData(dataRoutes, initialActionData); + + // Create mock remix context + let remixContext = createRemixContext( + dataRoutes, + state.location, + loaderData, + actionData + ); + + // Patch fetch so that mock routes can handle action/loader requests + monkeyPatchFetch(queryRoute, dataRoutes); + + return ( + + ); + }; +} + +function createRemixContext( + routes: MockRouteObject[], + currentLocation: Location, + initialLoaderData?: RouteData, + initialActionData?: RouteData +): EntryContext { + let manifest = createManifest(routes); + let matches = matchRoutes(routes, currentLocation) || []; + + return { + actionData: initialActionData, + appState: { + trackBoundaries: true, + trackCatchBoundaries: true, + catchBoundaryRouteId: null, + renderBoundaryRouteId: null, + loaderBoundaryRouteId: null, + error: undefined, + catch: undefined, + }, + matches: convertToEntryRouteMatch(matches), + routeData: initialLoaderData || [], + manifest: manifest, + routeModules: createRouteModules(routes), + }; +} + +function createManifest(routes: MockRouteObject[]): AssetsManifest { + return { + routes: createRouteManifest(routes), + entry: { imports: [], module: "" }, + url: "", + version: "", + }; +} + +function createRouteManifest( + routes: MockRouteObject[], + manifest?: RouteManifest, + parentId?: string +): RouteManifest { + return routes.reduce((manifest, route) => { + if (route.children) { + createRouteManifest(route.children, manifest, route.id); + } + manifest[route.id!] = convertToEntryRoute(route, parentId); + return manifest; + }, manifest || {}); +} + +function createRouteModules( + routes: MockRouteObject[], + routeModules?: RouteModules +): RouteModules { + return routes.reduce((modules, route) => { + if (route.children) { + createRouteModules(route.children, modules); + } + + if (typeof route.id === "undefined") { + throw new Error("Route id must be defined"); + } + + modules[route.id] = { + CatchBoundary: route.CatchBoundary, + ErrorBoundary: route.ErrorBoundary, + default: () => <>{route.element}, + handle: route.handle, + links: route.links, + meta: route.meta, + unstable_shouldReload: route.unstable_shouldReload, + }; + return modules; + }, routeModules || {}); +} + +const originalFetch = + typeof global !== "undefined" ? global.fetch : window.fetch; + +function monkeyPatchFetch( + queryRoute: StaticHandler["queryRoute"], + dataRoutes: StaticHandler["dataRoutes"] +) { + let fetchPatch = async ( + input: RequestInfo | URL, + init: RequestInit = {} + ): Promise => { + let request = new Request(input, init); + let url = new URL(request.url); + + // if we have matches, send the request to mock routes via @remix-run/router rather than the normal + // @remix-run/server-runtime so that stubs can also be used in browser environments. + let matches = matchRoutes(dataRoutes, url); + if (matches && matchRoutes.length > 0) { + let response = await queryRoute(request); + + if (response instanceof Response) { + return response; + } + + return json(response); + } + + // if no matches, passthrough to the original fetch as mock routes couldn't handle the request. + return originalFetch(request, init); + }; + + if (typeof global !== "undefined") { + global.fetch = fetchPatch; + } else { + window.fetch = fetchPatch; + } +} + +function convertToEntryRoute( + route: MockRouteObject, + parentId?: string +): EntryRoute { + return { + id: route.id!, + index: route.index, + caseSensitive: route.caseSensitive, + path: route.path, + parentId, + hasAction: !!route.action, + hasLoader: !!route.loader, + module: "", + hasCatchBoundary: !!route.CatchBoundary, + hasErrorBoundary: !!route.ErrorBoundary, + }; +} + +function convertToEntryRouteMatch( + routes: AgnosticRouteMatch[] +) { + return routes.map((match) => { + return { + params: match.params, + pathname: match.pathname, + route: convertToEntryRoute(match.route), + }; + }); +} + +// Converts route data from a path based index to a route id index value. +// e.g. { "/post/:postId": post } to { "0": post } +function convertRouteData( + routes: MockRouteObject[], + routeData?: RouteData +): RouteData | undefined { + if (!routeData) return undefined; + return Object.keys(routeData).reduce((data, path) => { + let routeId = routes.find((route) => route.path === path)?.id; + if (routeId) { + data[routeId] = routeData[path]; + } + return data; + }, {}); +} diff --git a/packages/remix-testing/index.ts b/packages/remix-testing/index.ts new file mode 100644 index 00000000000..e5ba9729b81 --- /dev/null +++ b/packages/remix-testing/index.ts @@ -0,0 +1 @@ +export * from "./create-remix-stub"; diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json new file mode 100644 index 00000000000..5596f8f294d --- /dev/null +++ b/packages/remix-testing/package.json @@ -0,0 +1,41 @@ +{ + "name": "@remix-run/testing", + "version": "1.7.4", + "description": "Dev tools and CLI for Remix", + "homepage": "https://remix.run", + "bugs": { + "url": "https://github.com/remix-run/remix/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/remix-run/remix", + "directory": "packages/remix-testing" + }, + "license": "MIT", + "main": "./dist/index.js", + "typings": "./dist/index.d.ts", + "module": "./dist/esm/index.js", + "dependencies": { + "@remix-run/react": "1.7.4", + "@remix-run/server-runtime": "1.7.4", + "history": "^5.3.0", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@remix-run/router": "1.0.3", + "@types/node": "^18.11.9", + "@types/react": "^18.0.24", + "@types/react-dom": "^18.0.8", + "typescript": "^4.8.4" + }, + "engines": { + "node": ">=14" + }, + "files": [ + "dist/", + "CHANGELOG.md", + "LICENSE.md", + "README.md" + ] +} diff --git a/packages/remix-testing/rollup.config.js b/packages/remix-testing/rollup.config.js new file mode 100644 index 00000000000..abbb750809b --- /dev/null +++ b/packages/remix-testing/rollup.config.js @@ -0,0 +1,80 @@ +const path = require("path"); +const babel = require("@rollup/plugin-babel").default; +const nodeResolve = require("@rollup/plugin-node-resolve").default; +const copy = require("rollup-plugin-copy"); + +const { + copyToPlaygrounds, + createBanner, + getOutputDir, + isBareModuleId, + magicExportsPlugin, +} = require("../../rollup.utils"); +const { name: packageName, version } = require("./package.json"); + +/** @returns {import("rollup").RollupOptions[]} */ +module.exports = function rollup() { + let sourceDir = "packages/remix-testing"; + let outputDir = getOutputDir(packageName); + let outputDist = path.join(outputDir, "dist"); + + // This CommonJS build of remix-testing is for node; both for use in running our + // server and for 3rd party tools that work with node. + /** @type {import("rollup").RollupOptions} */ + let remixTestingCJS = { + external(id) { + return isBareModuleId(id); + }, + input: `${sourceDir}/index.ts`, + output: { + banner: createBanner(packageName, version), + dir: outputDist, + format: "cjs", + preserveModules: true, + exports: "auto", + }, + plugins: [ + babel({ + babelHelpers: "bundled", + exclude: /node_modules/, + extensions: [".ts", ".tsx"], + }), + nodeResolve({ extensions: [".ts", ".tsx"] }), + copy({ + targets: [ + { src: "LICENSE.md", dest: [outputDir, sourceDir] }, + { src: `${sourceDir}/package.json`, dest: outputDir }, + { src: `${sourceDir}/README.md`, dest: outputDir }, + ], + }), + magicExportsPlugin({ packageName, version }), + copyToPlaygrounds(), + ], + }; + + // The browser build of remix-testing is ESM so we can treeshake it. + /** @type {import("rollup").RollupOptions} */ + let remixTestingESM = { + external(id) { + return isBareModuleId(id); + }, + input: `${sourceDir}/index.ts`, + output: { + banner: createBanner("@remix-run/testing", version), + dir: `${outputDist}/esm`, + format: "esm", + preserveModules: true, + }, + plugins: [ + babel({ + babelHelpers: "bundled", + exclude: /node_modules/, + extensions: [".ts", ".tsx"], + }), + nodeResolve({ extensions: [".ts", ".tsx"] }), + copyToPlaygrounds(), + ], + }; + + return [remixTestingCJS, remixTestingESM]; +}; diff --git a/packages/remix-testing/tsconfig.json b/packages/remix-testing/tsconfig.json new file mode 100644 index 00000000000..9ba9ed88b4e --- /dev/null +++ b/packages/remix-testing/tsconfig.json @@ -0,0 +1,20 @@ +{ + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["dist", "__tests__", "node_modules"], + "compilerOptions": { + "lib": ["DOM", "DOM.Iterable", "ES2020"], + "target": "ES2020", + "module": "ES2020", + "skipLibCheck": true, + "composite": true, + + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "strict": true, + "jsx": "react", + "declaration": true, + "emitDeclarationOnly": true, + "rootDir": ".", + "outDir": "../../build/node_modules/@remix-run/testing/dist" + } +} diff --git a/scripts/publish.js b/scripts/publish.js index 12accadb20f..3b540f16061 100644 --- a/scripts/publish.js +++ b/scripts/publish.js @@ -56,6 +56,7 @@ async function run() { "netlify", "react", "serve", + "testing", ]) { publish(path.join(buildDir, "@remix-run", name), tag); } diff --git a/scripts/utils.js b/scripts/utils.js index 1f710af293d..c89fb8189f3 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -17,7 +17,7 @@ let remixPackages = { "vercel", ], runtimes: ["cloudflare", "deno", "node"], - core: ["dev", "server-runtime", "react", "eslint-config"], + core: ["dev", "server-runtime", "react", "eslint-config", "testing"], get all() { return [...this.adapters, ...this.runtimes, ...this.core, "serve"]; }, diff --git a/tsconfig.json b/tsconfig.json index fee9d10bfcf..f5fc85cc8ad 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,7 @@ { "path": "packages/remix-react" }, { "path": "packages/remix-serve" }, { "path": "packages/remix-server-runtime" }, + { "path": "packages/remix-testing" }, { "path": "packages/remix-vercel" } ] } diff --git a/yarn.lock b/yarn.lock index f177824e62b..8c871cfbcb2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2247,6 +2247,11 @@ "@changesets/types" "^5.0.0" dotenv "^8.1.0" +"@remix-run/router@1.0.3": + version "1.0.3" + resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz#953b88c20ea00d0eddaffdc1b115c08474aa295d" + integrity sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q== + "@remix-run/web-blob@^3.0.3", "@remix-run/web-blob@^3.0.4": version "3.0.4" resolved "https://registry.npmjs.org/@remix-run/web-blob/-/web-blob-3.0.4.tgz" @@ -2862,6 +2867,11 @@ resolved "https://registry.npmjs.org/@types/node/-/node-14.18.16.tgz" integrity sha512-X3bUMdK/VmvrWdoTkz+VCn6nwKwrKCFTHtqwBIaQJNx4RUIBBUFXM00bqPz/DsDd+Icjmzm6/tyYZzeGVqb6/Q== +"@types/node@^18.11.9": + version "18.11.9" + resolved "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" + integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== + "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz" @@ -2899,6 +2909,13 @@ dependencies: "@types/react" "*" +"@types/react-dom@^18.0.8": + version "18.0.8" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.8.tgz#d2606d855186cd42cc1b11e63a71c39525441685" + integrity sha512-C3GYO0HLaOkk9dDAz3Dl4sbe4AKUGTCfFIZsz3n/82dPNN8Du533HzKatDxeUYWu24wJgMP1xICqkWk1YOLOIw== + dependencies: + "@types/react" "*" + "@types/react-test-renderer@^18.0.0": version "18.0.0" resolved "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz" @@ -2924,6 +2941,15 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/react@^18.0.24": + version "18.0.24" + resolved "https://registry.npmjs.org/@types/react/-/react-18.0.24.tgz#2f79ed5b27f08d05107aab45c17919754cc44c20" + integrity sha512-wRJWT6ouziGUy+9uX0aW4YOJxAY0bG6/AOk5AW5QSvZqI7dk6VBIbXvcVgIw/W5Jrl24f77df98GEKTJGOLx7Q== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/resolve@1.17.1": version "1.17.1" resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz" @@ -12440,6 +12466,11 @@ typescript@^4.7.4: resolved "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz" integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== +typescript@^4.8.4: + version "4.8.4" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" + integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== + uid-safe@2.1.5, uid-safe@^2.1.5: version "2.1.5" resolved "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz" From 3f9e0a6c0011a00bc4a4fc6d67ba15808ddbfd98 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Fri, 4 Nov 2022 14:20:50 -0400 Subject: [PATCH 02/36] chore: use experimental Signed-off-by: Logan McAnsh --- packages/remix-testing/index.ts | 7 +++++- packages/remix-testing/package.json | 9 +++---- yarn.lock | 37 ++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/packages/remix-testing/index.ts b/packages/remix-testing/index.ts index e5ba9729b81..fbd85e6b234 100644 --- a/packages/remix-testing/index.ts +++ b/packages/remix-testing/index.ts @@ -1 +1,6 @@ -export * from "./create-remix-stub"; +export { createRemixStub } from "./create-remix-stub"; +export type { + MockIndexRouteObject, + MockNonIndexRouteObject, + MockRouteObject, +} from "./create-remix-stub"; diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 5596f8f294d..0228072559b 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -16,14 +16,15 @@ "typings": "./dist/index.d.ts", "module": "./dist/esm/index.js", "dependencies": { - "@remix-run/react": "1.7.4", - "@remix-run/server-runtime": "1.7.4", + "@remix-run/react": "v0.0.0-experimental-96f235c51", + "@remix-run/router": "^1.0.3", + "@remix-run/server-runtime": "v0.0.0-experimental-96f235c51", "history": "^5.3.0", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^6.4.3" }, "devDependencies": { - "@remix-run/router": "1.0.3", "@types/node": "^18.11.9", "@types/react": "^18.0.24", "@types/react-dom": "^18.0.8", diff --git a/yarn.lock b/yarn.lock index 8c871cfbcb2..74a472e309f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2247,11 +2247,31 @@ "@changesets/types" "^5.0.0" dotenv "^8.1.0" -"@remix-run/router@1.0.3": +"@remix-run/react@v0.0.0-experimental-96f235c51": + version "0.0.0-experimental-96f235c51" + resolved "https://registry.npmjs.org/@remix-run/react/-/react-0.0.0-experimental-96f235c51.tgz#c307813896ac51fcc799cd055aa78a745a1cb251" + integrity sha512-fEtkxXx2IjG1pC3hkVx/9JXKUg8aZjgsrKIjtC15+MVzaTXkuzrKIpQ/R2zQ5tYzM0wGKpLERWnnyxKCTbQtMw== + dependencies: + history "^5.3.0" + react-router-dom "6.3.0" + +"@remix-run/router@1.0.3", "@remix-run/router@^1.0.3": version "1.0.3" resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz#953b88c20ea00d0eddaffdc1b115c08474aa295d" integrity sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q== +"@remix-run/server-runtime@v0.0.0-experimental-96f235c51": + version "0.0.0-experimental-96f235c51" + resolved "https://registry.npmjs.org/@remix-run/server-runtime/-/server-runtime-0.0.0-experimental-96f235c51.tgz#c64ade2328941e3c97b52764d20cb71c6dc8d89d" + integrity sha512-prWk73oXmoyqK1k1hZj5KMFZJxGH8W6N+ZjdJerUPC0vSki0CJgBJD3rlLwa4bdJtgLLkKe1mx2kBhSOfHohEA== + dependencies: + "@types/cookie" "^0.4.0" + "@web3-storage/multipart-parser" "^1.0.0" + cookie "^0.4.1" + react-router-dom "6.3.0" + 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.npmjs.org/@remix-run/web-blob/-/web-blob-3.0.4.tgz" @@ -10764,6 +10784,14 @@ react-router-dom@6.3.0: history "^5.2.0" react-router "6.3.0" +react-router-dom@^6.4.3: + version "6.4.3" + resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.4.3.tgz#70093b5f65f85f1df9e5d4182eb7ff3a08299275" + integrity sha512-MiaYQU8CwVCaOfJdYvt84KQNjT78VF0TJrA17SIQgNHRvLnXDJO6qsFqq8F/zzB1BWZjCFIrQpu4QxcshitziQ== + dependencies: + "@remix-run/router" "1.0.3" + react-router "6.4.3" + react-router@6.3.0: version "6.3.0" resolved "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz" @@ -10771,6 +10799,13 @@ react-router@6.3.0: dependencies: history "^5.2.0" +react-router@6.4.3: + version "6.4.3" + resolved "https://registry.npmjs.org/react-router/-/react-router-6.4.3.tgz#9ed3ee4d6e95889e9b075a5d63e29acc7def0d49" + integrity sha512-BT6DoGn6aV1FVP5yfODMOiieakp3z46P1Fk0RNzJMACzE7C339sFuHebfvWtnB4pzBvXXkHP2vscJzWRuUjTtA== + dependencies: + "@remix-run/router" "1.0.3" + react@^18.2.0: version "18.2.0" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" From 17564423869df5fcab0c664ff97fa8a4df9f9925 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Fri, 4 Nov 2022 15:29:18 -0400 Subject: [PATCH 03/36] chore: update imports to @remix-run/server-runtime/dist/router Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 44 +++++++++----------- packages/remix-testing/package.json | 2 - yarn.lock | 2 +- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 3ae9140e8fa..30b24dc0272 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -2,24 +2,26 @@ import * as React from "react"; import { unstable_createStaticHandler as createStaticHandler, matchRoutes, -} from "@remix-run/router"; -import { createMemoryHistory } from "history"; + createMemoryHistory, +} from "@remix-run/server-runtime/dist/router"; +import type { + InitialEntry, + StaticHandler, + LoaderFunction, + ActionFunction, + Location, + AgnosticRouteMatch, + MemoryHistory, +} from "@remix-run/server-runtime/dist/router"; +import type { Update } from "@remix-run/server-runtime/dist/router/history"; import { RemixEntry } from "@remix-run/react/dist/components"; -import type { MemoryHistory, Update } from "history"; import type { ShouldReloadFunction } from "@remix-run/react"; +import { json } from "@remix-run/server-runtime"; import type { ErrorBoundaryComponent, LinksFunction, MetaFunction, } from "@remix-run/server-runtime"; -import { json } from "@remix-run/server-runtime"; -import type { - InitialEntry, - StaticHandler, - LoaderFunction, - ActionFunction, - Location, -} from "@remix-run/router"; import type { AssetsManifest, EntryContext } from "@remix-run/react/dist/entry"; import type { RouteData } from "@remix-run/react/dist/routeData"; import type { @@ -27,7 +29,6 @@ import type { RouteModules, } from "@remix-run/react/dist/routeModules"; import type { EntryRoute, RouteManifest } from "@remix-run/react/dist/routes"; -import type { AgnosticRouteMatch } from "@remix-run/router/dist/utils"; /** * Base RouteObject with common props shared by all types of mock routes @@ -76,19 +77,19 @@ type RemixStubOptions = { * The initial entries in the history stack. This allows you to start a test with * multiple locations already in the history stack (for testing a back navigation, etc.) * The test will default to the last entry in initialEntries if no initialIndex is provided. - * e.g. initialEntries-(["/home", "/about", "/contact"]} + * e.g. initialEntries={["/home", "/about", "/contact"]} */ initialEntries?: InitialEntry[]; /** * Used to set the route's initial loader data. - * e.g. initialLoaderData={("/contact": {locale: "en-US" }} + * e.g. initialLoaderData={{ "/contact": { locale: "en-US" } } */ initialLoaderData?: RouteData; /** * Used to set the route's initial action data. - * e.g. initialActionData={("/login": { errors: { email: "invalid email" } }} + * e.g. initialActionData={{ "/login": { errors: { email: "invalid email" } } } */ initialActionData?: RouteData; @@ -96,8 +97,8 @@ type RemixStubOptions = { * The initial index in the history stack to render. This allows you to start a test at a specific entry. * It defaults to the last entry in initialEntries. * e.g. - * initialEntries: ["/", "/events/123"] - * initialIndex: 1 // start at "/events/123" + * initialEntries={["/", "/events/123"]} + * initialIndex={1} // start at "/events/123" */ initialIndex?: number; }; @@ -210,7 +211,7 @@ function createRouteModules( routes: MockRouteObject[], routeModules?: RouteModules ): RouteModules { - return routes.reduce((modules, route) => { + return routes.reduce((modules, route) => { if (route.children) { createRouteModules(route.children, modules); } @@ -251,12 +252,7 @@ function monkeyPatchFetch( let matches = matchRoutes(dataRoutes, url); if (matches && matchRoutes.length > 0) { let response = await queryRoute(request); - - if (response instanceof Response) { - return response; - } - - return json(response); + return response instanceof Response ? response : json(response); } // if no matches, passthrough to the original fetch as mock routes couldn't handle the request. diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 0228072559b..61336e1f957 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -17,9 +17,7 @@ "module": "./dist/esm/index.js", "dependencies": { "@remix-run/react": "v0.0.0-experimental-96f235c51", - "@remix-run/router": "^1.0.3", "@remix-run/server-runtime": "v0.0.0-experimental-96f235c51", - "history": "^5.3.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.4.3" diff --git a/yarn.lock b/yarn.lock index 74a472e309f..84e41532dec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2255,7 +2255,7 @@ history "^5.3.0" react-router-dom "6.3.0" -"@remix-run/router@1.0.3", "@remix-run/router@^1.0.3": +"@remix-run/router@1.0.3": version "1.0.3" resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz#953b88c20ea00d0eddaffdc1b115c08474aa295d" integrity sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q== From 0a892ad701dacd38541c69c88b295afa3d0bfa70 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Fri, 4 Nov 2022 15:33:35 -0400 Subject: [PATCH 04/36] Revert "chore: update imports to @remix-run/server-runtime/dist/router" This reverts commit b61c363e8e94ca03ad169109fddcf170132da6b5. --- packages/remix-testing/create-remix-stub.tsx | 44 +++++++++++--------- packages/remix-testing/package.json | 2 + yarn.lock | 2 +- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 30b24dc0272..3ae9140e8fa 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -2,26 +2,24 @@ import * as React from "react"; import { unstable_createStaticHandler as createStaticHandler, matchRoutes, - createMemoryHistory, -} from "@remix-run/server-runtime/dist/router"; -import type { - InitialEntry, - StaticHandler, - LoaderFunction, - ActionFunction, - Location, - AgnosticRouteMatch, - MemoryHistory, -} from "@remix-run/server-runtime/dist/router"; -import type { Update } from "@remix-run/server-runtime/dist/router/history"; +} from "@remix-run/router"; +import { createMemoryHistory } from "history"; import { RemixEntry } from "@remix-run/react/dist/components"; +import type { MemoryHistory, Update } from "history"; import type { ShouldReloadFunction } from "@remix-run/react"; -import { json } from "@remix-run/server-runtime"; import type { ErrorBoundaryComponent, LinksFunction, MetaFunction, } from "@remix-run/server-runtime"; +import { json } from "@remix-run/server-runtime"; +import type { + InitialEntry, + StaticHandler, + LoaderFunction, + ActionFunction, + Location, +} from "@remix-run/router"; import type { AssetsManifest, EntryContext } from "@remix-run/react/dist/entry"; import type { RouteData } from "@remix-run/react/dist/routeData"; import type { @@ -29,6 +27,7 @@ import type { RouteModules, } from "@remix-run/react/dist/routeModules"; import type { EntryRoute, RouteManifest } from "@remix-run/react/dist/routes"; +import type { AgnosticRouteMatch } from "@remix-run/router/dist/utils"; /** * Base RouteObject with common props shared by all types of mock routes @@ -77,19 +76,19 @@ type RemixStubOptions = { * The initial entries in the history stack. This allows you to start a test with * multiple locations already in the history stack (for testing a back navigation, etc.) * The test will default to the last entry in initialEntries if no initialIndex is provided. - * e.g. initialEntries={["/home", "/about", "/contact"]} + * e.g. initialEntries-(["/home", "/about", "/contact"]} */ initialEntries?: InitialEntry[]; /** * Used to set the route's initial loader data. - * e.g. initialLoaderData={{ "/contact": { locale: "en-US" } } + * e.g. initialLoaderData={("/contact": {locale: "en-US" }} */ initialLoaderData?: RouteData; /** * Used to set the route's initial action data. - * e.g. initialActionData={{ "/login": { errors: { email: "invalid email" } } } + * e.g. initialActionData={("/login": { errors: { email: "invalid email" } }} */ initialActionData?: RouteData; @@ -97,8 +96,8 @@ type RemixStubOptions = { * The initial index in the history stack to render. This allows you to start a test at a specific entry. * It defaults to the last entry in initialEntries. * e.g. - * initialEntries={["/", "/events/123"]} - * initialIndex={1} // start at "/events/123" + * initialEntries: ["/", "/events/123"] + * initialIndex: 1 // start at "/events/123" */ initialIndex?: number; }; @@ -211,7 +210,7 @@ function createRouteModules( routes: MockRouteObject[], routeModules?: RouteModules ): RouteModules { - return routes.reduce((modules, route) => { + return routes.reduce((modules, route) => { if (route.children) { createRouteModules(route.children, modules); } @@ -252,7 +251,12 @@ function monkeyPatchFetch( let matches = matchRoutes(dataRoutes, url); if (matches && matchRoutes.length > 0) { let response = await queryRoute(request); - return response instanceof Response ? response : json(response); + + if (response instanceof Response) { + return response; + } + + return json(response); } // if no matches, passthrough to the original fetch as mock routes couldn't handle the request. diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 61336e1f957..0228072559b 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -17,7 +17,9 @@ "module": "./dist/esm/index.js", "dependencies": { "@remix-run/react": "v0.0.0-experimental-96f235c51", + "@remix-run/router": "^1.0.3", "@remix-run/server-runtime": "v0.0.0-experimental-96f235c51", + "history": "^5.3.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.4.3" diff --git a/yarn.lock b/yarn.lock index 84e41532dec..74a472e309f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2255,7 +2255,7 @@ history "^5.3.0" react-router-dom "6.3.0" -"@remix-run/router@1.0.3": +"@remix-run/router@1.0.3", "@remix-run/router@^1.0.3": version "1.0.3" resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz#953b88c20ea00d0eddaffdc1b115c08474aa295d" integrity sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q== From 60818b98a24062bd1c9d24edaef806d99b5ea250 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Fri, 4 Nov 2022 15:34:25 -0400 Subject: [PATCH 05/36] Revert "chore: use experimental" This reverts commit 76d710f9b9fccfd945c0131069042ae88a42e9a4. --- packages/remix-testing/index.ts | 7 +----- packages/remix-testing/package.json | 9 ++++--- yarn.lock | 37 +---------------------------- 3 files changed, 6 insertions(+), 47 deletions(-) diff --git a/packages/remix-testing/index.ts b/packages/remix-testing/index.ts index fbd85e6b234..e5ba9729b81 100644 --- a/packages/remix-testing/index.ts +++ b/packages/remix-testing/index.ts @@ -1,6 +1 @@ -export { createRemixStub } from "./create-remix-stub"; -export type { - MockIndexRouteObject, - MockNonIndexRouteObject, - MockRouteObject, -} from "./create-remix-stub"; +export * from "./create-remix-stub"; diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 0228072559b..5596f8f294d 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -16,15 +16,14 @@ "typings": "./dist/index.d.ts", "module": "./dist/esm/index.js", "dependencies": { - "@remix-run/react": "v0.0.0-experimental-96f235c51", - "@remix-run/router": "^1.0.3", - "@remix-run/server-runtime": "v0.0.0-experimental-96f235c51", + "@remix-run/react": "1.7.4", + "@remix-run/server-runtime": "1.7.4", "history": "^5.3.0", "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-router-dom": "^6.4.3" + "react-dom": "^18.2.0" }, "devDependencies": { + "@remix-run/router": "1.0.3", "@types/node": "^18.11.9", "@types/react": "^18.0.24", "@types/react-dom": "^18.0.8", diff --git a/yarn.lock b/yarn.lock index 74a472e309f..8c871cfbcb2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2247,31 +2247,11 @@ "@changesets/types" "^5.0.0" dotenv "^8.1.0" -"@remix-run/react@v0.0.0-experimental-96f235c51": - version "0.0.0-experimental-96f235c51" - resolved "https://registry.npmjs.org/@remix-run/react/-/react-0.0.0-experimental-96f235c51.tgz#c307813896ac51fcc799cd055aa78a745a1cb251" - integrity sha512-fEtkxXx2IjG1pC3hkVx/9JXKUg8aZjgsrKIjtC15+MVzaTXkuzrKIpQ/R2zQ5tYzM0wGKpLERWnnyxKCTbQtMw== - dependencies: - history "^5.3.0" - react-router-dom "6.3.0" - -"@remix-run/router@1.0.3", "@remix-run/router@^1.0.3": +"@remix-run/router@1.0.3": version "1.0.3" resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz#953b88c20ea00d0eddaffdc1b115c08474aa295d" integrity sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q== -"@remix-run/server-runtime@v0.0.0-experimental-96f235c51": - version "0.0.0-experimental-96f235c51" - resolved "https://registry.npmjs.org/@remix-run/server-runtime/-/server-runtime-0.0.0-experimental-96f235c51.tgz#c64ade2328941e3c97b52764d20cb71c6dc8d89d" - integrity sha512-prWk73oXmoyqK1k1hZj5KMFZJxGH8W6N+ZjdJerUPC0vSki0CJgBJD3rlLwa4bdJtgLLkKe1mx2kBhSOfHohEA== - dependencies: - "@types/cookie" "^0.4.0" - "@web3-storage/multipart-parser" "^1.0.0" - cookie "^0.4.1" - react-router-dom "6.3.0" - 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.npmjs.org/@remix-run/web-blob/-/web-blob-3.0.4.tgz" @@ -10784,14 +10764,6 @@ react-router-dom@6.3.0: history "^5.2.0" react-router "6.3.0" -react-router-dom@^6.4.3: - version "6.4.3" - resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.4.3.tgz#70093b5f65f85f1df9e5d4182eb7ff3a08299275" - integrity sha512-MiaYQU8CwVCaOfJdYvt84KQNjT78VF0TJrA17SIQgNHRvLnXDJO6qsFqq8F/zzB1BWZjCFIrQpu4QxcshitziQ== - dependencies: - "@remix-run/router" "1.0.3" - react-router "6.4.3" - react-router@6.3.0: version "6.3.0" resolved "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz" @@ -10799,13 +10771,6 @@ react-router@6.3.0: dependencies: history "^5.2.0" -react-router@6.4.3: - version "6.4.3" - resolved "https://registry.npmjs.org/react-router/-/react-router-6.4.3.tgz#9ed3ee4d6e95889e9b075a5d63e29acc7def0d49" - integrity sha512-BT6DoGn6aV1FVP5yfODMOiieakp3z46P1Fk0RNzJMACzE7C339sFuHebfvWtnB4pzBvXXkHP2vscJzWRuUjTtA== - dependencies: - "@remix-run/router" "1.0.3" - react@^18.2.0: version "18.2.0" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" From 2230d591b98b3b00dd320286a8d49b5f3eb52cbf Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Mon, 7 Nov 2022 11:39:03 -0500 Subject: [PATCH 06/36] chore: remove deep imports Signed-off-by: Logan McAnsh --- packages/remix-react/index.tsx | 12 +++++++++++- packages/remix-testing/create-remix-stub.tsx | 20 +++++++++++--------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/remix-react/index.tsx b/packages/remix-react/index.tsx index 7cb608e2650..024e855fb19 100644 --- a/packages/remix-react/index.tsx +++ b/packages/remix-react/index.tsx @@ -35,6 +35,7 @@ export { Link, NavLink, Form, + RemixEntry, PrefetchPageLinks, LiveReload, useFormAction, @@ -54,7 +55,12 @@ export type { ThrownResponse } from "./errors"; export { useCatch } from "./errorBoundaries"; export type { HtmlLinkDescriptor } from "./links"; -export type { ShouldReloadFunction, HtmlMetaDescriptor } from "./routeModules"; +export type { + ShouldReloadFunction, + HtmlMetaDescriptor, + CatchBoundaryComponent, + RouteModules, +} from "./routeModules"; export { ScrollRestoration } from "./scroll-restoration"; @@ -62,3 +68,7 @@ export type { RemixServerProps } from "./server"; export { RemixServer } from "./server"; export type { Fetcher } from "./transition"; + +export type { AssetsManifest, EntryContext } from "./entry"; +export type { RouteData } from "./routeData"; +export type { EntryRoute, RouteManifest } from "./routes"; diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 3ae9140e8fa..545e1e79c54 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -4,9 +4,18 @@ import { matchRoutes, } from "@remix-run/router"; import { createMemoryHistory } from "history"; -import { RemixEntry } from "@remix-run/react/dist/components"; +import { RemixEntry } from "@remix-run/react"; +import type { + AssetsManifest, + EntryContext, + RouteData, + ShouldReloadFunction, + CatchBoundaryComponent, + RouteModules, + EntryRoute, + RouteManifest, +} from "@remix-run/react"; import type { MemoryHistory, Update } from "history"; -import type { ShouldReloadFunction } from "@remix-run/react"; import type { ErrorBoundaryComponent, LinksFunction, @@ -20,13 +29,6 @@ import type { ActionFunction, Location, } from "@remix-run/router"; -import type { AssetsManifest, EntryContext } from "@remix-run/react/dist/entry"; -import type { RouteData } from "@remix-run/react/dist/routeData"; -import type { - CatchBoundaryComponent, - RouteModules, -} from "@remix-run/react/dist/routeModules"; -import type { EntryRoute, RouteManifest } from "@remix-run/react/dist/routes"; import type { AgnosticRouteMatch } from "@remix-run/router/dist/utils"; /** From 1de9bb1ed21f39f980c45c8617466e92c787645e Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Mon, 7 Nov 2022 11:45:49 -0500 Subject: [PATCH 07/36] chore: move router to deps until remix uses 6.4 internally Signed-off-by: Logan McAnsh --- packages/remix-testing/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 5596f8f294d..2d05bc641f0 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -17,13 +17,13 @@ "module": "./dist/esm/index.js", "dependencies": { "@remix-run/react": "1.7.4", + "@remix-run/router": "1.0.3", "@remix-run/server-runtime": "1.7.4", "history": "^5.3.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { - "@remix-run/router": "1.0.3", "@types/node": "^18.11.9", "@types/react": "^18.0.24", "@types/react-dom": "^18.0.8", From e44ee0198aa4e8555375e4b0af31434eebefd789 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Mon, 7 Nov 2022 11:46:07 -0500 Subject: [PATCH 08/36] chore: explicit exports Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 8 ++++---- packages/remix-testing/index.ts | 7 ++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 545e1e79c54..d9532c8e767 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -7,13 +7,13 @@ import { createMemoryHistory } from "history"; import { RemixEntry } from "@remix-run/react"; import type { AssetsManifest, - EntryContext, - RouteData, - ShouldReloadFunction, CatchBoundaryComponent, - RouteModules, + EntryContext, EntryRoute, + RouteData, RouteManifest, + RouteModules, + ShouldReloadFunction, } from "@remix-run/react"; import type { MemoryHistory, Update } from "history"; import type { diff --git a/packages/remix-testing/index.ts b/packages/remix-testing/index.ts index e5ba9729b81..fbd85e6b234 100644 --- a/packages/remix-testing/index.ts +++ b/packages/remix-testing/index.ts @@ -1 +1,6 @@ -export * from "./create-remix-stub"; +export { createRemixStub } from "./create-remix-stub"; +export type { + MockIndexRouteObject, + MockNonIndexRouteObject, + MockRouteObject, +} from "./create-remix-stub"; From 9e6244e6f70365e52844b66efdfc9a54a5f9cf8d Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 8 Nov 2022 12:24:06 -0500 Subject: [PATCH 09/36] nested route data Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 30 ++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index d9532c8e767..61556936f2d 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -218,7 +218,7 @@ function createRouteModules( } if (typeof route.id === "undefined") { - throw new Error("Route id must be defined"); + throw new Error("Route ID must be defined"); } modules[route.id] = { @@ -306,14 +306,28 @@ function convertToEntryRouteMatch( // e.g. { "/post/:postId": post } to { "0": post } function convertRouteData( routes: MockRouteObject[], - routeData?: RouteData + initialRouteData?: RouteData, + routeData: RouteData = {} ): RouteData | undefined { - if (!routeData) return undefined; - return Object.keys(routeData).reduce((data, path) => { - let routeId = routes.find((route) => route.path === path)?.id; - if (routeId) { - data[routeId] = routeData[path]; + if (!initialRouteData) return undefined; + return routes.reduce((data, route) => { + if (route.children) { + convertRouteData(route.children, initialRouteData, data); } + // Check if any of the initial route data entries match this route + Object.keys(initialRouteData).forEach((routePath) => { + if ( + routePath === route.path || + // Let '/' refer to the root routes data + (routePath === "/" && route.id === "0" && !route.path) + ) { + if (typeof route.id === "undefined") { + throw new Error("Route ID must be defined"); + } + + data[route.id] = initialRouteData[routePath]; + } + }); return data; - }, {}); + }, routeData); } From d071451be1429c7b6519329ba248aab7e5299ab3 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 8 Nov 2022 12:57:36 -0500 Subject: [PATCH 10/36] chore: import from server-runtime/router Signed-off-by: Logan McAnsh --- packages/remix-server-runtime/index.ts | 3 +++ packages/remix-testing/create-remix-stub.tsx | 6 +++--- packages/remix-testing/package.json | 1 - 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/remix-server-runtime/index.ts b/packages/remix-server-runtime/index.ts index 400c3b89351..8607d334697 100644 --- a/packages/remix-server-runtime/index.ts +++ b/packages/remix-server-runtime/index.ts @@ -74,3 +74,6 @@ export type { UploadHandlerPart, UploadHandler, } from "./reexport"; + +export type { MemoryHistory } from "./router"; +export { createMemoryHistory } from "./router"; diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 61556936f2d..7c75e1a80f1 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -3,7 +3,6 @@ import { unstable_createStaticHandler as createStaticHandler, matchRoutes, } from "@remix-run/router"; -import { createMemoryHistory } from "history"; import { RemixEntry } from "@remix-run/react"; import type { AssetsManifest, @@ -15,13 +14,13 @@ import type { RouteModules, ShouldReloadFunction, } from "@remix-run/react"; -import type { MemoryHistory, Update } from "history"; import type { ErrorBoundaryComponent, LinksFunction, MetaFunction, + MemoryHistory, } from "@remix-run/server-runtime"; -import { json } from "@remix-run/server-runtime"; +import { json, createMemoryHistory } from "@remix-run/server-runtime"; import type { InitialEntry, StaticHandler, @@ -30,6 +29,7 @@ import type { Location, } from "@remix-run/router"; import type { AgnosticRouteMatch } from "@remix-run/router/dist/utils"; +import type { Update } from "@remix-run/router/dist/history"; /** * Base RouteObject with common props shared by all types of mock routes diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 2d05bc641f0..79363e1b2fa 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -19,7 +19,6 @@ "@remix-run/react": "1.7.4", "@remix-run/router": "1.0.3", "@remix-run/server-runtime": "1.7.4", - "history": "^5.3.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, From 52b7d6c30ff0c84dd2a00bd4356820e74872b1e5 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 8 Nov 2022 13:05:27 -0500 Subject: [PATCH 11/36] chore: script yalc store publishing Signed-off-by: Logan McAnsh --- yalc.sh | 4 ++++ 1 file changed, 4 insertions(+) create mode 100755 yalc.sh diff --git a/yalc.sh b/yalc.sh new file mode 100755 index 00000000000..63e82a2cb70 --- /dev/null +++ b/yalc.sh @@ -0,0 +1,4 @@ +packages=('testing' 'server-runtime' 'react') +for i in "${packages[@]}"; do + yalc publish ./build/node_modules/@remix-run/$i +done From bce671f73d39332735c643bf89b52ba999496298 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 8 Nov 2022 13:24:25 -0500 Subject: [PATCH 12/36] chore: use experimental, publish all packages to yalc store Signed-off-by: Logan McAnsh --- packages/remix-testing/package.json | 4 ++-- yalc.sh | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 79363e1b2fa..fac4e67a29d 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -16,9 +16,9 @@ "typings": "./dist/index.d.ts", "module": "./dist/esm/index.js", "dependencies": { - "@remix-run/react": "1.7.4", + "@remix-run/react": "0.0.0-experimental-96f235c51", "@remix-run/router": "1.0.3", - "@remix-run/server-runtime": "1.7.4", + "@remix-run/server-runtime": "0.0.0-experimental-96f235c51", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/yalc.sh b/yalc.sh index 63e82a2cb70..c851db85370 100755 --- a/yalc.sh +++ b/yalc.sh @@ -1,4 +1,19 @@ -packages=('testing' 'server-runtime' 'react') +packages=( +'architect' +'cloudflare' +'cloudflare-pages' +'cloudflare-workers' +'deno' +'dev' +'express' +'netlify' +'node' +'react' +'serve' +'server-runtime' +'testing' +'vercel' +) for i in "${packages[@]}"; do yalc publish ./build/node_modules/@remix-run/$i done From 62cf0abf7cab2b096f812115cbb752b6395a80d5 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Thu, 10 Nov 2022 12:20:50 -0500 Subject: [PATCH 13/36] imports Signed-off-by: Logan McAnsh --- packages/remix-server-runtime/index.ts | 16 ++- packages/remix-testing/create-remix-stub.tsx | 106 +++++-------------- packages/remix-testing/index.ts | 5 - 3 files changed, 43 insertions(+), 84 deletions(-) diff --git a/packages/remix-server-runtime/index.ts b/packages/remix-server-runtime/index.ts index 8607d334697..828f13566fd 100644 --- a/packages/remix-server-runtime/index.ts +++ b/packages/remix-server-runtime/index.ts @@ -75,5 +75,17 @@ export type { UploadHandler, } from "./reexport"; -export type { MemoryHistory } from "./router"; -export { createMemoryHistory } from "./router"; +export type { + MemoryHistory, + InitialEntry, + StaticHandler, + Location, + AgnosticRouteObject, +} from "./router"; +export { + createMemoryHistory, + unstable_createStaticHandler, + matchRoutes, +} from "./router"; +export type { Update } from "./router/history"; +export type { AgnosticRouteMatch } from "./router/utils"; diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 7c75e1a80f1..af8175da622 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -1,77 +1,28 @@ import * as React from "react"; -import { - unstable_createStaticHandler as createStaticHandler, - matchRoutes, -} from "@remix-run/router"; -import { RemixEntry } from "@remix-run/react"; import type { AssetsManifest, - CatchBoundaryComponent, EntryContext, EntryRoute, RouteData, RouteManifest, RouteModules, - ShouldReloadFunction, } from "@remix-run/react"; +import { RemixEntry } from "@remix-run/react"; import type { - ErrorBoundaryComponent, - LinksFunction, - MetaFunction, - MemoryHistory, -} from "@remix-run/server-runtime"; -import { json, createMemoryHistory } from "@remix-run/server-runtime"; -import type { + AgnosticRouteMatch, + AgnosticRouteObject, InitialEntry, - StaticHandler, - LoaderFunction, - ActionFunction, Location, -} from "@remix-run/router"; -import type { AgnosticRouteMatch } from "@remix-run/router/dist/utils"; -import type { Update } from "@remix-run/router/dist/history"; - -/** - * Base RouteObject with common props shared by all types of mock routes - */ -type BaseMockRouteObject = { - id?: string; - caseSensitive?: boolean; - path?: string; - element?: React.ReactNode | null; - loader?: LoaderFunction; - action?: ActionFunction; - links?: LinksFunction; - meta?: MetaFunction; - handle?: any; - CatchBoundary?: CatchBoundaryComponent; - ErrorBoundary?: ErrorBoundaryComponent; - unstable_shouldReload?: ShouldReloadFunction; -}; - -/** - * Index routes must not have children - */ -export declare type MockIndexRouteObject = BaseMockRouteObject & { - children?: undefined; - index: true; -}; - -/** - * Non-index routes may have children, but cannot have index - */ -export declare type MockNonIndexRouteObject = BaseMockRouteObject & { - children?: MockRouteObject[]; - index?: false; -}; - -/** - * A route object represents a logical route, with (optionally) its child - * routes organized in a tree-like structure. - */ -export declare type MockRouteObject = - | MockIndexRouteObject - | MockNonIndexRouteObject; + MemoryHistory, + StaticHandler, + Update, +} from "@remix-run/server-runtime"; +import { + createMemoryHistory, + json, + matchRoutes, + unstable_createStaticHandler as createStaticHandler, +} from "@remix-run/server-runtime"; type RemixStubOptions = { /** @@ -104,7 +55,7 @@ type RemixStubOptions = { initialIndex?: number; }; -export function createRemixStub(routes: MockRouteObject[]) { +export function createRemixStub(routes: AgnosticRouteObject[]) { // Setup request handler to handle requests to the mock routes let { dataRoutes, queryRoute } = createStaticHandler(routes); return function RemixStub({ @@ -159,7 +110,7 @@ export function createRemixStub(routes: MockRouteObject[]) { } function createRemixContext( - routes: MockRouteObject[], + routes: AgnosticRouteObject[], currentLocation: Location, initialLoaderData?: RouteData, initialActionData?: RouteData @@ -185,7 +136,7 @@ function createRemixContext( }; } -function createManifest(routes: MockRouteObject[]): AssetsManifest { +function createManifest(routes: AgnosticRouteObject[]): AssetsManifest { return { routes: createRouteManifest(routes), entry: { imports: [], module: "" }, @@ -195,7 +146,7 @@ function createManifest(routes: MockRouteObject[]): AssetsManifest { } function createRouteManifest( - routes: MockRouteObject[], + routes: AgnosticRouteObject[], manifest?: RouteManifest, parentId?: string ): RouteManifest { @@ -209,7 +160,7 @@ function createRouteManifest( } function createRouteModules( - routes: MockRouteObject[], + routes: AgnosticRouteObject[], routeModules?: RouteModules ): RouteModules { return routes.reduce((modules, route) => { @@ -222,13 +173,14 @@ function createRouteModules( } modules[route.id] = { - CatchBoundary: route.CatchBoundary, - ErrorBoundary: route.ErrorBoundary, + CatchBoundary: undefined, + ErrorBoundary: undefined, + // @ts-ignore default: () => <>{route.element}, handle: route.handle, - links: route.links, - meta: route.meta, - unstable_shouldReload: route.unstable_shouldReload, + links: undefined, + meta: undefined, + unstable_shouldReload: undefined, }; return modules; }, routeModules || {}); @@ -273,7 +225,7 @@ function monkeyPatchFetch( } function convertToEntryRoute( - route: MockRouteObject, + route: AgnosticRouteObject, parentId?: string ): EntryRoute { return { @@ -285,13 +237,13 @@ function convertToEntryRoute( hasAction: !!route.action, hasLoader: !!route.loader, module: "", - hasCatchBoundary: !!route.CatchBoundary, - hasErrorBoundary: !!route.ErrorBoundary, + hasCatchBoundary: false, + hasErrorBoundary: false, }; } function convertToEntryRouteMatch( - routes: AgnosticRouteMatch[] + routes: AgnosticRouteMatch[] ) { return routes.map((match) => { return { @@ -305,7 +257,7 @@ function convertToEntryRouteMatch( // Converts route data from a path based index to a route id index value. // e.g. { "/post/:postId": post } to { "0": post } function convertRouteData( - routes: MockRouteObject[], + routes: AgnosticRouteObject[], initialRouteData?: RouteData, routeData: RouteData = {} ): RouteData | undefined { diff --git a/packages/remix-testing/index.ts b/packages/remix-testing/index.ts index fbd85e6b234..c31905b9157 100644 --- a/packages/remix-testing/index.ts +++ b/packages/remix-testing/index.ts @@ -1,6 +1 @@ export { createRemixStub } from "./create-remix-stub"; -export type { - MockIndexRouteObject, - MockNonIndexRouteObject, - MockRouteObject, -} from "./create-remix-stub"; From 3d0684fa9540e5f3759f1ca0a198dafae5b53218 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Thu, 10 Nov 2022 12:43:54 -0500 Subject: [PATCH 14/36] rebase on document-request-experimental Signed-off-by: Logan McAnsh --- packages/remix-testing/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index fac4e67a29d..737dd697d80 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/testing", - "version": "1.7.4", + "version": "0.0.0-experimental-5b4bceda6", "description": "Dev tools and CLI for Remix", "homepage": "https://remix.run", "bugs": { @@ -16,9 +16,9 @@ "typings": "./dist/index.d.ts", "module": "./dist/esm/index.js", "dependencies": { - "@remix-run/react": "0.0.0-experimental-96f235c51", + "@remix-run/react": "0.0.0-experimental-5b4bceda6", "@remix-run/router": "1.0.3", - "@remix-run/server-runtime": "0.0.0-experimental-96f235c51", + "@remix-run/server-runtime": "0.0.0-experimental-5b4bceda6", "react": "^18.2.0", "react-dom": "^18.2.0" }, From e73427a2fc7bc238e64100fb452b7676b4acb669 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Mon, 14 Nov 2022 14:58:36 -0500 Subject: [PATCH 15/36] chore: remove @remix-run/router Signed-off-by: Logan McAnsh --- packages/remix-testing/package.json | 1 - yarn.lock | 5 ----- 2 files changed, 6 deletions(-) diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 737dd697d80..eba45c5f66b 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -17,7 +17,6 @@ "module": "./dist/esm/index.js", "dependencies": { "@remix-run/react": "0.0.0-experimental-5b4bceda6", - "@remix-run/router": "1.0.3", "@remix-run/server-runtime": "0.0.0-experimental-5b4bceda6", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/yarn.lock b/yarn.lock index 8c871cfbcb2..24289b5243f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2247,11 +2247,6 @@ "@changesets/types" "^5.0.0" dotenv "^8.1.0" -"@remix-run/router@1.0.3": - version "1.0.3" - resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.0.3.tgz#953b88c20ea00d0eddaffdc1b115c08474aa295d" - integrity sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q== - "@remix-run/web-blob@^3.0.3", "@remix-run/web-blob@^3.0.4": version "3.0.4" resolved "https://registry.npmjs.org/@remix-run/web-blob/-/web-blob-3.0.4.tgz" From f9a005dbf98675c1403f15cbc5284f710a8cf70a Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 15 Nov 2022 19:40:55 -0500 Subject: [PATCH 16/36] chore: yalc use push Signed-off-by: Logan McAnsh --- yalc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yalc.sh b/yalc.sh index c851db85370..48e2ad2151c 100755 --- a/yalc.sh +++ b/yalc.sh @@ -15,5 +15,5 @@ packages=( 'vercel' ) for i in "${packages[@]}"; do - yalc publish ./build/node_modules/@remix-run/$i + yalc push ./build/node_modules/@remix-run/$i done From e621712b85e13ecf98da5eda8e8bf700a8d6ad9f Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 15 Nov 2022 19:43:14 -0500 Subject: [PATCH 17/36] chore: update version Signed-off-by: Logan McAnsh --- packages/remix-server-runtime/index.ts | 2 ++ packages/remix-testing/package.json | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/remix-server-runtime/index.ts b/packages/remix-server-runtime/index.ts index 828f13566fd..bf8c7b16c52 100644 --- a/packages/remix-server-runtime/index.ts +++ b/packages/remix-server-runtime/index.ts @@ -81,6 +81,8 @@ export type { StaticHandler, Location, AgnosticRouteObject, + AgnosticIndexRouteObject, + AgnosticNonIndexRouteObject, } from "./router"; export { createMemoryHistory, diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index eba45c5f66b..0b794a23e80 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -1,7 +1,7 @@ { "name": "@remix-run/testing", - "version": "0.0.0-experimental-5b4bceda6", - "description": "Dev tools and CLI for Remix", + "version": "1.7.5", + "description": "Testing utilities for Remix apps", "homepage": "https://remix.run", "bugs": { "url": "https://github.com/remix-run/remix/issues" @@ -16,8 +16,8 @@ "typings": "./dist/index.d.ts", "module": "./dist/esm/index.js", "dependencies": { - "@remix-run/react": "0.0.0-experimental-5b4bceda6", - "@remix-run/server-runtime": "0.0.0-experimental-5b4bceda6", + "@remix-run/react": "1.7.5", + "@remix-run/server-runtime": "1.7.5", "react": "^18.2.0", "react-dom": "^18.2.0" }, From d9a9ba2666fa3b70546a9ebf58095352ad4a7642 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 15 Nov 2022 19:46:37 -0500 Subject: [PATCH 18/36] add extended type with element Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 52 ++++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index af8175da622..a12bd365ad8 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -9,8 +9,9 @@ import type { } from "@remix-run/react"; import { RemixEntry } from "@remix-run/react"; import type { + AgnosticIndexRouteObject, + AgnosticNonIndexRouteObject, AgnosticRouteMatch, - AgnosticRouteObject, InitialEntry, Location, MemoryHistory, @@ -55,7 +56,19 @@ type RemixStubOptions = { initialIndex?: number; }; -export function createRemixStub(routes: AgnosticRouteObject[]) { +type IndexRouteObject = AgnosticIndexRouteObject & { + element: React.ReactNode; + children?: undefined; +}; + +type NonIndexRouteObject = AgnosticNonIndexRouteObject & { + element: React.ReactNode; + children?: RouteObject[]; +}; + +type RouteObject = IndexRouteObject | NonIndexRouteObject; + +export function createRemixStub(routes: RouteObject[]) { // Setup request handler to handle requests to the mock routes let { dataRoutes, queryRoute } = createStaticHandler(routes); return function RemixStub({ @@ -110,7 +123,7 @@ export function createRemixStub(routes: AgnosticRouteObject[]) { } function createRemixContext( - routes: AgnosticRouteObject[], + routes: RouteObject[], currentLocation: Location, initialLoaderData?: RouteData, initialActionData?: RouteData @@ -136,7 +149,7 @@ function createRemixContext( }; } -function createManifest(routes: AgnosticRouteObject[]): AssetsManifest { +function createManifest(routes: RouteObject[]): AssetsManifest { return { routes: createRouteManifest(routes), entry: { imports: [], module: "" }, @@ -146,7 +159,7 @@ function createManifest(routes: AgnosticRouteObject[]): AssetsManifest { } function createRouteManifest( - routes: AgnosticRouteObject[], + routes: RouteObject[], manifest?: RouteManifest, parentId?: string ): RouteManifest { @@ -160,7 +173,7 @@ function createRouteManifest( } function createRouteModules( - routes: AgnosticRouteObject[], + routes: RouteObject[], routeModules?: RouteModules ): RouteModules { return routes.reduce((modules, route) => { @@ -168,14 +181,9 @@ function createRouteModules( createRouteModules(route.children, modules); } - if (typeof route.id === "undefined") { - throw new Error("Route ID must be defined"); - } - - modules[route.id] = { + modules[route.id!] = { CatchBoundary: undefined, ErrorBoundary: undefined, - // @ts-ignore default: () => <>{route.element}, handle: route.handle, links: undefined, @@ -203,7 +211,7 @@ function monkeyPatchFetch( // if we have matches, send the request to mock routes via @remix-run/router rather than the normal // @remix-run/server-runtime so that stubs can also be used in browser environments. let matches = matchRoutes(dataRoutes, url); - if (matches && matchRoutes.length > 0) { + if (matches && matches.length > 0) { let response = await queryRoute(request); if (response instanceof Response) { @@ -217,15 +225,11 @@ function monkeyPatchFetch( return originalFetch(request, init); }; - if (typeof global !== "undefined") { - global.fetch = fetchPatch; - } else { - window.fetch = fetchPatch; - } + globalThis.fetch = fetchPatch; } function convertToEntryRoute( - route: AgnosticRouteObject, + route: RouteObject, parentId?: string ): EntryRoute { return { @@ -243,7 +247,7 @@ function convertToEntryRoute( } function convertToEntryRouteMatch( - routes: AgnosticRouteMatch[] + routes: AgnosticRouteMatch[] ) { return routes.map((match) => { return { @@ -257,7 +261,7 @@ function convertToEntryRouteMatch( // Converts route data from a path based index to a route id index value. // e.g. { "/post/:postId": post } to { "0": post } function convertRouteData( - routes: AgnosticRouteObject[], + routes: RouteObject[], initialRouteData?: RouteData, routeData: RouteData = {} ): RouteData | undefined { @@ -273,11 +277,7 @@ function convertRouteData( // Let '/' refer to the root routes data (routePath === "/" && route.id === "0" && !route.path) ) { - if (typeof route.id === "undefined") { - throw new Error("Route ID must be defined"); - } - - data[route.id] = initialRouteData[routePath]; + data[route.id!] = initialRouteData[routePath]; } }); return data; From 1edd2bf29072d5049d6c1f4c249e4e3b9dbaff95 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 15 Nov 2022 19:46:51 -0500 Subject: [PATCH 19/36] chore: add "future" key to context Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index a12bd365ad8..3cd6150bccc 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -139,12 +139,13 @@ function createRemixContext( catchBoundaryRouteId: null, renderBoundaryRouteId: null, loaderBoundaryRouteId: null, - error: undefined, - catch: undefined, + }, + future: { + v2_meta: false, }, matches: convertToEntryRouteMatch(matches), routeData: initialLoaderData || [], - manifest: manifest, + manifest, routeModules: createRouteModules(routes), }; } From ec217ecbf50acb563fcbb64a06cbe31efa669627 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 15 Nov 2022 19:47:02 -0500 Subject: [PATCH 20/36] chore: convert routes Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 3cd6150bccc..00dd8f73884 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -97,12 +97,12 @@ export function createRemixStub(routes: RouteObject[]) { React.useLayoutEffect(() => history.listen(dispatch), [history]); // Convert path based ids in user supplied initial loader/action data to data route ids - let loaderData = convertRouteData(dataRoutes, initialLoaderData); - let actionData = convertRouteData(dataRoutes, initialActionData); + let loaderData = convertRouteData(routes, initialLoaderData); + let actionData = convertRouteData(routes, initialActionData); // Create mock remix context let remixContext = createRemixContext( - dataRoutes, + routes, state.location, loaderData, actionData From e02e1fedf834ad0c19cd93556231835e6cf8403a Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Thu, 17 Nov 2022 12:41:01 -0500 Subject: [PATCH 21/36] Revert: chore: convert routes This reverts commit ec217ecbf50acb563fcbb64a06cbe31efa669627. Signed-off-by: Logan McAnsh --- packages/remix-server-runtime/index.ts | 17 ++++++----- packages/remix-testing/create-remix-stub.tsx | 32 ++++++++++---------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/packages/remix-server-runtime/index.ts b/packages/remix-server-runtime/index.ts index bf8c7b16c52..b3bc9206e30 100644 --- a/packages/remix-server-runtime/index.ts +++ b/packages/remix-server-runtime/index.ts @@ -8,8 +8,8 @@ export { json, redirect } from "./responses"; export { createRequestHandler } from "./server"; export { createSession, - isSession, createSessionStorageFactory, + isSession, } from "./sessions"; export { createCookieSessionStorageFactory } from "./sessions/cookieStorage"; export { createMemorySessionStorageFactory } from "./sessions/memoryStorage"; @@ -71,23 +71,24 @@ export type { SignFunction, TypedResponse, UnsignFunction, - UploadHandlerPart, UploadHandler, + UploadHandlerPart, } from "./reexport"; export type { - MemoryHistory, - InitialEntry, - StaticHandler, - Location, - AgnosticRouteObject, + AgnosticDataRouteObject, AgnosticIndexRouteObject, AgnosticNonIndexRouteObject, + AgnosticRouteObject, + InitialEntry, + Location, + MemoryHistory, + StaticHandler, } from "./router"; export { createMemoryHistory, - unstable_createStaticHandler, matchRoutes, + unstable_createStaticHandler, } from "./router"; export type { Update } from "./router/history"; export type { AgnosticRouteMatch } from "./router/utils"; diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 00dd8f73884..77222e3d90f 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -17,6 +17,7 @@ import type { MemoryHistory, StaticHandler, Update, + AgnosticDataRouteObject, } from "@remix-run/server-runtime"; import { createMemoryHistory, @@ -72,7 +73,7 @@ export function createRemixStub(routes: RouteObject[]) { // Setup request handler to handle requests to the mock routes let { dataRoutes, queryRoute } = createStaticHandler(routes); return function RemixStub({ - initialEntries = ["/"], + initialEntries, initialLoaderData = {}, initialActionData, initialIndex, @@ -86,23 +87,21 @@ export function createRemixStub(routes: RouteObject[]) { } let history = historyRef.current; + let [state, dispatch] = React.useReducer( - (_: Update, update: Update) => update, - { - action: history.action, - location: history.location, - } + (_current: Update, update: Update) => update, + { action: history.action, location: history.location } ); React.useLayoutEffect(() => history.listen(dispatch), [history]); // Convert path based ids in user supplied initial loader/action data to data route ids - let loaderData = convertRouteData(routes, initialLoaderData); - let actionData = convertRouteData(routes, initialActionData); + let loaderData = convertRouteData(dataRoutes, initialLoaderData); + let actionData = convertRouteData(dataRoutes, initialActionData); // Create mock remix context let remixContext = createRemixContext( - routes, + dataRoutes, state.location, loaderData, actionData @@ -123,7 +122,7 @@ export function createRemixStub(routes: RouteObject[]) { } function createRemixContext( - routes: RouteObject[], + routes: AgnosticDataRouteObject[], currentLocation: Location, initialLoaderData?: RouteData, initialActionData?: RouteData @@ -150,7 +149,7 @@ function createRemixContext( }; } -function createManifest(routes: RouteObject[]): AssetsManifest { +function createManifest(routes: AgnosticDataRouteObject[]): AssetsManifest { return { routes: createRouteManifest(routes), entry: { imports: [], module: "" }, @@ -160,7 +159,7 @@ function createManifest(routes: RouteObject[]): AssetsManifest { } function createRouteManifest( - routes: RouteObject[], + routes: AgnosticDataRouteObject[], manifest?: RouteManifest, parentId?: string ): RouteManifest { @@ -174,7 +173,7 @@ function createRouteManifest( } function createRouteModules( - routes: RouteObject[], + routes: AgnosticDataRouteObject[], routeModules?: RouteModules ): RouteModules { return routes.reduce((modules, route) => { @@ -185,6 +184,7 @@ function createRouteModules( modules[route.id!] = { CatchBoundary: undefined, ErrorBoundary: undefined, + // @ts-expect-error - types are still `agnostic` here default: () => <>{route.element}, handle: route.handle, links: undefined, @@ -230,7 +230,7 @@ function monkeyPatchFetch( } function convertToEntryRoute( - route: RouteObject, + route: AgnosticDataRouteObject, parentId?: string ): EntryRoute { return { @@ -248,7 +248,7 @@ function convertToEntryRoute( } function convertToEntryRouteMatch( - routes: AgnosticRouteMatch[] + routes: AgnosticRouteMatch[] ) { return routes.map((match) => { return { @@ -262,7 +262,7 @@ function convertToEntryRouteMatch( // Converts route data from a path based index to a route id index value. // e.g. { "/post/:postId": post } to { "0": post } function convertRouteData( - routes: RouteObject[], + routes: AgnosticDataRouteObject[], initialRouteData?: RouteData, routeData: RouteData = {} ): RouteData | undefined { From b262e200514c33bf7649d78dc4e4f68edb7ccc7c Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 22 Nov 2022 11:02:34 -0500 Subject: [PATCH 22/36] chore: allow setting remix config "future" Signed-off-by: Logan McAnsh --- packages/remix-react/components.tsx | 3 +-- packages/remix-testing/create-remix-stub.tsx | 26 +++++++++++++------- packages/remix-testing/package.json | 6 ++--- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/packages/remix-react/components.tsx b/packages/remix-react/components.tsx index ced5b54c778..139a462ffe5 100644 --- a/packages/remix-react/components.tsx +++ b/packages/remix-react/components.tsx @@ -1245,8 +1245,7 @@ export function useSubmitImpl(key?: string): SubmitFunction { ); } - let { protocol, host } = window.location; - let url = new URL(action, `${protocol}//${host}`); + let url = new URL(action, window.location.origin); if (method.toLowerCase() === "get") { // Start with a fresh set of params and wipe out the old params to diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 77222e3d90f..8c151378481 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -9,6 +9,7 @@ import type { } from "@remix-run/react"; import { RemixEntry } from "@remix-run/react"; import type { + AgnosticDataRouteObject, AgnosticIndexRouteObject, AgnosticNonIndexRouteObject, AgnosticRouteMatch, @@ -17,7 +18,6 @@ import type { MemoryHistory, StaticHandler, Update, - AgnosticDataRouteObject, } from "@remix-run/server-runtime"; import { createMemoryHistory, @@ -69,7 +69,12 @@ type NonIndexRouteObject = AgnosticNonIndexRouteObject & { type RouteObject = IndexRouteObject | NonIndexRouteObject; -export function createRemixStub(routes: RouteObject[]) { +type RemixConfigFuture = Partial; + +export function createRemixStub( + routes: RouteObject[], + remixConfigFuture?: RemixConfigFuture +) { // Setup request handler to handle requests to the mock routes let { dataRoutes, queryRoute } = createStaticHandler(routes); return function RemixStub({ @@ -81,19 +86,19 @@ export function createRemixStub(routes: RouteObject[]) { let historyRef = React.useRef(); if (historyRef.current == null) { historyRef.current = createMemoryHistory({ - initialEntries: initialEntries, - initialIndex: initialIndex, + initialEntries, + initialIndex, }); } let history = historyRef.current; let [state, dispatch] = React.useReducer( - (_current: Update, update: Update) => update, + (_: Update, update: Update) => update, { action: history.action, location: history.location } ); - React.useLayoutEffect(() => history.listen(dispatch), [history]); + React.useLayoutEffect( // Convert path based ids in user supplied initial loader/action data to data route ids let loaderData = convertRouteData(dataRoutes, initialLoaderData); @@ -104,7 +109,8 @@ export function createRemixStub(routes: RouteObject[]) { dataRoutes, state.location, loaderData, - actionData + actionData, + remixConfigFuture ); // Patch fetch so that mock routes can handle action/loader requests @@ -125,7 +131,8 @@ function createRemixContext( routes: AgnosticDataRouteObject[], currentLocation: Location, initialLoaderData?: RouteData, - initialActionData?: RouteData + initialActionData?: RouteData, + future?: RemixConfigFuture ): EntryContext { let manifest = createManifest(routes); let matches = matchRoutes(routes, currentLocation) || []; @@ -141,9 +148,10 @@ function createRemixContext( }, future: { v2_meta: false, + ...future, }, matches: convertToEntryRouteMatch(matches), - routeData: initialLoaderData || [], + routeData: initialLoaderData || {}, manifest, routeModules: createRouteModules(routes), }; diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 0b794a23e80..e8cda85d560 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/testing", - "version": "1.7.5", + "version": "1.7.6", "description": "Testing utilities for Remix apps", "homepage": "https://remix.run", "bugs": { @@ -16,8 +16,8 @@ "typings": "./dist/index.d.ts", "module": "./dist/esm/index.js", "dependencies": { - "@remix-run/react": "1.7.5", - "@remix-run/server-runtime": "1.7.5", + "@remix-run/react": "1.7.6", + "@remix-run/server-runtime": "1.7.6", "react": "^18.2.0", "react-dom": "^18.2.0" }, From 5ec3e58f139101b209270225cd0ad0f37d71ac60 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 22 Nov 2022 11:03:01 -0500 Subject: [PATCH 23/36] fix: enable v5Compat for createMemoryHistory so listener is called Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 8c151378481..23ea3444061 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -88,6 +88,7 @@ export function createRemixStub( historyRef.current = createMemoryHistory({ initialEntries, initialIndex, + v5Compat: true, }); } @@ -99,6 +100,13 @@ export function createRemixStub( ); React.useLayoutEffect( + () => + history.listen((listener) => { + console.log({ listener }); + return dispatch(listener); + }), + [history] + ); // Convert path based ids in user supplied initial loader/action data to data route ids let loaderData = convertRouteData(dataRoutes, initialLoaderData); @@ -193,7 +201,7 @@ function createRouteModules( CatchBoundary: undefined, ErrorBoundary: undefined, // @ts-expect-error - types are still `agnostic` here - default: () => <>{route.element}, + default: () => route.element, handle: route.handle, links: undefined, meta: undefined, @@ -269,6 +277,7 @@ function convertToEntryRouteMatch( // Converts route data from a path based index to a route id index value. // e.g. { "/post/:postId": post } to { "0": post } +// TODO: may not need function convertRouteData( routes: AgnosticDataRouteObject[], initialRouteData?: RouteData, From e6e1c94e7eebcfe9c42b2386776985e9e994a010 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 22 Nov 2022 11:09:40 -0500 Subject: [PATCH 24/36] chore: remove log Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 23ea3444061..34f9d2f170c 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -99,14 +99,7 @@ export function createRemixStub( { action: history.action, location: history.location } ); - React.useLayoutEffect( - () => - history.listen((listener) => { - console.log({ listener }); - return dispatch(listener); - }), - [history] - ); + React.useLayoutEffect(() => history.listen(dispatch), [history]); // Convert path based ids in user supplied initial loader/action data to data route ids let loaderData = convertRouteData(dataRoutes, initialLoaderData); From 9748dbc18da997e04ce65c1ce82895ccb0c107bd Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 22 Nov 2022 14:16:40 -0500 Subject: [PATCH 25/36] chore: mark unstable Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 34f9d2f170c..484119943c4 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -71,7 +71,7 @@ type RouteObject = IndexRouteObject | NonIndexRouteObject; type RemixConfigFuture = Partial; -export function createRemixStub( +export function unstable_createRemixStub( routes: RouteObject[], remixConfigFuture?: RemixConfigFuture ) { From b22c8d6804cc66ab8328ca2d0dd94f78cafde932 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 22 Nov 2022 14:26:42 -0500 Subject: [PATCH 26/36] chore: mark unstable Signed-off-by: Logan McAnsh --- packages/remix-testing/index.ts | 2 +- yalc.sh | 19 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-) delete mode 100755 yalc.sh diff --git a/packages/remix-testing/index.ts b/packages/remix-testing/index.ts index c31905b9157..a1028e7389f 100644 --- a/packages/remix-testing/index.ts +++ b/packages/remix-testing/index.ts @@ -1 +1 @@ -export { createRemixStub } from "./create-remix-stub"; +export { unstable_createRemixStub } from "./create-remix-stub"; diff --git a/yalc.sh b/yalc.sh deleted file mode 100755 index 48e2ad2151c..00000000000 --- a/yalc.sh +++ /dev/null @@ -1,19 +0,0 @@ -packages=( -'architect' -'cloudflare' -'cloudflare-pages' -'cloudflare-workers' -'deno' -'dev' -'express' -'netlify' -'node' -'react' -'serve' -'server-runtime' -'testing' -'vercel' -) -for i in "${packages[@]}"; do - yalc push ./build/node_modules/@remix-run/$i -done From 11025b93234000612695b544f8aedad32744846b Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 22 Nov 2022 14:27:19 -0500 Subject: [PATCH 27/36] chore: revert Signed-off-by: Logan McAnsh --- packages/remix-react/components.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/remix-react/components.tsx b/packages/remix-react/components.tsx index 139a462ffe5..ced5b54c778 100644 --- a/packages/remix-react/components.tsx +++ b/packages/remix-react/components.tsx @@ -1245,7 +1245,8 @@ export function useSubmitImpl(key?: string): SubmitFunction { ); } - let url = new URL(action, window.location.origin); + let { protocol, host } = window.location; + let url = new URL(action, `${protocol}//${host}`); if (method.toLowerCase() === "get") { // Start with a fresh set of params and wipe out the old params to From 2201c4739eb20673961043f2f6082d71b7ce2721 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 29 Nov 2022 10:21:54 -0500 Subject: [PATCH 28/36] chore: make element on RouteObject optional Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 484119943c4..139be8bb3f2 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -58,12 +58,12 @@ type RemixStubOptions = { }; type IndexRouteObject = AgnosticIndexRouteObject & { - element: React.ReactNode; + element?: React.ReactNode; children?: undefined; }; type NonIndexRouteObject = AgnosticNonIndexRouteObject & { - element: React.ReactNode; + element?: React.ReactNode; children?: RouteObject[]; }; @@ -71,7 +71,7 @@ type RouteObject = IndexRouteObject | NonIndexRouteObject; type RemixConfigFuture = Partial; -export function unstable_createRemixStub( +export function createRemixStub( routes: RouteObject[], remixConfigFuture?: RemixConfigFuture ) { From 1e5d58e16c69a49a7e85d5ddb05986df63c764ed Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 29 Nov 2022 10:22:02 -0500 Subject: [PATCH 29/36] chore: update export Signed-off-by: Logan McAnsh --- packages/remix-testing/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remix-testing/index.ts b/packages/remix-testing/index.ts index a1028e7389f..8b0aed3c2eb 100644 --- a/packages/remix-testing/index.ts +++ b/packages/remix-testing/index.ts @@ -1 +1 @@ -export { unstable_createRemixStub } from "./create-remix-stub"; +export { createRemixStub as unstable_createRemixStub } from "./create-remix-stub"; From 7814544b906bcc9c5abe7eaae00ea214eeb46945 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 29 Nov 2022 10:23:03 -0500 Subject: [PATCH 30/36] chore: rename custom RouteObject to StubRouteObject Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 139be8bb3f2..0a1bbe7ddfa 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -64,15 +64,16 @@ type IndexRouteObject = AgnosticIndexRouteObject & { type NonIndexRouteObject = AgnosticNonIndexRouteObject & { element?: React.ReactNode; - children?: RouteObject[]; + children?: StubRouteObject[]; }; -type RouteObject = IndexRouteObject | NonIndexRouteObject; +// TODO: once Remix is on RR@6.4 we can just use the native type +type StubRouteObject = IndexRouteObject | NonIndexRouteObject; type RemixConfigFuture = Partial; export function createRemixStub( - routes: RouteObject[], + routes: StubRouteObject[], remixConfigFuture?: RemixConfigFuture ) { // Setup request handler to handle requests to the mock routes From 99b55665df0199aefeaee2c8b011ccfb1da3ff2d Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 29 Nov 2022 11:26:59 -0500 Subject: [PATCH 31/36] chore: update comment Signed-off-by: Logan McAnsh --- packages/remix-testing/create-remix-stub.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index 0a1bbe7ddfa..cd65ff9e22b 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -31,19 +31,19 @@ type RemixStubOptions = { * The initial entries in the history stack. This allows you to start a test with * multiple locations already in the history stack (for testing a back navigation, etc.) * The test will default to the last entry in initialEntries if no initialIndex is provided. - * e.g. initialEntries-(["/home", "/about", "/contact"]} + * e.g. initialEntries={["/home", "/about", "/contact"]} */ initialEntries?: InitialEntry[]; /** * Used to set the route's initial loader data. - * e.g. initialLoaderData={("/contact": {locale: "en-US" }} + * e.g. initialLoaderData={{ "/contact": { locale: "en-US" } }} */ initialLoaderData?: RouteData; /** * Used to set the route's initial action data. - * e.g. initialActionData={("/login": { errors: { email: "invalid email" } }} + * e.g. initialActionData={{ "/login": { errors: { email: "invalid email" } }} */ initialActionData?: RouteData; @@ -57,18 +57,18 @@ type RemixStubOptions = { initialIndex?: number; }; -type IndexRouteObject = AgnosticIndexRouteObject & { +type IndexStubRouteObject = AgnosticIndexRouteObject & { element?: React.ReactNode; children?: undefined; }; -type NonIndexRouteObject = AgnosticNonIndexRouteObject & { +type NonIndexStubRouteObject = AgnosticNonIndexRouteObject & { element?: React.ReactNode; children?: StubRouteObject[]; }; // TODO: once Remix is on RR@6.4 we can just use the native type -type StubRouteObject = IndexRouteObject | NonIndexRouteObject; +type StubRouteObject = IndexStubRouteObject | NonIndexStubRouteObject; type RemixConfigFuture = Partial; From fd9e36aa421ad48e59d260e7c8752133dd865cbe Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 29 Nov 2022 11:38:11 -0500 Subject: [PATCH 32/36] chore: use path.join in rollup config Signed-off-by: Logan McAnsh --- packages/remix-testing/rollup.config.js | 44 +++++++++++-------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/packages/remix-testing/rollup.config.js b/packages/remix-testing/rollup.config.js index abbb750809b..3085aa450e6 100644 --- a/packages/remix-testing/rollup.config.js +++ b/packages/remix-testing/rollup.config.js @@ -1,4 +1,4 @@ -const path = require("path"); +const path = require("node:path"); const babel = require("@rollup/plugin-babel").default; const nodeResolve = require("@rollup/plugin-node-resolve").default; const copy = require("rollup-plugin-copy"); @@ -18,14 +18,22 @@ module.exports = function rollup() { let outputDir = getOutputDir(packageName); let outputDist = path.join(outputDir, "dist"); - // This CommonJS build of remix-testing is for node; both for use in running our - // server and for 3rd party tools that work with node. + let sharedPlugins = [ + babel({ + babelHelpers: "bundled", + exclude: /node_modules/, + extensions: [".ts", ".tsx"], + }), + nodeResolve({ extensions: [".ts", ".tsx"] }), + copyToPlaygrounds(), + ] + /** @type {import("rollup").RollupOptions} */ let remixTestingCJS = { external(id) { return isBareModuleId(id); }, - input: `${sourceDir}/index.ts`, + input: path.join(sourceDir, 'index.ts'), output: { banner: createBanner(packageName, version), dir: outputDist, @@ -34,21 +42,15 @@ module.exports = function rollup() { exports: "auto", }, plugins: [ - babel({ - babelHelpers: "bundled", - exclude: /node_modules/, - extensions: [".ts", ".tsx"], - }), - nodeResolve({ extensions: [".ts", ".tsx"] }), + ...sharedPlugins, + magicExportsPlugin({ packageName, version }), copy({ targets: [ { src: "LICENSE.md", dest: [outputDir, sourceDir] }, - { src: `${sourceDir}/package.json`, dest: outputDir }, - { src: `${sourceDir}/README.md`, dest: outputDir }, + { src: path.join(sourceDir, 'package.json'), dest: outputDir }, + { src: path.join(sourceDir, 'README.md'), dest: outputDir }, ], }), - magicExportsPlugin({ packageName, version }), - copyToPlaygrounds(), ], }; @@ -58,21 +60,15 @@ module.exports = function rollup() { external(id) { return isBareModuleId(id); }, - input: `${sourceDir}/index.ts`, + input: path.join(sourceDir, 'index.ts'), output: { - banner: createBanner("@remix-run/testing", version), - dir: `${outputDist}/esm`, + banner: createBanner(packageName, version), + dir: path.join(outputDist, 'esm'), format: "esm", preserveModules: true, }, plugins: [ - babel({ - babelHelpers: "bundled", - exclude: /node_modules/, - extensions: [".ts", ".tsx"], - }), - nodeResolve({ extensions: [".ts", ".tsx"] }), - copyToPlaygrounds(), + ...sharedPlugins, ], }; From a5698409827d06438dd40ef89d0c80bb0c73f20a Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 29 Nov 2022 14:35:03 -0500 Subject: [PATCH 33/36] Create poor-shrimps-boil.md --- .changeset/poor-shrimps-boil.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/poor-shrimps-boil.md diff --git a/.changeset/poor-shrimps-boil.md b/.changeset/poor-shrimps-boil.md new file mode 100644 index 00000000000..872982dce1b --- /dev/null +++ b/.changeset/poor-shrimps-boil.md @@ -0,0 +1,9 @@ +--- +"remix": patch +"@remix-run/react": patch +"@remix-run/serve": patch +"@remix-run/server-runtime": patch +"@remix-run/testing": patch +--- + +adds a new testing package to allow easier testing of components using Remix specific apis like useFetcher, useActionData, etc. From 21852933556cb1b5a3c39e81ff7e193afb33f37c Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 29 Nov 2022 14:56:26 -0500 Subject: [PATCH 34/36] feat: add installGlobals that adds jsdom's FormData to global Signed-off-by: Logan McAnsh --- packages/remix-testing/index.ts | 1 + packages/remix-testing/install-globals.ts | 16 ++++++++++++++++ packages/remix-testing/package.json | 1 + packages/remix-testing/rollup.config.js | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 packages/remix-testing/install-globals.ts diff --git a/packages/remix-testing/index.ts b/packages/remix-testing/index.ts index 8b0aed3c2eb..74c50eac4ec 100644 --- a/packages/remix-testing/index.ts +++ b/packages/remix-testing/index.ts @@ -1 +1,2 @@ export { createRemixStub as unstable_createRemixStub } from "./create-remix-stub"; +export { installGlobals as unstable_installGlobals } from './install-globals' \ No newline at end of file diff --git a/packages/remix-testing/install-globals.ts b/packages/remix-testing/install-globals.ts new file mode 100644 index 00000000000..fafce6f62c4 --- /dev/null +++ b/packages/remix-testing/install-globals.ts @@ -0,0 +1,16 @@ +import { installGlobals as installNodeGlobals } from "@remix-run/node"; + +async function loadModule(modulePath: string) { + try { + return await import(modulePath) + } catch { + throw new Error(`Unable to import module ${modulePath}`) + } +} + +export async function installGlobals() { + installNodeGlobals() + let JSDOM = await loadModule('jsdom'); + let jsdom = new JSDOM.JSDOM(``); + globalThis.FormData = jsdom.window.FormData; +} \ No newline at end of file diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index e8cda85d560..75d5981bf91 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -16,6 +16,7 @@ "typings": "./dist/index.d.ts", "module": "./dist/esm/index.js", "dependencies": { + "@remix-run/node": "1.7.6", "@remix-run/react": "1.7.6", "@remix-run/server-runtime": "1.7.6", "react": "^18.2.0", diff --git a/packages/remix-testing/rollup.config.js b/packages/remix-testing/rollup.config.js index 3085aa450e6..606d189f7de 100644 --- a/packages/remix-testing/rollup.config.js +++ b/packages/remix-testing/rollup.config.js @@ -14,7 +14,7 @@ const { name: packageName, version } = require("./package.json"); /** @returns {import("rollup").RollupOptions[]} */ module.exports = function rollup() { - let sourceDir = "packages/remix-testing"; + let sourceDir = path.join("packages", "remix-testing") let outputDir = getOutputDir(packageName); let outputDist = path.join(outputDir, "dist"); From 657b0ac4296e5848d1f1f909dd3f1d9855e53e40 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 29 Nov 2022 15:29:17 -0500 Subject: [PATCH 35/36] chore: add happy-dom as a possible framework, but throw immediately Signed-off-by: Logan McAnsh --- packages/remix-testing/index.ts | 2 +- packages/remix-testing/install-globals.ts | 24 +- packages/remix-testing/package.json | 3 + packages/remix-testing/rollup.config.js | 18 +- yarn.lock | 392 +++++++++++++++++++++- 5 files changed, 411 insertions(+), 28 deletions(-) diff --git a/packages/remix-testing/index.ts b/packages/remix-testing/index.ts index 74c50eac4ec..5eab1dda9a2 100644 --- a/packages/remix-testing/index.ts +++ b/packages/remix-testing/index.ts @@ -1,2 +1,2 @@ export { createRemixStub as unstable_createRemixStub } from "./create-remix-stub"; -export { installGlobals as unstable_installGlobals } from './install-globals' \ No newline at end of file +export { installGlobals as unstable_installGlobals } from "./install-globals"; diff --git a/packages/remix-testing/install-globals.ts b/packages/remix-testing/install-globals.ts index fafce6f62c4..4069cf2e12d 100644 --- a/packages/remix-testing/install-globals.ts +++ b/packages/remix-testing/install-globals.ts @@ -1,16 +1,20 @@ import { installGlobals as installNodeGlobals } from "@remix-run/node"; -async function loadModule(modulePath: string) { - try { - return await import(modulePath) - } catch { - throw new Error(`Unable to import module ${modulePath}`) +export async function installGlobals(framework: 'jsdom' | 'happy-dom') { + installNodeGlobals(); + + if (framework === 'happy-dom') { + throw new Error( + `happy-dom is not currently supported as it doesn't have a FormData implementation` + ); } -} -export async function installGlobals() { - installNodeGlobals() - let JSDOM = await loadModule('jsdom'); + let JSDOM = await import("jsdom").catch(() => { + throw new Error( + `Could not locate jsdom. Please verify you have it installed.` + ); + }); + let jsdom = new JSDOM.JSDOM(``); globalThis.FormData = jsdom.window.FormData; -} \ No newline at end of file +} diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 75d5981bf91..cb98a137b47 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -23,9 +23,12 @@ "react-dom": "^18.2.0" }, "devDependencies": { + "@types/jsdom": "^20.0.1", "@types/node": "^18.11.9", "@types/react": "^18.0.24", "@types/react-dom": "^18.0.8", + "happy-dom": "^7.7.0", + "jsdom": "^20.0.3", "typescript": "^4.8.4" }, "engines": { diff --git a/packages/remix-testing/rollup.config.js b/packages/remix-testing/rollup.config.js index 606d189f7de..46a9d2b14f3 100644 --- a/packages/remix-testing/rollup.config.js +++ b/packages/remix-testing/rollup.config.js @@ -14,7 +14,7 @@ const { name: packageName, version } = require("./package.json"); /** @returns {import("rollup").RollupOptions[]} */ module.exports = function rollup() { - let sourceDir = path.join("packages", "remix-testing") + let sourceDir = path.join("packages", "remix-testing"); let outputDir = getOutputDir(packageName); let outputDist = path.join(outputDir, "dist"); @@ -26,14 +26,14 @@ module.exports = function rollup() { }), nodeResolve({ extensions: [".ts", ".tsx"] }), copyToPlaygrounds(), - ] + ]; /** @type {import("rollup").RollupOptions} */ let remixTestingCJS = { external(id) { return isBareModuleId(id); }, - input: path.join(sourceDir, 'index.ts'), + input: path.join(sourceDir, "index.ts"), output: { banner: createBanner(packageName, version), dir: outputDist, @@ -47,8 +47,8 @@ module.exports = function rollup() { copy({ targets: [ { src: "LICENSE.md", dest: [outputDir, sourceDir] }, - { src: path.join(sourceDir, 'package.json'), dest: outputDir }, - { src: path.join(sourceDir, 'README.md'), dest: outputDir }, + { src: path.join(sourceDir, "package.json"), dest: outputDir }, + { src: path.join(sourceDir, "README.md"), dest: outputDir }, ], }), ], @@ -60,16 +60,14 @@ module.exports = function rollup() { external(id) { return isBareModuleId(id); }, - input: path.join(sourceDir, 'index.ts'), + input: path.join(sourceDir, "index.ts"), output: { banner: createBanner(packageName, version), - dir: path.join(outputDist, 'esm'), + dir: path.join(outputDist, "esm"), format: "esm", preserveModules: true, }, - plugins: [ - ...sharedPlugins, - ], + plugins: [...sharedPlugins], }; return [remixTestingCJS, remixTestingESM]; diff --git a/yarn.lock b/yarn.lock index 24289b5243f..09396c65a3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2453,6 +2453,11 @@ resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + "@ts-morph/common@~0.11.0": version "0.11.1" resolved "https://registry.npmjs.org/@ts-morph/common/-/common-0.11.1.tgz" @@ -2561,6 +2566,13 @@ dependencies: "@types/express" "*" +"@types/concat-stream@^1.6.0": + version "1.6.1" + resolved "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz#24bcfc101ecf68e886aaedce60dfd74b632a1b74" + integrity sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA== + dependencies: + "@types/node" "*" + "@types/connect@*": version "3.4.35" resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" @@ -2646,6 +2658,13 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/form-data@0.0.33": + version "0.0.33" + resolved "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8" + integrity sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw== + dependencies: + "@types/node" "*" + "@types/fs-extra@^8.0.1": version "8.1.2" resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz" @@ -2742,6 +2761,15 @@ ast-types "^0.14.1" recast "^0.20.3" +"@types/jsdom@^20.0.1": + version "20.0.1" + resolved "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz#07c14bc19bd2f918c1929541cdaacae894744808" + integrity sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ== + dependencies: + "@types/node" "*" + "@types/tough-cookie" "*" + parse5 "^7.0.0" + "@types/jsesc@^3.0.1": version "3.0.1" resolved "https://registry.npmjs.org/@types/jsesc/-/jsesc-3.0.1.tgz" @@ -2852,6 +2880,11 @@ resolved "https://registry.npmjs.org/@types/node/-/node-16.10.1.tgz" integrity sha512-4/Z9DMPKFexZj/Gn3LylFgamNKHm4K3QDi0gz9B26Uk0c8izYf97B5fxfpspMNkWlFupblKM/nV8+NA9Ffvr+w== +"@types/node@^10.0.3": + version "10.17.60" + resolved "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" + integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== + "@types/node@^12.7.1": version "12.20.55" resolved "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz" @@ -2867,6 +2900,11 @@ resolved "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== +"@types/node@^8.0.0": + version "8.10.66" + resolved "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" + integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw== + "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz" @@ -2887,7 +2925,7 @@ resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz" integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== -"@types/qs@*": +"@types/qs@*", "@types/qs@^6.2.31": version "6.9.7" resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== @@ -3075,6 +3113,11 @@ dependencies: "@types/node" "*" +"@types/tough-cookie@*": + version "4.0.2" + resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz#6286b4c7228d58ab7866d19716f3696e03a09397" + integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw== + "@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2": version "2.0.6" resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz" @@ -3294,6 +3337,11 @@ abab@^2.0.3, abab@^2.0.5: resolved "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== +abab@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" @@ -3322,6 +3370,14 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" +acorn-globals@^7.0.0: + version "7.0.1" + resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" + integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q== + dependencies: + acorn "^8.1.0" + acorn-walk "^8.0.2" + acorn-jsx@^5.0.0, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" @@ -3332,7 +3388,7 @@ acorn-walk@^7.1.1: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn-walk@^8.2.0: +acorn-walk@^8.0.2, acorn-walk@^8.2.0: version "8.2.0" resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== @@ -3347,6 +3403,11 @@ acorn@^8.0.0, acorn@^8.7.0, acorn@^8.8.0: resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== +acorn@^8.1.0, acorn@^8.8.1: + version "8.8.1" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + acorn@^8.2.4: version "8.5.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz" @@ -3799,6 +3860,11 @@ arrify@^1.0.1: resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== +asap@~2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== + asn1@~0.2.3: version "0.2.6" resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz" @@ -4340,7 +4406,7 @@ caniuse-lite@^1.0.30001400: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001430.tgz" integrity sha512-IB1BXTZKPDVPM7cnV4iaKaHxckvdr/3xtctB3f7Hmenx3qYBhGtTZ//7EllK66aKXW98Lx0+7Yr0kxBtIt3tzg== -caseless@~0.12.0: +caseless@^0.12.0, caseless@~0.12.0: version "0.12.0" resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= @@ -4728,6 +4794,16 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +concat-stream@^1.6.0, concat-stream@^1.6.2: + version "1.6.2" + resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + concurrently@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/concurrently/-/concurrently-7.0.0.tgz" @@ -4882,6 +4958,11 @@ cssom@^0.4.4: resolved "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz" integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== +cssom@^0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" + integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== + cssom@~0.3.6: version "0.3.8" resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz" @@ -4998,6 +5079,15 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" +data-urls@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143" + integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ== + dependencies: + abab "^2.0.6" + whatwg-mimetype "^3.0.0" + whatwg-url "^11.0.0" + dataloader@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz" @@ -5067,6 +5157,11 @@ decimal.js@^10.2.1: resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz" integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== +decimal.js@^10.4.2: + version "10.4.2" + resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz#0341651d1d997d86065a2ce3a441fbd0d8e8b98e" + integrity sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz" @@ -5260,6 +5355,13 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" +domexception@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== + dependencies: + webidl-conversions "^7.0.0" + domhandler@^4.0.0, domhandler@^4.2.0: version "4.2.2" resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.2.2.tgz" @@ -5386,6 +5488,11 @@ entities@^2.0.0: resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== +entities@^4.4.0: + version "4.4.0" + resolved "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" + integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== + error-ex@^1.3.1: version "1.3.2" resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" @@ -6543,6 +6650,15 @@ forever-agent@~0.6.1: resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +form-data@^2.2.0: + version "2.5.1" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + form-data@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz" @@ -6552,6 +6668,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" @@ -6699,6 +6824,11 @@ get-package-type@^0.1.0: resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-port@^3.1.0: + version "3.2.0" + resolved "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + integrity sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg== + get-port@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz" @@ -6931,6 +7061,19 @@ gunzip-maybe@^1.4.2: pumpify "^1.3.3" through2 "^2.0.3" +happy-dom@^7.7.0: + version "7.7.0" + resolved "https://registry.npmjs.org/happy-dom/-/happy-dom-7.7.0.tgz#60de93fda57a4d563d6b37a777abfc6a9592182b" + integrity sha512-U10JXl5qSaHswXT5kyE7lvSDoyK48GyPGpe74qI9KT29frt1AlS+jnwy77RUJIknx+4b52DK1NllXTgHH8k20w== + dependencies: + css.escape "^1.5.1" + he "^1.2.0" + node-fetch "^2.x.x" + sync-request "^6.1.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + hard-rejection@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz" @@ -7043,6 +7186,11 @@ hast-util-whitespace@^2.0.0: resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz" integrity sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg== +he@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + headers-polyfill@^3.0.4: version "3.0.7" resolved "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.0.7.tgz" @@ -7067,6 +7215,13 @@ html-encoding-sniffer@^2.0.1: dependencies: whatwg-encoding "^1.0.5" +html-encoding-sniffer@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" + integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== + dependencies: + whatwg-encoding "^2.0.0" + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" @@ -7082,6 +7237,16 @@ htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" +http-basic@^8.1.1: + version "8.1.3" + resolved "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz#a7cabee7526869b9b710136970805b1004261bbf" + integrity sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw== + dependencies: + caseless "^0.12.0" + concat-stream "^1.6.2" + http-response-object "^3.0.1" + parse-cache-control "^1.0.1" + http-cache-semantics@^4.0.0: version "4.1.0" resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" @@ -7118,6 +7283,22 @@ http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: agent-base "6" debug "4" +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +http-response-object@^3.0.1: + version "3.0.2" + resolved "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz#7f435bb210454e4360d074ef1f989d5ea8aa9810" + integrity sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA== + dependencies: + "@types/node" "^10.0.3" + http-signature@~1.3.6: version "1.3.6" resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz" @@ -7140,7 +7321,7 @@ http2-wrapper@^1.0.0-beta.5.2: quick-lru "^5.1.1" resolve-alpn "^1.0.0" -https-proxy-agent@5: +https-proxy-agent@5, https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== @@ -7178,6 +7359,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@1.1.13, ieee754@^1.1.13, ieee754@^1.1.4: version "1.1.13" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz" @@ -8355,6 +8543,38 @@ jsdom@^16.6.0: ws "^7.4.6" xml-name-validator "^3.0.0" +jsdom@^20.0.3: + version "20.0.3" + resolved "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz#886a41ba1d4726f67a8858028c99489fed6ad4db" + integrity sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ== + dependencies: + abab "^2.0.6" + acorn "^8.8.1" + acorn-globals "^7.0.0" + cssom "^0.5.0" + cssstyle "^2.3.0" + data-urls "^3.0.2" + decimal.js "^10.4.2" + domexception "^4.0.0" + escodegen "^2.0.0" + form-data "^4.0.0" + html-encoding-sniffer "^3.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.1" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.2" + parse5 "^7.1.1" + saxes "^6.0.0" + symbol-tree "^3.2.4" + tough-cookie "^4.1.2" + w3c-xmlserializer "^4.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^11.0.0" + ws "^8.11.0" + xml-name-validator "^4.0.0" + jsesc@3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz" @@ -9778,7 +9998,7 @@ node-fetch@2.6.1: resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== -node-fetch@^2.5.0, node-fetch@^2.6.7: +node-fetch@^2.5.0, node-fetch@^2.6.7, node-fetch@^2.x.x: version "2.6.7" resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== @@ -9870,6 +10090,11 @@ nwsapi@^2.2.0: resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== +nwsapi@^2.2.2: + version "2.2.2" + resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" + integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== + object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" @@ -10162,6 +10387,11 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-cache-control@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e" + integrity sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg== + parse-entities@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz" @@ -10221,6 +10451,13 @@ parse5@6.0.1, parse5@^6.0.1: resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== +parse5@^7.0.0, parse5@^7.1.1: + version "7.1.2" + resolved "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + parseurl@^1.3.3, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" @@ -10491,6 +10728,13 @@ promise-inflight@^1.0.1: resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise@^8.0.0: + version "8.3.0" + resolved "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" + integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== + dependencies: + asap "~2.0.6" + prompt-actions@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/prompt-actions/-/prompt-actions-3.0.2.tgz" @@ -10669,6 +10913,13 @@ qs@6.9.7, qs@^6.9.4: resolved "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz" integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== +qs@^6.4.0: + version "6.11.0" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + qs@~6.5.2: version "6.5.3" resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" @@ -10679,6 +10930,11 @@ querystring@0.2.0: resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" @@ -10821,7 +11077,7 @@ readable-stream@1.1.x: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.0, readable-stream@~2.3.6: +readable-stream@^2.0.0, readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -11085,6 +11341,11 @@ requireindex@^1.2.0, requireindex@~1.2.0: resolved "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz" integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + resolve-alpn@^1.0.0: version "1.2.1" resolved "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz" @@ -11293,7 +11554,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -11310,6 +11571,13 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" +saxes@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" + integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA== + dependencies: + xmlchars "^2.2.0" + scheduler@^0.23.0: version "0.23.0" resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" @@ -12025,6 +12293,22 @@ symbol-tree@^3.2.4: resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +sync-request@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68" + integrity sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw== + dependencies: + http-response-object "^3.0.1" + sync-rpc "^1.2.1" + then-request "^6.0.0" + +sync-rpc@^1.2.1: + version "1.3.6" + resolved "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz#b2e8b2550a12ccbc71df8644810529deb68665a7" + integrity sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw== + dependencies: + get-port "^3.1.0" + synckit@^0.8.3: version "0.8.4" resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.4.tgz" @@ -12114,6 +12398,23 @@ text-table@^0.2.0: resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +then-request@^6.0.0: + version "6.0.2" + resolved "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz#ec18dd8b5ca43aaee5cb92f7e4c1630e950d4f0c" + integrity sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA== + dependencies: + "@types/concat-stream" "^1.6.0" + "@types/form-data" "0.0.33" + "@types/node" "^8.0.0" + "@types/qs" "^6.2.31" + caseless "~0.12.0" + concat-stream "^1.6.0" + form-data "^2.2.0" + http-basic "^8.1.1" + http-response-object "^3.0.1" + promise "^8.0.0" + qs "^6.4.0" + throat@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz" @@ -12252,6 +12553,16 @@ tough-cookie@^4.0.0: punycode "^2.1.1" universalify "^0.1.2" +tough-cookie@^4.1.2: + version "4.1.2" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" + integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" + tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" @@ -12267,6 +12578,13 @@ tr46@^2.1.0: dependencies: punycode "^2.1.1" +tr46@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" + integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== + dependencies: + punycode "^2.1.1" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" @@ -12451,6 +12769,11 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + typescript@4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz" @@ -12661,6 +12984,11 @@ universalify@^0.1.0, universalify@^0.1.2: resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + universalify@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" @@ -12704,6 +13032,14 @@ urix@^0.1.0: resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + url@0.10.3: version "0.10.3" resolved "https://registry.npmjs.org/url/-/url-0.10.3.tgz" @@ -12855,6 +13191,13 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" +w3c-xmlserializer@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073" + integrity sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw== + dependencies: + xml-name-validator "^4.0.0" + walker@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz" @@ -12903,6 +13246,11 @@ webidl-conversions@^6.1.0: resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz" integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz" @@ -12910,11 +13258,31 @@ whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" +whatwg-encoding@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== + dependencies: + iconv-lite "0.6.3" + whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== + +whatwg-url@^11.0.0: + version "11.0.0" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" + integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" + whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" @@ -13047,6 +13415,11 @@ ws@^7.4.5, ws@^7.4.6: resolved "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz" integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== +ws@^8.11.0: + version "8.11.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== + xdm@^2.0.0: version "2.0.6" resolved "https://registry.npmjs.org/xdm/-/xdm-2.0.6.tgz" @@ -13081,6 +13454,11 @@ xml-name-validator@^3.0.0: resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xml-name-validator@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" + integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== + xml2js@0.4.19: version "0.4.19" resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz" From 65bda9db800a3f112cc97329375baaf3d93069b1 Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 29 Nov 2022 15:29:30 -0500 Subject: [PATCH 36/36] chore: default to jsdom Signed-off-by: Logan McAnsh --- packages/remix-testing/install-globals.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remix-testing/install-globals.ts b/packages/remix-testing/install-globals.ts index 4069cf2e12d..4c5b318c804 100644 --- a/packages/remix-testing/install-globals.ts +++ b/packages/remix-testing/install-globals.ts @@ -1,6 +1,6 @@ import { installGlobals as installNodeGlobals } from "@remix-run/node"; -export async function installGlobals(framework: 'jsdom' | 'happy-dom') { +export async function installGlobals(framework: 'jsdom' | 'happy-dom' = 'jsdom') { installNodeGlobals(); if (framework === 'happy-dom') {