Skip to content

chore(deps): update remix guide and playground - #1204

Open
edmundhung wants to merge 3 commits into
mainfrom
update-security-guide-playground
Open

chore(deps): update remix guide and playground#1204
edmundhung wants to merge 3 commits into
mainfrom
update-security-guide-playground

Conversation

@edmundhung

@edmundhung edmundhung commented Apr 24, 2026

Copy link
Copy Markdown
Owner
Generated Summary

guide/package.json

  • Bumps Remix Cloudflare and React packages to ^2.17.4: @remix-run/cloudflare, @remix-run/cloudflare-pages, @remix-run/react
  • Updates dev tooling: @remix-run/dev -> ^2.17.4, @cloudflare/workers-types -> ^4.20250408.0, wrangler -> ^3.114.17

playground/package.json

  • Aligns playground Remix packages and dev tooling to ^2.17.4: @remix-run/node, @remix-run/react, @remix-run/serve, @remix-run/dev

playground/app/routes/file-upload.tsx

  • Replaces server-side parse flow to use a custom parseFileUpload(formData) -> parse(payload, { resolve(...) }) that:
    • Normalizes empty single/array file uploads (empty file -> undefined; empty entries filtered)
    • Treats JsonFile as a Blob and validates MIME/type via Zod
    • Runs schema.safeParse and maps Zod issues to a { [fieldPath]: string[] } error shape with formatPaths
    • Returns parse result via submission.reply() (action returns json(submission.reply()))
  • Client-side validation still uses parseWithZod in onValidate when enabled; no public API/signature changes.

Example (server parse resolver):

function parseFileUpload(payload: FormData) {
  return parse(payload, {
    resolve(payload) {
      const result = schema.safeParse({
        file: normalizeFile(payload.file),
        files: normalizeFiles(payload.files),
      });
      return {
        value: result.success ? result.data : undefined,
        error: result.success ? undefined : getError(result.error.issues),
      };
    },
  });
}

@changeset-bot

changeset-bot Bot commented Apr 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 9934b12

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Apr 24, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Upgrade Remix and Cloudflare-related dependencies in two package.json files; replace server-side file upload parsing/validation flow in playground/app/routes/file-upload.tsx to use a custom parse/normalize -> zod.safeParse -> formatted-error resolver pipeline.

Changes

Cohort / File(s) Summary
Guide: Remix & Cloudflare tooling
guide/package.json
Bumps @remix-run/cloudflare, @remix-run/cloudflare-pages, @remix-run/react, and @remix-run/dev to ^2.17.4; updates @cloudflare/workers-types to ^4.20250408.0; bumps wrangler to ^3.114.17.
Playground: Remix runtime & dev tooling
playground/package.json
Updates @remix-run/node, @remix-run/react, @remix-run/serve, and @remix-run/dev from ^2.9.1 to ^2.17.4.
Playground: File upload parsing & validation
playground/app/routes/file-upload.tsx
Replaces parseWithZod with parseFileUpload using @conform-to/dom parsing; treats JsonFile as Blob; normalizes/removes empty uploads (single empty -> undefined, filters empty arrays); validates via schema.safeParse; formats Zod errors into { [path]: string[] } and returns as resolver error, successful parse returns value; action returns json(submission.reply()) based on new parse result.

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant Server
  participant Parser as "parseFileUpload\n(`@conform-to/dom`)"
  participant Normalizer
  participant Zod as "schema.safeParse"
  participant Resolver

  Browser->>Server: POST multipart/form-data (files + fields)
  Server->>Parser: parse incoming FormData
  Parser->>Normalizer: produce raw field values (File/Blob/arrays)
  Normalizer->>Zod: normalize (remove empty uploads, convert JsonFile→Blob) and call safeParse
  Zod-->>Resolver: success (value) or failure (errors)
  Resolver-->>Server: format errors into {path: string[]} or return value
  Server-->>Browser: json(submission.reply()) with parsed result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hopped through code and chewed a bit of string,

Files now parse and sing when uploads swing.
Empty crumbs are tossed aside with care,
Versions bumped — we leap without a scare.
🥕✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: dependency version updates across guide and playground package.json files for Remix and related tooling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Apr 24, 2026

Copy link
Copy Markdown

Deploying conform with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9934b12
Status: ✅  Deploy successful!
Preview URL: https://23be4cc2.conform.pages.dev
Branch Preview URL: https://update-security-guide-playgr.conform.pages.dev

View logs

@pkg-pr-new

pkg-pr-new Bot commented Apr 24, 2026

