@maggioli-design-system/magma-codemods 2.0.0-beta.0
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 +193 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +77 -0
- package/dist/generate/diff-docs.d.ts +36 -0
- package/dist/generate/diff-docs.js +180 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +166 -0
- package/dist/manifest/manifest.d.ts +3 -0
- package/dist/manifest/manifest.generated.d.ts +2 -0
- package/dist/manifest/manifest.generated.js +1901 -0
- package/dist/manifest/manifest.js +546 -0
- package/dist/manifest/registry.d.ts +32 -0
- package/dist/manifest/registry.js +102 -0
- package/dist/manifest/schema.d.ts +245 -0
- package/dist/manifest/schema.js +9 -0
- package/dist/report/diff.d.ts +2 -0
- package/dist/report/diff.js +95 -0
- package/dist/report/reporter.d.ts +27 -0
- package/dist/report/reporter.js +118 -0
- package/dist/report/types.d.ts +51 -0
- package/dist/report/types.js +2 -0
- package/dist/surfaces/angular.d.ts +3 -0
- package/dist/surfaces/angular.js +489 -0
- package/dist/surfaces/css.d.ts +5 -0
- package/dist/surfaces/css.js +287 -0
- package/dist/surfaces/html.d.ts +3 -0
- package/dist/surfaces/html.js +402 -0
- package/dist/surfaces/inline-templates.d.ts +3 -0
- package/dist/surfaces/inline-templates.js +98 -0
- package/dist/surfaces/react.d.ts +3 -0
- package/dist/surfaces/react.js +496 -0
- package/dist/surfaces/shared/attribute-ops.d.ts +56 -0
- package/dist/surfaces/shared/attribute-ops.js +62 -0
- package/dist/surfaces/shared/class-ops.d.ts +55 -0
- package/dist/surfaces/shared/class-ops.js +91 -0
- package/dist/surfaces/shared/edits.d.ts +19 -0
- package/dist/surfaces/shared/edits.js +30 -0
- package/dist/surfaces/shared/negate.d.ts +13 -0
- package/dist/surfaces/shared/negate.js +51 -0
- package/dist/surfaces/shared/transform.d.ts +17 -0
- package/dist/surfaces/shared/transform.js +8 -0
- package/dist/surfaces/shared/value-model.d.ts +49 -0
- package/dist/surfaces/shared/value-model.js +18 -0
- package/package.json +61 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic entry point for the Magma v1 → v2 codemods.
|
|
3
|
+
*
|
|
4
|
+
* The CLI (`src/cli.ts`) is a thin wrapper around {@link runMigration}.
|
|
5
|
+
*/
|
|
6
|
+
import { execFileSync } from 'node:child_process';
|
|
7
|
+
import { readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { extname } from 'node:path';
|
|
9
|
+
import { globby } from 'globby';
|
|
10
|
+
import { manifest as bundledManifest } from './manifest/manifest.js';
|
|
11
|
+
import { unifiedDiff } from './report/diff.js';
|
|
12
|
+
import { Reporter } from './report/reporter.js';
|
|
13
|
+
import { transformAngular } from './surfaces/angular.js';
|
|
14
|
+
import { transformCss } from './surfaces/css.js';
|
|
15
|
+
import { transformHtml } from './surfaces/html.js';
|
|
16
|
+
import { transformInlineTemplates } from './surfaces/inline-templates.js';
|
|
17
|
+
import { transformReact } from './surfaces/react.js';
|
|
18
|
+
const DEFAULT_IGNORE = [
|
|
19
|
+
'**/node_modules/**',
|
|
20
|
+
'**/dist/**',
|
|
21
|
+
'**/.git/**',
|
|
22
|
+
'**/build/**',
|
|
23
|
+
'**/.next/**',
|
|
24
|
+
'**/coverage/**',
|
|
25
|
+
];
|
|
26
|
+
const EXTENSIONS = ['html', 'htm', 'tsx', 'jsx', 'ts', 'css', 'scss'];
|
|
27
|
+
/** Pick the transform for a file given the framework (or `auto` by extension). Returns null to skip. */
|
|
28
|
+
export const routeFile = (file, framework) => {
|
|
29
|
+
const ext = extname(file).toLowerCase();
|
|
30
|
+
const css = {
|
|
31
|
+
surface: 'css',
|
|
32
|
+
run: (s, m, c) => transformCss(s, m, c, { scss: ext === '.scss' }),
|
|
33
|
+
};
|
|
34
|
+
const react = { surface: 'react', run: transformReact };
|
|
35
|
+
const html = { surface: 'html', run: transformHtml };
|
|
36
|
+
const angular = { surface: 'angular', run: transformAngular };
|
|
37
|
+
const inline = { surface: 'angular', run: transformInlineTemplates };
|
|
38
|
+
switch (framework) {
|
|
39
|
+
case 'css':
|
|
40
|
+
return css;
|
|
41
|
+
case 'react':
|
|
42
|
+
return react;
|
|
43
|
+
case 'html':
|
|
44
|
+
return html;
|
|
45
|
+
case 'angular':
|
|
46
|
+
if (ext === '.html' || ext === '.htm')
|
|
47
|
+
return angular;
|
|
48
|
+
if (ext === '.ts')
|
|
49
|
+
return inline;
|
|
50
|
+
return null;
|
|
51
|
+
case 'auto':
|
|
52
|
+
default:
|
|
53
|
+
if (ext === '.css' || ext === '.scss')
|
|
54
|
+
return css;
|
|
55
|
+
if (ext === '.tsx' || ext === '.jsx')
|
|
56
|
+
return react;
|
|
57
|
+
if (ext === '.ts')
|
|
58
|
+
return inline;
|
|
59
|
+
if (ext === '.html' || ext === '.htm')
|
|
60
|
+
return html;
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const isGitClean = (cwd) => {
|
|
65
|
+
try {
|
|
66
|
+
const out = execFileSync('git', ['status', '--porcelain'], {
|
|
67
|
+
cwd,
|
|
68
|
+
encoding: 'utf8',
|
|
69
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
70
|
+
});
|
|
71
|
+
return out.trim() === '';
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return 'not-a-repo';
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const loadManifest = (manifestPath) => manifestPath ? JSON.parse(readFileSync(manifestPath, 'utf8')) : bundledManifest;
|
|
78
|
+
/** Expand the input paths into a concrete, de-duplicated file list. */
|
|
79
|
+
export const collectFiles = async (paths, cwd, ignore) => {
|
|
80
|
+
const files = new Set();
|
|
81
|
+
const patterns = [];
|
|
82
|
+
for (const p of paths) {
|
|
83
|
+
let isDir = false;
|
|
84
|
+
try {
|
|
85
|
+
isDir = statSync(p).isDirectory();
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (isDir)
|
|
91
|
+
patterns.push(`${p.replace(/\/$/, '')}/**/*.{${EXTENSIONS.join(',')}}`);
|
|
92
|
+
else
|
|
93
|
+
files.add(p);
|
|
94
|
+
}
|
|
95
|
+
if (patterns.length) {
|
|
96
|
+
const matched = await globby(patterns, {
|
|
97
|
+
cwd,
|
|
98
|
+
absolute: true,
|
|
99
|
+
onlyFiles: true,
|
|
100
|
+
ignore: [...DEFAULT_IGNORE, ...ignore],
|
|
101
|
+
});
|
|
102
|
+
for (const m of matched)
|
|
103
|
+
files.add(m);
|
|
104
|
+
}
|
|
105
|
+
return [...files].sort();
|
|
106
|
+
};
|
|
107
|
+
export const runMigration = async (options) => {
|
|
108
|
+
const cwd = options.cwd ?? process.cwd();
|
|
109
|
+
const write = options.write === true;
|
|
110
|
+
const manifest = loadManifest(options.manifestPath);
|
|
111
|
+
if (write && options.force !== true) {
|
|
112
|
+
const clean = isGitClean(cwd);
|
|
113
|
+
if (clean === false) {
|
|
114
|
+
throw new Error('Refusing to --write: the git working tree is not clean. Commit/stash first, or pass --force.');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const reporter = new Reporter({
|
|
118
|
+
fromVersion: manifest.fromVersion,
|
|
119
|
+
toVersion: manifest.toVersion,
|
|
120
|
+
dryRun: !write,
|
|
121
|
+
});
|
|
122
|
+
const ctxBase = {
|
|
123
|
+
only: options.only ? new Set(options.only) : undefined,
|
|
124
|
+
skip: options.skip ? new Set(options.skip) : undefined,
|
|
125
|
+
};
|
|
126
|
+
const files = await collectFiles(options.paths, cwd, options.ignore ?? []);
|
|
127
|
+
for (const file of files) {
|
|
128
|
+
const route = routeFile(file, options.framework);
|
|
129
|
+
if (!route)
|
|
130
|
+
continue;
|
|
131
|
+
let source;
|
|
132
|
+
try {
|
|
133
|
+
source = readFileSync(file, 'utf8');
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
reporter.addError({
|
|
137
|
+
file,
|
|
138
|
+
surface: route.surface,
|
|
139
|
+
message: `cannot read file: ${error.message}`,
|
|
140
|
+
});
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
const result = route.run(source, manifest, { file, ...ctxBase });
|
|
145
|
+
const fileReport = {
|
|
146
|
+
file,
|
|
147
|
+
surface: route.surface,
|
|
148
|
+
changed: result.changed,
|
|
149
|
+
findings: result.findings,
|
|
150
|
+
diff: result.changed ? unifiedDiff(file, source, result.output) : undefined,
|
|
151
|
+
};
|
|
152
|
+
reporter.addFile(fileReport);
|
|
153
|
+
if (write && result.changed)
|
|
154
|
+
writeFileSync(file, result.output);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
reporter.addError({ file, surface: route.surface, message: error.message });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const report = reporter.build();
|
|
161
|
+
if (options.reportPath)
|
|
162
|
+
writeFileSync(options.reportPath, reporter.toJSON(report));
|
|
163
|
+
return { report, reporter };
|
|
164
|
+
};
|
|
165
|
+
export * from './report/types.js';
|
|
166
|
+
export { exitCode } from './report/reporter.js';
|