Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6e4258a
docs(13): create phase plan for transform infrastructure
thejackshelton Apr 3, 2026
a15fa56
test(13-02): add failing tests for pruned binary-extensions
thejackshelton Apr 3, 2026
f12d855
test(13-01): add failing tests for applyTransforms orchestrator
thejackshelton Apr 3, 2026
83d4ab0
feat(13-02): prune binary-extensions.ts to ~50 essential entries
thejackshelton Apr 3, 2026
4d3a997
test(13-02): add failing tests for RNME-01 and RNME-02 import renames
thejackshelton Apr 3, 2026
88a237a
feat(13-01): implement SourceReplacement/TransformFn types and applyT…
thejackshelton Apr 3, 2026
372c036
feat(13-02): add RNME-01 and RNME-02 to IMPORT_RENAME_ROUNDS Round 1
thejackshelton Apr 3, 2026
ebaeb5c
docs(13-02): complete prune binary-extensions and add RNME-01/RNME-02…
thejackshelton Apr 3, 2026
52fd0da
test(14-01): add failing tests for fixJsxImportSource, fixModuleResol…
thejackshelton Apr 3, 2026
3bf0e6a
feat(14-01): implement fixJsxImportSource, fixModuleResolution, fixPa…
thejackshelton Apr 3, 2026
d01d7e5
feat(14-01): wire config transforms into runV2Migration as Step 3b
thejackshelton Apr 3, 2026
07e5b10
docs(14-01): complete config validation plan
thejackshelton Apr 3, 2026
a25b39a
test(14-02): add failing tests for useVisibleTask$ eagerness removal …
thejackshelton Apr 3, 2026
16e4071
feat(14-02): implement removeEagernessTransform for useVisibleTask$ e…
thejackshelton Apr 3, 2026
6629afd
feat(14-02): wire applyTransforms + removeEagernessTransform into run…
thejackshelton Apr 3, 2026
e2580dc
docs(14-02): complete eagerness removal transform plan
thejackshelton Apr 3, 2026
30821f9
test(15-01): add failing tests for migrateQwikLabsTransform
thejackshelton Apr 3, 2026
57e1be0
feat(15-01): extract walkNode and implement migrateQwikLabsTransform
thejackshelton Apr 3, 2026
de10ab5
docs(15-01): complete qwik-labs ecosystem migration plan
thejackshelton Apr 3, 2026
071d75b
test(15-02): add failing tests for useComputed$(async) and useResourc…
thejackshelton Apr 3, 2026
c0d1c5f
feat(15-02): implement useComputed$(async) and useResource$ transform…
thejackshelton Apr 3, 2026
9ab1d18
feat(15-02): wire all 4 Phase 15 transforms into run-migration.ts Ste…
thejackshelton Apr 3, 2026
2fc7b10
docs(15-02): complete async hook transforms plan
thejackshelton Apr 3, 2026
bf91728
feat(16-01): implement XFRM-04 QwikCityProvider -> useQwikRouter() tr…
thejackshelton Apr 3, 2026
6323a56
feat(16-01): wire XFRM-04 QwikCityProvider transform into run-migrati…
thejackshelton Apr 3, 2026
f7c51dd
fix(XFRM-04): correct QwikCityProvider transform pipeline ordering
thejackshelton Apr 3, 2026
135bfdb
test(17-01): add pipeline integration test for runV2Migration() end-t…
thejackshelton Apr 3, 2026
11b9601
docs(17-01): complete transform test coverage plan — MTEST-01/02 done
thejackshelton Apr 3, 2026
c95baaf
chore: remove .planning files from git tracking
thejackshelton Apr 3, 2026
0003a26
fix: resolve lint errors (unused import, useless fallback spreads)
thejackshelton Apr 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 0 additions & 188 deletions .planning/STATE.md

This file was deleted.

70 changes: 0 additions & 70 deletions .planning/quick/11-set-up-ci-github-actions-workflow/11-SUMMARY.md

This file was deleted.

72 changes: 72 additions & 0 deletions migrations/v2/apply-transforms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import MagicString from "magic-string";
import { parseSync } from "oxc-parser";
import { readFileSync, writeFileSync } from "node:fs";
import type { SourceReplacement, TransformFn } from "./types.ts";

