@mittwald/flow-codemods 1.1.0-next.10
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 +106 -0
- package/dist/catalog/entries.d.ts +17 -0
- package/dist/catalog/entries.d.ts.map +1 -0
- package/dist/catalog/entries.js +9 -0
- package/dist/catalog/select.d.ts +28 -0
- package/dist/catalog/select.d.ts.map +1 -0
- package/dist/catalog/select.js +27 -0
- package/dist/catalog/types.d.ts +48 -0
- package/dist/catalog/types.d.ts.map +1 -0
- package/dist/catalog/types.js +0 -0
- package/dist/checks/context.d.ts +16 -0
- package/dist/checks/context.d.ts.map +1 -0
- package/dist/checks/context.js +72 -0
- package/dist/checks/load.d.ts +13 -0
- package/dist/checks/load.d.ts.map +1 -0
- package/dist/checks/load.js +53 -0
- package/dist/checks/types.d.ts +49 -0
- package/dist/checks/types.d.ts.map +1 -0
- package/dist/checks/types.js +0 -0
- package/dist/cli/args.d.ts +22 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +56 -0
- package/dist/cli/choose.d.ts +31 -0
- package/dist/cli/choose.d.ts.map +1 -0
- package/dist/cli/choose.js +31 -0
- package/dist/cli/codemod.d.ts +24 -0
- package/dist/cli/codemod.d.ts.map +1 -0
- package/dist/cli/codemod.js +76 -0
- package/dist/cli/detect.d.ts +35 -0
- package/dist/cli/detect.d.ts.map +1 -0
- package/dist/cli/detect.js +62 -0
- package/dist/cli/list.d.ts +71 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +293 -0
- package/dist/cli/upgrade.d.ts +34 -0
- package/dist/cli/upgrade.d.ts.map +1 -0
- package/dist/cli/upgrade.js +217 -0
- package/dist/cli/verify.d.ts +77 -0
- package/dist/cli/verify.d.ts.map +1 -0
- package/dist/cli/verify.js +148 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +117 -0
- package/dist/detect/align-to-combine.d.ts +8 -0
- package/dist/detect/align-to-combine.d.ts.map +1 -0
- package/dist/detect/align-to-combine.js +9 -0
- package/dist/detect/overlay-controller-add-on-close-return-type.d.ts +9 -0
- package/dist/detect/overlay-controller-add-on-close-return-type.d.ts.map +1 -0
- package/dist/detect/overlay-controller-add-on-close-return-type.js +10 -0
- package/dist/detect/tooltip-trigger-delay-type.d.ts +11 -0
- package/dist/detect/tooltip-trigger-delay-type.d.ts.map +1 -0
- package/dist/detect/tooltip-trigger-delay-type.js +12 -0
- package/dist/flowPackages.generated.d.ts +3 -0
- package/dist/flowPackages.generated.d.ts.map +1 -0
- package/dist/flowPackages.generated.js +18 -0
- package/dist/git.d.ts +13 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +41 -0
- package/dist/install.d.ts +37 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +71 -0
- package/dist/manifest.d.ts +45 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +88 -0
- package/dist/migrations.generated.d.ts +4 -0
- package/dist/migrations.generated.d.ts.map +1 -0
- package/dist/migrations.generated.js +213 -0
- package/dist/resolve/range.d.ts +50 -0
- package/dist/resolve/range.d.ts.map +1 -0
- package/dist/resolve/range.js +173 -0
- package/dist/resolve/registry.d.ts +33 -0
- package/dist/resolve/registry.d.ts.map +1 -0
- package/dist/resolve/registry.js +69 -0
- package/dist/resolve/target.d.ts +63 -0
- package/dist/resolve/target.d.ts.map +1 -0
- package/dist/resolve/target.js +115 -0
- package/dist/run/jscodeshift.d.ts +42 -0
- package/dist/run/jscodeshift.d.ts.map +1 -0
- package/dist/run/jscodeshift.js +88 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/verify/align-to-combine.d.ts +11 -0
- package/dist/verify/align-to-combine.d.ts.map +1 -0
- package/dist/verify/align-to-combine.js +22 -0
- package/dist/verify/overlay-controller-add-on-close-return-type.d.ts +14 -0
- package/dist/verify/overlay-controller-add-on-close-return-type.d.ts.map +1 -0
- package/dist/verify/overlay-controller-add-on-close-return-type.js +21 -0
- package/dist/verify/tooltip-trigger-delay-type.d.ts +13 -0
- package/dist/verify/tooltip-trigger-delay-type.d.ts.map +1 -0
- package/dist/verify/tooltip-trigger-delay-type.js +18 -0
- package/package.json +41 -0
- package/src/migrations/accent-box-color-to-background-color/transform.ts +218 -0
- package/src/migrations/action-prop-to-on-action/transform.ts +110 -0
- package/src/migrations/align-to-combine/transform.ts +212 -0
- package/src/migrations/button-color-accent-to-success/transform.ts +164 -0
- package/src/migrations/button-props-interfaces/transform.ts +229 -0
- package/src/migrations/color-primary-to-default/transform.ts +173 -0
- package/src/migrations/imports-to-package-root/transform.ts +107 -0
- package/src/migrations/muted-action-error-to-abort-action-error/transform.ts +260 -0
- package/src/migrations/password-tools-rule/transform.ts +219 -0
- package/src/migrations/password-tools-subpath-renamed/transform.ts +61 -0
- package/src/tools/to-remote-package.ts +37 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import type { Transform } from "jscodeshift";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Replaces `AsyncRule` and `SyncRule` with `Rule` (alpha.802).
|
|
5
|
+
*
|
|
6
|
+
* `@mittwald/password-tools-js` merged both classes into a single abstract
|
|
7
|
+
* `Rule`, and the `mittwald-password-tools-js` entry stopped re-exporting the
|
|
8
|
+
* old names. A custom rule extends `Rule` and may return its result
|
|
9
|
+
* synchronously or as a promise — the distinction the two classes encoded is
|
|
10
|
+
* gone, so both names collapse onto the same one.
|
|
11
|
+
*
|
|
12
|
+
* Only names imported from the `mittwald-password-tools-js` entry of
|
|
13
|
+
* `@mittwald/flow-react-components` are touched, so a same-named import from
|
|
14
|
+
* another package is left alone. `@mittwald/flow-remote-react-components` has
|
|
15
|
+
* no such entry. A name imported under a local alias (`import { AsyncRule as
|
|
16
|
+
* Base }`) keeps its alias — only the imported name changes. Namespace usages
|
|
17
|
+
* (`Pw.AsyncRule`) are rewritten as well.
|
|
18
|
+
*
|
|
19
|
+
* Because both names collapse onto `Rule`, a file importing more than one of
|
|
20
|
+
* them would end up with a duplicate specifier. Those collapse onto one.
|
|
21
|
+
*/
|
|
22
|
+
const passwordToolsRuleTransform: Transform = (fileInfo, { j }) => {
|
|
23
|
+
const flowPackages = [
|
|
24
|
+
"@mittwald/flow-react-components/mittwald-password-tools-js",
|
|
25
|
+
];
|
|
26
|
+
const renames = new Map([
|
|
27
|
+
["AsyncRule", "Rule"],
|
|
28
|
+
["SyncRule", "Rule"],
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
const isFlowImport = (source: string): boolean =>
|
|
32
|
+
flowPackages.includes(source);
|
|
33
|
+
|
|
34
|
+
// ast-types models `importKind` on the declaration only, while babel also
|
|
35
|
+
// puts it on the specifier — which is where a per-specifier `type X` lives.
|
|
36
|
+
const isTypeOnly = (specifier: object): boolean =>
|
|
37
|
+
(specifier as { importKind?: string }).importKind === "type";
|
|
38
|
+
const makeValueImport = (specifier: object): void => {
|
|
39
|
+
(specifier as { importKind?: string }).importKind = "value";
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const root = j(fileInfo.source, { parser: "tsx" });
|
|
43
|
+
|
|
44
|
+
/** Local identifiers that refer to a renamed export, mapped to the new name. */
|
|
45
|
+
const localRenames = new Map<string, string>();
|
|
46
|
+
/**
|
|
47
|
+
* Whether any import specifier was rewritten. An aliased `Align as Row` adds
|
|
48
|
+
* nothing to `localRenames` — its local name stays `Row` — so counting those
|
|
49
|
+
* alone would treat an alias-only file as untouched and discard the rewrite.
|
|
50
|
+
*/
|
|
51
|
+
let renamedAnImport = false;
|
|
52
|
+
/** Local names of `import * as Flow` namespace imports from a Flow package. */
|
|
53
|
+
const flowNamespaces = new Set<string>();
|
|
54
|
+
|
|
55
|
+
const flowImports = root
|
|
56
|
+
.find(j.ImportDeclaration)
|
|
57
|
+
.filter((path) => isFlowImport(String(path.node.source.value)));
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* `imported:local` pairs the file already binds without a rename. A rename
|
|
61
|
+
* that lands on one of these must not add a second specifier for it — the
|
|
62
|
+
* name is available from the import that already carries it, which is also
|
|
63
|
+
* the entry that really exports it.
|
|
64
|
+
*/
|
|
65
|
+
const claimed = new Set<string>();
|
|
66
|
+
|
|
67
|
+
flowImports.forEach((path) => {
|
|
68
|
+
for (const specifier of path.node.specifiers ?? []) {
|
|
69
|
+
if (
|
|
70
|
+
specifier.type === "ImportNamespaceSpecifier" &&
|
|
71
|
+
specifier.local?.name
|
|
72
|
+
) {
|
|
73
|
+
flowNamespaces.add(String(specifier.local.name));
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (
|
|
78
|
+
specifier.type !== "ImportSpecifier" ||
|
|
79
|
+
specifier.imported.type !== "Identifier" ||
|
|
80
|
+
renames.has(specifier.imported.name)
|
|
81
|
+
) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
claimed.add(
|
|
86
|
+
`${specifier.imported.name}:${String(
|
|
87
|
+
specifier.local?.name ?? specifier.imported.name,
|
|
88
|
+
)}`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
flowImports.forEach((path) => {
|
|
94
|
+
const specifiers = path.node.specifiers ?? [];
|
|
95
|
+
const survivors: typeof specifiers = [];
|
|
96
|
+
|
|
97
|
+
for (const specifier of specifiers) {
|
|
98
|
+
if (
|
|
99
|
+
specifier.type !== "ImportSpecifier" ||
|
|
100
|
+
specifier.imported.type !== "Identifier"
|
|
101
|
+
) {
|
|
102
|
+
survivors.push(specifier);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const imported = specifier.imported.name;
|
|
107
|
+
const renamed = renames.get(imported);
|
|
108
|
+
if (!renamed) {
|
|
109
|
+
survivors.push(specifier);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const local = String(specifier.local?.name ?? imported);
|
|
114
|
+
const isAlias = local !== imported;
|
|
115
|
+
const newLocal = isAlias ? local : renamed;
|
|
116
|
+
const key = `${renamed}:${newLocal}`;
|
|
117
|
+
|
|
118
|
+
renamedAnImport = true;
|
|
119
|
+
if (!isAlias) {
|
|
120
|
+
// An aliased import keeps its local name and needs no further change.
|
|
121
|
+
localRenames.set(local, renamed);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Renaming can collide with a name the file already binds — directly, or
|
|
125
|
+
// because a second old name maps onto the same new one. Either way the
|
|
126
|
+
// binding already exists, so this specifier goes away instead of
|
|
127
|
+
// producing a duplicate declaration, which would not parse.
|
|
128
|
+
const collision = claimed.has(key);
|
|
129
|
+
claimed.add(key);
|
|
130
|
+
if (collision) {
|
|
131
|
+
// A value import must not lose out to a type-only one.
|
|
132
|
+
if (!isTypeOnly(specifier)) {
|
|
133
|
+
for (const kept of survivors) {
|
|
134
|
+
if (
|
|
135
|
+
kept.type === "ImportSpecifier" &&
|
|
136
|
+
kept.imported.type === "Identifier" &&
|
|
137
|
+
`${kept.imported.name}:${String(
|
|
138
|
+
kept.local?.name ?? kept.imported.name,
|
|
139
|
+
)}` === key
|
|
140
|
+
) {
|
|
141
|
+
makeValueImport(kept);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Mutate in place so an `import type` / `type X` modifier survives.
|
|
149
|
+
specifier.imported.name = renamed;
|
|
150
|
+
if (!isAlias && specifier.local) {
|
|
151
|
+
specifier.local.name = renamed;
|
|
152
|
+
}
|
|
153
|
+
survivors.push(specifier);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (survivors.length === specifiers.length) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Every specifier moved to an import that already binds the name. Leaving
|
|
161
|
+
// the declaration behind would turn it into a side-effect import of an
|
|
162
|
+
// entry the file no longer uses.
|
|
163
|
+
if (survivors.length === 0) {
|
|
164
|
+
j(path).remove();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
path.node.specifiers = survivors;
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
if (!renamedAnImport && flowNamespaces.size === 0) {
|
|
172
|
+
return fileInfo.source;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* `JSXIdentifier` extends `Identifier`, so this one pass covers JSX tags,
|
|
177
|
+
* value references and type references alike. Positions where the name is not
|
|
178
|
+
* a reference to the import — an object key, a member's property, a JSX
|
|
179
|
+
* attribute name — are skipped.
|
|
180
|
+
*/
|
|
181
|
+
root.find(j.Identifier).forEach((path) => {
|
|
182
|
+
const parent = path.parent.node;
|
|
183
|
+
|
|
184
|
+
const isNamespaceMember =
|
|
185
|
+
(parent.type === "MemberExpression" ||
|
|
186
|
+
parent.type === "JSXMemberExpression") &&
|
|
187
|
+
parent.property === path.node;
|
|
188
|
+
|
|
189
|
+
if (isNamespaceMember) {
|
|
190
|
+
const object = parent.object;
|
|
191
|
+
if (object.type === "Identifier" || object.type === "JSXIdentifier") {
|
|
192
|
+
const renamed = renames.get(path.node.name);
|
|
193
|
+
if (renamed && flowNamespaces.has(String(object.name))) {
|
|
194
|
+
path.node.name = renamed;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (
|
|
201
|
+
parent.type === "ImportSpecifier" ||
|
|
202
|
+
parent.type === "JSXAttribute" ||
|
|
203
|
+
((parent.type === "ObjectProperty" || parent.type === "Property") &&
|
|
204
|
+
parent.key === path.node &&
|
|
205
|
+
!parent.computed)
|
|
206
|
+
) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const renamed = localRenames.get(path.node.name);
|
|
211
|
+
if (renamed) {
|
|
212
|
+
path.node.name = renamed;
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
return root.toSource();
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
export default passwordToolsRuleTransform;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Transform } from "jscodeshift";
|
|
2
|
+
|
|
3
|
+
const oldPath = "@mittwald/flow-react-components/password-tools";
|
|
4
|
+
const newPath = "@mittwald/flow-react-components/mittwald-password-tools-js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Rewrites the module specifier
|
|
8
|
+
* `@mittwald/flow-react-components/password-tools` to
|
|
9
|
+
* `@mittwald/flow-react-components/mittwald-password-tools-js` (alpha.1000).
|
|
10
|
+
*
|
|
11
|
+
* Every form that names a module is covered: `import`, `import type`, `export …
|
|
12
|
+
* from`, a side-effect import, `import()` and `require()`. Only that exact
|
|
13
|
+
* specifier is touched — a deeper path under it never existed, so there is
|
|
14
|
+
* nothing to prefix-match and no risk of rewriting an unrelated
|
|
15
|
+
* `password-tools` of someone else's.
|
|
16
|
+
*/
|
|
17
|
+
const passwordToolsSubpathRenamedTransform: Transform = (fileInfo, { j }) => {
|
|
18
|
+
const root = j(fileInfo.source, { parser: "tsx" });
|
|
19
|
+
let changed = false;
|
|
20
|
+
|
|
21
|
+
const rewrite = (node: { value?: unknown }): void => {
|
|
22
|
+
if (node.value === oldPath) {
|
|
23
|
+
node.value = newPath;
|
|
24
|
+
changed = true;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// import … from "…", export … from "…", import "…"
|
|
29
|
+
root.find(j.ImportDeclaration).forEach((path) => rewrite(path.node.source));
|
|
30
|
+
root
|
|
31
|
+
.find(j.ExportNamedDeclaration)
|
|
32
|
+
.forEach((path) => path.node.source && rewrite(path.node.source));
|
|
33
|
+
root
|
|
34
|
+
.find(j.ExportAllDeclaration)
|
|
35
|
+
.forEach((path) => rewrite(path.node.source));
|
|
36
|
+
|
|
37
|
+
// import("…") and require("…")
|
|
38
|
+
root
|
|
39
|
+
.find(j.CallExpression)
|
|
40
|
+
.filter((path) => {
|
|
41
|
+
const callee = path.node.callee;
|
|
42
|
+
return (
|
|
43
|
+
callee.type === "Import" ||
|
|
44
|
+
(callee.type === "Identifier" && callee.name === "require")
|
|
45
|
+
);
|
|
46
|
+
})
|
|
47
|
+
.forEach((path) => {
|
|
48
|
+
const [argument] = path.node.arguments;
|
|
49
|
+
if (
|
|
50
|
+
argument &&
|
|
51
|
+
(argument.type === "StringLiteral" || argument.type === "Literal")
|
|
52
|
+
) {
|
|
53
|
+
rewrite(argument);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Returning the source untouched keeps this file out of the "changed" count.
|
|
58
|
+
return changed ? root.toSource() : fileInfo.source;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export default passwordToolsSubpathRenamedTransform;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Transform } from "jscodeshift";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Ports imports from `@mittwald/flow-react-components` to
|
|
5
|
+
* `@mittwald/flow-remote-react-components`.
|
|
6
|
+
*
|
|
7
|
+
* Not a migration: no version range calls for it, so it has no catalogue entry
|
|
8
|
+
* (see `notAMigration` in `src/tests/remoteScope.test.ts`) and lives outside
|
|
9
|
+
* `src/migrations`, in `src/tools` alongside any other transform the CLI runs
|
|
10
|
+
* by id without a matching entry. It is still resolved and run the same way a
|
|
11
|
+
* migration's `transform.ts` is — `transformExists`/`runCodemod` in
|
|
12
|
+
* `src/run/jscodeshift.ts` fall back to this directory when an id names no
|
|
13
|
+
* migration.
|
|
14
|
+
*/
|
|
15
|
+
const toRemotePackageTransform: Transform = (fileInfo, { j }) => {
|
|
16
|
+
const flowPackage = "@mittwald/flow-react-components";
|
|
17
|
+
|
|
18
|
+
const root = j(fileInfo.source, {
|
|
19
|
+
parser: "ts",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
root
|
|
23
|
+
.find(j.ImportDeclaration)
|
|
24
|
+
.filter((i) => String(i.node.source.value).startsWith(flowPackage))
|
|
25
|
+
.forEach((i) => {
|
|
26
|
+
const importPath = String(i.node.source.value);
|
|
27
|
+
|
|
28
|
+
i.node.source.value = importPath.replace(
|
|
29
|
+
flowPackage,
|
|
30
|
+
"@mittwald/flow-remote-react-components",
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return root.toSource();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default toRemotePackageTransform;
|