@mittwald/flow-codemods 1.1.43 → 1.1.45
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.
|
@@ -39,6 +39,21 @@ const keptSubpaths = new Set([
|
|
|
39
39
|
// owned by password-tools-subpath-renamed
|
|
40
40
|
"password-tools",
|
|
41
41
|
]);
|
|
42
|
+
/**
|
|
43
|
+
* Splits a bundler's asset query or fragment off a specifier. `all.css?url` is
|
|
44
|
+
* the subpath `all.css`, requested as a URL — not a subpath named
|
|
45
|
+
* `all.css?url`. Matching the whole string carried the suffix past the
|
|
46
|
+
* leave-alone set and into the catch-all below, which rewrote `import
|
|
47
|
+
* flowStyles from "…/all.css?url"` into a named import of a JS export that does
|
|
48
|
+
* not exist, and `import "…/all-layered.css?inline"` into a side-effect import
|
|
49
|
+
* of the package root — stylesheet gone, no error anywhere.
|
|
50
|
+
*/
|
|
51
|
+
const splitAssetSuffix = (subpath) => {
|
|
52
|
+
const suffixAt = subpath.search(/[?#]/);
|
|
53
|
+
return suffixAt === -1
|
|
54
|
+
? [subpath, ""]
|
|
55
|
+
: [subpath.slice(0, suffixAt), subpath.slice(suffixAt)];
|
|
56
|
+
};
|
|
42
57
|
const importsToPackageRootTransform = (fileInfo, { j }) => {
|
|
43
58
|
const flowPackage = "@mittwald/flow-react-components";
|
|
44
59
|
const root = j(fileInfo.source, {
|
|
@@ -50,14 +65,21 @@ const importsToPackageRootTransform = (fileInfo, { j }) => {
|
|
|
50
65
|
.forEach((i) => {
|
|
51
66
|
const specifiers = i.node.specifiers ?? [];
|
|
52
67
|
const importPath = String(i.node.source.value);
|
|
53
|
-
const importRelativePath = importPath.slice(flowPackage.length + 1);
|
|
68
|
+
const [importRelativePath, assetSuffix] = splitAssetSuffix(importPath.slice(flowPackage.length + 1));
|
|
54
69
|
if (keptSubpaths.has(importRelativePath)) {
|
|
55
70
|
return;
|
|
56
71
|
}
|
|
57
72
|
if (importRelativePath === "all.css" ||
|
|
58
73
|
importRelativePath === "globals.css" ||
|
|
59
74
|
importRelativePath === "global.css") {
|
|
60
|
-
i.node.source.value = `${flowPackage}/all.css`;
|
|
75
|
+
i.node.source.value = `${flowPackage}/all.css${assetSuffix}`;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Everything below rewrites a *module* import: it moves the specifier
|
|
79
|
+
// onto a JS entry and turns a default specifier into a named one. An
|
|
80
|
+
// asset import survives neither, and a suffix reaching this point names a
|
|
81
|
+
// path this transform cannot resolve to an export — leave it to a human.
|
|
82
|
+
if (assetSuffix !== "") {
|
|
61
83
|
return;
|
|
62
84
|
}
|
|
63
85
|
if (importRelativePath.startsWith("react-hook-form")) {
|
|
@@ -23,11 +23,22 @@ const passwordToolsRuleTransform = (fileInfo, { j }) => {
|
|
|
23
23
|
const flowPackages = [
|
|
24
24
|
"@mittwald/flow-react-components/mittwald-password-tools-js",
|
|
25
25
|
];
|
|
26
|
+
/**
|
|
27
|
+
* The same entry under the name it had when this change shipped. It was
|
|
28
|
+
* renamed later (alpha.1000, `password-tools-subpath-renamed`), and `since`
|
|
29
|
+
* puts that rename _after_ this transform — so a consumer coming from before
|
|
30
|
+
* alpha.802 still spells the import `password-tools` when this runs, and
|
|
31
|
+
* matching only the current name left `AsyncRule` untouched for the rename to
|
|
32
|
+
* carry onto an entry that does not export it. Kept out of `flowPackages`
|
|
33
|
+
* because `remoteScope.test.ts` holds every name in there against the export
|
|
34
|
+
* map the packages have _today_, where this one is gone.
|
|
35
|
+
*/
|
|
36
|
+
const renamedFlowPackage = "@mittwald/flow-react-components/password-tools";
|
|
26
37
|
const renames = new Map([
|
|
27
38
|
["AsyncRule", "Rule"],
|
|
28
39
|
["SyncRule", "Rule"],
|
|
29
40
|
]);
|
|
30
|
-
const isFlowImport = (source) => flowPackages.includes(source);
|
|
41
|
+
const isFlowImport = (source) => flowPackages.includes(source) || source === renamedFlowPackage;
|
|
31
42
|
// ast-types models `importKind` on the declaration only, while babel also
|
|
32
43
|
// puts it on the specifier — which is where a per-specifier `type X` lives.
|
|
33
44
|
const isTypeOnly = (specifier) => specifier.importKind === "type";
|
|
@@ -12,9 +12,11 @@ const newPath = "@mittwald/flow-react-components/all.css";
|
|
|
12
12
|
* always the side-effect form (`import "…/styles"`), which is why that case is
|
|
13
13
|
* the one the fixtures lead with.
|
|
14
14
|
*
|
|
15
|
-
* Exact match, not a prefix: `./styles` was a single export with
|
|
16
|
-
* underneath it, so there is no deeper path to rewrite and no risk of
|
|
17
|
-
* an unrelated `styles` of someone else's.
|
|
15
|
+
* Exact match on the path, not a prefix: `./styles` was a single export with
|
|
16
|
+
* nothing underneath it, so there is no deeper path to rewrite and no risk of
|
|
17
|
+
* touching an unrelated `styles` of someone else's. A bundler query or fragment
|
|
18
|
+
* (`?url`, `?inline`) is split off before that comparison and carried over — it
|
|
19
|
+
* addresses the export, it does not name a different one.
|
|
18
20
|
*
|
|
19
21
|
* What this cannot reach is an `@import` in a `.css` or `.scss` file —
|
|
20
22
|
* jscodeshift only walks the JavaScript and TypeScript extensions. `apply` says
|
|
@@ -23,11 +25,23 @@ const newPath = "@mittwald/flow-react-components/all.css";
|
|
|
23
25
|
const renamedCssExportTransform = (fileInfo, { j }) => {
|
|
24
26
|
const root = j(fileInfo.source, { parser: "tsx" });
|
|
25
27
|
let changed = false;
|
|
28
|
+
// A bundler addresses an asset through a query or fragment on the specifier,
|
|
29
|
+
// so `…/styles?url` is the old export requested as a URL. The rename applies
|
|
30
|
+
// to it just the same: match the path, carry the suffix over. Comparing the
|
|
31
|
+
// whole string leaves it pointing at an export the package no longer has.
|
|
26
32
|
const rewrite = (node) => {
|
|
27
|
-
if (node.value
|
|
28
|
-
|
|
29
|
-
changed = true;
|
|
33
|
+
if (typeof node.value !== "string") {
|
|
34
|
+
return;
|
|
30
35
|
}
|
|
36
|
+
const suffixAt = node.value.search(/[?#]/);
|
|
37
|
+
const [path, suffix] = suffixAt === -1
|
|
38
|
+
? [node.value, ""]
|
|
39
|
+
: [node.value.slice(0, suffixAt), node.value.slice(suffixAt)];
|
|
40
|
+
if (path !== oldPath) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
node.value = `${newPath}${suffix}`;
|
|
44
|
+
changed = true;
|
|
31
45
|
};
|
|
32
46
|
// import … from "…", import "…"
|
|
33
47
|
root.find(j.ImportDeclaration).forEach((path) => rewrite(path.node.source));
|
|
@@ -235,7 +235,7 @@ export const migrations = [
|
|
|
235
235
|
kind: "migration",
|
|
236
236
|
action: "codemod",
|
|
237
237
|
remotePackage: false,
|
|
238
|
-
apply: 'Rewrite every subdirectory import from `@mittwald/flow-react-components` to the package root, except `react-hook-form` and `nextjs`, which move to `@mittwald/flow-react-components/react-hook-form` and `@mittwald/flow-react-components/nextjs`. If you hit missing module errors, set `"module": "esnext"` in `tsconfig.json`.',
|
|
238
|
+
apply: 'Rewrite every subdirectory import from `@mittwald/flow-react-components` to the package root, except `react-hook-form` and `nextjs`, which move to `@mittwald/flow-react-components/react-hook-form` and `@mittwald/flow-react-components/nextjs`. Asset imports are not part of this: a CSS specifier stays a CSS specifier — `all.css` and `all-layered.css` unchanged, a stale `global.css` or `globals.css` rewritten to `all.css` — and keeps any bundler query it carries (`?url`, `?inline`, `?raw`). It never becomes a named import from the package root, which has no JS binding behind a stylesheet. If you hit missing module errors, set `"module": "esnext"` in `tsconfig.json`.',
|
|
239
239
|
},
|
|
240
240
|
{
|
|
241
241
|
id: "renamed-css-export",
|
|
@@ -244,6 +244,6 @@ export const migrations = [
|
|
|
244
244
|
kind: "migration",
|
|
245
245
|
action: "codemod",
|
|
246
246
|
remotePackage: false,
|
|
247
|
-
apply: "Replace the import `@mittwald/flow-react-components/styles` with `@mittwald/flow-react-components/all.css
|
|
247
|
+
apply: "Replace the import `@mittwald/flow-react-components/styles` with `@mittwald/flow-react-components/all.css`, keeping any bundler query the specifier carries (`.../styles?url` becomes `.../all.css?url`). A codemod does this for JavaScript and TypeScript files. An `@import` of the old path inside a `.css` or `.scss` file is not covered — search for it by hand.",
|
|
248
248
|
},
|
|
249
249
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mittwald/flow-codemods",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.45",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Codemods and an upgrade CLI for consumers of Flow, mittwald's design system",
|
|
6
6
|
"homepage": "https://flow.mittwald.de",
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"vitest": "^4.1.11",
|
|
39
39
|
"yaml": "^2.8.1"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "207967ac9159f9c55934801f5e8df02e7371bd29"
|
|
42
42
|
}
|