/**
* Parse-once, fan-out orchestrator for AST-based source transforms.
*
* Algorithm:
* 1. Early return if no transforms provided
* 2. Read source from disk once
* 3. Parse once with oxc-parser; share ParseResult across all transforms
* 4. Fan out: collect SourceReplacement[] from each transform into a flat list
* 5. Early return if no replacements collected (file unchanged)
* 6. Sort replacements descending by `start` (later offsets first) to prevent
* MagicString offset corruption when applying earlier edits
* 7. Apply all replacements via a single MagicString instance
* 8. Write back to disk only if content changed
*
* @param filePath - Absolute path to the file to transform
* @param transforms - Array of transform functions to apply
*/
export function applyTransforms(filePath: string, transforms: TransformFn[]): void {
// Step 1: Early return for empty transform list
if (transforms.length === 0) return;

// Step 2: Read source once
const source = readFileSync(filePath, "utf-8");

// Step 3: Parse once
const parseResult = parseSync(filePath, source, { sourceType: "module" });

// Step 4: Fan out — collect all replacements
const allReplacements: SourceReplacement[] = [];
for (const transform of transforms) {
const replacements = transform(filePath, source, parseResult);
allReplacements.push(...replacements);
}

// Step 5: Early return if nothing to replace
if (allReplacements.length === 0) return;

// Step 6: Sort descending by start so later offsets are applied first
allReplacements.sort((a, b) => b.start - a.start);

// Step 6b: Detect overlapping replacements before applying (magic-string does not
// always throw a useful error; we surface a descriptive one instead).
// After descending sort, replacement[i].start >= replacement[i+1].start.
// A collision occurs when replacement[i+1].end > replacement[i].start.
for (let i = 0; i < allReplacements.length - 1; i++) {
const curr = allReplacements[i]!;
const next = allReplacements[i + 1]!;
if (next.end > curr.start) {
throw new Error(
`applyTransforms: overlapping replacements detected in "${filePath}". ` +
`Replacement at [${next.start}, ${next.end}) overlaps with [${curr.start}, ${curr.end}). ` +
`Each transform must produce non-overlapping SourceReplacement ranges.`,
);
}
}

// Step 7: Apply via single MagicString instance
const ms = new MagicString(source);
for (const { start, end, replacement } of allReplacements) {
ms.overwrite(start, end, replacement);
}

// Step 8: Write back only when content changed
if (ms.hasChanged()) {
writeFileSync(filePath, ms.toString(), "utf-8");
}
}
184 changes: 11 additions & 173 deletions migrations/v2/binary-extensions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { extname } from "node:path";

/**
* Set of known binary file extensions (lowercased, including the dot).
* Based on the sindresorhus/binary-extensions list.
* Pruned set of binary file extensions relevant to Qwik projects (lowercased, including the dot).
* Contains ~50 essential entries covering images, fonts, archives, executables, audio, video, and
* other common binary formats. Excludes niche formats unlikely to appear in a Qwik project.
*/
export const BINARY_EXTENSIONS: Set<string> = new Set([
// Images
Expand All @@ -16,42 +17,17 @@ export const BINARY_EXTENSIONS: Set<string> = new Set([
".svg",
".tiff",
".tif",
".psd",
".ai",
".eps",
".raw",
".cr2",
".nef",
".orf",
".sr2",
".avif",
".heic",
".heif",
".jxl",
".apng",
".cur",
".ani",
".jfif",
".jp2",
".j2k",
".jpf",
".jpx",
".jpm",

// Documents
".pdf",
".doc",
".docx",
".xls",
".xlsx",
".ppt",
".pptx",
".odt",
".ods",
".odp",
".pages",
".numbers",
".key",
// Fonts
".woff",
".woff2",
".ttf",
".eot",
".otf",

// Archives
".zip",
Expand All @@ -61,56 +37,16 @@ export const BINARY_EXTENSIONS: Set<string> = new Set([
".7z",
".bz2",
".xz",
".lz",
".lzma",
".z",
".tgz",
".tbz",
".tbz2",
".txz",
".tlz",
".cab",
".deb",
".rpm",
".apk",
".ipa",
".crx",
".iso",
".img",
".dmg",
".pkg",
".msi",

// Executables and binaries
".exe",
".dll",
".so",
".dylib",
".lib",
".a",
".o",
".obj",
".pdb",
".com",
".bat",
".cmd",
".scr",
".msc",
".bin",
".elf",
".out",
".app",

// Fonts
".woff",
".woff2",
".ttf",
".eot",
".otf",
".fon",
".fnt",
".pfb",
".pfm",

// Audio
".mp3",
Expand All @@ -119,122 +55,24 @@ export const BINARY_EXTENSIONS: Set<string> = new Set([
".flac",
".aac",
".m4a",
".wma",
".aiff",
".aif",
".au",
".opus",
".mid",
".midi",
".ra",
".ram",
".amr",

// Video
".mp4",
".avi",
".mov",
".mkv",
".wmv",
".flv",
".webm",
".m4v",
".3gp",
".3g2",
".ogv",
".mts",
".m2ts",
".vob",
".mpg",
".mpeg",
".m2v",
".m4p",
".m4b",
".m4r",
".f4v",
".f4a",
".f4b",
".f4p",
".swf",
".asf",
".rm",
".rmvb",
".divx",

// Java / compiled bytecode
".class",
".jar",
".war",
".ear",

// Python compiled
".pyc",
".pyo",
".pyd",

// WebAssembly
".wasm",

// Databases / data stores
// Documents / data
".pdf",
".sqlite",
".sqlite3",
".db",
".db3",
".s3db",
".sl3",
".mdb",
".accdb",

// 3D / game assets
".blend",
".fbx",
".obj",
".dae",
".3ds",
".max",
".ma",
".mb",
".stl",
".glb",
".gltf",
".nif",
".bsa",
".pak",
".unity",
".unitypackage",

// Flash
".swf",
".fla",

// Disk images
".vmdk",
".vhd",
".vdi",
".qcow2",

// Certificates / keys
".der",
".cer",
".crt",
".p12",
".pfx",
".p7b",

// Other binary formats
".nupkg",
".snupkg",
".rdb",
".ldb",
".lnk",
".DS_Store",
".plist",
".xib",
".nib",
".icns",
".dSYM",
".map",
".min",
]);

/**
Expand Down
Loading
Loading