Copy link
Copy Markdown
More templates

@conform-to/dom

npm i https://pkg.pr.new/@conform-to/dom@1204

@conform-to/react

npm i https://pkg.pr.new/@conform-to/react@1204

@conform-to/valibot

npm i https://pkg.pr.new/@conform-to/valibot@1204

@conform-to/validitystate

npm i https://pkg.pr.new/@conform-to/validitystate@1204

@conform-to/yup

npm i https://pkg.pr.new/@conform-to/yup@1204

@conform-to/zod

npm i https://pkg.pr.new/@conform-to/zod@1204

commit: 9934b12

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
guide/package.json (1)

6-12: ⚠️ Potential issue | 🟠 Major

vite added to devDependencies but scripts and config still target the classic Remix compiler.

The scripts invoke remix build / remix dev --manual (classic compiler), and remix.config.js uses classic-only options (serverBuildPath, serverDependenciesToBundle, serverMinify, serverModuleFormat, serverPlatform). No vite.config.{js,ts} exists in the guide directory, and @remix-run/dev/vite is not referenced. Under this setup, vite ^6.4.2 is unused dead weight.

If migrating to the Remix Vite plugin is the intent, complete the migration:

  • Add vite.config.ts with @remix-run/dev/vite + @remix-run/dev/vite/cloudflare
  • Replace scripts with vite build / vite dev (remove --manual and predev)
  • Remove classic-only options from remix.config.js
  • Update server.ts wiring for Vite output

Otherwise, remove vite from devDependencies.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@guide/package.json` around lines 6 - 12, The project added vite to
devDependencies but the repo still uses the classic Remix compiler; either
complete the Vite migration or remove vite. To migrate: add a vite.config.ts
that imports and uses `@remix-run/dev/vite` (and `@remix-run/dev/vite/cloudflare` if
deploying to Pages), update package.json scripts replacing "remix build"/"remix
dev --manual" and the "predev" step with "vite build" and "vite dev" (remove
--manual and predev), remove classic-only keys from remix.config.js
(serverBuildPath, serverDependenciesToBundle, serverMinify, serverModuleFormat,
serverPlatform), and update server.ts wiring to consume Vite/Remix Vite output;
otherwise simply remove vite from devDependencies and keep existing
scripts/config.
♻️ Duplicate comments (1)
playground/package.json (1)

5-10: ⚠️ Potential issue | 🟠 Major

Same vite vs. classic-compiler mismatch as guide/package.json.

Scripts use remix build, remix dev, and remix-serve build/index.js — classic Remix compiler output paths. playground/remix.config.js is the minimal classic config. With no vite.config.* present, the newly added vite ^6.4.2 is unused.

Additionally, remix-serve build/index.js will not serve a Vite-built Remix app (Vite output layout is build/server/index.js + build/client/), so a partial migration here would break pnpm start.

Please either complete the Vite plugin migration (add vite.config.ts, update scripts to vite build/vite dev, update start to the Vite output path) or drop vite from devDependencies.

#!/bin/bash
fd -HI -t f 'vite\.config\.(js|ts|mjs|cjs)$' playground
rg -nP -C2 '@remix-run/dev/vite' playground
cat playground/package.json | jq '.scripts'
cat playground/remix.config.js

Also applies to: 40-40

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@playground/package.json` around lines 5 - 10, package.json scripts ("start",
"build", "dev") currently call classic Remix commands and expect classic output
(build/index.js), but vite is present in devDependencies while no vite.config.*
exists and remix.config.js is classic; either finish the Vite migration or
remove vite: Option A — complete migration by adding a Vite config
(vite.config.ts using `@remix-run/dev/vite`), update "build" to run vite build,
"dev" to vite dev, and change "start" to run the Vite server output
(build/server/index.js with appropriate serve command); Option B — revert to
classic setup by removing vite from devDependencies and keep "remix build",
"remix dev", and "remix-serve build/index.js" as-is; update package.json
accordingly and ensure playground/remix.config.js remains consistent with the
chosen approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@guide/package.json`:
- Around line 6-12: The project added vite to devDependencies but the repo still
uses the classic Remix compiler; either complete the Vite migration or remove
vite. To migrate: add a vite.config.ts that imports and uses `@remix-run/dev/vite`
(and `@remix-run/dev/vite/cloudflare` if deploying to Pages), update package.json
scripts replacing "remix build"/"remix dev --manual" and the "predev" step with
"vite build" and "vite dev" (remove --manual and predev), remove classic-only
keys from remix.config.js (serverBuildPath, serverDependenciesToBundle,
serverMinify, serverModuleFormat, serverPlatform), and update server.ts wiring
to consume Vite/Remix Vite output; otherwise simply remove vite from
devDependencies and keep existing scripts/config.

---

Duplicate comments:
In `@playground/package.json`:
- Around line 5-10: package.json scripts ("start", "build", "dev") currently
call classic Remix commands and expect classic output (build/index.js), but vite
is present in devDependencies while no vite.config.* exists and remix.config.js
is classic; either finish the Vite migration or remove vite: Option A — complete
migration by adding a Vite config (vite.config.ts using `@remix-run/dev/vite`),
update "build" to run vite build, "dev" to vite dev, and change "start" to run
the Vite server output (build/server/index.js with appropriate serve command);
Option B — revert to classic setup by removing vite from devDependencies and
keep "remix build", "remix dev", and "remix-serve build/index.js" as-is; update
package.json accordingly and ensure playground/remix.config.js remains
consistent with the chosen approach.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 025d6bf5-084a-4f65-bec3-a54873928bd4

📥 Commits

Reviewing files that changed from the base of the PR and between 7fbb924 and 3919731.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • guide/package.json
  • playground/package.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@playground/package.json`:
