@mmapp/react-compiler 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -0
- package/compile-blueprint-chat.mjs +99 -0
- package/compile-blueprint-glass-console.mjs +98 -0
- package/compile-chat-defs.mjs +92 -0
- package/dist/babel/index.d.mts +3 -0
- package/dist/babel/index.d.ts +3 -0
- package/dist/babel/index.js +4851 -0
- package/dist/babel/index.mjs +7 -0
- package/dist/chunk-26U577GB.mjs +3465 -0
- package/dist/chunk-2FBDFAX6.mjs +2362 -0
- package/dist/chunk-2L4QSMXG.mjs +175 -0
- package/dist/chunk-2REDFOER.mjs +931 -0
- package/dist/chunk-46YKSHQR.mjs +175 -0
- package/dist/chunk-4XHK6FWL.mjs +2058 -0
- package/dist/chunk-5M7DKKBC.mjs +215 -0
- package/dist/chunk-5VNJ7C6N.mjs +154 -0
- package/dist/chunk-6CQOAAMV.mjs +1803 -0
- package/dist/chunk-6SEVAAVT.mjs +3516 -0
- package/dist/chunk-6YLR5ZDA.mjs +2829 -0
- package/dist/chunk-AOGY2GK6.mjs +3292 -0
- package/dist/chunk-AXXUXRNA.mjs +1434 -0
- package/dist/chunk-CHLVKMQW.mjs +175 -0
- package/dist/chunk-CKGOZAB7.mjs +939 -0
- package/dist/chunk-D34RAZUX.mjs +2223 -0
- package/dist/chunk-EQGA6A6D.mjs +121 -0
- package/dist/chunk-EY2CSXYA.mjs +822 -0
- package/dist/chunk-FIQ65CDR.mjs +925 -0
- package/dist/chunk-FOZXJFAR.mjs +186 -0
- package/dist/chunk-FX6URXWN.mjs +186 -0
- package/dist/chunk-G7SMOWOL.mjs +828 -0
- package/dist/chunk-GGB4G5YY.mjs +175 -0
- package/dist/chunk-HLRGCCIL.mjs +4839 -0
- package/dist/chunk-HOIUP6IF.mjs +690 -0
- package/dist/chunk-I3AU7GRD.mjs +120 -0
- package/dist/chunk-ILFGMUVD.mjs +1933 -0
- package/dist/chunk-IPTX5MJU.mjs +3223 -0
- package/dist/chunk-ITGUSH2Z.mjs +2783 -0
- package/dist/chunk-IXHBCAMF.mjs +3306 -0
- package/dist/chunk-J7TWJ3TM.mjs +2784 -0
- package/dist/chunk-JDPLDGVF.mjs +4810 -0
- package/dist/chunk-K53XP2DL.mjs +148 -0
- package/dist/chunk-K5HX2SVL.mjs +1902 -0
- package/dist/chunk-KFGYOOVS.mjs +214 -0
- package/dist/chunk-KFVVOS5N.mjs +925 -0
- package/dist/chunk-L2OZ4CDV.mjs +113 -0
- package/dist/chunk-MIZV3TAN.mjs +3293 -0
- package/dist/chunk-NKKLQE5V.mjs +148 -0
- package/dist/chunk-NOW23XFZ.mjs +186 -0
- package/dist/chunk-NRXQKQ74.mjs +148 -0
- package/dist/chunk-OWI6XWCD.mjs +3375 -0
- package/dist/chunk-PRUMNNDI.mjs +3192 -0
- package/dist/chunk-QTBD5B3F.mjs +148 -0
- package/dist/chunk-SKSDPPNT.mjs +3788 -0
- package/dist/chunk-SP2YUS33.mjs +186 -0
- package/dist/chunk-SU4E6E7B.mjs +3153 -0
- package/dist/chunk-SYUUKW5A.mjs +3379 -0
- package/dist/chunk-UL2XZEMA.mjs +3128 -0
- package/dist/chunk-XMWUHQVV.mjs +939 -0
- package/dist/chunk-XZNEDRGN.mjs +3876 -0
- package/dist/chunk-Y6FXYEAI.mjs +10 -0
- package/dist/chunk-YFS6JMYO.mjs +3342 -0
- package/dist/chunk-Z6AIQ4KL.mjs +113 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +11585 -0
- package/dist/cli/index.mjs +701 -0
- package/dist/codemod/cli.d.mts +1 -0
- package/dist/codemod/cli.d.ts +1 -0
- package/dist/codemod/cli.js +1104 -0
- package/dist/codemod/cli.mjs +157 -0
- package/dist/codemod/index.d.mts +148 -0
- package/dist/codemod/index.d.ts +148 -0
- package/dist/codemod/index.js +981 -0
- package/dist/codemod/index.mjs +25 -0
- package/dist/dev-server-Bs_sz2DG.d.mts +111 -0
- package/dist/dev-server-Bs_sz2DG.d.ts +111 -0
- package/dist/dev-server-CjoufJ-u.d.mts +109 -0
- package/dist/dev-server-CjoufJ-u.d.ts +109 -0
- package/dist/dev-server.d.mts +3 -0
- package/dist/dev-server.d.ts +3 -0
- package/dist/dev-server.js +7603 -0
- package/dist/dev-server.mjs +11 -0
- package/dist/envelope-DD7v0v6E.d.mts +265 -0
- package/dist/envelope-DD7v0v6E.d.ts +265 -0
- package/dist/envelope-vCVjrHlo.d.mts +265 -0
- package/dist/envelope-vCVjrHlo.d.ts +265 -0
- package/dist/envelope.d.mts +2 -0
- package/dist/envelope.d.ts +2 -0
- package/dist/envelope.js +5184 -0
- package/dist/envelope.mjs +9 -0
- package/dist/index-B5gSgvnd.d.mts +44 -0
- package/dist/index-B5gSgvnd.d.ts +44 -0
- package/dist/index-Bs0MnR54.d.mts +103 -0
- package/dist/index-Bs0MnR54.d.ts +103 -0
- package/dist/index-DR0nNc_f.d.mts +101 -0
- package/dist/index-DR0nNc_f.d.ts +101 -0
- package/dist/index-revho_gS.d.mts +104 -0
- package/dist/index-revho_gS.d.ts +104 -0
- package/dist/index.d.mts +1099 -0
- package/dist/index.d.ts +1099 -0
- package/dist/index.js +10162 -0
- package/dist/index.mjs +372 -0
- package/dist/init-IXEE2RCF.mjs +340 -0
- package/dist/project-compiler-EGJUTAJU.mjs +10 -0
- package/dist/project-compiler-VFR6CSDX.mjs +10 -0
- package/dist/project-decompiler-5GY2KSG4.mjs +7 -0
- package/dist/pull-A2QUHW4K.mjs +109 -0
- package/dist/pull-JBEQWVPE.mjs +109 -0
- package/dist/testing/index.d.mts +211 -0
- package/dist/testing/index.d.ts +211 -0
- package/dist/testing/index.js +5106 -0
- package/dist/testing/index.mjs +247 -0
- package/dist/vite/index.d.mts +59 -0
- package/dist/vite/index.d.ts +59 -0
- package/dist/vite/index.js +5023 -0
- package/dist/vite/index.mjs +8 -0
- package/examples/README.md +72 -0
- package/examples/authentication/main.workflow.tsx +139 -0
- package/examples/authentication/mm.config.ts +22 -0
- package/examples/authentication/models/auth.ts +45 -0
- package/examples/authentication/pages/LoginPage.tsx +79 -0
- package/examples/authentication/pages/SignupPage.tsx +87 -0
- package/examples/counter.workflow.tsx +65 -0
- package/examples/dashboard.workflow.tsx +419 -0
- package/examples/invoice-approval/actions/invoice.server.ts +72 -0
- package/examples/invoice-approval/main.workflow.tsx +168 -0
- package/examples/invoice-approval/mm.config.ts +18 -0
- package/examples/invoice-approval/models/invoice.ts +46 -0
- package/examples/invoice-approval/pages/InvoiceDetailPage.tsx +175 -0
- package/examples/invoice-approval/pages/InvoiceFormPage.tsx +198 -0
- package/examples/invoice-approval/pages/InvoiceListPage.tsx +141 -0
- package/examples/todo-app.workflow.tsx +131 -0
- package/examples/uber-app/actions/matching.server.ts +177 -0
- package/examples/uber-app/actions/notifications.server.ts +176 -0
- package/examples/uber-app/actions/payments.server.ts +184 -0
- package/examples/uber-app/actions/pricing.server.ts +176 -0
- package/examples/uber-app/app/admin/analytics.tsx +102 -0
- package/examples/uber-app/app/admin/fleet.tsx +102 -0
- package/examples/uber-app/app/admin/surge-pricing.tsx +95 -0
- package/examples/uber-app/app/driver/dashboard.tsx +87 -0
- package/examples/uber-app/app/driver/earnings.tsx +101 -0
- package/examples/uber-app/app/driver/navigation.tsx +94 -0
- package/examples/uber-app/app/driver/ride-acceptance.tsx +103 -0
- package/examples/uber-app/app/rider/home.tsx +109 -0
- package/examples/uber-app/app/rider/payment-methods.tsx +134 -0
- package/examples/uber-app/app/rider/ride-history.tsx +90 -0
- package/examples/uber-app/app/rider/ride-tracking.tsx +108 -0
- package/examples/uber-app/components/DriverCard.tsx +176 -0
- package/examples/uber-app/components/MapView.tsx +216 -0
- package/examples/uber-app/components/RatingStars.tsx +227 -0
- package/examples/uber-app/components/RideCard.tsx +167 -0
- package/examples/uber-app/mm.config.ts +30 -0
- package/examples/uber-app/models/location.model.ts +70 -0
- package/examples/uber-app/models/payment.model.ts +87 -0
- package/examples/uber-app/models/rating.model.ts +54 -0
- package/examples/uber-app/models/ride.model.ts +118 -0
- package/examples/uber-app/models/user.model.ts +66 -0
- package/examples/uber-app/models/vehicle.model.ts +63 -0
- package/examples/uber-app/tests/payment.test.tsx +129 -0
- package/examples/uber-app/tests/ride-flow.test.tsx +123 -0
- package/examples/uber-app/workflows/dispute-resolution.workflow.tsx +205 -0
- package/examples/uber-app/workflows/driver-onboarding.workflow.tsx +227 -0
- package/examples/uber-app/workflows/payment-processing.workflow.tsx +223 -0
- package/examples/uber-app/workflows/ride-request.workflow.tsx +194 -0
- package/package.json +77 -0
- package/package.json.backup +86 -0
- package/scripts/decompile.ts +226 -0
- package/scripts/seed-auth.ts +267 -0
- package/scripts/seed-uber.ts +248 -0
- package/scripts/validate-uber.ts +119 -0
- package/seed-blueprint-chat.mjs +444 -0
- package/seed-blueprint-glass-console.mjs +445 -0
- package/seed-compiled.mjs +318 -0
- package/src/RoundTripValidator.ts +400 -0
- package/src/__tests__/atom-rendering-coverage.test.ts +680 -0
- package/src/__tests__/auth-module-compilation.test.ts +247 -0
- package/src/__tests__/auth-template-compilation.test.ts +589 -0
- package/src/__tests__/change-extractor.test.ts +142 -0
- package/src/__tests__/cli-pull.test.ts +73 -0
- package/src/__tests__/cli-test.test.ts +72 -0
- package/src/__tests__/component-extractor.test.ts +331 -0
- package/src/__tests__/context-extractor.test.ts +145 -0
- package/src/__tests__/decompiler.test.ts +718 -0
- package/src/__tests__/define-blueprint.test.ts +133 -0
- package/src/__tests__/definition-validator.test.ts +519 -0
- package/src/__tests__/during-extractor.test.ts +152 -0
- package/src/__tests__/effect-extractor.test.ts +107 -0
- package/src/__tests__/event-emission.test.ts +127 -0
- package/src/__tests__/examples.test.ts +236 -0
- package/src/__tests__/full-blueprint-coverage.test.ts +1221 -0
- package/src/__tests__/golden-suite.test.ts +403 -0
- package/src/__tests__/grammar-island-extractor.test.ts +289 -0
- package/src/__tests__/instance-key.test.ts +82 -0
- package/src/__tests__/ir-migration.test.ts +255 -0
- package/src/__tests__/lock-file.test.ts +117 -0
- package/src/__tests__/model-extractor.test.ts +195 -0
- package/src/__tests__/model-field-acl.test.ts +237 -0
- package/src/__tests__/model-hooks.test.ts +130 -0
- package/src/__tests__/model-ref-resolution.test.ts +268 -0
- package/src/__tests__/model-roundtrip.test.ts +502 -0
- package/src/__tests__/model-runtime.test.ts +112 -0
- package/src/__tests__/model-transitions.test.ts +183 -0
- package/src/__tests__/nrt-action-trace.test.ts +391 -0
- package/src/__tests__/pipeline-hardening.test.ts +413 -0
- package/src/__tests__/project-compiler.test.ts +546 -0
- package/src/__tests__/project-decompiler.test.ts +343 -0
- package/src/__tests__/query-compilation.test.ts +145 -0
- package/src/__tests__/round-trip/PLAN.md +158 -0
- package/src/__tests__/round-trip/README.md +52 -0
- package/src/__tests__/round-trip/RESULTS.md +86 -0
- package/src/__tests__/round-trip/fixtures/data-heavy/main.workflow.tsx +55 -0
- package/src/__tests__/round-trip/fixtures/data-heavy/mm.config.ts +11 -0
- package/src/__tests__/round-trip/fixtures/data-heavy/models/contact.ts +54 -0
- package/src/__tests__/round-trip/fixtures/full-workflow/main.workflow.tsx +79 -0
- package/src/__tests__/round-trip/fixtures/full-workflow/mm.config.ts +12 -0
- package/src/__tests__/round-trip/fixtures/full-workflow/models/order.ts +50 -0
- package/src/__tests__/round-trip/fixtures/simple-crud/main.workflow.tsx +25 -0
- package/src/__tests__/round-trip/fixtures/simple-crud/mm.config.ts +11 -0
- package/src/__tests__/round-trip/fixtures/simple-crud/models/task.ts +32 -0
- package/src/__tests__/round-trip/fixtures/view-heavy/main.workflow.tsx +79 -0
- package/src/__tests__/round-trip/fixtures/view-heavy/mm.config.ts +10 -0
- package/src/__tests__/round-trip/round-trip.test.ts +2598 -0
- package/src/__tests__/round-trip-ir.test.ts +300 -0
- package/src/__tests__/round-trip.test.ts +1212 -0
- package/src/__tests__/route-merging.test.ts +372 -0
- package/src/__tests__/router-composition.test.ts +489 -0
- package/src/__tests__/router-extractor.test.ts +176 -0
- package/src/__tests__/server-action-extractor.test.ts +128 -0
- package/src/__tests__/smart-type-inference.test.ts +365 -0
- package/src/__tests__/source-envelope.test.ts +284 -0
- package/src/__tests__/source-fidelity.test.ts +516 -0
- package/src/__tests__/state-extractor.test.ts +115 -0
- package/src/__tests__/strict-mode.test.ts +227 -0
- package/src/__tests__/transition-effect-extractor.test.ts +119 -0
- package/src/__tests__/transition-extractor.test.ts +68 -0
- package/src/__tests__/ts-to-expression.test.ts +462 -0
- package/src/__tests__/type-generator.test.ts +201 -0
- package/src/__tests__/uber-validation.test.ts +502 -0
- package/src/action-compiler.ts +361 -0
- package/src/babel/emitters/experience-transform.ts +199 -0
- package/src/babel/emitters/ir-to-tsx-emitter.ts +110 -0
- package/src/babel/emitters/pure-form-emitter.ts +1023 -0
- package/src/babel/emitters/runtime-glue-emitter.ts +39 -0
- package/src/babel/extractors/change-extractor.ts +199 -0
- package/src/babel/extractors/component-extractor.ts +907 -0
- package/src/babel/extractors/computed-extractor.ts +262 -0
- package/src/babel/extractors/context-extractor.ts +277 -0
- package/src/babel/extractors/during-extractor.ts +295 -0
- package/src/babel/extractors/effect-extractor.ts +340 -0
- package/src/babel/extractors/event-extractor.ts +235 -0
- package/src/babel/extractors/grammar-island-extractor.ts +302 -0
- package/src/babel/extractors/model-extractor.ts +1018 -0
- package/src/babel/extractors/router-extractor.ts +303 -0
- package/src/babel/extractors/server-action-extractor.ts +173 -0
- package/src/babel/extractors/server-action-hook-extractor.ts +72 -0
- package/src/babel/extractors/server-state-extractor.ts +88 -0
- package/src/babel/extractors/state-extractor.ts +214 -0
- package/src/babel/extractors/transition-effect-extractor.ts +176 -0
- package/src/babel/extractors/transition-extractor.ts +143 -0
- package/src/babel/index.ts +24 -0
- package/src/babel/transpilers/ts-to-expression.ts +674 -0
- package/src/babel/visitor.ts +807 -0
- package/src/cli/auth.ts +255 -0
- package/src/cli/build.ts +288 -0
- package/src/cli/deploy.ts +206 -0
- package/src/cli/index.ts +328 -0
- package/src/cli/init.ts +388 -0
- package/src/cli/installer.ts +261 -0
- package/src/cli/lock-file.ts +94 -0
- package/src/cli/mmrc.ts +22 -0
- package/src/cli/pull.ts +172 -0
- package/src/cli/registry-client.ts +175 -0
- package/src/cli/test.ts +397 -0
- package/src/cli/type-generator.ts +243 -0
- package/src/codemod/__tests__/forward.test.ts +239 -0
- package/src/codemod/__tests__/reverse.test.ts +145 -0
- package/src/codemod/__tests__/round-trip.test.ts +137 -0
- package/src/codemod/annotation.ts +97 -0
- package/src/codemod/classify.ts +197 -0
- package/src/codemod/cli.ts +207 -0
- package/src/codemod/control-flow.ts +409 -0
- package/src/codemod/forward.ts +244 -0
- package/src/codemod/import-manager.ts +171 -0
- package/src/codemod/index.ts +120 -0
- package/src/codemod/reverse.ts +197 -0
- package/src/codemod/rules.ts +174 -0
- package/src/codemod/state-transform.ts +126 -0
- package/src/decompiler/ast-builder.ts +538 -0
- package/src/decompiler/config-generator.ts +151 -0
- package/src/decompiler/index.ts +315 -0
- package/src/decompiler/project-decompiler.ts +1776 -0
- package/src/decompiler/project.ts +862 -0
- package/src/decompiler/split-strategy.ts +140 -0
- package/src/decompiler/state-emitter.ts +1053 -0
- package/src/decompiler/sx-emitter.ts +318 -0
- package/src/decompiler/workspace-hydrator.ts +189 -0
- package/src/dev-server.ts +238 -0
- package/src/envelope/fs-tree.ts +217 -0
- package/src/envelope/source-envelope.ts +264 -0
- package/src/envelope.ts +315 -0
- package/src/incremental-compiler.ts +401 -0
- package/src/index.ts +99 -0
- package/src/model-compiler.ts +277 -0
- package/src/project-compiler.ts +1629 -0
- package/src/route-extractor.ts +333 -0
- package/src/testing/index.ts +32 -0
- package/src/testing/snapshot.ts +252 -0
- package/src/testing/test-utils.ts +226 -0
- package/src/types.ts +68 -0
- package/src/vite/index.ts +288 -0
- package/test-compile.mjs +142 -0
- package/tsconfig.json +25 -0
- package/tsup.config.ts +23 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
transform
|
|
4
|
+
} from "../chunk-CKGOZAB7.mjs";
|
|
5
|
+
import "../chunk-Y6FXYEAI.mjs";
|
|
6
|
+
|
|
7
|
+
// src/codemod/cli.ts
|
|
8
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
9
|
+
import { resolve, relative, dirname } from "path";
|
|
10
|
+
import { glob } from "glob";
|
|
11
|
+
function parseArgs(argv) {
|
|
12
|
+
const args = argv.slice(2);
|
|
13
|
+
const direction = args[0];
|
|
14
|
+
if (!direction || !["forward", "reverse", "verify"].includes(direction)) {
|
|
15
|
+
console.error("Usage: mm-codemod <forward|reverse|verify> <paths...> [options]");
|
|
16
|
+
console.error("");
|
|
17
|
+
console.error("Options:");
|
|
18
|
+
console.error(" --dry-run Print diff without writing");
|
|
19
|
+
console.error(" --strip-annotations Remove @mm-original comments");
|
|
20
|
+
console.error(" --mode <mode> State mode: preserve|migrate|annotate");
|
|
21
|
+
console.error(" --out <dir> Output directory (default: in-place)");
|
|
22
|
+
console.error(" --verbose Log every transformation");
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const paths = [];
|
|
26
|
+
let dryRun = false;
|
|
27
|
+
let stripAnnotations = false;
|
|
28
|
+
let stateMode = "preserve";
|
|
29
|
+
let verbose = false;
|
|
30
|
+
let outDir;
|
|
31
|
+
for (let i = 1; i < args.length; i++) {
|
|
32
|
+
const arg = args[i];
|
|
33
|
+
if (arg === "--dry-run") {
|
|
34
|
+
dryRun = true;
|
|
35
|
+
} else if (arg === "--strip-annotations") {
|
|
36
|
+
stripAnnotations = true;
|
|
37
|
+
} else if (arg === "--mode") {
|
|
38
|
+
stateMode = args[++i];
|
|
39
|
+
} else if (arg === "--out") {
|
|
40
|
+
outDir = args[++i];
|
|
41
|
+
} else if (arg === "--verbose") {
|
|
42
|
+
verbose = true;
|
|
43
|
+
} else if (!arg.startsWith("-")) {
|
|
44
|
+
paths.push(arg);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (paths.length === 0) {
|
|
48
|
+
console.error("Error: No paths specified");
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
return { direction, paths, dryRun, stripAnnotations, stateMode, verbose, outDir };
|
|
52
|
+
}
|
|
53
|
+
async function findFiles(paths) {
|
|
54
|
+
const files = [];
|
|
55
|
+
for (const p of paths) {
|
|
56
|
+
const resolved = resolve(p);
|
|
57
|
+
const matches = await glob("**/*.{tsx,jsx}", {
|
|
58
|
+
cwd: resolved,
|
|
59
|
+
absolute: true,
|
|
60
|
+
ignore: ["**/node_modules/**", "**/__tests__/**", "**/dist/**"]
|
|
61
|
+
});
|
|
62
|
+
files.push(...matches);
|
|
63
|
+
}
|
|
64
|
+
return files.sort();
|
|
65
|
+
}
|
|
66
|
+
function transformFile(filePath, options, verbose) {
|
|
67
|
+
const source = readFileSync(filePath, "utf-8");
|
|
68
|
+
try {
|
|
69
|
+
const result = transform(source, options);
|
|
70
|
+
const changed = result.code !== source;
|
|
71
|
+
if (verbose && changed) {
|
|
72
|
+
console.log(` [${options.direction}] ${relative(process.cwd(), filePath)}`);
|
|
73
|
+
}
|
|
74
|
+
return { code: result.code, changed };
|
|
75
|
+
} catch (err) {
|
|
76
|
+
console.error(` [ERROR] ${relative(process.cwd(), filePath)}: ${err.message}`);
|
|
77
|
+
return { code: source, changed: false };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function main() {
|
|
81
|
+
const opts = parseArgs(process.argv);
|
|
82
|
+
const files = await findFiles(opts.paths);
|
|
83
|
+
console.log(`mm-codemod: ${opts.direction} \u2014 ${files.length} file(s)`);
|
|
84
|
+
if (opts.direction === "verify") {
|
|
85
|
+
let pass = 0;
|
|
86
|
+
let fail = 0;
|
|
87
|
+
for (const file of files) {
|
|
88
|
+
const source = readFileSync(file, "utf-8");
|
|
89
|
+
const forward = transform(source, {
|
|
90
|
+
direction: "forward",
|
|
91
|
+
annotate: true,
|
|
92
|
+
stateMode: opts.stateMode
|
|
93
|
+
});
|
|
94
|
+
const roundTripped = transform(forward.code, {
|
|
95
|
+
direction: "reverse",
|
|
96
|
+
annotate: false,
|
|
97
|
+
stateMode: opts.stateMode
|
|
98
|
+
});
|
|
99
|
+
const normalize = (s) => s.replace(/\s+/g, " ").trim();
|
|
100
|
+
if (normalize(roundTripped.code) === normalize(source)) {
|
|
101
|
+
pass++;
|
|
102
|
+
if (opts.verbose) console.log(` [PASS] ${relative(process.cwd(), file)}`);
|
|
103
|
+
} else {
|
|
104
|
+
fail++;
|
|
105
|
+
console.log(` [FAIL] ${relative(process.cwd(), file)}`);
|
|
106
|
+
if (opts.verbose) {
|
|
107
|
+
console.log(" Expected (normalized):");
|
|
108
|
+
console.log(` ${normalize(source).slice(0, 200)}...`);
|
|
109
|
+
console.log(" Got (normalized):");
|
|
110
|
+
console.log(` ${normalize(roundTripped.code).slice(0, 200)}...`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
console.log(`
|
|
115
|
+
Results: ${pass} pass, ${fail} fail out of ${files.length} files`);
|
|
116
|
+
process.exit(fail > 0 ? 1 : 0);
|
|
117
|
+
}
|
|
118
|
+
const codemodOptions = {
|
|
119
|
+
direction: opts.direction,
|
|
120
|
+
annotate: !opts.stripAnnotations,
|
|
121
|
+
stateMode: opts.stateMode
|
|
122
|
+
};
|
|
123
|
+
let changed = 0;
|
|
124
|
+
let unchanged = 0;
|
|
125
|
+
let errors = 0;
|
|
126
|
+
for (const file of files) {
|
|
127
|
+
try {
|
|
128
|
+
const result = transformFile(file, codemodOptions, opts.verbose);
|
|
129
|
+
if (!result.changed) {
|
|
130
|
+
unchanged++;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
changed++;
|
|
134
|
+
if (opts.dryRun) {
|
|
135
|
+
console.log(` [WOULD CHANGE] ${relative(process.cwd(), file)}`);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
let outPath = file;
|
|
139
|
+
if (opts.outDir) {
|
|
140
|
+
const rel = relative(resolve(opts.paths[0]), file);
|
|
141
|
+
outPath = resolve(opts.outDir, rel);
|
|
142
|
+
const dir = dirname(outPath);
|
|
143
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
144
|
+
}
|
|
145
|
+
writeFileSync(outPath, result.code, "utf-8");
|
|
146
|
+
} catch (err) {
|
|
147
|
+
errors++;
|
|
148
|
+
console.error(` [ERROR] ${relative(process.cwd(), file)}: ${err.message}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
console.log(`
|
|
152
|
+
Done: ${changed} changed, ${unchanged} unchanged, ${errors} errors`);
|
|
153
|
+
}
|
|
154
|
+
main().catch((err) => {
|
|
155
|
+
console.error(err);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* State transform — handles useState ↔ useQuery/useMutation migration.
|
|
5
|
+
*
|
|
6
|
+
* Three modes:
|
|
7
|
+
* preserve (default): useState stays as-is
|
|
8
|
+
* annotate: Adds @mm-field comments without changing code
|
|
9
|
+
* migrate: Converts annotated useState to useQuery/useMutation
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
type StateMode = 'preserve' | 'annotate' | 'migrate';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Import manager — tracks atom usage and rewrites imports.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
interface ImportTracker {
|
|
19
|
+
/** Mark an atom as used (forward: add to imports) */
|
|
20
|
+
addAtom(name: string): void;
|
|
21
|
+
/** Mark an atom as removed (reverse: remove from imports) */
|
|
22
|
+
removeAtom(name: string): void;
|
|
23
|
+
/** Get the set of atoms that need importing */
|
|
24
|
+
getUsedAtoms(): Set<string>;
|
|
25
|
+
/** Get the set of atoms that were removed */
|
|
26
|
+
getRemovedAtoms(): Set<string>;
|
|
27
|
+
}
|
|
28
|
+
declare function createImportTracker(): ImportTracker;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Element classifier — analyzes tag name + className to determine target atom.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
interface ClassifyResult {
|
|
35
|
+
atom: string;
|
|
36
|
+
/** Classes to remove from className (implicit in atom) */
|
|
37
|
+
removeClasses: string[];
|
|
38
|
+
/** Props to add to the element */
|
|
39
|
+
addProps: Record<string, string | boolean>;
|
|
40
|
+
/** Original tag for annotation */
|
|
41
|
+
originalTag: string;
|
|
42
|
+
}
|
|
43
|
+
interface ReverseClassifyResult {
|
|
44
|
+
htmlTag: string;
|
|
45
|
+
/** Classes to inject into className */
|
|
46
|
+
injectClasses: string[];
|
|
47
|
+
/** Props to remove (encoded in HTML tag) */
|
|
48
|
+
removeProps: string[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Extract static class names from a className JSX attribute value.
|
|
52
|
+
* Handles: string literals, template literals (static parts), cn() first arg.
|
|
53
|
+
*/
|
|
54
|
+
declare function extractStaticClasses(attrValue: t.Node | null | undefined): string[];
|
|
55
|
+
/**
|
|
56
|
+
* Classify a raw HTML element into its target workflow atom.
|
|
57
|
+
*/
|
|
58
|
+
declare function classifyElement(tagName: string, classNames: string[]): ClassifyResult | null;
|
|
59
|
+
/**
|
|
60
|
+
* Reverse-classify a workflow atom into its target HTML element.
|
|
61
|
+
*/
|
|
62
|
+
declare function reverseClassifyAtom(atomName: string, props: Map<string, t.Node>): ReverseClassifyResult | null;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Bidirectional element mapping rules.
|
|
66
|
+
*
|
|
67
|
+
* Each rule defines:
|
|
68
|
+
* - htmlTag: The raw React element tag name
|
|
69
|
+
* - atom: The workflow atom component name
|
|
70
|
+
* - classSignal: Tailwind classes that trigger this mapping (forward)
|
|
71
|
+
* - implicitClasses: Classes that are implicit in the atom and should be
|
|
72
|
+
* removed on forward / added on reverse
|
|
73
|
+
* - props: Additional props to set on forward / remove on reverse
|
|
74
|
+
*/
|
|
75
|
+
interface MappingRule {
|
|
76
|
+
htmlTag: string;
|
|
77
|
+
atom: string;
|
|
78
|
+
/** Classes in className that signal this atom (forward classification) */
|
|
79
|
+
classSignal?: string[];
|
|
80
|
+
/** Classes implicit in the atom — removed on forward, injected on reverse */
|
|
81
|
+
implicitClasses?: string[];
|
|
82
|
+
/** Props added on forward, removed on reverse */
|
|
83
|
+
props?: Record<string, string | boolean>;
|
|
84
|
+
/** Priority when multiple rules match (higher wins) */
|
|
85
|
+
priority?: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Forward rules: HTML element → Atom
|
|
89
|
+
* Ordered by specificity — more specific signals checked first.
|
|
90
|
+
*/
|
|
91
|
+
declare const FORWARD_RULES: MappingRule[];
|
|
92
|
+
/**
|
|
93
|
+
* Reverse rules: Atom → HTML element
|
|
94
|
+
* Derived from forward rules but keyed by atom name.
|
|
95
|
+
*/
|
|
96
|
+
interface ReverseRule {
|
|
97
|
+
atom: string;
|
|
98
|
+
htmlTag: string;
|
|
99
|
+
/** Classes to inject into className on reverse */
|
|
100
|
+
injectClasses?: string[];
|
|
101
|
+
/** Props to remove on reverse (they're encoded in the HTML tag) */
|
|
102
|
+
removeProps?: string[];
|
|
103
|
+
}
|
|
104
|
+
declare const REVERSE_RULES: ReverseRule[];
|
|
105
|
+
/**
|
|
106
|
+
* Atom import source
|
|
107
|
+
*/
|
|
108
|
+
declare const ATOM_IMPORT_SOURCE = "@mindmatrix/react/atoms";
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Bidirectional React ↔ Workflow Atom Codemod
|
|
112
|
+
*
|
|
113
|
+
* Babel plugin entry point. Dispatches by `direction` option.
|
|
114
|
+
*
|
|
115
|
+
* Usage as Babel plugin:
|
|
116
|
+
* plugins: [['@mindmatrix/react-compiler/codemod', { direction: 'forward' }]]
|
|
117
|
+
*
|
|
118
|
+
* Usage programmatic:
|
|
119
|
+
* import { transform } from '@mindmatrix/react-compiler/codemod';
|
|
120
|
+
* const result = transform(source, { direction: 'forward' });
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
interface CodemodOptions {
|
|
124
|
+
/** Transform direction */
|
|
125
|
+
direction: 'forward' | 'reverse';
|
|
126
|
+
/** Add/strip @mm-original annotations */
|
|
127
|
+
annotate?: boolean;
|
|
128
|
+
/** State transform mode (default: 'preserve') */
|
|
129
|
+
stateMode?: StateMode;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Babel plugin — use via .babelrc or programmatic config.
|
|
133
|
+
*/
|
|
134
|
+
declare const codemodPlugin: any;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Programmatic transform API.
|
|
138
|
+
*
|
|
139
|
+
* @param source - Source code string
|
|
140
|
+
* @param options - Codemod options
|
|
141
|
+
* @returns Transformed source code
|
|
142
|
+
*/
|
|
143
|
+
declare function transform(source: string, options: CodemodOptions): {
|
|
144
|
+
code: string;
|
|
145
|
+
map: any;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export { ATOM_IMPORT_SOURCE, type ClassifyResult, type CodemodOptions, FORWARD_RULES, type MappingRule, REVERSE_RULES, type ReverseClassifyResult, type ReverseRule, classifyElement, codemodPlugin, createImportTracker, codemodPlugin as default, extractStaticClasses, reverseClassifyAtom, transform };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* State transform — handles useState ↔ useQuery/useMutation migration.
|
|
5
|
+
*
|
|
6
|
+
* Three modes:
|
|
7
|
+
* preserve (default): useState stays as-is
|
|
8
|
+
* annotate: Adds @mm-field comments without changing code
|
|
9
|
+
* migrate: Converts annotated useState to useQuery/useMutation
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
type StateMode = 'preserve' | 'annotate' | 'migrate';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Import manager — tracks atom usage and rewrites imports.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
interface ImportTracker {
|
|
19
|
+
/** Mark an atom as used (forward: add to imports) */
|
|
20
|
+
addAtom(name: string): void;
|
|
21
|
+
/** Mark an atom as removed (reverse: remove from imports) */
|
|
22
|
+
removeAtom(name: string): void;
|
|
23
|
+
/** Get the set of atoms that need importing */
|
|
24
|
+
getUsedAtoms(): Set<string>;
|
|
25
|
+
/** Get the set of atoms that were removed */
|
|
26
|
+
getRemovedAtoms(): Set<string>;
|
|
27
|
+
}
|
|
28
|
+
declare function createImportTracker(): ImportTracker;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Element classifier — analyzes tag name + className to determine target atom.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
interface ClassifyResult {
|
|
35
|
+
atom: string;
|
|
36
|
+
/** Classes to remove from className (implicit in atom) */
|
|
37
|
+
removeClasses: string[];
|
|
38
|
+
/** Props to add to the element */
|
|
39
|
+
addProps: Record<string, string | boolean>;
|
|
40
|
+
/** Original tag for annotation */
|
|
41
|
+
originalTag: string;
|
|
42
|
+
}
|
|
43
|
+
interface ReverseClassifyResult {
|
|
44
|
+
htmlTag: string;
|
|
45
|
+
/** Classes to inject into className */
|
|
46
|
+
injectClasses: string[];
|
|
47
|
+
/** Props to remove (encoded in HTML tag) */
|
|
48
|
+
removeProps: string[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Extract static class names from a className JSX attribute value.
|
|
52
|
+
* Handles: string literals, template literals (static parts), cn() first arg.
|
|
53
|
+
*/
|
|
54
|
+
declare function extractStaticClasses(attrValue: t.Node | null | undefined): string[];
|
|
55
|
+
/**
|
|
56
|
+
* Classify a raw HTML element into its target workflow atom.
|
|
57
|
+
*/
|
|
58
|
+
declare function classifyElement(tagName: string, classNames: string[]): ClassifyResult | null;
|
|
59
|
+
/**
|
|
60
|
+
* Reverse-classify a workflow atom into its target HTML element.
|
|
61
|
+
*/
|
|
62
|
+
declare function reverseClassifyAtom(atomName: string, props: Map<string, t.Node>): ReverseClassifyResult | null;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Bidirectional element mapping rules.
|
|
66
|
+
*
|
|
67
|
+
* Each rule defines:
|
|
68
|
+
* - htmlTag: The raw React element tag name
|
|
69
|
+
* - atom: The workflow atom component name
|
|
70
|
+
* - classSignal: Tailwind classes that trigger this mapping (forward)
|
|
71
|
+
* - implicitClasses: Classes that are implicit in the atom and should be
|
|
72
|
+
* removed on forward / added on reverse
|
|
73
|
+
* - props: Additional props to set on forward / remove on reverse
|
|
74
|
+
*/
|
|
75
|
+
interface MappingRule {
|
|
76
|
+
htmlTag: string;
|
|
77
|
+
atom: string;
|
|
78
|
+
/** Classes in className that signal this atom (forward classification) */
|
|
79
|
+
classSignal?: string[];
|
|
80
|
+
/** Classes implicit in the atom — removed on forward, injected on reverse */
|
|
81
|
+
implicitClasses?: string[];
|
|
82
|
+
/** Props added on forward, removed on reverse */
|
|
83
|
+
props?: Record<string, string | boolean>;
|
|
84
|
+
/** Priority when multiple rules match (higher wins) */
|
|
85
|
+
priority?: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Forward rules: HTML element → Atom
|
|
89
|
+
* Ordered by specificity — more specific signals checked first.
|
|
90
|
+
*/
|
|
91
|
+
declare const FORWARD_RULES: MappingRule[];
|
|
92
|
+
/**
|
|
93
|
+
* Reverse rules: Atom → HTML element
|
|
94
|
+
* Derived from forward rules but keyed by atom name.
|
|
95
|
+
*/
|
|
96
|
+
interface ReverseRule {
|
|
97
|
+
atom: string;
|
|
98
|
+
htmlTag: string;
|
|
99
|
+
/** Classes to inject into className on reverse */
|
|
100
|
+
injectClasses?: string[];
|
|
101
|
+
/** Props to remove on reverse (they're encoded in the HTML tag) */
|
|
102
|
+
removeProps?: string[];
|
|
103
|
+
}
|
|
104
|
+
declare const REVERSE_RULES: ReverseRule[];
|
|
105
|
+
/**
|
|
106
|
+
* Atom import source
|
|
107
|
+
*/
|
|
108
|
+
declare const ATOM_IMPORT_SOURCE = "@mindmatrix/react/atoms";
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Bidirectional React ↔ Workflow Atom Codemod
|
|
112
|
+
*
|
|
113
|
+
* Babel plugin entry point. Dispatches by `direction` option.
|
|
114
|
+
*
|
|
115
|
+
* Usage as Babel plugin:
|
|
116
|
+
* plugins: [['@mindmatrix/react-compiler/codemod', { direction: 'forward' }]]
|
|
117
|
+
*
|
|
118
|
+
* Usage programmatic:
|
|
119
|
+
* import { transform } from '@mindmatrix/react-compiler/codemod';
|
|
120
|
+
* const result = transform(source, { direction: 'forward' });
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
interface CodemodOptions {
|
|
124
|
+
/** Transform direction */
|
|
125
|
+
direction: 'forward' | 'reverse';
|
|
126
|
+
/** Add/strip @mm-original annotations */
|
|
127
|
+
annotate?: boolean;
|
|
128
|
+
/** State transform mode (default: 'preserve') */
|
|
129
|
+
stateMode?: StateMode;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Babel plugin — use via .babelrc or programmatic config.
|
|
133
|
+
*/
|
|
134
|
+
declare const codemodPlugin: any;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Programmatic transform API.
|
|
138
|
+
*
|
|
139
|
+
* @param source - Source code string
|
|
140
|
+
* @param options - Codemod options
|
|
141
|
+
* @returns Transformed source code
|
|
142
|
+
*/
|
|
143
|
+
declare function transform(source: string, options: CodemodOptions): {
|
|
144
|
+
code: string;
|
|
145
|
+
map: any;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export { ATOM_IMPORT_SOURCE, type ClassifyResult, type CodemodOptions, FORWARD_RULES, type MappingRule, REVERSE_RULES, type ReverseClassifyResult, type ReverseRule, classifyElement, codemodPlugin, createImportTracker, codemodPlugin as default, extractStaticClasses, reverseClassifyAtom, transform };
|