Skip to content

Add Wix migrate tool#1802

Open
PaulAdamDavis wants to merge 7 commits into
mainfrom
wix-csv
Open

Add Wix migrate tool#1802
PaulAdamDavis wants to merge 7 commits into
mainfrom
wix-csv

Conversation

@PaulAdamDavis
Copy link
Copy Markdown
Member

No description provided.

Comment thread packages/migrate/sources/wix-csv.js Fixed
Comment thread packages/migrate/sources/wix-csv.js Fixed
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cc617df2-dc46-4110-8f29-ec23734aceef

📥 Commits

Reviewing files that changed from the base of the PR and between c1e8da7 and 34f5561.

📒 Files selected for processing (2)
  • packages/mg-wix-csv/LICENSE
  • packages/mg-wix-csv/README.md
✅ Files skipped from review due to trivial changes (2)
  • packages/mg-wix-csv/LICENSE
  • packages/mg-wix-csv/README.md

Walkthrough

This pull request introduces @tryghost/mg-wix-csv, a new migration package that converts Wix CSV post exports into Ghost-compatible import artifacts. The package includes CSV parsing with field normalization, Wix rich-content JSON → Ghost HTML serialization, Wix image URI → static CDN URL conversion, TypeScript declarations, unit/integration tests, and integration into the migrate CLI via a task-runner pipeline that can fetch assets, fix links, convert HTML to Lexical, package results into a ZIP, and upload to object storage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive No pull request description was provided by the author, so this check cannot assess whether the description relates to the changeset. Consider adding a brief description explaining the purpose and key features of the Wix CSV migration tool being added.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add Wix migrate tool' clearly and concisely summarizes the main objective of the changeset, which is to introduce a new Wix CSV migration tool to the migrate package.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch wix-csv

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
packages/migrate/sources/wix-csv.js (2)

17-19: ⚡ Quick win

Guard scrape before calling .includes() in wix-csv source

packages/migrate/sources/wix-csv.js uses ctx.options.scrape.includes(...) in initialize. The CLI (packages/migrate/commands/wix-csv.js) defines --scrape as an array with defaultValue ['assets'] and initializes context.errors = [], so ctx.errors.push is safe during normal command execution. This still throws if the source is invoked directly with a missing/non-array options.scrape, so normalize/guard scrape in initialize.

Suggested fix
-            ctx.allowScrape = {
-                assets: ctx.options.scrape.includes('assets') || ctx.options.scrape.includes('img') || ctx.options.scrape.includes('media') || ctx.options.scrape.includes('files')
-            };
+            const scrapeOptions = Array.isArray(ctx.options.scrape) ? ctx.options.scrape : [];
+            ctx.allowScrape = {
+                assets: scrapeOptions.includes('assets') || scrapeOptions.includes('img') || scrapeOptions.includes('media') || scrapeOptions.includes('files')
+            };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/migrate/sources/wix-csv.js` around lines 17 - 19, The initialize
logic calls ctx.options.scrape.includes(...) without ensuring scrape is an
array; update initialize to normalize/guard scrape first (e.g. use Array.isArray
on ctx.options.scrape and fall back to an empty array or ['assets']), assign the
normalized array back to ctx.options.scrape, then compute ctx.allowScrape (the
current property set in initialize) using the normalized variable so includes()
is safe when the source is invoked directly.

16-16: ⚡ Quick win

Downgrade: ctx.errors is already initialized for the wix-csv CLI path; local hardening is optional

packages/migrate/commands/wix-csv.js passes context = { errors: [] } into migrate.run(context), so packages/migrate/sources/wix-csv.js won’t hit ctx.errors being undefined in the normal flow. Adding a defensive ctx.errors initialization in sources/wix-csv.js can still protect any direct/alternate usage of the exported task runner.

Suggested local hardening
         task: async (ctx, task) => {
             ctx.options = options;
+            ctx.errors = Array.isArray(ctx.errors) ? ctx.errors : [];
             ctx.allowScrape = {
                 assets: ctx.options.scrape.includes('assets') || ctx.options.scrape.includes('img') || ctx.options.scrape.includes('media') || ctx.options.scrape.includes('files')
             };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/migrate/sources/wix-csv.js` at line 16, Initialize ctx.errors
