From 8d780ef31590a807043d89ee9dd2ac861df9d8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20De=20Boey?= Date: Tue, 17 May 2022 23:05:58 +0200 Subject: [PATCH 1/5] feat(remix-deno): export new `@remix-run/server-runtime` upload functions & types (#3215) --- packages/remix-deno/index.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/remix-deno/index.ts b/packages/remix-deno/index.ts index e422c53858a..161cc02580d 100644 --- a/packages/remix-deno/index.ts +++ b/packages/remix-deno/index.ts @@ -18,7 +18,11 @@ export { isCookie, isSession, json, + MaxPartSizeExceededError, redirect, + unstable_composeUploadHandlers, + unstable_createMemoryUploadHandler, + unstable_parseMultipartFormData, } from "@remix-run/server-runtime"; export type { @@ -42,6 +46,8 @@ export type { LinkDescriptor, LinksFunction, LoaderFunction, + MemoryUploadHandlerFilterArgs, + MemoryUploadHandlerOptions, MetaDescriptor, MetaFunction, PageLinkDescriptor, @@ -54,4 +60,6 @@ export type { SessionData, SessionIdStorageStrategy, SessionStorage, + UploadHandler, + UploadHandlerPart, } from "@remix-run/server-runtime"; From 8303a240b36cb134da15bc8c7162d6ff229877b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20De=20Boey?= Date: Wed, 18 May 2022 00:42:59 +0200 Subject: [PATCH 2/5] feat(remix-dev/cli): let `replace-remix-imports` migration re-install to update lockfile (#2864) --- .../__tests__/replace-remix-imports-test.ts | 9 ++--- packages/remix-dev/cli/commands.ts | 15 +++----- packages/remix-dev/cli/create.ts | 7 ++-- .../cli/getPreferredPackageManager.ts | 12 ++++++ .../migrations/replace-remix-imports/index.ts | 21 +++++++---- packages/remix-dev/cli/migrate/run.ts | 7 ++-- packages/remix-dev/cli/migrate/types.ts | 2 +- packages/remix-dev/cli/run.ts | 37 +++++-------------- 8 files changed, 53 insertions(+), 57 deletions(-) create mode 100644 packages/remix-dev/cli/getPreferredPackageManager.ts diff --git a/packages/remix-dev/__tests__/replace-remix-imports-test.ts b/packages/remix-dev/__tests__/replace-remix-imports-test.ts index 9f259202d94..3d635afd909 100644 --- a/packages/remix-dev/__tests__/replace-remix-imports-test.ts +++ b/packages/remix-dev/__tests__/replace-remix-imports-test.ts @@ -1,10 +1,10 @@ +import os from "os"; import path from "path"; import fse from "fs-extra"; -import os from "os"; +import glob from "fast-glob"; +import shell from "shelljs"; import stripAnsi from "strip-ansi"; import type { PackageJson } from "type-fest"; -import shell from "shelljs"; -import glob from "fast-glob"; import { run } from "../cli/run"; import { readConfig } from "../config"; @@ -110,6 +110,5 @@ describe("`replace-remix-imports` migration", () => { expect(result.code).toBe(0); expect(output).toContain("successfully migrated"); - expect(output).toContain("npm install"); - }, 25_000); + }, 200_000); }); diff --git a/packages/remix-dev/cli/commands.ts b/packages/remix-dev/cli/commands.ts index 3201296fd66..320ac28166d 100644 --- a/packages/remix-dev/cli/commands.ts +++ b/packages/remix-dev/cli/commands.ts @@ -17,9 +17,10 @@ import * as compiler from "../compiler"; import type { RemixConfig } from "../config"; import { readConfig } from "../config"; import { formatRoutes, RoutesFormat, isRoutesFormat } from "../config/format"; -import { createApp } from "./create"; import { loadEnv } from "../env"; import { log } from "../logging"; +import { createApp } from "./create"; +import { getPreferredPackageManager } from "./getPreferredPackageManager"; import { setupRemix, isSetupPlatform, SetupPlatform } from "./setup"; export * as migrate from "./migrate"; @@ -29,7 +30,6 @@ export async function create({ projectDir, remixVersion, installDeps, - packageManager, useTypeScript, githubToken, debug, @@ -38,7 +38,6 @@ export async function create({ projectDir: string; remixVersion?: string; installDeps: boolean; - packageManager: "npm" | "yarn" | "pnpm"; useTypeScript: boolean; githubToken?: string; debug?: boolean; @@ -49,7 +48,6 @@ export async function create({ projectDir, remixVersion, installDeps, - packageManager, useTypeScript, githubToken, debug, @@ -58,10 +56,7 @@ export async function create({ spinner.clear(); } -export async function init( - projectDir: string, - packageManager: "npm" | "yarn" | "pnpm" -) { +export async function init(projectDir: string) { let initScriptDir = path.join(projectDir, "remix.init"); let initScript = path.resolve(initScriptDir, "index.js"); let initPackageJson = path.resolve(initScriptDir, "package.json"); @@ -69,10 +64,12 @@ export async function init( let isTypeScript = fse.existsSync(path.join(projectDir, "tsconfig.json")); if (await fse.pathExists(initScript)) { + let packageManager = getPreferredPackageManager(); + if (await fse.pathExists(initPackageJson)) { execSync(`${packageManager} install`, { - stdio: "ignore", cwd: initScriptDir, + stdio: "ignore", }); } diff --git a/packages/remix-dev/cli/create.ts b/packages/remix-dev/cli/create.ts index d5637a106dd..a7a7a168329 100644 --- a/packages/remix-dev/cli/create.ts +++ b/packages/remix-dev/cli/create.ts @@ -14,6 +14,7 @@ import sortPackageJSON from "sort-package-json"; import * as colors from "../colors"; import packageJson from "../package.json"; import { convertTemplateToJavaScript } from "./convert-to-javascript"; +import { getPreferredPackageManager } from "./getPreferredPackageManager"; const remixDevPackageVersion = packageJson.version; @@ -22,7 +23,6 @@ interface CreateAppArgs { projectDir: string; remixVersion?: string; installDeps: boolean; - packageManager: "npm" | "yarn" | "pnpm"; useTypeScript: boolean; githubToken?: string; debug?: boolean; @@ -33,7 +33,6 @@ export async function createApp({ projectDir, remixVersion = remixDevPackageVersion, installDeps, - packageManager, useTypeScript = true, githubToken = process.env.GITHUB_TOKEN, debug, @@ -197,6 +196,8 @@ export async function createApp({ } if (installDeps) { + let packageManager = getPreferredPackageManager(); + let npmConfig = execSync( `${packageManager} config get @remix-run:registry`, { @@ -212,8 +213,8 @@ export async function createApp({ } execSync(`${packageManager} install`, { - stdio: "inherit", cwd: projectDir, + stdio: "inherit", }); } } diff --git a/packages/remix-dev/cli/getPreferredPackageManager.ts b/packages/remix-dev/cli/getPreferredPackageManager.ts new file mode 100644 index 00000000000..d4dd9dd4264 --- /dev/null +++ b/packages/remix-dev/cli/getPreferredPackageManager.ts @@ -0,0 +1,12 @@ +type PackageManager = "npm" | "pnpm" | "yarn"; + +/** + * Determine which package manager the user prefers. + * + * npm, pnpm and Yarn set the user agent environment variable + * that can be used to determine which package manager ran + * the command. + */ +export const getPreferredPackageManager = () => + ((process.env.npm_config_user_agent ?? "").split("/")[0] || + "npm") as PackageManager; diff --git a/packages/remix-dev/cli/migrate/migrations/replace-remix-imports/index.ts b/packages/remix-dev/cli/migrate/migrations/replace-remix-imports/index.ts index b60cc717374..dbd32dd46dd 100644 --- a/packages/remix-dev/cli/migrate/migrations/replace-remix-imports/index.ts +++ b/packages/remix-dev/cli/migrate/migrations/replace-remix-imports/index.ts @@ -1,3 +1,4 @@ +import { execSync } from "child_process"; import { join } from "path"; import NpmCliPackageJson from "@npmcli/package-json"; import glob from "fast-glob"; @@ -6,6 +7,7 @@ import semver from "semver"; import * as colors from "../../../../colors"; import { readConfig } from "../../../../config"; +import { getPreferredPackageManager } from "../../../getPreferredPackageManager"; import * as jscodeshift from "../../jscodeshift"; import type { MigrationFunction } from "../../types"; import type { Dependency } from "./dependency"; @@ -74,13 +76,13 @@ const shouldKeepPostinstall = (original?: string): boolean => { }; export const replaceRemixImports: MigrationFunction = async ({ - projectDir, flags, + projectDir, }) => { let pkg = await NpmCliPackageJson.load(projectDir); // 0. resolve runtime and adapter - let { runtime, adapter } = await resolveTransformOptions(pkg.content); + let { adapter, runtime } = await resolveTransformOptions(pkg.content); let deps = depsToEntries(pkg.content.dependencies); let remixDeps = deps.filter(({ name }) => isRemixPackage(name)); @@ -142,13 +144,20 @@ export const replaceRemixImports: MigrationFunction = async ({ // write updates to package.json await pkg.save(); - // 3. Run codemod + // 3. Update lockfile for new dependencies by reinstalling + console.log("\nšŸ’æ I'm updating your lockfile"); + console.log(because("your dependencies changed.")); + let packageManager = getPreferredPackageManager(); + execSync(`${packageManager} install`, { cwd: projectDir, stdio: "inherit" }); + console.log("āœ… Your lockfile looks good!"); + + // 4. Run codemod console.log("\nšŸ’æ I'm replacing any `remix` imports"); console.log(because("importing from `remix` is deprecated.")); let config = await readConfig(projectDir); let files = glob.sync("**/*.+(js|jsx|ts|tsx)", { - cwd: config.appDirectory, absolute: true, + cwd: config.appDirectory, }); let codemodOk = await jscodeshift.run({ files, @@ -166,8 +175,4 @@ export const replaceRemixImports: MigrationFunction = async ({ console.log("āœ… Your Remix imports look good!"); console.log("\nšŸšš I've successfully migrated your project! šŸŽ‰"); - console.log( - "\nšŸ‘‰ Reinstall from your updated `package.json` to update your lockfile" - ); - console.log(` ${colors.blue("npm install")}`); }; diff --git a/packages/remix-dev/cli/migrate/run.ts b/packages/remix-dev/cli/migrate/run.ts index df52775f612..0b48578fb2e 100644 --- a/packages/remix-dev/cli/migrate/run.ts +++ b/packages/remix-dev/cli/migrate/run.ts @@ -1,9 +1,9 @@ import fse from "fs-extra"; +import * as colors from "../../colors"; import type { Flags } from "./flags"; import { migrations } from "./migrations"; import type { Migration } from "./types"; -import * as colors from "../../colors"; const parseMigration = (migrationId: string): Migration => { let migration = migrations.find(({ id }) => id === migrationId); @@ -27,11 +27,12 @@ const checkProjectDir = (projectDir: string): string => { }; export const run = async (input: { + flags: Flags; migrationId: string; projectDir: string; - flags: Flags; }) => { let projectDir = checkProjectDir(input.projectDir); let migration = parseMigration(input.migrationId); - return migration.function({ projectDir, flags: input.flags }); + + return migration.function({ flags: input.flags, projectDir }); }; diff --git a/packages/remix-dev/cli/migrate/types.ts b/packages/remix-dev/cli/migrate/types.ts index e57729d76cb..89a79fb54d8 100644 --- a/packages/remix-dev/cli/migrate/types.ts +++ b/packages/remix-dev/cli/migrate/types.ts @@ -1,8 +1,8 @@ import type { Flags } from "./flags"; export type MigrationFunction = (args: { - projectDir: string; flags: Flags; + projectDir: string; }) => Promise; export interface Migration { diff --git a/packages/remix-dev/cli/run.ts b/packages/remix-dev/cli/run.ts index 8dcc7d1dd72..74237e2e147 100644 --- a/packages/remix-dev/cli/run.ts +++ b/packages/remix-dev/cli/run.ts @@ -11,19 +11,7 @@ import * as colors from "../colors"; import * as commands from "./commands"; import { convertTemplateToJavaScript } from "./convert-to-javascript"; import { validateNewProjectPath, validateTemplate } from "./create"; - -/** - * Determine which package manager the user prefers. - * - * npm, Yarn and pnpm set the user agent environment variable - * that can be used to determine which package manager ran - * the command. - */ -const getPreferredPackageManager = () => - ((process.env.npm_config_user_agent ?? "").split("/")[0] || "npm") as - | "npm" - | "yarn" - | "pnpm"; +import { getPreferredPackageManager } from "./getPreferredPackageManager"; const helpText = ` ${colors.logoBlue("R")} ${colors.logoGreen("E")} ${colors.logoYellow( @@ -241,7 +229,7 @@ export async function run(argv: string[] = process.argv.slice(2)) { return; } - let pm = getPreferredPackageManager(); + let packageManager = getPreferredPackageManager(); let answers = await inquirer .prompt<{ appType: "template" | "stack"; @@ -307,7 +295,7 @@ export async function run(argv: string[] = process.argv.slice(2)) { { name: "install", type: "confirm", - message: `Do you want me to run \`${pm} install\`?`, + message: `Do you want me to run \`${packageManager} install\`?`, when() { return flags.install === undefined; }, @@ -321,7 +309,7 @@ export async function run(argv: string[] = process.argv.slice(2)) { "šŸšØ Your terminal doesn't support interactivity; using default " + "configuration.\n\n" + "If you'd like to use different settings, try passing them " + - `as arguments. Run \`${pm} create remix@latest --help\` to see ` + + `as arguments. Run \`${packageManager} create remix@latest --help\` to see ` + "available options." ) ); @@ -342,7 +330,6 @@ export async function run(argv: string[] = process.argv.slice(2)) { projectDir, remixVersion: flags.remixVersion, installDeps, - packageManager: pm, useTypeScript: flags.typescript !== false, githubToken: process.env.GITHUB_TOKEN, debug: flags.debug, @@ -378,7 +365,7 @@ export async function run(argv: string[] = process.argv.slice(2)) { if (hasInitScript) { if (installDeps) { console.log("šŸ’æ Running remix.init script"); - await commands.init(projectDir, pm); + await commands.init(projectDir); await fse.remove(initScriptDir); } else { console.log(); @@ -387,7 +374,7 @@ export async function run(argv: string[] = process.argv.slice(2)) { "šŸ’æ You've opted out of installing dependencies so we won't run the " + path.join("remix.init", "index.js") + " script for you just yet. Once you've installed " + - `dependencies, you can run it manually with \`${npxInterop[pm]} remix init\`` + `dependencies, you can run it manually with \`${npxInterop[packageManager]} remix init\`` ) ); console.log(); @@ -413,10 +400,7 @@ export async function run(argv: string[] = process.argv.slice(2)) { break; } case "init": - await commands.init( - input[1] || process.env.REMIX_ROOT || process.cwd(), - getPreferredPackageManager() - ); + await commands.init(input[1] || process.env.REMIX_ROOT || process.cwd()); break; case "routes": await commands.routes(input[1], flags.json ? "json" : "jsx"); @@ -434,13 +418,10 @@ export async function run(argv: string[] = process.argv.slice(2)) { break; case "migrate": { let { projectDir, migrationId } = await commands.migrate.resolveInput( - { - projectId: input[1], - migrationId: flags.migration, - }, + { migrationId: flags.migration, projectId: input[1] }, flags ); - await commands.migrate.run({ migrationId, projectDir, flags }); + await commands.migrate.run({ flags, migrationId, projectDir }); break; } case "dev": From 3eab3659329573f986615d0f7e69b6c9355d5ffe Mon Sep 17 00:00:00 2001 From: Logan McAnsh Date: Tue, 17 May 2022 23:50:37 -0400 Subject: [PATCH 3/5] chore(remix-dev): remove suggested `paths` from default tsconfig (#3181) --- integration/tsconfig-test.ts | 3 --- .../remix-dev/compiler/utils/tsconfig/write-config-defaults.ts | 3 --- 2 files changed, 6 deletions(-) diff --git a/integration/tsconfig-test.ts b/integration/tsconfig-test.ts index aee7099660e..f2f80e8d4ac 100644 --- a/integration/tsconfig-test.ts +++ b/integration/tsconfig-test.ts @@ -27,9 +27,6 @@ const DEFAULT_CONFIG = { strict: true, target: "ES2019", baseUrl: ".", - paths: { - "~/*": ["./app/*"], - }, }, }; diff --git a/packages/remix-dev/compiler/utils/tsconfig/write-config-defaults.ts b/packages/remix-dev/compiler/utils/tsconfig/write-config-defaults.ts index 7e20646ce69..320e37e4c7b 100644 --- a/packages/remix-dev/compiler/utils/tsconfig/write-config-defaults.ts +++ b/packages/remix-dev/compiler/utils/tsconfig/write-config-defaults.ts @@ -13,9 +13,6 @@ let suggestedCompilerOptions: TsConfigJson.CompilerOptions = { allowJs: true, forceConsistentCasingInFileNames: true, lib: ["DOM", "DOM.Iterable", "ES2019"], - paths: { - "~/*": ["./app/*"], - }, strict: true, target: "ES2019", }; From d141d683c9d9c020e377e94664048516d9a40de7 Mon Sep 17 00:00:00 2001 From: Chance Strickland Date: Wed, 18 May 2022 07:32:50 -0500 Subject: [PATCH 4/5] chore: ignore test workflow on scripts change --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 28918bbcacc..55f4862f081 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,6 +10,7 @@ on: - v* paths-ignore: - "docs/**" + - "scripts/**" - "**/README.md" pull_request: {} From b4fb6c5ebc548afa85b275931e31a564a226fdc0 Mon Sep 17 00:00:00 2001 From: Chance Strickland Date: Wed, 18 May 2022 08:42:00 -0500 Subject: [PATCH 5/5] fix(scripts): Prevent publishing without a tag (#3223) --- scripts/publish-private.js | 13 ++++++++++++- scripts/publish.js | 13 ++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/scripts/publish-private.js b/scripts/publish-private.js index 89b8d978319..37fe0bb00c2 100644 --- a/scripts/publish-private.js +++ b/scripts/publish-private.js @@ -10,6 +10,10 @@ function getTaggedVersion() { return output.replace(/^v/g, ""); } +/** + * @param {string} dir + * @param {string} tag + */ function publish(dir, tag) { execSync(`npm publish --tag ${tag} ${dir}`, { stdio: "inherit" }); } @@ -23,7 +27,14 @@ async function run() { } let prerelease = semver.prerelease(taggedVersion); - let tag = prerelease ? prerelease[0] : "latest"; + let prereleaseTag = prerelease ? String(prerelease[0]) : undefined; + let tag = prereleaseTag + ? prereleaseTag.includes("nightly") + ? "nightly" + : prereleaseTag.includes("experimental") + ? "experimental" + : prereleaseTag + : "latest"; // Publish all @remix-run/* packages for (let name of [ diff --git a/scripts/publish.js b/scripts/publish.js index 32d893f04c2..12accadb20f 100644 --- a/scripts/publish.js +++ b/scripts/publish.js @@ -10,11 +10,14 @@ function getTaggedVersion() { return output.replace(/^v/g, ""); } +/** + * @param {string} dir + * @param {string} tag + */ function publish(dir, tag) { - execSync( - `npm publish --access public${tag != null ? ` --tag ${tag}` : ""} ${dir}`, - { stdio: "inherit" } - ); + execSync(`npm publish --access public --tag ${tag} ${dir}`, { + stdio: "inherit", + }); } async function run() { @@ -31,7 +34,7 @@ async function run() { ? prereleaseTag.includes("nightly") ? "nightly" : prereleaseTag.includes("experimental") - ? null + ? "experimental" : prereleaseTag : "latest";