Break editor into a module
This commit is contained in:
168
scripts/cutover-host.sh
Normal file
168
scripts/cutover-host.sh
Normal file
@@ -0,0 +1,168 @@
|
||||
#!/bin/bash
|
||||
# Host cutover script: switch from monolithic to module-consuming.
|
||||
#
|
||||
# Run AFTER:
|
||||
# 1. ./scripts/migrate-to-module.sh has copied files to goods-editor-module/
|
||||
# 2. You've cd'd into goods-editor-module/, npm install'd, and npm run build'd
|
||||
#
|
||||
# What this does
|
||||
# ──────────────
|
||||
# 1. Renames the current monolithic files to *.monolith.* (kept for reference)
|
||||
# 2. Renames the *.host.* files to their canonical names
|
||||
# 3. Deletes the module-owned source from src/ (it now lives in the
|
||||
# module). The deletion is the actual cutover; until this runs, both
|
||||
# the inline copy and the module import would conflict.
|
||||
#
|
||||
# Run from the apparel-designer root:
|
||||
# bash scripts/cutover-host.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
ROOT_DIR="$( cd "$SCRIPT_DIR/.." &> /dev/null && pwd )"
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
echo "Cutting over apparel-designer to consume goods-editor module..."
|
||||
echo ""
|
||||
|
||||
# Step 1: Backup the current monolithic files.
|
||||
echo "→ Backing up monolithic files"
|
||||
[ -f src/App.jsx ] && mv src/App.jsx src/App.monolith.jsx
|
||||
[ -f server.js ] && mv server.js server.monolith.js
|
||||
[ -f package.json ] && mv package.json package.monolith.json
|
||||
echo " src/App.jsx → src/App.monolith.jsx"
|
||||
echo " server.js → server.monolith.js"
|
||||
echo " package.json → package.monolith.json"
|
||||
echo ""
|
||||
|
||||
# Step 2: Promote the *.host.* files to canonical names.
|
||||
echo "→ Promoting host files"
|
||||
[ -f src/App.host.jsx ] && mv src/App.host.jsx src/App.jsx
|
||||
[ -f server.host.js ] && mv server.host.js server.js
|
||||
[ -f package.host.json ] && mv package.host.json package.json
|
||||
echo " src/App.host.jsx → src/App.jsx"
|
||||
echo " server.host.js → server.js"
|
||||
echo " package.host.json → package.json"
|
||||
echo ""
|
||||
|
||||
# Step 3: Delete module-owned source.
|
||||
#
|
||||
# Per the architecture decisions, the host keeps:
|
||||
# • src/constants/shirt.js — host's shirt color/size catalog
|
||||
# • src/constants/templates.js — host's template definitions
|
||||
# • src/constants/products.js — host's product config
|
||||
# • src/styles/Header.css — styles the host's Header.jsx
|
||||
# • src/styles/PWAInstall.css — styles the host's PWAInstall.jsx
|
||||
#
|
||||
# These are referenced by host-owned components and the new
|
||||
# App.host.jsx. We delete the OTHER files but preserve these.
|
||||
|
||||
echo "→ Removing module-owned source directories from src/"
|
||||
DIRS_TO_DELETE=(
|
||||
"src/components/canvas"
|
||||
"src/components/sidebar"
|
||||
"src/components/panels"
|
||||
"src/components/editor"
|
||||
"src/hooks"
|
||||
"src/utils"
|
||||
"src/i18n"
|
||||
"src/test"
|
||||
)
|
||||
for dir in "${DIRS_TO_DELETE[@]}"; do
|
||||
if [ -d "$dir" ]; then
|
||||
rm -rf "$dir"
|
||||
echo " rm -rf $dir"
|
||||
fi
|
||||
done
|
||||
|
||||
# Module-owned constants files (delete individually). The host
|
||||
# keeps shirt.js, templates.js, and products.js — those carry
|
||||
# data App.host.jsx imports.
|
||||
MODULE_OWNED_CONSTANTS=(
|
||||
"src/constants/fonts.js"
|
||||
"src/constants/stickers.js"
|
||||
"src/constants/elements.js"
|
||||
"src/constants/imageFilters.js"
|
||||
"src/constants/textMetrics.js"
|
||||
"src/constants/transformer.js"
|
||||
)
|
||||
for file in "${MODULE_OWNED_CONSTANTS[@]}"; do
|
||||
if [ -f "$file" ]; then
|
||||
rm "$file"
|
||||
echo " rm $file"
|
||||
fi
|
||||
done
|
||||
|
||||
# Module-owned CSS files (delete individually). The host keeps
|
||||
# Header.css and PWAInstall.css — those style host-owned components.
|
||||
MODULE_OWNED_CSS=(
|
||||
"src/styles/CanvasHint.css"
|
||||
"src/styles/DesignCanvas.css"
|
||||
"src/styles/ElementToolbar.css"
|
||||
"src/styles/LayersPanel.css"
|
||||
"src/styles/MobileBottomSheet.css"
|
||||
"src/styles/ModelSilhouette.css"
|
||||
"src/styles/PhotoPreEditor.css"
|
||||
"src/styles/PreviewModal.css"
|
||||
"src/styles/PropertiesPanel.css"
|
||||
"src/styles/ShirtOptionsPanel.css"
|
||||
"src/styles/Sidebar.css"
|
||||
"src/styles/StickersTab.css"
|
||||
"src/styles/TShirtSVG.css"
|
||||
"src/styles/TemplatesTab.css"
|
||||
"src/styles/TextTab.css"
|
||||
"src/styles/UploadTab.css"
|
||||
"src/styles/ZoomControls.css"
|
||||
"src/styles/editor-shell.css"
|
||||
)
|
||||
for file in "${MODULE_OWNED_CSS[@]}"; do
|
||||
if [ -f "$file" ]; then
|
||||
rm "$file"
|
||||
echo " rm $file"
|
||||
fi
|
||||
done
|
||||
|
||||
FILES_TO_DELETE=(
|
||||
"src/components/MobileBottomSheet.jsx"
|
||||
"src/App.css"
|
||||
)
|
||||
for file in "${FILES_TO_DELETE[@]}"; do
|
||||
if [ -f "$file" ]; then
|
||||
rm "$file"
|
||||
echo " rm $file"
|
||||
fi
|
||||
done
|
||||
|
||||
# E2E directory — tests live in the module now.
|
||||
if [ -d "e2e" ]; then
|
||||
rm -rf e2e
|
||||
echo " rm -rf e2e"
|
||||
fi
|
||||
[ -f "playwright.config.js" ] && rm playwright.config.js && echo " rm playwright.config.js"
|
||||
[ -f "vitest.config.js" ] && rm vitest.config.js && echo " rm vitest.config.js"
|
||||
|
||||
# Fonts moved to the module too. Note that `public/stickers/`
|
||||
# stays in place — the host's vite.config.js still has the
|
||||
# `stickerManifestPlugin` that reads from `public/stickers/`
|
||||
# and exposes the `virtual:sticker-manifest` import that
|
||||
# goods-editor/src/constants/stickers.js consumes. Don't delete
|
||||
# either the public/stickers/ directory OR the plugin from
|
||||
# vite.config.js.
|
||||
if [ -d "fonts" ]; then
|
||||
rm -rf fonts
|
||||
echo " rm -rf fonts"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Cutover complete. Next steps:"
|
||||
echo " 1. rm -rf node_modules package-lock.json"
|
||||
echo " 2. npm install"
|
||||
echo " 3. npm run dev"
|
||||
echo ""
|
||||
echo "If something's broken, restore the monolith with:"
|
||||
echo " mv src/App.monolith.jsx src/App.jsx"
|
||||
echo " mv server.monolith.js server.js"
|
||||
echo " mv package.monolith.json package.json"
|
||||
echo " # (Then npm install to restore old deps; src/ won't have the"
|
||||
echo " # module-owned files anymore, but you can restore those from"
|
||||
echo " # the goods-editor-module/ copy or from git.)"
|
||||
161
scripts/migrate-to-module.sh
Normal file
161
scripts/migrate-to-module.sh
Normal file
@@ -0,0 +1,161 @@
|
||||
#!/bin/bash
|
||||
# Migration script: copy files from apparel-designer into goods-editor-module.
|
||||
#
|
||||
# Why this exists
|
||||
# ───────────────
|
||||
# The module-extraction refactor moves ~80 files from an existing app
|
||||
# into a new module repo. Most files copy verbatim — no surgery needed.
|
||||
# Doing this via shell is dramatically faster than reading/writing each
|
||||
# file through an AI tool.
|
||||
#
|
||||
# What this script does
|
||||
# ─────────────────────
|
||||
# 1. Copies utils, hooks, constants, i18n, styles, test setup, scripts
|
||||
# 2. Copies the canvas / sidebar / panels / editor / mobile components
|
||||
# 3. Copies the fonts/ directory and public/stickers/
|
||||
# 4. Copies all test files (Vitest *.test.js + e2e/)
|
||||
# 5. Reports what was moved
|
||||
#
|
||||
# What this script does NOT do
|
||||
# ────────────────────────────
|
||||
# - It does not copy App.jsx, main.jsx, index.html (host-side files)
|
||||
# - It does not copy Header.jsx, PWAInstall.jsx, OfflineIndicator.jsx (host-side)
|
||||
# - It does not copy server.js (refactored separately into the module's
|
||||
# server/ directory)
|
||||
# - It does not run npm install or build anything
|
||||
# - It does not delete anything from the source — the apparel-designer
|
||||
# project is left intact until you've verified the module works.
|
||||
#
|
||||
# Run from the parent directory of both repos:
|
||||
# cd /Users/khalid/Documents/Claude-Desktop
|
||||
# bash apparel-designer/scripts/migrate-to-module.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Resolve paths relative to this script's location so it doesn't matter
|
||||
# where you invoke it from.
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
SOURCE_DIR="$( cd "$SCRIPT_DIR/.." &> /dev/null && pwd )"
|
||||
PARENT_DIR="$( cd "$SOURCE_DIR/.." &> /dev/null && pwd )"
|
||||
DEST_DIR="$PARENT_DIR/goods-editor-module"
|
||||
|
||||
if [ ! -d "$DEST_DIR" ]; then
|
||||
echo "Error: goods-editor-module not found at $DEST_DIR"
|
||||
echo "Expected layout:"
|
||||
echo " $PARENT_DIR/"
|
||||
echo " apparel-designer/ (source, where this script lives)"
|
||||
echo " goods-editor-module/ (destination)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Source: $SOURCE_DIR"
|
||||
echo "Destination: $DEST_DIR"
|
||||
echo ""
|
||||
|
||||
# Helper: copy a directory's contents, preserving structure.
|
||||
# Usage: copy_dir <source-relative> <dest-relative>
|
||||
copy_dir() {
|
||||
local src="$SOURCE_DIR/$1"
|
||||
local dst="$DEST_DIR/$2"
|
||||
if [ ! -d "$src" ]; then
|
||||
echo " skip (missing): $1"
|
||||
return
|
||||
fi
|
||||
mkdir -p "$dst"
|
||||
cp -R "$src/." "$dst/"
|
||||
local count
|
||||
count=$(find "$dst" -type f | wc -l | tr -d ' ')
|
||||
echo " $1 → $2 ($count files)"
|
||||
}
|
||||
|
||||
# Helper: copy a single file.
|
||||
# Usage: copy_file <source-relative> <dest-relative>
|
||||
copy_file() {
|
||||
local src="$SOURCE_DIR/$1"
|
||||
local dst="$DEST_DIR/$2"
|
||||
if [ ! -f "$src" ]; then
|
||||
echo " skip (missing): $1"
|
||||
return
|
||||
fi
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
cp "$src" "$dst"
|
||||
echo " $1 → $2"
|
||||
}
|
||||
|
||||
echo "=== Phase 1: Utilities, hooks, constants, i18n, styles ==="
|
||||
copy_dir "src/utils" "src/utils"
|
||||
copy_dir "src/hooks" "src/hooks"
|
||||
copy_dir "src/constants" "src/constants"
|
||||
copy_dir "src/i18n" "src/i18n"
|
||||
copy_dir "src/styles" "src/styles"
|
||||
copy_dir "src/test" "src/test"
|
||||
echo ""
|
||||
|
||||
echo "=== Phase 2: Canvas / sidebar / panels / editor components ==="
|
||||
copy_dir "src/components/canvas" "src/components/canvas"
|
||||
copy_dir "src/components/sidebar" "src/components/sidebar"
|
||||
copy_dir "src/components/panels" "src/components/panels"
|
||||
copy_dir "src/components/editor" "src/components/editor"
|
||||
copy_file "src/components/MobileBottomSheet.jsx" "src/components/MobileBottomSheet.jsx"
|
||||
echo ""
|
||||
|
||||
echo "=== Phase 3: App.css (canvas-area styles, etc.) ==="
|
||||
# App.css contains styles used by DesignCanvas / the canvas-area frame.
|
||||
# These are module concerns even though the file is named "App.css".
|
||||
# We copy it into src/styles/ with a clearer name.
|
||||
copy_file "src/App.css" "src/styles/editor-shell.css"
|
||||
echo ""
|
||||
|
||||
echo "=== Phase 4: Fonts and the font-fetch script ==="
|
||||
copy_dir "fonts" "fonts"
|
||||
if [ -f "$SOURCE_DIR/scripts/fetch-fonts.mjs" ]; then
|
||||
mkdir -p "$DEST_DIR/scripts"
|
||||
cp "$SOURCE_DIR/scripts/fetch-fonts.mjs" "$DEST_DIR/scripts/fetch-fonts.mjs"
|
||||
echo " scripts/fetch-fonts.mjs → scripts/fetch-fonts.mjs"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== Phase 5: Default sticker library ==="
|
||||
# The module ships defaults; host can extend/replace via props.
|
||||
if [ -d "$SOURCE_DIR/public/stickers" ]; then
|
||||
mkdir -p "$DEST_DIR/src/assets/stickers"
|
||||
cp -R "$SOURCE_DIR/public/stickers/." "$DEST_DIR/src/assets/stickers/"
|
||||
count=$(find "$DEST_DIR/src/assets/stickers" -type f | wc -l | tr -d ' ')
|
||||
echo " public/stickers → src/assets/stickers ($count files)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== Phase 6: Playwright E2E tests ==="
|
||||
if [ -d "$SOURCE_DIR/e2e" ]; then
|
||||
cp -R "$SOURCE_DIR/e2e" "$DEST_DIR/e2e"
|
||||
count=$(find "$DEST_DIR/e2e" -type f | wc -l | tr -d ' ')
|
||||
echo " e2e/ → e2e/ ($count files)"
|
||||
fi
|
||||
if [ -f "$SOURCE_DIR/playwright.config.js" ]; then
|
||||
cp "$SOURCE_DIR/playwright.config.js" "$DEST_DIR/playwright.config.js"
|
||||
echo " playwright.config.js → playwright.config.js"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== Phase 7: ESLint config ==="
|
||||
if [ -f "$SOURCE_DIR/eslint.config.js" ]; then
|
||||
cp "$SOURCE_DIR/eslint.config.js" "$DEST_DIR/eslint.config.js"
|
||||
echo " eslint.config.js → eslint.config.js"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== Done. Summary ==="
|
||||
echo ""
|
||||
echo "Files in $DEST_DIR:"
|
||||
find "$DEST_DIR/src" -type f 2>/dev/null | wc -l | xargs echo " src/ files:"
|
||||
find "$DEST_DIR/e2e" -type f 2>/dev/null | wc -l | xargs echo " e2e/ files:"
|
||||
find "$DEST_DIR/fonts" -type f 2>/dev/null | wc -l | xargs echo " fonts/ files:"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. cd $DEST_DIR"
|
||||
echo " 2. npm install"
|
||||
echo " 3. The surgical-new-files (index.js, ApparelDesigner.jsx, server,"
|
||||
echo " dev-host, release script, README) are already in place."
|
||||
echo " 4. npm run build # builds the library to dist/"
|
||||
echo " 5. npm run dev # runs the example dev host"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user