From 1b3d7f3c6642f859597b773dac6c407c2951a645 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Tue, 29 Mar 2022 08:30:13 +0100 Subject: [PATCH 01/12] feat: add Netlify Edge runtime and adapter fix: add import map fix: declare globals fix: add types to server declaration fix: tidying up chore: remove deprecated magic imports refactor: change Netlify template to support both runtimes refactor: move edge functions template into examples feat: add edge manifest --- .vscode/settings.json | 13 ++++- deno-import-map.json | 8 +++ examples/netlify-edge/.gitignore | 7 +++ examples/netlify-edge/.vscode/settings.json | 5 ++ examples/netlify-edge/README.md | 3 ++ examples/netlify-edge/app/entry.client.tsx | 4 ++ examples/netlify-edge/app/entry.server.tsx | 21 ++++++++ examples/netlify-edge/app/root.tsx | 32 +++++++++++ examples/netlify-edge/app/routes/index.tsx | 32 +++++++++++ examples/netlify-edge/edge-server.ts | 10 ++++ examples/netlify-edge/netlify.toml | 6 +++ examples/netlify-edge/package.json | 26 +++++++++ examples/netlify-edge/public/favicon.ico | Bin 0 -> 16958 bytes examples/netlify-edge/remix.config.js | 4 ++ package.json | 2 + packages/remix-dev/compiler.ts | 15 +++++- .../plugins/serverBareModulesPlugin.ts | 3 +- packages/remix-dev/config.ts | 5 ++ packages/remix-netlify-edge/README.md | 13 +++++ packages/remix-netlify-edge/crypto.ts | 51 ++++++++++++++++++ packages/remix-netlify-edge/globals.d.ts | 10 ++++ .../remix-netlify-edge/implementations.ts | 15 ++++++ packages/remix-netlify-edge/index.ts | 51 ++++++++++++++++++ packages/remix-netlify-edge/package.json | 17 ++++++ packages/remix-netlify-edge/server.ts | 29 ++++++++++ packages/remix-netlify-edge/tsconfig.json | 22 ++++++++ rollup.config.js | 1 + templates/netlify/app/entry.client.tsx | 2 +- templates/netlify/app/entry.server.tsx | 2 +- templates/netlify/app/root.tsx | 2 +- templates/netlify/edge-server.ts | 11 ++++ templates/netlify/netlify.toml | 22 ++++---- templates/netlify/package.json | 2 +- templates/netlify/remix.config.js | 4 ++ tsconfig.json | 1 + yarn.lock | 9 +++- 36 files changed, 441 insertions(+), 19 deletions(-) create mode 100644 deno-import-map.json create mode 100644 examples/netlify-edge/.gitignore create mode 100644 examples/netlify-edge/.vscode/settings.json create mode 100644 examples/netlify-edge/README.md create mode 100644 examples/netlify-edge/app/entry.client.tsx create mode 100644 examples/netlify-edge/app/entry.server.tsx create mode 100644 examples/netlify-edge/app/root.tsx create mode 100644 examples/netlify-edge/app/routes/index.tsx create mode 100644 examples/netlify-edge/edge-server.ts create mode 100644 examples/netlify-edge/netlify.toml create mode 100644 examples/netlify-edge/package.json create mode 100644 examples/netlify-edge/public/favicon.ico create mode 100644 examples/netlify-edge/remix.config.js create mode 100644 packages/remix-netlify-edge/README.md create mode 100644 packages/remix-netlify-edge/crypto.ts create mode 100644 packages/remix-netlify-edge/globals.d.ts create mode 100644 packages/remix-netlify-edge/implementations.ts create mode 100644 packages/remix-netlify-edge/index.ts create mode 100644 packages/remix-netlify-edge/package.json create mode 100644 packages/remix-netlify-edge/server.ts create mode 100644 packages/remix-netlify-edge/tsconfig.json create mode 100644 templates/netlify/edge-server.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 25fa6215fdd..a90cc0dd8df 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,12 @@ { - "typescript.tsdk": "node_modules/typescript/lib" -} + "typescript.tsdk": "node_modules/typescript/lib", + "deno.enablePaths": [ + "./examples/netlify-edge/edge-server.ts", + "./templates/deno/", + "./templates/netlify/edge-server.ts", + "./packages/remix-netlify-edge/server.ts", + "./packages/remix-netlify-edge/globals.ts" + ], + "deno.unstable": true, + "deno.importMap": "deno-import-map.json" +} \ No newline at end of file diff --git a/deno-import-map.json b/deno-import-map.json new file mode 100644 index 00000000000..01b69573053 --- /dev/null +++ b/deno-import-map.json @@ -0,0 +1,8 @@ +{ + "imports": { + "netlify:edge": "https://dinosaurs:are-the-future!@edge-bootstrap.netlify.app/v1/index.ts", + "@remix-run/netlify-edge": "./packages/remix-netlify-edge/index.ts", + "@remix-run/dev/server-build": "./packages/remix-dev/server-build.ts", + "@remix-run/server-runtime": "./packages/remix-server-runtime/index.ts" + } +} diff --git a/examples/netlify-edge/.gitignore b/examples/netlify-edge/.gitignore new file mode 100644 index 00000000000..0290a4a5cb4 --- /dev/null +++ b/examples/netlify-edge/.gitignore @@ -0,0 +1,7 @@ +/node_modules/ + +/.cache +/build +/public/build + +.netlify \ No newline at end of file diff --git a/examples/netlify-edge/.vscode/settings.json b/examples/netlify-edge/.vscode/settings.json new file mode 100644 index 00000000000..f8b3eabd029 --- /dev/null +++ b/examples/netlify-edge/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "deno.enable": true, + "deno.lint": true, + "deno.config": "./deno.json" +} \ No newline at end of file diff --git a/examples/netlify-edge/README.md b/examples/netlify-edge/README.md new file mode 100644 index 00000000000..3a8eda2b014 --- /dev/null +++ b/examples/netlify-edge/README.md @@ -0,0 +1,3 @@ +# Remix Netlify Edge demo + +A temporary example to make development easier diff --git a/examples/netlify-edge/app/entry.client.tsx b/examples/netlify-edge/app/entry.client.tsx new file mode 100644 index 00000000000..f44d91c038f --- /dev/null +++ b/examples/netlify-edge/app/entry.client.tsx @@ -0,0 +1,4 @@ +import ReactDOM from "react-dom"; +import { RemixBrowser } from "@remix-run/react"; + +ReactDOM.hydrate(, document); diff --git a/examples/netlify-edge/app/entry.server.tsx b/examples/netlify-edge/app/entry.server.tsx new file mode 100644 index 00000000000..332a0748152 --- /dev/null +++ b/examples/netlify-edge/app/entry.server.tsx @@ -0,0 +1,21 @@ +import ReactDOMServer from "react-dom/server"; +import { RemixServer } from "@remix-run/react"; +import type { EntryContext } from "@remix-run/server-runtime"; + +export default function handleRequest( + request: Request, + responseStatusCode: number, + responseHeaders: Headers, + remixContext: EntryContext +) { + let markup = ReactDOMServer.renderToString( + + ); + + responseHeaders.set("Content-Type", "text/html"); + + return new Response("" + markup, { + status: responseStatusCode, + headers: responseHeaders, + }); +} diff --git a/examples/netlify-edge/app/root.tsx b/examples/netlify-edge/app/root.tsx new file mode 100644 index 00000000000..b715f83a898 --- /dev/null +++ b/examples/netlify-edge/app/root.tsx @@ -0,0 +1,32 @@ +import { + Links, + LiveReload, + Meta, + Outlet, + Scripts, + ScrollRestoration, +} from "@remix-run/react"; +import type { MetaFunction } from "@remix-run/server-runtime"; + +export const meta: MetaFunction = () => ({ + charset: "utf-8", + title: "New Remix App", + viewport: "width=device-width,initial-scale=1", +}); + +export default function App() { + return ( + + + + + + + + + + + + + ); +} diff --git a/examples/netlify-edge/app/routes/index.tsx b/examples/netlify-edge/app/routes/index.tsx new file mode 100644 index 00000000000..cbca6124ea7 --- /dev/null +++ b/examples/netlify-edge/app/routes/index.tsx @@ -0,0 +1,32 @@ +export default function Index() { + return ( + + ); +} diff --git a/examples/netlify-edge/edge-server.ts b/examples/netlify-edge/edge-server.ts new file mode 100644 index 00000000000..cc9b8fca438 --- /dev/null +++ b/examples/netlify-edge/edge-server.ts @@ -0,0 +1,10 @@ +// Import path interpreted by the Remix compiler +import * as build from "@remix-run/dev/server-build"; +import { createRequestHandler } from "@remix-run/netlify-edge"; +import type { Context } from "netlify:edge"; +export default createRequestHandler({ + build, + // process.env.NODE_ENV is provided by Remix at compile time + mode: process.env.NODE_ENV, + getLoadContext: (_request: Request, context?: Context) => context, +}); diff --git a/examples/netlify-edge/netlify.toml b/examples/netlify-edge/netlify.toml new file mode 100644 index 00000000000..cc41abbf03f --- /dev/null +++ b/examples/netlify-edge/netlify.toml @@ -0,0 +1,6 @@ +[build] +command = "yarn build" +publish = "public" + +[dev] +framework = "#static" diff --git a/examples/netlify-edge/package.json b/examples/netlify-edge/package.json new file mode 100644 index 00000000000..7d04ba03888 --- /dev/null +++ b/examples/netlify-edge/package.json @@ -0,0 +1,26 @@ +{ + "name": "remix-template-netlify-edge", + "version": "0.0.1", + "private": true, + "sideEffects": false, + "scripts": { + "ntl": "ntl-internal", + "build": "node ../../build/node_modules/@remix-run/dev/cli.js build", + "dev": "remix build && run-p dev:*", + "dev:remix": "remix watch" + }, + "devDependencies": { + "@remix-run/dev": "*", + "cross-env": "^7.0.3", + "npm-run-all": "^4.1.5" + }, + "engines": { + "node": ">=14" + }, + "dependencies": { + "@remix-run/netlify-edge": "*", + "@remix-run/react": "*", + "react": "^17.0.2", + "react-dom": "^17.0.2" + } +} diff --git a/examples/netlify-edge/public/favicon.ico b/examples/netlify-edge/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8830cf6821b354114848e6354889b8ecf6d2bc61 GIT binary patch literal 16958 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 EKbET!0{{R3 literal 0 HcmV?d00001 diff --git a/examples/netlify-edge/remix.config.js b/examples/netlify-edge/remix.config.js new file mode 100644 index 00000000000..dcc4a1337a0 --- /dev/null +++ b/examples/netlify-edge/remix.config.js @@ -0,0 +1,4 @@ +module.exports = { + serverBuildTarget: "netlify-edge", + server: "./edge-server.ts", +}; diff --git a/package.json b/package.json index bd8f5694275..b4ba267e80a 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "format": "prettier --ignore-path .eslintignore --write ./ && npm run lint:fix" }, "workspaces": [ + "examples/netlify-edge", "packages/create-remix", "packages/remix", "packages/remix-architect", @@ -33,6 +34,7 @@ "packages/remix-eslint-config", "packages/remix-express", "packages/remix-netlify", + "packages/remix-netlify-edge", "packages/remix-node", "packages/remix-react", "packages/remix-serve", diff --git a/packages/remix-dev/compiler.ts b/packages/remix-dev/compiler.ts index 7e9acf27031..00a6e535a71 100644 --- a/packages/remix-dev/compiler.ts +++ b/packages/remix-dev/compiler.ts @@ -348,7 +348,10 @@ async function createBrowserBuild( NodeModulesPolyfillPlugin(), ]; - if (config.serverBuildTarget === "deno") { + if ( + config.serverBuildTarget === "deno" || + config.serverBuildTarget === "netlify-edge" + ) { // @ts-expect-error let { cache } = await import("esbuild-plugin-cache"); plugins.unshift( @@ -426,6 +429,16 @@ function createServerBuild( plugins.unshift(NodeModulesPolyfillPlugin()); } + if (config.serverBuildTarget === "netlify-edge") { + let edgeManifest = { + functions: [{ function: "server", path: "/*" }], + version: 1, + }; + let edgeDir = path.dirname(config.serverBuildPath); + fse.ensureDirSync(edgeDir); + fse.writeJSONSync(path.join(edgeDir, "manifest.json"), edgeManifest); + } + return esbuild .build({ absWorkingDir: config.rootDirectory, diff --git a/packages/remix-dev/compiler/plugins/serverBareModulesPlugin.ts b/packages/remix-dev/compiler/plugins/serverBareModulesPlugin.ts index 3fa6ffd2556..ba0bdeb653e 100644 --- a/packages/remix-dev/compiler/plugins/serverBareModulesPlugin.ts +++ b/packages/remix-dev/compiler/plugins/serverBareModulesPlugin.ts @@ -80,9 +80,10 @@ export function serverBareModulesPlugin( } switch (remixConfig.serverBuildTarget) { - // Always bundle everything for cloudflare. + // Always bundle everything for Cloudflare and Netlify Edge. case "cloudflare-pages": case "cloudflare-workers": + case "netlify-edge": return undefined; } diff --git a/packages/remix-dev/config.ts b/packages/remix-dev/config.ts index 3214b27bcae..92b4d2f4ab5 100644 --- a/packages/remix-dev/config.ts +++ b/packages/remix-dev/config.ts @@ -21,6 +21,7 @@ export type ServerBuildTarget = | "node-cjs" | "arc" | "netlify" + | "netlify-edge" | "vercel" | "cloudflare-pages" | "cloudflare-workers" @@ -290,6 +291,7 @@ export async function readConfig( case "cloudflare-pages": case "cloudflare-workers": case "deno": + case "netlify-edge": serverModuleFormat = "esm"; serverPlatform = "neutral"; break; @@ -328,6 +330,9 @@ export async function readConfig( case "netlify": serverBuildPath = ".netlify/functions-internal/server.js"; break; + case "netlify-edge": + serverBuildPath = ".netlify/edge-functions/server.js"; + break; case "vercel": serverBuildPath = "api/index.js"; break; diff --git a/packages/remix-netlify-edge/README.md b/packages/remix-netlify-edge/README.md new file mode 100644 index 00000000000..40685a7476f --- /dev/null +++ b/packages/remix-netlify-edge/README.md @@ -0,0 +1,13 @@ +# Welcome to Remix! + +[Remix](https://remix.run) is a web framework that helps you build better websites with React. + +To get started, open a new shell and run: + +```sh +npx create-remix@latest +``` + +Then follow the prompts you see in your terminal. + +For more information about Remix, [visit remix.run](https://remix.run)! diff --git a/packages/remix-netlify-edge/crypto.ts b/packages/remix-netlify-edge/crypto.ts new file mode 100644 index 00000000000..60d183176e7 --- /dev/null +++ b/packages/remix-netlify-edge/crypto.ts @@ -0,0 +1,51 @@ +import type { SignFunction, UnsignFunction } from "@remix-run/server-runtime"; + +const encoder = new TextEncoder(); + +export const sign: SignFunction = async (value, secret) => { + let key = await crypto.subtle.importKey( + "raw", + encoder.encode(secret), + { name: "HMAC", hash: "SHA-256" }, + false, + ["sign"] + ); + + let data = encoder.encode(value); + let signature = await crypto.subtle.sign("HMAC", key, data); + let hash = btoa(String.fromCharCode(...new Uint8Array(signature))).replace( + /=+$/, + "" + ); + + return value + "." + hash; +}; + +export const unsign: UnsignFunction = async (cookie, secret) => { + let key = await crypto.subtle.importKey( + "raw", + encoder.encode(secret), + { name: "HMAC", hash: "SHA-256" }, + false, + ["verify"] + ); + + let value = cookie.slice(0, cookie.lastIndexOf(".")); + let hash = cookie.slice(cookie.lastIndexOf(".") + 1); + + let data = encoder.encode(value); + let signature = byteStringToUint8Array(atob(hash)); + let valid = await crypto.subtle.verify("HMAC", key, signature, data); + + return valid ? value : false; +}; + +function byteStringToUint8Array(byteString: string): Uint8Array { + let array = new Uint8Array(byteString.length); + + for (let i = 0; i < byteString.length; i++) { + array[i] = byteString.charCodeAt(i); + } + + return array; +} diff --git a/packages/remix-netlify-edge/globals.d.ts b/packages/remix-netlify-edge/globals.d.ts new file mode 100644 index 00000000000..b63800669a0 --- /dev/null +++ b/packages/remix-netlify-edge/globals.d.ts @@ -0,0 +1,10 @@ +export {}; +declare global { + interface ProcessEnv { + NODE_ENV: "development" | "production" | "test"; + } + interface Process { + env: ProcessEnv; + } + let process: Process; +} diff --git a/packages/remix-netlify-edge/implementations.ts b/packages/remix-netlify-edge/implementations.ts new file mode 100644 index 00000000000..51fa94796d5 --- /dev/null +++ b/packages/remix-netlify-edge/implementations.ts @@ -0,0 +1,15 @@ +import { + createCookieFactory, + createCookieSessionStorageFactory, + createMemorySessionStorageFactory, + createSessionStorageFactory, +} from "@remix-run/server-runtime"; + +import { sign, unsign } from "./crypto"; + +export const createCookie = createCookieFactory({ sign, unsign }); +export const createCookieSessionStorage = + createCookieSessionStorageFactory(createCookie); +export const createSessionStorage = createSessionStorageFactory(createCookie); +export const createMemorySessionStorage = + createMemorySessionStorageFactory(createSessionStorage); diff --git a/packages/remix-netlify-edge/index.ts b/packages/remix-netlify-edge/index.ts new file mode 100644 index 00000000000..1b6bbc5f711 --- /dev/null +++ b/packages/remix-netlify-edge/index.ts @@ -0,0 +1,51 @@ +export { createRequestHandler } from "./server"; + +export { + createCookie, + createCookieSessionStorage, + createMemorySessionStorage, + createSessionStorage, +} from "./implementations"; + +export { + createSession, + isCookie, + isSession, + json, + redirect, +} from "@remix-run/server-runtime"; + +export type { + ActionFunction, + AppData, + AppLoadContext, + CreateRequestHandlerFunction, + Cookie, + CookieOptions, + CookieParseOptions, + CookieSerializeOptions, + CookieSignatureOptions, + DataFunctionArgs, + EntryContext, + ErrorBoundaryComponent, + HandleDataRequestFunction, + HandleDocumentRequestFunction, + HeadersFunction, + HtmlLinkDescriptor, + HtmlMetaDescriptor, + LinkDescriptor, + LinksFunction, + LoaderFunction, + MetaDescriptor, + MetaFunction, + PageLinkDescriptor, + RequestHandler, + RouteComponent, + RouteHandle, + ServerBuild, + ServerEntryModule, + Session, + SessionData, + SessionIdStorageStrategy, + SessionStorage, +} from "@remix-run/server-runtime"; diff --git a/packages/remix-netlify-edge/package.json b/packages/remix-netlify-edge/package.json new file mode 100644 index 00000000000..6ebb249054a --- /dev/null +++ b/packages/remix-netlify-edge/package.json @@ -0,0 +1,17 @@ +{ + "name": "@remix-run/netlify-edge", + "description": "Netlify Edge platform abstractions for Remix", + "version": "1.0.0", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/remix-run/remix", + "directory": "packages/remix-netlify-edge" + }, + "bugs": { + "url": "https://github.com/remix-run/remix/issues" + }, + "dependencies": { + "@remix-run/server-runtime": "1.3.4" + } +} diff --git a/packages/remix-netlify-edge/server.ts b/packages/remix-netlify-edge/server.ts new file mode 100644 index 00000000000..f76fb59bdca --- /dev/null +++ b/packages/remix-netlify-edge/server.ts @@ -0,0 +1,29 @@ +import { createRequestHandler as createRemixRequestHandler } from "@remix-run/server-runtime"; +import type { ServerBuild } from "@remix-run/server-runtime"; +export function createRequestHandler({ + build, + mode, + getLoadContext, +}: { + build: ServerBuild; + mode?: string; + getLoadContext?: ( + request: Request, + context?: Context + ) => Promise | Context; +}) { + let remixHandler = createRemixRequestHandler(build, mode); + return async (request: Request, context: Context): Promise => { + try { + let loadContext = getLoadContext + ? await getLoadContext(request, context) + : undefined; + + return await remixHandler(request, loadContext); + } catch (e) { + console.error(e); + + return new Response("Internal Error", { status: 500 }); + } + }; +} diff --git a/packages/remix-netlify-edge/tsconfig.json b/packages/remix-netlify-edge/tsconfig.json new file mode 100644 index 00000000000..a0733d92d28 --- /dev/null +++ b/packages/remix-netlify-edge/tsconfig.json @@ -0,0 +1,22 @@ +{ + "include": [ + "**/*.ts" + ], + "compilerOptions": { + "lib": [ + "ES2019", + "WebWorker" + ], + "target": "ES2019", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "strict": true, + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "../../build/node_modules/@remix-run/netlify-edge", + "rootDir": ".", + // Avoid naming conflicts between history and react-router-dom relying on + // lib.dom.d.ts Window and this being a WebWorker env. + "skipLibCheck": true + } +} \ No newline at end of file diff --git a/rollup.config.js b/rollup.config.js index 155611e9069..0cbf84f1e46 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -672,6 +672,7 @@ function remixServerAdapters() { ...getAdapterConfig("cloudflare-workers"), ...getAdapterConfig("express"), ...getAdapterConfig("netlify"), + ...getAdapterConfig("netlify-edge"), ...getAdapterConfig("vercel"), ]; } diff --git a/templates/netlify/app/entry.client.tsx b/templates/netlify/app/entry.client.tsx index 3eec1fd0a02..57dba485b92 100644 --- a/templates/netlify/app/entry.client.tsx +++ b/templates/netlify/app/entry.client.tsx @@ -1,4 +1,4 @@ -import { RemixBrowser } from "@remix-run/react"; import { hydrate } from "react-dom"; +import { RemixBrowser } from "@remix-run/react"; hydrate(, document); diff --git a/templates/netlify/app/entry.server.tsx b/templates/netlify/app/entry.server.tsx index aa0aa0978b1..ed1c7304c54 100644 --- a/templates/netlify/app/entry.server.tsx +++ b/templates/netlify/app/entry.server.tsx @@ -1,6 +1,6 @@ -import type { EntryContext } from "@remix-run/node"; import { RemixServer } from "@remix-run/react"; import { renderToString } from "react-dom/server"; +import type { EntryContext } from "@remix-run/server-runtime"; export default function handleRequest( request: Request, diff --git a/templates/netlify/app/root.tsx b/templates/netlify/app/root.tsx index 927a0f745df..b715f83a898 100644 --- a/templates/netlify/app/root.tsx +++ b/templates/netlify/app/root.tsx @@ -1,4 +1,3 @@ -import type { MetaFunction } from "@remix-run/node"; import { Links, LiveReload, @@ -7,6 +6,7 @@ import { Scripts, ScrollRestoration, } from "@remix-run/react"; +import type { MetaFunction } from "@remix-run/server-runtime"; export const meta: MetaFunction = () => ({ charset: "utf-8", diff --git a/templates/netlify/edge-server.ts b/templates/netlify/edge-server.ts new file mode 100644 index 00000000000..5c4551d2b9d --- /dev/null +++ b/templates/netlify/edge-server.ts @@ -0,0 +1,11 @@ +// Import path interpreted by the Remix compiler +import * as build from "@remix-run/dev/server-build"; +// TODO: replace this with public URL when available +import { createRequestHandler } from "@remix-run/netlify-edge"; +import type { Context } from "netlify:edge"; +export default createRequestHandler({ + build, + // process.env.NODE_ENV is provided by Remix at compile time + mode: process.env.NODE_ENV, + getLoadContext: (_request: Request, context?: Context) => context, +}); diff --git a/templates/netlify/netlify.toml b/templates/netlify/netlify.toml index fd51b27efe4..8f3426475c7 100644 --- a/templates/netlify/netlify.toml +++ b/templates/netlify/netlify.toml @@ -1,17 +1,19 @@ [build] - command = "remix build" - publish = "public" +command = "remix build" +publish = "public" [dev] - command = "remix watch" - port = 3000 +command = "remix watch" +port = 3000 +# Remove this if using Netlify Edge Functions [[redirects]] - from = "/*" - to = "/.netlify/functions/server" - status = 200 +from = "/*" +to = "/.netlify/functions/server" +status = 200 [[headers]] - for = "/build/*" - [headers.values] - "Cache-Control" = "public, max-age=31536000, s-maxage=31536000" +for = "/build/*" + +[headers.values] +"Cache-Control" = "public, max-age=31536000, s-maxage=31536000" diff --git a/templates/netlify/package.json b/templates/netlify/package.json index 8312d22b611..7c397a2bc71 100644 --- a/templates/netlify/package.json +++ b/templates/netlify/package.json @@ -10,7 +10,7 @@ "start": "cross-env NODE_ENV=production netlify dev" }, "dependencies": { - "@netlify/functions": "^0.10.0", + "@netlify/functions": "^1.0.0", "@remix-run/netlify": "*", "@remix-run/node": "*", "@remix-run/react": "*", diff --git a/templates/netlify/remix.config.js b/templates/netlify/remix.config.js index 4df8db6341a..90b55c9f782 100644 --- a/templates/netlify/remix.config.js +++ b/templates/netlify/remix.config.js @@ -2,8 +2,12 @@ * @type {import('@remix-run/dev').AppConfig} */ module.exports = { + // For regular Netlify Functions runtime, use these values: serverBuildTarget: "netlify", server: "./server.js", + // To use Netlify Edge Functions (beta) runtime, change values to the following: + // serverBuildTarget: "netlify-edge", + // server: "./edge-server.ts", ignoredRouteFiles: [".*"], // appDirectory: "app", // assetsBuildDirectory: "public/build", diff --git a/tsconfig.json b/tsconfig.json index 8ccfcf30261..3cbf957bdf1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ { "path": "packages/remix-dev" }, { "path": "packages/remix-express" }, { "path": "packages/remix-netlify" }, + { "path": "packages/remix-netlify-edge" }, { "path": "packages/remix-node" }, { "path": "packages/remix-react" }, { "path": "packages/remix-serve" }, diff --git a/yarn.lock b/yarn.lock index 587a58335eb..40965247870 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3810,6 +3810,13 @@ core-util-is@~1.0.0: resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -3821,7 +3828,7 @@ cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== From ef68922d6b098529a3ff549ed8b523da7422e493 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Fri, 8 Apr 2022 10:10:43 +0100 Subject: [PATCH 02/12] feat: add remix.init to Netlify template feat: add import map fix: resolve path for runtime --- packages/remix-dev/compiler.ts | 33 ++ packages/remix-netlify-edge/server.ts | 2 +- packages/remix-netlify/package.json | 4 +- templates/netlify/app/entry.client.tsx | 2 +- templates/netlify/app/entry.server.tsx | 2 +- templates/netlify/app/root.tsx | 2 +- templates/netlify/netlify.toml | 1 - templates/netlify/package.json | 2 +- templates/netlify/remix.config.js | 4 - templates/netlify/remix.init/README.md | 51 +++ .../edge-server.js} | 3 - templates/netlify/remix.init/index.js | 48 +++ templates/netlify/remix.init/netlify.toml | 13 + .../netlify/remix.init/package-lock.json | 390 ++++++++++++++++++ templates/netlify/remix.init/package.json | 10 + .../netlify/remix.init/remix.config-edge.js | 8 + templates/netlify/remix.init/vscode.json | 10 + yarn.lock | 8 +- 18 files changed, 574 insertions(+), 19 deletions(-) create mode 100644 templates/netlify/remix.init/README.md rename templates/netlify/{edge-server.ts => remix.init/edge-server.js} (65%) create mode 100644 templates/netlify/remix.init/index.js create mode 100644 templates/netlify/remix.init/netlify.toml create mode 100644 templates/netlify/remix.init/package-lock.json create mode 100644 templates/netlify/remix.init/package.json create mode 100644 templates/netlify/remix.init/remix.config-edge.js create mode 100644 templates/netlify/remix.init/vscode.json diff --git a/packages/remix-dev/compiler.ts b/packages/remix-dev/compiler.ts index 00a6e535a71..b4b41738ee0 100644 --- a/packages/remix-dev/compiler.ts +++ b/packages/remix-dev/compiler.ts @@ -432,11 +432,44 @@ function createServerBuild( if (config.serverBuildTarget === "netlify-edge") { let edgeManifest = { functions: [{ function: "server", path: "/*" }], + import_map: "../remix-import-map.json", version: 1, }; let edgeDir = path.dirname(config.serverBuildPath); + fse.ensureDirSync(edgeDir); fse.writeJSONSync(path.join(edgeDir, "manifest.json"), edgeManifest); + + // This generated import map is processed by the netlify CLI and combined with the internal map + let importMapPath = path.join( + config.rootDirectory, + ".netlify", + "remix-import-map.json" + ); + + let runtimePath: string | undefined; + + try { + // If the user has it locally-installed, use that + runtimePath = `file://${require.resolve("@remix-run/netlify-edge", { + paths: [config.rootDirectory], + })}`; + } catch { + console.error("Please install '@remix-run/netlify-edge'"); + // When published, we can fall back to a URL import instead of bailing + // e.g. runtimePath = "https://esm.sh/@remix-run/netlify-edge"; + } + + if (runtimePath) { + let importMap = { + imports: { + "@remix-run/netlify-edge": runtimePath, + }, + }; + + fse.ensureDirSync(path.dirname(importMapPath)); + fse.writeJSONSync(importMapPath, importMap); + } } return esbuild diff --git a/packages/remix-netlify-edge/server.ts b/packages/remix-netlify-edge/server.ts index f76fb59bdca..e9ce25f2096 100644 --- a/packages/remix-netlify-edge/server.ts +++ b/packages/remix-netlify-edge/server.ts @@ -17,7 +17,7 @@ export function createRequestHandler({ try { let loadContext = getLoadContext ? await getLoadContext(request, context) - : undefined; + : context; return await remixHandler(request, loadContext); } catch (e) { diff --git a/packages/remix-netlify/package.json b/packages/remix-netlify/package.json index 1487465f2bd..9b119b666c0 100644 --- a/packages/remix-netlify/package.json +++ b/packages/remix-netlify/package.json @@ -15,9 +15,9 @@ "@remix-run/node": "1.3.5" }, "peerDependencies": { - "@netlify/functions": "^0.10.0" + "@netlify/functions": "^1.0.0" }, "devDependencies": { - "@netlify/functions": "^0.10.0" + "@netlify/functions": "^1.0.0" } } diff --git a/templates/netlify/app/entry.client.tsx b/templates/netlify/app/entry.client.tsx index 57dba485b92..3eec1fd0a02 100644 --- a/templates/netlify/app/entry.client.tsx +++ b/templates/netlify/app/entry.client.tsx @@ -1,4 +1,4 @@ -import { hydrate } from "react-dom"; import { RemixBrowser } from "@remix-run/react"; +import { hydrate } from "react-dom"; hydrate(, document); diff --git a/templates/netlify/app/entry.server.tsx b/templates/netlify/app/entry.server.tsx index ed1c7304c54..ff25f886acc 100644 --- a/templates/netlify/app/entry.server.tsx +++ b/templates/netlify/app/entry.server.tsx @@ -1,6 +1,6 @@ +import type { EntryContext } from "@remix-run/server-runtime"; import { RemixServer } from "@remix-run/react"; import { renderToString } from "react-dom/server"; -import type { EntryContext } from "@remix-run/server-runtime"; export default function handleRequest( request: Request, diff --git a/templates/netlify/app/root.tsx b/templates/netlify/app/root.tsx index b715f83a898..0a2fa73ee38 100644 --- a/templates/netlify/app/root.tsx +++ b/templates/netlify/app/root.tsx @@ -1,3 +1,4 @@ +import type { MetaFunction } from "@remix-run/server-runtime"; import { Links, LiveReload, @@ -6,7 +7,6 @@ import { Scripts, ScrollRestoration, } from "@remix-run/react"; -import type { MetaFunction } from "@remix-run/server-runtime"; export const meta: MetaFunction = () => ({ charset: "utf-8", diff --git a/templates/netlify/netlify.toml b/templates/netlify/netlify.toml index 8f3426475c7..ea741ab4ac8 100644 --- a/templates/netlify/netlify.toml +++ b/templates/netlify/netlify.toml @@ -6,7 +6,6 @@ publish = "public" command = "remix watch" port = 3000 -# Remove this if using Netlify Edge Functions [[redirects]] from = "/*" to = "/.netlify/functions/server" diff --git a/templates/netlify/package.json b/templates/netlify/package.json index 7c397a2bc71..07de55870b7 100644 --- a/templates/netlify/package.json +++ b/templates/netlify/package.json @@ -10,7 +10,7 @@ "start": "cross-env NODE_ENV=production netlify dev" }, "dependencies": { - "@netlify/functions": "^1.0.0", + "@netlify/functions": "latest", "@remix-run/netlify": "*", "@remix-run/node": "*", "@remix-run/react": "*", diff --git a/templates/netlify/remix.config.js b/templates/netlify/remix.config.js index 90b55c9f782..4df8db6341a 100644 --- a/templates/netlify/remix.config.js +++ b/templates/netlify/remix.config.js @@ -2,12 +2,8 @@ * @type {import('@remix-run/dev').AppConfig} */ module.exports = { - // For regular Netlify Functions runtime, use these values: serverBuildTarget: "netlify", server: "./server.js", - // To use Netlify Edge Functions (beta) runtime, change values to the following: - // serverBuildTarget: "netlify-edge", - // server: "./edge-server.ts", ignoredRouteFiles: [".*"], // appDirectory: "app", // assetsBuildDirectory: "public/build", diff --git a/templates/netlify/remix.init/README.md b/templates/netlify/remix.init/README.md new file mode 100644 index 00000000000..93a398ad5ca --- /dev/null +++ b/templates/netlify/remix.init/README.md @@ -0,0 +1,51 @@ +# Welcome to Remix! + +- [Remix Docs](https://remix.run/docs) + +## Netlify Setup + +1. Install the [Netlify CLI](https://www.netlify.com/products/dev/): + +```sh +npm i -g netlify-cli +``` + +If you have previously installed the Netlify CLI, you should update it to the latest version: + +```sh +npm i -g netlify-cli@latest +``` + +2. Sign up and log in to Netlify: + +```sh +netlify login +``` + +3. Create a new site: + +```sh +netlify init +``` + +## Development + +The Netlify CLI starts your app in development mode, rebuilding assets on file changes. + +```sh +npm run dev +``` + +Open up [http://localhost:3000](http://localhost:3000), and you should be ready to go! + +## Deployment + +There are two ways to deploy your app to Netlify, you can either link your app to your git repo and have it auto deploy changes to Netlify, or you can deploy your app manually. If you've followed the setup instructions already, all you need to do is run this: + +```sh +# preview deployment +netlify deploy --build + +# production deployment +netlify deploy --build --prod +``` diff --git a/templates/netlify/edge-server.ts b/templates/netlify/remix.init/edge-server.js similarity index 65% rename from templates/netlify/edge-server.ts rename to templates/netlify/remix.init/edge-server.js index 5c4551d2b9d..71434d0c297 100644 --- a/templates/netlify/edge-server.ts +++ b/templates/netlify/remix.init/edge-server.js @@ -1,11 +1,8 @@ // Import path interpreted by the Remix compiler import * as build from "@remix-run/dev/server-build"; -// TODO: replace this with public URL when available import { createRequestHandler } from "@remix-run/netlify-edge"; -import type { Context } from "netlify:edge"; export default createRequestHandler({ build, // process.env.NODE_ENV is provided by Remix at compile time mode: process.env.NODE_ENV, - getLoadContext: (_request: Request, context?: Context) => context, }); diff --git a/templates/netlify/remix.init/index.js b/templates/netlify/remix.init/index.js new file mode 100644 index 00000000000..e31b525b5cb --- /dev/null +++ b/templates/netlify/remix.init/index.js @@ -0,0 +1,48 @@ +const select = require("@inquirer/select"); +const fs = require("fs/promises"); +const { join } = require("path"); + +const files = [ + ["README.md"], + ["netlify.toml"], + ["edge-server.js", "server.js"], + ["remix.config-edge.js", "remix.config.js"], + ["vscode.json", join(".vscode", "settings.json")], +]; + +async function main({ rootDirectory }) { + if (await shouldUseEdge()) { + await fs.mkdir(join(rootDirectory, ".vscode")); + + for (let [file, target] of files) { + await fs.copyFile( + join(__dirname, file), + join(rootDirectory, target || file) + ); + } + } +} + +async function shouldUseEdge() { + let edge = await select({ + name: "edge", + default: false, + message: "Run your Remix site with:", + choices: [ + { + name: "Netlify Functions", + description: "Choose this for stable support for production sites", + value: false, + }, + { + name: "Netlify Edge Functions (beta)", + description: + "Try this experimental beta for improved performance on non-critical sites", + value: true, + }, + ], + }); + return edge; +} + +module.exports = main; diff --git a/templates/netlify/remix.init/netlify.toml b/templates/netlify/remix.init/netlify.toml new file mode 100644 index 00000000000..e6ee338bd9a --- /dev/null +++ b/templates/netlify/remix.init/netlify.toml @@ -0,0 +1,13 @@ +[build] +command = "remix build" +publish = "public" + +[dev] +command = "remix watch" +port = 3000 + +[[headers]] +for = "/build/*" + +[headers.values] +"Cache-Control" = "public, max-age=31536000, s-maxage=31536000" diff --git a/templates/netlify/remix.init/package-lock.json b/templates/netlify/remix.init/package-lock.json new file mode 100644 index 00000000000..e8aa28aadf4 --- /dev/null +++ b/templates/netlify/remix.init/package-lock.json @@ -0,0 +1,390 @@ +{ + "name": "remix.init", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "remix.init", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@inquirer/select": "^0.0.18-alpha.0" + } + }, + "node_modules/@inquirer/core": { + "version": "0.0.18-alpha.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-0.0.18-alpha.0.tgz", + "integrity": "sha512-skK1xe87YyIXHDdA4kYzkzEzaUEnndh7ygOQrKHCrIzHy/V8xmJfyDIAJauNZXSBn9RHqxCCqAqTo1ifyIJwCw==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-spinners": "^2.6.1", + "cli-width": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "^0.0.8", + "run-async": "^2.3.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "node_modules/@inquirer/select": { + "version": "0.0.18-alpha.0", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-0.0.18-alpha.0.tgz", + "integrity": "sha512-NIjgoHx7YQTbsrVm0hWtdljFGwIKgenzmeeynvudpivbwh2ak1GzcOZ7STd+MJ1u3IAgC8F0FKx9PwwalcE/8Q==", + "dependencies": { + "@inquirer/core": "^0.0.18-alpha.0", + "chalk": "^4.1.1", + "figures": "^3.0.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@inquirer/core": { + "version": "0.0.18-alpha.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-0.0.18-alpha.0.tgz", + "integrity": "sha512-skK1xe87YyIXHDdA4kYzkzEzaUEnndh7ygOQrKHCrIzHy/V8xmJfyDIAJauNZXSBn9RHqxCCqAqTo1ifyIJwCw==", + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-spinners": "^2.6.1", + "cli-width": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "^0.0.8", + "run-async": "^2.3.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "@inquirer/select": { + "version": "0.0.18-alpha.0", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-0.0.18-alpha.0.tgz", + "integrity": "sha512-NIjgoHx7YQTbsrVm0hWtdljFGwIKgenzmeeynvudpivbwh2ak1GzcOZ7STd+MJ1u3IAgC8F0FKx9PwwalcE/8Q==", + "requires": { + "@inquirer/core": "^0.0.18-alpha.0", + "chalk": "^4.1.1", + "figures": "^3.0.0" + } + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==" + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + } + } +} diff --git a/templates/netlify/remix.init/package.json b/templates/netlify/remix.init/package.json new file mode 100644 index 00000000000..36c92682879 --- /dev/null +++ b/templates/netlify/remix.init/package.json @@ -0,0 +1,10 @@ +{ + "name": "remix.init", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "private": true, + "dependencies": { + "@inquirer/select": "^0.0.18-alpha.0" + } +} diff --git a/templates/netlify/remix.init/remix.config-edge.js b/templates/netlify/remix.init/remix.config-edge.js new file mode 100644 index 00000000000..17a92d956ae --- /dev/null +++ b/templates/netlify/remix.init/remix.config-edge.js @@ -0,0 +1,8 @@ +/** + * @type {import('@remix-run/dev').AppConfig} + */ +module.exports = { + serverBuildTarget: "netlify-edge", + server: "./server.js", + ignoredRouteFiles: [".*"], +}; diff --git a/templates/netlify/remix.init/vscode.json b/templates/netlify/remix.init/vscode.json new file mode 100644 index 00000000000..7e1abd18a1a --- /dev/null +++ b/templates/netlify/remix.init/vscode.json @@ -0,0 +1,10 @@ +{ + "deno.enablePaths": [ + "server.js", + "server.ts", + "netlify/edge-functions/", + ".netlify/edge-functions/" + ], + "deno.unstable": true, + "deno.importMap": ".netlify/edge-functions-import-map.json" +} diff --git a/yarn.lock b/yarn.lock index 40965247870..7106fae0b85 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1373,10 +1373,10 @@ outvariant "^1.2.1" strict-event-emitter "^0.2.0" -"@netlify/functions@^0.10.0": - version "0.10.0" - resolved "https://registry.npmjs.org/@netlify/functions/-/functions-0.10.0.tgz" - integrity sha512-NNFADTPnokuoMY1OUhaXlE/Jrzk5lHOl1uB4L/8pw1UJ/CaectZJACMExijbJnqaKIhOQG0WmbBQUh1lgnK/Qg== +"@netlify/functions@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@netlify/functions/-/functions-1.0.0.tgz#5b6c02fafc567033c93b15a080cc021e5f10f254" + integrity sha512-7fnJv3vr8uyyyOYPChwoec6MjzsCw1CoRUO2DhQ1BD6bOyJRlD4DUaOOGlMILB2LCT8P24p5LexEGx8AJb7xdA== dependencies: is-promise "^4.0.0" From 0964557b70ddcbd13636d1c8a7b8f81deb0f6f55 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Fri, 8 Apr 2022 14:04:49 +0100 Subject: [PATCH 03/12] chore: remove netlify edge example --- .vscode/settings.json | 3 +- examples/netlify-edge/.gitignore | 7 ----- examples/netlify-edge/.vscode/settings.json | 5 --- examples/netlify-edge/README.md | 3 -- examples/netlify-edge/app/entry.client.tsx | 4 --- examples/netlify-edge/app/entry.server.tsx | 21 ------------- examples/netlify-edge/app/root.tsx | 32 -------------------- examples/netlify-edge/app/routes/index.tsx | 32 -------------------- examples/netlify-edge/edge-server.ts | 10 ------ examples/netlify-edge/netlify.toml | 6 ---- examples/netlify-edge/package.json | 26 ---------------- examples/netlify-edge/public/favicon.ico | Bin 16958 -> 0 bytes examples/netlify-edge/remix.config.js | 4 --- package.json | 1 - 14 files changed, 1 insertion(+), 153 deletions(-) delete mode 100644 examples/netlify-edge/.gitignore delete mode 100644 examples/netlify-edge/.vscode/settings.json delete mode 100644 examples/netlify-edge/README.md delete mode 100644 examples/netlify-edge/app/entry.client.tsx delete mode 100644 examples/netlify-edge/app/entry.server.tsx delete mode 100644 examples/netlify-edge/app/root.tsx delete mode 100644 examples/netlify-edge/app/routes/index.tsx delete mode 100644 examples/netlify-edge/edge-server.ts delete mode 100644 examples/netlify-edge/netlify.toml delete mode 100644 examples/netlify-edge/package.json delete mode 100644 examples/netlify-edge/public/favicon.ico delete mode 100644 examples/netlify-edge/remix.config.js diff --git a/.vscode/settings.json b/.vscode/settings.json index a90cc0dd8df..bb6b124509a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,8 @@ { "typescript.tsdk": "node_modules/typescript/lib", "deno.enablePaths": [ - "./examples/netlify-edge/edge-server.ts", "./templates/deno/", - "./templates/netlify/edge-server.ts", + "./templates/netlify/remix.init/edge-server.js", "./packages/remix-netlify-edge/server.ts", "./packages/remix-netlify-edge/globals.ts" ], diff --git a/examples/netlify-edge/.gitignore b/examples/netlify-edge/.gitignore deleted file mode 100644 index 0290a4a5cb4..00000000000 --- a/examples/netlify-edge/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -/node_modules/ - -/.cache -/build -/public/build - -.netlify \ No newline at end of file diff --git a/examples/netlify-edge/.vscode/settings.json b/examples/netlify-edge/.vscode/settings.json deleted file mode 100644 index f8b3eabd029..00000000000 --- a/examples/netlify-edge/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "deno.enable": true, - "deno.lint": true, - "deno.config": "./deno.json" -} \ No newline at end of file diff --git a/examples/netlify-edge/README.md b/examples/netlify-edge/README.md deleted file mode 100644 index 3a8eda2b014..00000000000 --- a/examples/netlify-edge/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Remix Netlify Edge demo - -A temporary example to make development easier diff --git a/examples/netlify-edge/app/entry.client.tsx b/examples/netlify-edge/app/entry.client.tsx deleted file mode 100644 index f44d91c038f..00000000000 --- a/examples/netlify-edge/app/entry.client.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import ReactDOM from "react-dom"; -import { RemixBrowser } from "@remix-run/react"; - -ReactDOM.hydrate(, document); diff --git a/examples/netlify-edge/app/entry.server.tsx b/examples/netlify-edge/app/entry.server.tsx deleted file mode 100644 index 332a0748152..00000000000 --- a/examples/netlify-edge/app/entry.server.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import ReactDOMServer from "react-dom/server"; -import { RemixServer } from "@remix-run/react"; -import type { EntryContext } from "@remix-run/server-runtime"; - -export default function handleRequest( - request: Request, - responseStatusCode: number, - responseHeaders: Headers, - remixContext: EntryContext -) { - let markup = ReactDOMServer.renderToString( - - ); - - responseHeaders.set("Content-Type", "text/html"); - - return new Response("" + markup, { - status: responseStatusCode, - headers: responseHeaders, - }); -} diff --git a/examples/netlify-edge/app/root.tsx b/examples/netlify-edge/app/root.tsx deleted file mode 100644 index b715f83a898..00000000000 --- a/examples/netlify-edge/app/root.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { - Links, - LiveReload, - Meta, - Outlet, - Scripts, - ScrollRestoration, -} from "@remix-run/react"; -import type { MetaFunction } from "@remix-run/server-runtime"; - -export const meta: MetaFunction = () => ({ - charset: "utf-8", - title: "New Remix App", - viewport: "width=device-width,initial-scale=1", -}); - -export default function App() { - return ( - - - - - - - - - - - - - ); -} diff --git a/examples/netlify-edge/app/routes/index.tsx b/examples/netlify-edge/app/routes/index.tsx deleted file mode 100644 index cbca6124ea7..00000000000 --- a/examples/netlify-edge/app/routes/index.tsx +++ /dev/null @@ -1,32 +0,0 @@ -export default function Index() { - return ( - - ); -} diff --git a/examples/netlify-edge/edge-server.ts b/examples/netlify-edge/edge-server.ts deleted file mode 100644 index cc9b8fca438..00000000000 --- a/examples/netlify-edge/edge-server.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Import path interpreted by the Remix compiler -import * as build from "@remix-run/dev/server-build"; -import { createRequestHandler } from "@remix-run/netlify-edge"; -import type { Context } from "netlify:edge"; -export default createRequestHandler({ - build, - // process.env.NODE_ENV is provided by Remix at compile time - mode: process.env.NODE_ENV, - getLoadContext: (_request: Request, context?: Context) => context, -}); diff --git a/examples/netlify-edge/netlify.toml b/examples/netlify-edge/netlify.toml deleted file mode 100644 index cc41abbf03f..00000000000 --- a/examples/netlify-edge/netlify.toml +++ /dev/null @@ -1,6 +0,0 @@ -[build] -command = "yarn build" -publish = "public" - -[dev] -framework = "#static" diff --git a/examples/netlify-edge/package.json b/examples/netlify-edge/package.json deleted file mode 100644 index 7d04ba03888..00000000000 --- a/examples/netlify-edge/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "remix-template-netlify-edge", - "version": "0.0.1", - "private": true, - "sideEffects": false, - "scripts": { - "ntl": "ntl-internal", - "build": "node ../../build/node_modules/@remix-run/dev/cli.js build", - "dev": "remix build && run-p dev:*", - "dev:remix": "remix watch" - }, - "devDependencies": { - "@remix-run/dev": "*", - "cross-env": "^7.0.3", - "npm-run-all": "^4.1.5" - }, - "engines": { - "node": ">=14" - }, - "dependencies": { - "@remix-run/netlify-edge": "*", - "@remix-run/react": "*", - "react": "^17.0.2", - "react-dom": "^17.0.2" - } -} diff --git a/examples/netlify-edge/public/favicon.ico b/examples/netlify-edge/public/favicon.ico deleted file mode 100644 index 8830cf6821b354114848e6354889b8ecf6d2bc61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16958 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 EKbET!0{{R3 diff --git a/examples/netlify-edge/remix.config.js b/examples/netlify-edge/remix.config.js deleted file mode 100644 index dcc4a1337a0..00000000000 --- a/examples/netlify-edge/remix.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - serverBuildTarget: "netlify-edge", - server: "./edge-server.ts", -}; diff --git a/package.json b/package.json index b4ba267e80a..0af464d6a90 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "format": "prettier --ignore-path .eslintignore --write ./ && npm run lint:fix" }, "workspaces": [ - "examples/netlify-edge", "packages/create-remix", "packages/remix", "packages/remix-architect", From 359aad703b50ce07a13417e0f096c280659094b6 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Wed, 13 Apr 2022 21:58:56 +0100 Subject: [PATCH 04/12] fix: handle static files --- packages/remix-netlify-edge/server.ts | 35 ++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/remix-netlify-edge/server.ts b/packages/remix-netlify-edge/server.ts index e9ce25f2096..95060b2b732 100644 --- a/packages/remix-netlify-edge/server.ts +++ b/packages/remix-netlify-edge/server.ts @@ -1,6 +1,14 @@ import { createRequestHandler as createRemixRequestHandler } from "@remix-run/server-runtime"; import type { ServerBuild } from "@remix-run/server-runtime"; -export function createRequestHandler({ + +// This can be replaced with the full context type when that is published +interface BaseContext { + next: (options?: { sendConditionalRequest?: boolean }) => Promise; +} + +export function createRequestHandler< + Context extends BaseContext = BaseContext +>({ build, mode, getLoadContext, @@ -13,13 +21,34 @@ export function createRequestHandler({ ) => Promise | Context; }) { let remixHandler = createRemixRequestHandler(build, mode); - return async (request: Request, context: Context): Promise => { + + let assetPath = build.assets.url.split("/").slice(0, -1).join("/"); + + return async ( + request: Request, + context: Context + ): Promise => { + let { pathname } = new URL(request.url); + // Skip the handler for static files + if (pathname.startsWith(`${assetPath}/`)) { + return; + } try { let loadContext = getLoadContext ? await getLoadContext(request, context) : context; - return await remixHandler(request, loadContext); + let response = await remixHandler(request, loadContext); + if (response.status === 404) { + // Check if there is a matching static file + let originResponse = await context.next({ + sendConditionalRequest: true, + }); + if (originResponse.status !== 404) { + return originResponse; + } + } + return response; } catch (e) { console.error(e); From 97fea3a7a81c22967bf21b2b607cc09eb9a57096 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Wed, 13 Apr 2022 22:14:46 +0100 Subject: [PATCH 05/12] fix: import map paths --- .vscode/settings.json | 1 - packages/remix-dev/compiler.ts | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bb6b124509a..a3c5e6793f0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,6 @@ "deno.enablePaths": [ "./templates/deno/", "./templates/netlify/remix.init/edge-server.js", - "./packages/remix-netlify-edge/server.ts", "./packages/remix-netlify-edge/globals.ts" ], "deno.unstable": true, diff --git a/packages/remix-dev/compiler.ts b/packages/remix-dev/compiler.ts index b4b41738ee0..5c9fceca3d9 100644 --- a/packages/remix-dev/compiler.ts +++ b/packages/remix-dev/compiler.ts @@ -460,10 +460,13 @@ function createServerBuild( // e.g. runtimePath = "https://esm.sh/@remix-run/netlify-edge"; } + let buildPath = require.resolve("./server-build.d.ts"); + if (runtimePath) { let importMap = { imports: { "@remix-run/netlify-edge": runtimePath, + "@remix-run/dev/server-build": `file://${buildPath}`, }, }; From 931f11f227bf2fe4fc61e5a4897492f1b0cf5499 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Thu, 14 Apr 2022 07:47:36 +0100 Subject: [PATCH 06/12] chore: add comment re deno runtime --- packages/remix-netlify-edge/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/remix-netlify-edge/index.ts b/packages/remix-netlify-edge/index.ts index 1b6bbc5f711..c2d953b0d6b 100644 --- a/packages/remix-netlify-edge/index.ts +++ b/packages/remix-netlify-edge/index.ts @@ -1,5 +1,8 @@ export { createRequestHandler } from "./server"; +// Once the @remix-run/deno runtime has been published then we +// can remove these exports and re-export that instead. + export { createCookie, createCookieSessionStorage, From be7932e360d0b93c5e73743e050777ae2296d412 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Thu, 14 Apr 2022 07:53:58 +0100 Subject: [PATCH 07/12] chore: move deno runtime into subdir --- deno-import-map.json | 2 +- packages/remix-netlify-edge/index.ts | 36 +++++++++---------- .../remix-netlify-edge/remix-deno/README.md | 4 +++ .../{ => remix-deno}/crypto.ts | 0 .../{ => remix-deno}/globals.d.ts | 0 .../{ => remix-deno}/implementations.ts | 0 6 files changed, 23 insertions(+), 19 deletions(-) create mode 100644 packages/remix-netlify-edge/remix-deno/README.md rename packages/remix-netlify-edge/{ => remix-deno}/crypto.ts (100%) rename packages/remix-netlify-edge/{ => remix-deno}/globals.d.ts (100%) rename packages/remix-netlify-edge/{ => remix-deno}/implementations.ts (100%) diff --git a/deno-import-map.json b/deno-import-map.json index 01b69573053..ec08b4c705a 100644 --- a/deno-import-map.json +++ b/deno-import-map.json @@ -5,4 +5,4 @@ "@remix-run/dev/server-build": "./packages/remix-dev/server-build.ts", "@remix-run/server-runtime": "./packages/remix-server-runtime/index.ts" } -} +} \ No newline at end of file diff --git a/packages/remix-netlify-edge/index.ts b/packages/remix-netlify-edge/index.ts index c2d953b0d6b..893173348c9 100644 --- a/packages/remix-netlify-edge/index.ts +++ b/packages/remix-netlify-edge/index.ts @@ -1,23 +1,5 @@ export { createRequestHandler } from "./server"; -// Once the @remix-run/deno runtime has been published then we -// can remove these exports and re-export that instead. - -export { - createCookie, - createCookieSessionStorage, - createMemorySessionStorage, - createSessionStorage, -} from "./implementations"; - -export { - createSession, - isCookie, - isSession, - json, - redirect, -} from "@remix-run/server-runtime"; - export type { ActionFunction, AppData, @@ -52,3 +34,21 @@ export type { SessionIdStorageStrategy, SessionStorage, } from "@remix-run/server-runtime"; + +export { + createSession, + isCookie, + isSession, + json, + redirect, +} from "@remix-run/server-runtime"; + +// Once the @remix-run/deno runtime has been published then we +// can remove these exports and re-export that instead. + +export { + createCookie, + createCookieSessionStorage, + createMemorySessionStorage, + createSessionStorage, +} from "./remix-deno/implementations"; diff --git a/packages/remix-netlify-edge/remix-deno/README.md b/packages/remix-netlify-edge/remix-deno/README.md new file mode 100644 index 00000000000..a591d709a98 --- /dev/null +++ b/packages/remix-netlify-edge/remix-deno/README.md @@ -0,0 +1,4 @@ +# @remix-run/deno + +`@remix-run/deno` package is temporarily inlined within this directory while Deno support is experimental. +In the future, this directory would be removed and Remix + Deno apps would import `@remix-run/deno` from some URL. \ No newline at end of file diff --git a/packages/remix-netlify-edge/crypto.ts b/packages/remix-netlify-edge/remix-deno/crypto.ts similarity index 100% rename from packages/remix-netlify-edge/crypto.ts rename to packages/remix-netlify-edge/remix-deno/crypto.ts diff --git a/packages/remix-netlify-edge/globals.d.ts b/packages/remix-netlify-edge/remix-deno/globals.d.ts similarity index 100% rename from packages/remix-netlify-edge/globals.d.ts rename to packages/remix-netlify-edge/remix-deno/globals.d.ts diff --git a/packages/remix-netlify-edge/implementations.ts b/packages/remix-netlify-edge/remix-deno/implementations.ts similarity index 100% rename from packages/remix-netlify-edge/implementations.ts rename to packages/remix-netlify-edge/remix-deno/implementations.ts From 36fc06f87af551b9984553529f89364c653c60ca Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Thu, 14 Apr 2022 19:16:28 +0100 Subject: [PATCH 08/12] chore: publish netlify edge module as untranspiled TS --- .vscode/settings.json | 4 +- deno-import-map.json | 11 +++-- packages/remix-dev/compiler.ts | 18 ++++--- .../plugins/serverBareModulesPlugin.ts | 18 ++++++- packages/remix-netlify-edge/index.d.ts | 33 +++++++++++++ packages/remix-netlify-edge/index.js | 12 +++++ packages/remix-netlify-edge/mod.ts | 48 +++++++++++++++++++ packages/remix-netlify-edge/package.json | 16 ++++++- .../remix-netlify-edge/remix-deno/crypto.ts | 5 +- .../remix-deno/implementations.ts | 4 +- .../{index.ts => remix-deno/mod.ts} | 36 +++++++------- packages/remix-netlify-edge/server.ts | 4 +- rollup.config.js | 1 - scripts/publish.js | 2 + tsconfig.json | 1 - 15 files changed, 170 insertions(+), 43 deletions(-) create mode 100644 packages/remix-netlify-edge/index.d.ts create mode 100644 packages/remix-netlify-edge/index.js create mode 100644 packages/remix-netlify-edge/mod.ts rename packages/remix-netlify-edge/{index.ts => remix-deno/mod.ts} (74%) diff --git a/.vscode/settings.json b/.vscode/settings.json index a3c5e6793f0..e01d2a45bb7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,9 @@ "deno.enablePaths": [ "./templates/deno/", "./templates/netlify/remix.init/edge-server.js", - "./packages/remix-netlify-edge/globals.ts" + "./packages/remix-netlify-edge/mod.ts", + "./packages/remix-netlify-edge/server.ts", + "./packages/remix-netlify-edge/remix-deno/" ], "deno.unstable": true, "deno.importMap": "deno-import-map.json" diff --git a/deno-import-map.json b/deno-import-map.json index ec08b4c705a..f6b3a8e67fa 100644 --- a/deno-import-map.json +++ b/deno-import-map.json @@ -1,8 +1,9 @@ { "imports": { - "netlify:edge": "https://dinosaurs:are-the-future!@edge-bootstrap.netlify.app/v1/index.ts", - "@remix-run/netlify-edge": "./packages/remix-netlify-edge/index.ts", - "@remix-run/dev/server-build": "./packages/remix-dev/server-build.ts", - "@remix-run/server-runtime": "./packages/remix-server-runtime/index.ts" + "netlify:edge": "https://edge-bootstrap.netlify.app/v1/index.ts", + "@remix-run/netlify-edge": "./packages/remix-netlify-edge/mod.ts", + "@remix-run/netlify-edge/deno": "./packages/remix-netlify-edge/remix-deno/mod.ts", + "@remix-run/dev/server-build": "https://esm.sh/@remix-run/dev/server-build", + "@remix-run/server-runtime": "https://esm.sh/@remix-run/server-runtime@1.3.5?pin=v77" } -} \ No newline at end of file +} diff --git a/packages/remix-dev/compiler.ts b/packages/remix-dev/compiler.ts index 5c9fceca3d9..56f2ff170cb 100644 --- a/packages/remix-dev/compiler.ts +++ b/packages/remix-dev/compiler.ts @@ -451,13 +451,17 @@ function createServerBuild( try { // If the user has it locally-installed, use that - runtimePath = `file://${require.resolve("@remix-run/netlify-edge", { - paths: [config.rootDirectory], - })}`; + runtimePath = `file://${require.resolve( + "@remix-run/netlify-edge/mod.ts", + { + paths: [config.rootDirectory], + } + )}`; } catch { - console.error("Please install '@remix-run/netlify-edge'"); - // When published, we can fall back to a URL import instead of bailing - // e.g. runtimePath = "https://esm.sh/@remix-run/netlify-edge"; + // ...otherwise, load it from the package URL. The env var is so we can override in dev. + runtimePath = + process.env.NETLIFY_EDGE_RUNTIME_PATH ?? + "https://unpkg.com/@remix-run/netlify-edge/mod.ts"; } let buildPath = require.resolve("./server-build.d.ts"); @@ -467,6 +471,8 @@ function createServerBuild( imports: { "@remix-run/netlify-edge": runtimePath, "@remix-run/dev/server-build": `file://${buildPath}`, + "@remix-run/server-runtime": + "https://esm.sh/@remix-run/server-runtime@1.3.5?pin=v77", }, }; diff --git a/packages/remix-dev/compiler/plugins/serverBareModulesPlugin.ts b/packages/remix-dev/compiler/plugins/serverBareModulesPlugin.ts index ba0bdeb653e..f1f24de2a2e 100644 --- a/packages/remix-dev/compiler/plugins/serverBareModulesPlugin.ts +++ b/packages/remix-dev/compiler/plugins/serverBareModulesPlugin.ts @@ -10,6 +10,12 @@ import { } from "../virtualModules"; import { createMatchPath } from "../utils/tsconfig"; +// Modules that have Deno import mappings +const denoModules = new Set([ + "@remix-run/netlify-edge", + "@remix-run/server-runtime", +]); + /** * A plugin responsible for resolving bare module ids based on server target. * This includes externalizing for node based plaforms, and bundling for single file @@ -80,11 +86,19 @@ export function serverBareModulesPlugin( } switch (remixConfig.serverBuildTarget) { - // Always bundle everything for Cloudflare and Netlify Edge. + // Always bundle everything for Cloudflare case "cloudflare-pages": case "cloudflare-workers": - case "netlify-edge": return undefined; + case "netlify-edge": + // Bundle everything except URL imports and aliased modules for Netlify Edge + if ( + !path.startsWith("https:") && + !path.startsWith("file:") && + !denoModules.has(path) + ) { + return undefined; + } } for (let pattern of remixConfig.serverDependenciesToBundle) { diff --git a/packages/remix-netlify-edge/index.d.ts b/packages/remix-netlify-edge/index.d.ts new file mode 100644 index 00000000000..3428a5ec5bc --- /dev/null +++ b/packages/remix-netlify-edge/index.d.ts @@ -0,0 +1,33 @@ +import type { + CreateCookieFunction, + CreateCookieSessionStorageFunction, + CreateSessionStorageFunction, + CreateMemorySessionStorageFunction, + ServerBuild, +} from "@remix-run/server-runtime"; + +interface BaseContext { + next: (options?: { sendConditionalRequest?: boolean }) => Promise; +} +export declare function createRequestHandler< + Context extends BaseContext = BaseContext +>({ + build, + mode, + getLoadContext, +}: { + build: ServerBuild; + mode?: string; + getLoadContext?: ( + request: Request, + context?: Context + ) => Promise | Context; +}): (request: Request, context: Context) => Promise; +export {}; + +export * from "@remix-run/server-runtime"; + +export const createCookie: CreateCookieFunction; +export const createCookieSessionStorage: CreateCookieSessionStorageFunction; +export const createSessionStorage: CreateSessionStorageFunction; +export const createMemorySessionStorage: CreateMemorySessionStorageFunction; diff --git a/packages/remix-netlify-edge/index.js b/packages/remix-netlify-edge/index.js new file mode 100644 index 00000000000..64ae914463b --- /dev/null +++ b/packages/remix-netlify-edge/index.js @@ -0,0 +1,12 @@ +/** + * @remix-run/netlify-edge + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */ + +// This package is meant to be imported by Deno, but includes types for Node diff --git a/packages/remix-netlify-edge/mod.ts b/packages/remix-netlify-edge/mod.ts new file mode 100644 index 00000000000..374b30e981f --- /dev/null +++ b/packages/remix-netlify-edge/mod.ts @@ -0,0 +1,48 @@ +export { createRequestHandler } from "./server.ts"; +export type { + ActionFunction, + AppData, + AppLoadContext, + CreateRequestHandlerFunction, + Cookie, + CookieOptions, + CookieParseOptions, + CookieSerializeOptions, + CookieSignatureOptions, + DataFunctionArgs, + EntryContext, + ErrorBoundaryComponent, + HandleDataRequestFunction, + HandleDocumentRequestFunction, + HeadersFunction, + HtmlLinkDescriptor, + HtmlMetaDescriptor, + LinkDescriptor, + LinksFunction, + LoaderFunction, + MetaDescriptor, + MetaFunction, + PageLinkDescriptor, + RequestHandler, + RouteComponent, + RouteHandle, + ServerBuild, + ServerEntryModule, + Session, + SessionData, + SessionIdStorageStrategy, + SessionStorage, +} from "https://esm.sh/@remix-run/server-runtime@1.3.5"; +export { + createSession, + isCookie, + isSession, + json, + redirect, +} from "https://esm.sh/@remix-run/server-runtime@1.3.5"; +export { + createCookie, + createCookieSessionStorage, + createMemorySessionStorage, + createSessionStorage, +} from "./remix-deno/implementations.ts"; diff --git a/packages/remix-netlify-edge/package.json b/packages/remix-netlify-edge/package.json index 6ebb249054a..69410e22323 100644 --- a/packages/remix-netlify-edge/package.json +++ b/packages/remix-netlify-edge/package.json @@ -3,6 +3,14 @@ "description": "Netlify Edge platform abstractions for Remix", "version": "1.0.0", "license": "MIT", + "type": "module", + "main": "./index.js", + "types": "./index.d.ts", + "exports": { + ".": "./index.js", + "./mod.ts": "./mod.ts", + "./deno": "./remix-deno/mod.ts" + }, "repository": { "type": "git", "url": "https://github.com/remix-run/remix", @@ -11,7 +19,11 @@ "bugs": { "url": "https://github.com/remix-run/remix/issues" }, - "dependencies": { - "@remix-run/server-runtime": "1.3.4" + "files": [ + "**/*.ts", + "index.js" + ], + "peerDependencies": { + "@remix-run/server-runtime": "*" } } diff --git a/packages/remix-netlify-edge/remix-deno/crypto.ts b/packages/remix-netlify-edge/remix-deno/crypto.ts index 60d183176e7..70fb5fd7033 100644 --- a/packages/remix-netlify-edge/remix-deno/crypto.ts +++ b/packages/remix-netlify-edge/remix-deno/crypto.ts @@ -1,4 +1,7 @@ -import type { SignFunction, UnsignFunction } from "@remix-run/server-runtime"; +import type { + SignFunction, + UnsignFunction, +} from "https://esm.sh/@remix-run/server-runtime?pin=v77"; const encoder = new TextEncoder(); diff --git a/packages/remix-netlify-edge/remix-deno/implementations.ts b/packages/remix-netlify-edge/remix-deno/implementations.ts index 51fa94796d5..c7ca5aae404 100644 --- a/packages/remix-netlify-edge/remix-deno/implementations.ts +++ b/packages/remix-netlify-edge/remix-deno/implementations.ts @@ -3,9 +3,9 @@ import { createCookieSessionStorageFactory, createMemorySessionStorageFactory, createSessionStorageFactory, -} from "@remix-run/server-runtime"; +} from "https://esm.sh/@remix-run/server-runtime?pin=v77"; -import { sign, unsign } from "./crypto"; +import { sign, unsign } from "./crypto.ts"; export const createCookie = createCookieFactory({ sign, unsign }); export const createCookieSessionStorage = diff --git a/packages/remix-netlify-edge/index.ts b/packages/remix-netlify-edge/remix-deno/mod.ts similarity index 74% rename from packages/remix-netlify-edge/index.ts rename to packages/remix-netlify-edge/remix-deno/mod.ts index 893173348c9..0ca12806659 100644 --- a/packages/remix-netlify-edge/index.ts +++ b/packages/remix-netlify-edge/remix-deno/mod.ts @@ -1,4 +1,18 @@ -export { createRequestHandler } from "./server"; +import "./globals.d.ts"; +export { + createCookie, + createCookieSessionStorage, + createMemorySessionStorage, + createSessionStorage, +} from "./implementations.ts"; + +export { + createSession, + isCookie, + isSession, + json, + redirect, +} from "https://esm.sh/@remix-run/server-runtime?pin=v77"; export type { ActionFunction, @@ -33,22 +47,4 @@ export type { SessionData, SessionIdStorageStrategy, SessionStorage, -} from "@remix-run/server-runtime"; - -export { - createSession, - isCookie, - isSession, - json, - redirect, -} from "@remix-run/server-runtime"; - -// Once the @remix-run/deno runtime has been published then we -// can remove these exports and re-export that instead. - -export { - createCookie, - createCookieSessionStorage, - createMemorySessionStorage, - createSessionStorage, -} from "./remix-deno/implementations"; +} from "https://esm.sh/@remix-run/server-runtime?pin=v77"; diff --git a/packages/remix-netlify-edge/server.ts b/packages/remix-netlify-edge/server.ts index 95060b2b732..616a36a1ff3 100644 --- a/packages/remix-netlify-edge/server.ts +++ b/packages/remix-netlify-edge/server.ts @@ -1,5 +1,5 @@ -import { createRequestHandler as createRemixRequestHandler } from "@remix-run/server-runtime"; -import type { ServerBuild } from "@remix-run/server-runtime"; +import type { ServerBuild } from "https://esm.sh/@remix-run/server-runtime@1.3.5?pin=v77"; +import { createRequestHandler as createRemixRequestHandler } from "https://esm.sh/@remix-run/server-runtime@1.3.5?pin=v77"; // This can be replaced with the full context type when that is published interface BaseContext { diff --git a/rollup.config.js b/rollup.config.js index 0cbf84f1e46..155611e9069 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -672,7 +672,6 @@ function remixServerAdapters() { ...getAdapterConfig("cloudflare-workers"), ...getAdapterConfig("express"), ...getAdapterConfig("netlify"), - ...getAdapterConfig("netlify-edge"), ...getAdapterConfig("vercel"), ]; } diff --git a/scripts/publish.js b/scripts/publish.js index a50fb4b01d0..4cb7659b4fb 100644 --- a/scripts/publish.js +++ b/scripts/publish.js @@ -30,6 +30,8 @@ async function run() { // Publish eslint config directly from the package directory publish(path.join(packageDir, "remix-eslint-config"), tag); + publish(path.join(packageDir, "remix-netlify-edge"), tag); + // Publish all @remix-run/* packages for (let name of [ "dev", diff --git a/tsconfig.json b/tsconfig.json index 3cbf957bdf1..8ccfcf30261 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,6 @@ { "path": "packages/remix-dev" }, { "path": "packages/remix-express" }, { "path": "packages/remix-netlify" }, - { "path": "packages/remix-netlify-edge" }, { "path": "packages/remix-node" }, { "path": "packages/remix-react" }, { "path": "packages/remix-serve" }, From 5036dd95fa82fe09eb9135bb7de41a56fda2e303 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Sat, 16 Apr 2022 09:51:41 +0100 Subject: [PATCH 09/12] chore: switch to standard inquirer list --- templates/netlify/remix.init/index.js | 37 +- .../netlify/remix.init/package-lock.json | 633 ++++++++++++++++-- templates/netlify/remix.init/package.json | 2 +- 3 files changed, 599 insertions(+), 73 deletions(-) diff --git a/templates/netlify/remix.init/index.js b/templates/netlify/remix.init/index.js index e31b525b5cb..aabe47b7c55 100644 --- a/templates/netlify/remix.init/index.js +++ b/templates/netlify/remix.init/index.js @@ -1,4 +1,4 @@ -const select = require("@inquirer/select"); +const inquirer = require("inquirer"); const fs = require("fs/promises"); const { join } = require("path"); @@ -24,24 +24,23 @@ async function main({ rootDirectory }) { } async function shouldUseEdge() { - let edge = await select({ - name: "edge", - default: false, - message: "Run your Remix site with:", - choices: [ - { - name: "Netlify Functions", - description: "Choose this for stable support for production sites", - value: false, - }, - { - name: "Netlify Edge Functions (beta)", - description: - "Try this experimental beta for improved performance on non-critical sites", - value: true, - }, - ], - }); + let { edge } = await inquirer.prompt([ + { + name: "edge", + type: "list", + message: "Run your Remix site with:", + choices: [ + { + name: "Netlify Functions - Choose this for stable support for production sites", + value: false, + }, + { + name: "Netlify Edge Functions - Try this experimental beta for improved performance on non-critical sites", + value: true, + }, + ], + }, + ]); return edge; } diff --git a/templates/netlify/remix.init/package-lock.json b/templates/netlify/remix.init/package-lock.json index e8aa28aadf4..16e380761cc 100644 --- a/templates/netlify/remix.init/package-lock.json +++ b/templates/netlify/remix.init/package-lock.json @@ -9,33 +9,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@inquirer/select": "^0.0.18-alpha.0" - } - }, - "node_modules/@inquirer/core": { - "version": "0.0.18-alpha.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-0.0.18-alpha.0.tgz", - "integrity": "sha512-skK1xe87YyIXHDdA4kYzkzEzaUEnndh7ygOQrKHCrIzHy/V8xmJfyDIAJauNZXSBn9RHqxCCqAqTo1ifyIJwCw==", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-spinners": "^2.6.1", - "cli-width": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "^0.0.8", - "run-async": "^2.3.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "node_modules/@inquirer/select": { - "version": "0.0.18-alpha.0", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-0.0.18-alpha.0.tgz", - "integrity": "sha512-NIjgoHx7YQTbsrVm0hWtdljFGwIKgenzmeeynvudpivbwh2ak1GzcOZ7STd+MJ1u3IAgC8F0FKx9PwwalcE/8Q==", - "dependencies": { - "@inquirer/core": "^0.0.18-alpha.0", - "chalk": "^4.1.1", - "figures": "^3.0.0" + "inquirer": "^8.2.2" } }, "node_modules/ansi-escapes": { @@ -74,6 +48,58 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -89,6 +115,22 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cli-spinners": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", @@ -108,6 +150,14 @@ "node": ">= 10" } }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "engines": { + "node": ">=0.8" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -124,6 +174,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dependencies": { + "clone": "^1.0.2" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -137,6 +195,19 @@ "node": ">=0.8.0" } }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -159,6 +230,65 @@ "node": ">=8" } }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/inquirer": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.2.tgz", + "integrity": "sha512-pG7I/si6K/0X7p1qU+rfWnpTE1UIkTONN1wxtzh0d+dHXtT/JG6qBgLxoyHVsQa8cFABxAPh0pD6uUUHiAoaow==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -167,16 +297,127 @@ "node": ">=8" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -185,6 +426,51 @@ "node": ">=0.12.0" } }, + "node_modules/rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -220,6 +506,27 @@ "node": ">=8" } }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -230,35 +537,22 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dependencies": { + "defaults": "^1.0.3" + } } }, "dependencies": { - "@inquirer/core": { - "version": "0.0.18-alpha.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-0.0.18-alpha.0.tgz", - "integrity": "sha512-skK1xe87YyIXHDdA4kYzkzEzaUEnndh7ygOQrKHCrIzHy/V8xmJfyDIAJauNZXSBn9RHqxCCqAqTo1ifyIJwCw==", - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-spinners": "^2.6.1", - "cli-width": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "^0.0.8", - "run-async": "^2.3.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "@inquirer/select": { - "version": "0.0.18-alpha.0", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-0.0.18-alpha.0.tgz", - "integrity": "sha512-NIjgoHx7YQTbsrVm0hWtdljFGwIKgenzmeeynvudpivbwh2ak1GzcOZ7STd+MJ1u3IAgC8F0FKx9PwwalcE/8Q==", - "requires": { - "@inquirer/core": "^0.0.18-alpha.0", - "chalk": "^4.1.1", - "figures": "^3.0.0" - } - }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -280,6 +574,30 @@ "color-convert": "^2.0.1" } }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -289,6 +607,19 @@ "supports-color": "^7.1.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, "cli-spinners": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", @@ -299,6 +630,11 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -312,6 +648,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "requires": { + "clone": "^1.0.2" + } + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -322,6 +666,16 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -335,26 +689,168 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "inquirer": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.2.tgz", + "integrity": "sha512-pG7I/si6K/0X7p1qU+rfWnpTE1UIkTONN1wxtzh0d+dHXtT/JG6qBgLxoyHVsQa8cFABxAPh0pD6uUUHiAoaow==", + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + } + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" }, + "rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "requires": { + "tslib": "^2.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -381,10 +877,41 @@ "has-flag": "^4.0.0" } }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, "type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "requires": { + "defaults": "^1.0.3" + } } } } diff --git a/templates/netlify/remix.init/package.json b/templates/netlify/remix.init/package.json index 36c92682879..18c0e439ea6 100644 --- a/templates/netlify/remix.init/package.json +++ b/templates/netlify/remix.init/package.json @@ -5,6 +5,6 @@ "license": "MIT", "private": true, "dependencies": { - "@inquirer/select": "^0.0.18-alpha.0" + "inquirer": "^8.2.2" } } From 6620dae08b5f35b6a54c324852a4cbaf27ebc844 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Tue, 19 Apr 2022 15:04:12 +0100 Subject: [PATCH 10/12] fix: prompt wording --- templates/netlify/remix.init/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/netlify/remix.init/index.js b/templates/netlify/remix.init/index.js index aabe47b7c55..5fcbaadcab2 100644 --- a/templates/netlify/remix.init/index.js +++ b/templates/netlify/remix.init/index.js @@ -35,7 +35,7 @@ async function shouldUseEdge() { value: false, }, { - name: "Netlify Edge Functions - Try this experimental beta for improved performance on non-critical sites", + name: "Netlify Edge Functions (beta) - Try this for improved performance on non-critical sites", value: true, }, ], From e310d925ac427c448d8f4021e704e70df3202d6d Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Tue, 19 Apr 2022 15:17:52 +0100 Subject: [PATCH 11/12] chore: target tagged package --- packages/remix-dev/compiler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remix-dev/compiler.ts b/packages/remix-dev/compiler.ts index 0edfe050196..b83de983270 100644 --- a/packages/remix-dev/compiler.ts +++ b/packages/remix-dev/compiler.ts @@ -466,7 +466,7 @@ function createServerBuild( // ...otherwise, load it from the package URL. The env var is so we can override in dev. runtimePath = process.env.NETLIFY_EDGE_RUNTIME_PATH ?? - "https://unpkg.com/@remix-run/netlify-edge/mod.ts"; + "https://unpkg.com/@remix-run/netlify-edge@experimental-netlify-edge/mod.ts"; } let buildPath = require.resolve("./server-build.d.ts"); From a7ed7d302079e9aa34dfa20014960c6b72debd68 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Tue, 19 Apr 2022 15:19:47 +0100 Subject: [PATCH 12/12] chore: update internal deps --- deno-import-map.json | 2 +- packages/remix-dev/compiler.ts | 2 +- packages/remix-netlify-edge/mod.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/deno-import-map.json b/deno-import-map.json index f6b3a8e67fa..59f1b452fc9 100644 --- a/deno-import-map.json +++ b/deno-import-map.json @@ -4,6 +4,6 @@ "@remix-run/netlify-edge": "./packages/remix-netlify-edge/mod.ts", "@remix-run/netlify-edge/deno": "./packages/remix-netlify-edge/remix-deno/mod.ts", "@remix-run/dev/server-build": "https://esm.sh/@remix-run/dev/server-build", - "@remix-run/server-runtime": "https://esm.sh/@remix-run/server-runtime@1.3.5?pin=v77" + "@remix-run/server-runtime": "https://esm.sh/@remix-run/server-runtime@1.4.1?pin=v77" } } diff --git a/packages/remix-dev/compiler.ts b/packages/remix-dev/compiler.ts index b83de983270..9442aec7c14 100644 --- a/packages/remix-dev/compiler.ts +++ b/packages/remix-dev/compiler.ts @@ -477,7 +477,7 @@ function createServerBuild( "@remix-run/netlify-edge": runtimePath, "@remix-run/dev/server-build": `file://${buildPath}`, "@remix-run/server-runtime": - "https://esm.sh/@remix-run/server-runtime@1.3.5?pin=v77", + "https://esm.sh/@remix-run/server-runtime@1.4.1?pin=v77", }, }; diff --git a/packages/remix-netlify-edge/mod.ts b/packages/remix-netlify-edge/mod.ts index 374b30e981f..1db3cc9e501 100644 --- a/packages/remix-netlify-edge/mod.ts +++ b/packages/remix-netlify-edge/mod.ts @@ -32,14 +32,14 @@ export type { SessionData, SessionIdStorageStrategy, SessionStorage, -} from "https://esm.sh/@remix-run/server-runtime@1.3.5"; +} from "https://esm.sh/@remix-run/server-runtime@1.4.1"; export { createSession, isCookie, isSession, json, redirect, -} from "https://esm.sh/@remix-run/server-runtime@1.3.5"; +} from "https://esm.sh/@remix-run/server-runtime@1.4.1"; export { createCookie, createCookieSessionStorage,