defensively in the wix-csv source before using it: when setting ctx.options (the
place where ctx is prepared), add a guard like setting ctx.errors = ctx.errors
|| [] so the exported task runner in packages/migrate/sources/wix-csv.js can
safely push errors even if called directly outside the CLI path; update only the
initialization near the code that sets ctx.options to ensure existing CLI flow
(which passes context = { errors: [] }) remains unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/mg-wix-csv/src/lib/mapper.ts`:
- Around line 194-196: In mapContent, don't return an Error instance when no
rows exist—throw it so callers receive a rejected flow; replace the current
"return new errors.NoContentError({message: 'Input file is empty'})" with "throw
new errors.NoContentError(...)" (referencing mappedPosts.length and
errors.NoContentError in mapContent) so failure surfaces as an exception rather
than a successful return value.

In `@packages/mg-wix-csv/src/lib/rich-content.ts`:
- Around line 103-105: The code uses escapeHtml(linkUrl) when writing href but
escapeHtml does not block dangerous schemes (e.g., javascript:, data:);
validate/sanitize linkUrl before embedding by parsing the URL (or checking its
scheme) and only allow safe schemes (e.g., http, https, mailto, tel) or
explicitly reject/strip others, then continue to call escapeHtml on the cleaned
URL; update the logic around the anchor generation (the block that references
linkUrl, linkText and uses escapeHtml in this file, and the similar occurrence
at the other location around line 157) to perform this scheme whitelist check
and fall back to outputting plain text (or omitting href) when the URL is
disallowed.

In `@packages/mg-wix-csv/src/lib/wix-image.ts`:
- Around line 24-25: In parseWixImageUri, guard calls to decodeURIComponent for
match[1] and match[2] by wrapping each in try/catch and return null if a
URIError (malformed percent-encoding) is thrown; specifically catch URIError (or
inspect error.name) and avoid rethrowing so parseWixImageUri returns null
instead of crashing. Update any callers if they assume non-null. Add a
regression test that supplies a wix-image-like string that matches the regex but
contains malformed % sequences (e.g., "%ZZ") to assert parseWixImageUri(...)
returns null and does not throw.

---

Nitpick comments:
In `@packages/migrate/sources/wix-csv.js`:
- Around line 17-19: The initialize logic calls ctx.options.scrape.includes(...)
without ensuring scrape is an array; update initialize to normalize/guard scrape
first (e.g. use Array.isArray on ctx.options.scrape and fall back to an empty
array or ['assets']), assign the normalized array back to ctx.options.scrape,
then compute ctx.allowScrape (the current property set in initialize) using the
normalized variable so includes() is safe when the source is invoked directly.
- Line 16: Initialize ctx.errors defensively in the wix-csv source before using
it: when setting ctx.options (the place where ctx is prepared), add a guard like
setting ctx.errors = ctx.errors || [] so the exported task runner in
packages/migrate/sources/wix-csv.js can safely push errors even if called
directly outside the CLI path; update only the initialization near the code that
sets ctx.options to ensure existing CLI flow (which passes context = { errors:
[] }) remains unchanged.
🪄 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: CHILL

Plan: Pro

Run ID: f7d8d2f1-ec59-4fbc-8e1b-f063a7d77cb4

📥 Commits

Reviewing files that changed from the base of the PR and between 47c8550 and f51b91f.

⛔ Files ignored due to path filters (3)
  • packages/mg-wix-csv/src/test/fixtures/empty.csv is excluded by !**/*.csv
  • packages/mg-wix-csv/src/test/fixtures/posts.csv is excluded by !**/*.csv
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (18)
  • packages/mg-wix-csv/.eslintrc.cjs
  • packages/mg-wix-csv/.gitignore
  • packages/mg-wix-csv/README.md
  • packages/mg-wix-csv/package.json
  • packages/mg-wix-csv/src/index.ts
  • packages/mg-wix-csv/src/lib/mapper.ts
  • packages/mg-wix-csv/src/lib/rich-content.ts
  • packages/mg-wix-csv/src/lib/wix-image.ts
  • packages/mg-wix-csv/src/test/mapper.test.ts
  • packages/mg-wix-csv/src/test/rich-content.test.ts
  • packages/mg-wix-csv/src/test/wix-image.test.ts
  • packages/mg-wix-csv/src/types.d.ts
  • packages/mg-wix-csv/tsconfig.json
  • packages/migrate/bin/cli.js
  • packages/migrate/commands/wix-csv.js
  • packages/migrate/package.json
  • packages/migrate/sources/wix-csv.js
  • packages/migrate/test/wix-csv-command.test.js

Comment thread packages/mg-wix-csv/src/lib/mapper.ts
Comment thread packages/mg-wix-csv/src/lib/rich-content.ts
Comment thread packages/mg-wix-csv/src/lib/wix-image.ts Outdated
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.

2 participants