- Around line 21-31: The dependency entries for "@remix-run/node",
"@remix-run/react", "@remix-run/serve" (and the devDependency "@remix-run/dev")
were changed from caret ranges (e.g. "^2.9.1") to exact pins ("2.9.1"), which
prevents automatic patch/minor upgrades; either revert those values back to
caret-prefixed ranges (restore "^2.9.1" for the listed packages) so pnpm can
pick up patch/security fixes, or if exact pinning is intentional, add a short
comment in package.json or the PR description stating that "@remix-run/*"
versions are intentionally pinned for the playground to justify the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: bb0d0092-01ff-4de8-855e-4e244d00ee2f

📥 Commits

Reviewing files that changed from the base of the PR and between 3919731 and 8da4107.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • guide/package.json
  • playground/package.json

Comment thread playground/package.json Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
playground/app/routes/file-upload.tsx (1)

107-109: ⚠️ Potential issue | 🟠 Major

Client-side validation bypasses the empty-file normalization, yielding a different error than the server.

onValidate calls parseWithZod(formData, { schema }) directly, without going through the normalizeFile / normalizeFiles helpers used server-side. Because File extends Blob, a browser-sent empty file (empty name, size 0) still satisfies z.instanceof(Blob, { message: 'File is required' }) and instead trips the .refine(file => file.type === 'application/json', 'Only JSON file is accepted') check.

Net effect with client validation enabled:

  • Submit empty file → client shows "Only JSON file is accepted".
  • Same submission on server (no client validation) → "File is required".

Since this playground page exists to demonstrate correct behavior, the two paths should agree. Reuse parseFileUpload on the client as well.

🛠️ Proposed fix
 	const [form, fields] = useForm({
 		lastResult,
 		onValidate: !noClientValidate
-			? ({ formData }) => parseWithZod(formData, { schema })
+			? ({ formData }) => parseFileUpload(formData)
 			: undefined,
 	});

If parseWithZod is no longer needed, its import can be dropped too.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@playground/app/routes/file-upload.tsx` around lines 107 - 109, Client-side
validation currently calls parseWithZod(formData, { schema }) directly in the
onValidate handler, bypassing normalizeFile/normalizeFiles and causing
empty-file behavior to differ from the server; change the onValidate to call
parseFileUpload(formData) (the same parser used server-side) so client and
server use the same normalization/validation logic, and remove the now-unused
parseWithZod import if it becomes unused. Ensure you update the onValidate
reference in the file-upload route to use parseFileUpload and keep error
messaging consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@playground/app/routes/file-upload.tsx`:
- Around line 107-109: Client-side validation currently calls
parseWithZod(formData, { schema }) directly in the onValidate handler, bypassing
normalizeFile/normalizeFiles and causing empty-file behavior to differ from the
server; change the onValidate to call parseFileUpload(formData) (the same parser
used server-side) so client and server use the same normalization/validation
logic, and remove the now-unused parseWithZod import if it becomes unused.
Ensure you update the onValidate reference in the file-upload route to use
parseFileUpload and keep error messaging consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a8dc9e7e-4f14-4003-9162-61480e54ae18

📥 Commits

Reviewing files that changed from the base of the PR and between 8da4107 and 9934b12.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • playground/app/routes/file-upload.tsx
  • playground/package.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant