@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.
Files changed (101) hide show
  1. package/README.md +106 -0
  2. package/dist/catalog/entries.d.ts +17 -0
  3. package/dist/catalog/entries.d.ts.map +1 -0
  4. package/dist/catalog/entries.js +9 -0
  5. package/dist/catalog/select.d.ts +28 -0
  6. package/dist/catalog/select.d.ts.map +1 -0
  7. package/dist/catalog/select.js +27 -0
  8. package/dist/catalog/types.d.ts +48 -0
  9. package/dist/catalog/types.d.ts.map +1 -0
  10. package/dist/catalog/types.js +0 -0
  11. package/dist/checks/context.d.ts +16 -0
  12. package/dist/checks/context.d.ts.map +1 -0
  13. package/dist/checks/context.js +72 -0
  14. package/dist/checks/load.d.ts +13 -0
  15. package/dist/checks/load.d.ts.map +1 -0
  16. package/dist/checks/load.js +53 -0
  17. package/dist/checks/types.d.ts +49 -0
  18. package/dist/checks/types.d.ts.map +1 -0
  19. package/dist/checks/types.js +0 -0
  20. package/dist/cli/args.d.ts +22 -0
  21. package/dist/cli/args.d.ts.map +1 -0
  22. package/dist/cli/args.js +56 -0
  23. package/dist/cli/choose.d.ts +31 -0
  24. package/dist/cli/choose.d.ts.map +1 -0
  25. package/dist/cli/choose.js +31 -0
  26. package/dist/cli/codemod.d.ts +24 -0
  27. package/dist/cli/codemod.d.ts.map +1 -0
  28. package/dist/cli/codemod.js +76 -0
  29. package/dist/cli/detect.d.ts +35 -0
  30. package/dist/cli/detect.d.ts.map +1 -0
  31. package/dist/cli/detect.js +62 -0
  32. package/dist/cli/list.d.ts +71 -0
  33. package/dist/cli/list.d.ts.map +1 -0
  34. package/dist/cli/list.js +293 -0
  35. package/dist/cli/upgrade.d.ts +34 -0
  36. package/dist/cli/upgrade.d.ts.map +1 -0
  37. package/dist/cli/upgrade.js +217 -0
  38. package/dist/cli/verify.d.ts +77 -0
  39. package/dist/cli/verify.d.ts.map +1 -0
  40. package/dist/cli/verify.js +148 -0
  41. package/dist/cli.d.ts +3 -0
  42. package/dist/cli.d.ts.map +1 -0
  43. package/dist/cli.js +117 -0
  44. package/dist/detect/align-to-combine.d.ts +8 -0
  45. package/dist/detect/align-to-combine.d.ts.map +1 -0
  46. package/dist/detect/align-to-combine.js +9 -0
  47. package/dist/detect/overlay-controller-add-on-close-return-type.d.ts +9 -0
  48. package/dist/detect/overlay-controller-add-on-close-return-type.d.ts.map +1 -0
  49. package/dist/detect/overlay-controller-add-on-close-return-type.js +10 -0
  50. package/dist/detect/tooltip-trigger-delay-type.d.ts +11 -0
  51. package/dist/detect/tooltip-trigger-delay-type.d.ts.map +1 -0
  52. package/dist/detect/tooltip-trigger-delay-type.js +12 -0
  53. package/dist/flowPackages.generated.d.ts +3 -0
  54. package/dist/flowPackages.generated.d.ts.map +1 -0
  55. package/dist/flowPackages.generated.js +18 -0
  56. package/dist/git.d.ts +13 -0
  57. package/dist/git.d.ts.map +1 -0
  58. package/dist/git.js +41 -0
  59. package/dist/install.d.ts +37 -0
  60. package/dist/install.d.ts.map +1 -0
  61. package/dist/install.js +71 -0
  62. package/dist/manifest.d.ts +45 -0
  63. package/dist/manifest.d.ts.map +1 -0
  64. package/dist/manifest.js +88 -0
  65. package/dist/migrations.generated.d.ts +4 -0
  66. package/dist/migrations.generated.d.ts.map +1 -0
  67. package/dist/migrations.generated.js +213 -0
  68. package/dist/resolve/range.d.ts +50 -0
  69. package/dist/resolve/range.d.ts.map +1 -0
  70. package/dist/resolve/range.js +173 -0
  71. package/dist/resolve/registry.d.ts +33 -0
  72. package/dist/resolve/registry.d.ts.map +1 -0
  73. package/dist/resolve/registry.js +69 -0
  74. package/dist/resolve/target.d.ts +63 -0
  75. package/dist/resolve/target.d.ts.map +1 -0
  76. package/dist/resolve/target.js +115 -0
  77. package/dist/run/jscodeshift.d.ts +42 -0
  78. package/dist/run/jscodeshift.d.ts.map +1 -0
  79. package/dist/run/jscodeshift.js +88 -0
  80. package/dist/tsconfig.tsbuildinfo +1 -0
  81. package/dist/verify/align-to-combine.d.ts +11 -0
  82. package/dist/verify/align-to-combine.d.ts.map +1 -0
  83. package/dist/verify/align-to-combine.js +22 -0
  84. package/dist/verify/overlay-controller-add-on-close-return-type.d.ts +14 -0
  85. package/dist/verify/overlay-controller-add-on-close-return-type.d.ts.map +1 -0
  86. package/dist/verify/overlay-controller-add-on-close-return-type.js +21 -0
  87. package/dist/verify/tooltip-trigger-delay-type.d.ts +13 -0
  88. package/dist/verify/tooltip-trigger-delay-type.d.ts.map +1 -0
  89. package/dist/verify/tooltip-trigger-delay-type.js +18 -0
  90. package/package.json +41 -0
  91. package/src/migrations/accent-box-color-to-background-color/transform.ts +218 -0
  92. package/src/migrations/action-prop-to-on-action/transform.ts +110 -0
  93. package/src/migrations/align-to-combine/transform.ts +212 -0
  94. package/src/migrations/button-color-accent-to-success/transform.ts +164 -0
  95. package/src/migrations/button-props-interfaces/transform.ts +229 -0
  96. package/src/migrations/color-primary-to-default/transform.ts +173 -0
  97. package/src/migrations/imports-to-package-root/transform.ts +107 -0
  98. package/src/migrations/muted-action-error-to-abort-action-error/transform.ts +260 -0
  99. package/src/migrations/password-tools-rule/transform.ts +219 -0
  100. package/src/migrations/password-tools-subpath-renamed/transform.ts +61 -0
  101. package/src/tools/to-remote-package.ts +37 -0
@@ -0,0 +1,18 @@
1
+ // AUTO-GENERATED by `pnpm nx build codemods` — do not edit.
2
+ //
3
+ // Source: the non-private packages of packages/*
4
+ /** Every package published from the Flow monorepo, which all share one version. */
5
+ export const flowPackages = [
6
+ "@mittwald/ext-bridge",
7
+ "@mittwald/flow-design-tokens",
8
+ "@mittwald/flow-icons",
9
+ "@mittwald/flow-icons-pro",
10
+ "@mittwald/flow-react-components",
11
+ "@mittwald/flow-remote-core",
12
+ "@mittwald/flow-remote-elements",
13
+ "@mittwald/flow-remote-react-components",
14
+ "@mittwald/flow-remote-react-renderer",
15
+ "@mittwald/flow-stylesheet",
16
+ "@mittwald/mstudio-ext-react-components",
17
+ "@mittwald/react-tunnel",
18
+ ];
package/dist/git.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Whether the working tree has changes that a codemod run would mix into.
3
+ *
4
+ * `upgrade` refuses on a dirty tree unless `--allow-dirty`. This matters most
5
+ * where nobody is watching: `-y` is implied when stdin is not a TTY, so an
6
+ * agent or CI run would otherwise blend its own unfinished work into the
7
+ * codemod diff with no way to separate them afterwards.
8
+ *
9
+ * A directory that is not a git repository counts as clean — refusing there
10
+ * would block a legitimate run for a reason the consumer cannot fix.
11
+ */
12
+ export declare const hasUncommittedChanges: (cwd: string) => boolean;
13
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,QAAS,MAAM,KAAG,OAkCnD,CAAC"}
package/dist/git.js ADDED
@@ -0,0 +1,41 @@
1
+ import { execFileSync } from "node:child_process";
2
+ /**
3
+ * Whether the working tree has changes that a codemod run would mix into.
4
+ *
5
+ * `upgrade` refuses on a dirty tree unless `--allow-dirty`. This matters most
6
+ * where nobody is watching: `-y` is implied when stdin is not a TTY, so an
7
+ * agent or CI run would otherwise blend its own unfinished work into the
8
+ * codemod diff with no way to separate them afterwards.
9
+ *
10
+ * A directory that is not a git repository counts as clean — refusing there
11
+ * would block a legitimate run for a reason the consumer cannot fix.
12
+ */
13
+ export const hasUncommittedChanges = (cwd) => {
14
+ try {
15
+ const status = execFileSync("git", ["status", "--porcelain"], {
16
+ cwd,
17
+ encoding: "utf8",
18
+ // stderr captured, not ignored: exit 128 alone cannot tell "not a
19
+ // repository" from the other fatals, and the difference decides whether
20
+ // the guard may report a clean tree. `LC_ALL=C` pins the message this
21
+ // reads to English — git localises its fatals.
22
+ stdio: ["ignore", "pipe", "pipe"],
23
+ env: { ...process.env, LC_ALL: "C" },
24
+ });
25
+ return status.trim() !== "";
26
+ }
27
+ catch (error) {
28
+ // Exit 128 is *not* only "not a git repository". `detected dubious
29
+ // ownership` is 128 too, and that is the minimal CI container this guard
30
+ // exists for — treating every 128 as clean made it fail open in exactly
31
+ // the case nobody is watching. So match the message, not the code, and let
32
+ // every other failure throw. A missing binary throws `ENOENT` with no exit
33
+ // status and no stderr, and lands in the throw below.
34
+ const stderr = String(error.stderr ?? "");
35
+ if (error.status === 128 &&
36
+ /not a git repository/i.test(stderr)) {
37
+ return false;
38
+ }
39
+ throw new Error(`Could not check the working tree with git: ${error instanceof Error ? error.message : error}`, { cause: error });
40
+ }
41
+ };
@@ -0,0 +1,37 @@
1
+ export type PackageManager = "pnpm" | "npm" | "yarn" | "bun";
2
+ /**
3
+ * The package manager a project uses, from the lockfiles present.
4
+ *
5
+ * Npm is the fallback: it is the one manager that is always available next to
6
+ * Node, so a project with no lockfile still gets an install rather than an
7
+ * error.
8
+ */
9
+ export declare const detectPackageManager: (present: string[]) => PackageManager;
10
+ export declare const detectPackageManagerIn: (cwd: string) => PackageManager;
11
+ export interface InstallCommand {
12
+ command: string;
13
+ args: string[];
14
+ /** Extra environment for the install. Empty when none is needed. */
15
+ env: Record<string, string>;
16
+ }
17
+ /**
18
+ * How to install with a given manager, so that the install actually updates the
19
+ * lockfile.
20
+ *
21
+ * `upgrade` has just rewritten `package.json`, so the lockfile is deliberately
22
+ * stale. pnpm and Yarn Berry both switch on frozen/immutable installs by
23
+ * themselves when they detect CI, where an install then _fails_ instead of
24
+ * updating — and CI is exactly where this runs unattended. pnpm takes a flag;
25
+ * Yarn's flag differs between Classic and Berry, so it gets the environment
26
+ * variable instead, which Classic ignores harmlessly.
27
+ */
28
+ export declare const installCommand: (manager: PackageManager) => InstallCommand;
29
+ /**
30
+ * Runs the install.
31
+ *
32
+ * A named type rather than a bare call so tests can substitute it. There is no
33
+ * `--no-install` flag: the seam belongs in the code, not in the CLI surface.
34
+ */
35
+ export type InstallRunner = (manager: PackageManager, cwd: string) => void;
36
+ export declare const runInstall: InstallRunner;
37
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;AAe7D;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,YAAa,MAAM,EAAE,KAAG,cAOxD,CAAC;AAEF,eAAO,MAAM,sBAAsB,QAAS,MAAM,KAAG,cAKlD,CAAC;AAEJ,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,YAAa,cAAc,KAAG,cAkBxD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;AAE3E,eAAO,MAAM,UAAU,EAAE,aAOxB,CAAC"}
@@ -0,0 +1,71 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ /** Lockfile to manager, in precedence order. */
5
+ const lockfiles = [
6
+ ["pnpm-lock.yaml", "pnpm"],
7
+ // Both Bun lockfile names: `bun.lock` (text) is the default only from Bun
8
+ // 1.2; before that Bun writes the binary `bun.lockb`, which plenty of
9
+ // projects still have. Missing it would fall through to the npm default and
10
+ // run `npm install` on a Bun project, leaving a stray package-lock.json.
11
+ ["bun.lock", "bun"],
12
+ ["bun.lockb", "bun"],
13
+ ["yarn.lock", "yarn"],
14
+ ["package-lock.json", "npm"],
15
+ ];
16
+ /**
17
+ * The package manager a project uses, from the lockfiles present.
18
+ *
19
+ * Npm is the fallback: it is the one manager that is always available next to
20
+ * Node, so a project with no lockfile still gets an install rather than an
21
+ * error.
22
+ */
23
+ export const detectPackageManager = (present) => {
24
+ for (const [lockfile, manager] of lockfiles) {
25
+ if (present.includes(lockfile)) {
26
+ return manager;
27
+ }
28
+ }
29
+ return "npm";
30
+ };
31
+ export const detectPackageManagerIn = (cwd) => detectPackageManager(lockfiles
32
+ .map(([lockfile]) => lockfile)
33
+ .filter((lockfile) => existsSync(join(cwd, lockfile))));
34
+ /**
35
+ * How to install with a given manager, so that the install actually updates the
36
+ * lockfile.
37
+ *
38
+ * `upgrade` has just rewritten `package.json`, so the lockfile is deliberately
39
+ * stale. pnpm and Yarn Berry both switch on frozen/immutable installs by
40
+ * themselves when they detect CI, where an install then _fails_ instead of
41
+ * updating — and CI is exactly where this runs unattended. pnpm takes a flag;
42
+ * Yarn's flag differs between Classic and Berry, so it gets the environment
43
+ * variable instead, which Classic ignores harmlessly.
44
+ */
45
+ export const installCommand = (manager) => {
46
+ switch (manager) {
47
+ case "pnpm":
48
+ return {
49
+ command: "pnpm",
50
+ args: ["install", "--no-frozen-lockfile"],
51
+ env: {},
52
+ };
53
+ case "yarn":
54
+ return {
55
+ command: "yarn",
56
+ args: ["install"],
57
+ env: { YARN_ENABLE_IMMUTABLE_INSTALLS: "false" },
58
+ };
59
+ case "npm":
60
+ case "bun":
61
+ return { command: manager, args: ["install"], env: {} };
62
+ }
63
+ };
64
+ export const runInstall = (manager, cwd) => {
65
+ const { command, args, env } = installCommand(manager);
66
+ execFileSync(command, args, {
67
+ cwd,
68
+ stdio: "inherit",
69
+ env: { ...process.env, ...env },
70
+ });
71
+ };
@@ -0,0 +1,45 @@
1
+ export type DependencyField = "dependencies" | "devDependencies" | "peerDependencies" | "optionalDependencies";
2
+ export interface Manifest {
3
+ name?: string;
4
+ dependencies?: Record<string, string>;
5
+ devDependencies?: Record<string, string>;
6
+ peerDependencies?: Record<string, string>;
7
+ optionalDependencies?: Record<string, string>;
8
+ }
9
+ export interface FlowDependency {
10
+ field: DependencyField;
11
+ name: string;
12
+ range: string;
13
+ }
14
+ /** Every Flow-line dependency the manifest declares, in field order. */
15
+ export declare const findFlowDependencies: (manifest: Manifest, flowPackages: string[]) => FlowDependency[];
16
+ /**
17
+ * The range moved onto `target`, keeping whatever operator it had.
18
+ *
19
+ * A range this cannot read — `workspace:*`, `*`, a dist-tag, a URL — is
20
+ * returned unchanged. Rewriting it would replace a deliberate choice with a
21
+ * guess.
22
+ */
23
+ export declare const rewriteRange: (range: string, target: string) => string;
24
+ /** Whether `upgrade` may rewrite a dependency, or only report it. */
25
+ export declare const isWritable: (dependency: FlowDependency) => boolean;
26
+ /**
27
+ * A copy of the manifest with every writable Flow dependency moved onto
28
+ * `target`. Peer ranges are left as they are — see `writableFields`.
29
+ */
30
+ export declare const applyTarget: <T extends Manifest>(manifest: T, target: string, flowPackages: string[]) => T;
31
+ /**
32
+ * The version the consumer is on.
33
+ *
34
+ * The installed version is the accurate answer, so it wins. The fallback is the
35
+ * lowest version the declared range allows, which is deliberately conservative:
36
+ * being too low can only select _extra_ entries.
37
+ *
38
+ * That is safe because a transform must be harmless against code it has nothing
39
+ * to do with — not because it is idempotent. Idempotency only proves a second
40
+ * pass over its own output changes nothing; it says nothing about an
41
+ * era-specific transform meeting code from a later era.
42
+ * `imports-to-package-root` needed an explicit leave-alone set to earn this.
43
+ */
44
+ export declare const detectCurrentVersion: (dependencies: FlowDependency[], readInstalledVersion: (name: string) => string | undefined) => string | undefined;
45
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,iBAAiB,GACjB,kBAAkB,GAClB,sBAAsB,CAAC;AAS3B,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,aACrB,QAAQ,gBACJ,MAAM,EAAE,KACrB,cAAc,EAKd,CAAC;AAKJ;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,UAAW,MAAM,UAAU,MAAM,KAAG,MAQ5D,CAAC;AAgBF,qEAAqE;AACrE,eAAO,MAAM,UAAU,eAAgB,cAAc,KAAG,OACb,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,QAAQ,YAClC,CAAC,UACH,MAAM,gBACA,MAAM,EAAE,KACrB,CAcF,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,iBACjB,cAAc,EAAE,wBACR,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,KACzD,MAAM,GAAG,SAgBX,CAAC"}
@@ -0,0 +1,88 @@
1
+ import { minVersion, valid } from "semver";
2
+ const dependencyFields = [
3
+ "dependencies",
4
+ "devDependencies",
5
+ "peerDependencies",
6
+ "optionalDependencies",
7
+ ];
8
+ /** Every Flow-line dependency the manifest declares, in field order. */
9
+ export const findFlowDependencies = (manifest, flowPackages) => dependencyFields.flatMap((field) => Object.entries(manifest[field] ?? {})
10
+ .filter(([name]) => flowPackages.includes(name))
11
+ .map(([name, range]) => ({ field, name, range })));
12
+ /** A leading range operator, if the range has one. */
13
+ const operatorPattern = /^(\^|~|>=|<=|>|<|=)?\s*(.+)$/;
14
+ /**
15
+ * The range moved onto `target`, keeping whatever operator it had.
16
+ *
17
+ * A range this cannot read — `workspace:*`, `*`, a dist-tag, a URL — is
18
+ * returned unchanged. Rewriting it would replace a deliberate choice with a
19
+ * guess.
20
+ */
21
+ export const rewriteRange = (range, target) => {
22
+ const match = operatorPattern.exec(range.trim());
23
+ if (!match) {
24
+ return range;
25
+ }
26
+ const [, operator = "", version = ""] = match;
27
+ return valid(version) === null ? range : `${operator}${target}`;
28
+ };
29
+ /**
30
+ * Fields `upgrade` may rewrite. `peerDependencies` is deliberately absent: a
31
+ * peer range is the author's statement about which versions their package works
32
+ * with, not a version they install. Moving `^1.0.0` to `^1.0.14` would narrow
33
+ * what _their_ consumers are allowed to install — a breaking change to someone
34
+ * else's package, made silently by a command they ran to update their own. Only
35
+ * they can decide that, so `upgrade` reports the range and leaves it.
36
+ */
37
+ const writableFields = [
38
+ "dependencies",
39
+ "devDependencies",
40
+ "optionalDependencies",
41
+ ];
42
+ /** Whether `upgrade` may rewrite a dependency, or only report it. */
43
+ export const isWritable = (dependency) => writableFields.includes(dependency.field);
44
+ /**
45
+ * A copy of the manifest with every writable Flow dependency moved onto
46
+ * `target`. Peer ranges are left as they are — see `writableFields`.
47
+ */
48
+ export const applyTarget = (manifest, target, flowPackages) => {
49
+ const updated = structuredClone(manifest);
50
+ for (const dependency of findFlowDependencies(manifest, flowPackages)) {
51
+ if (!isWritable(dependency)) {
52
+ continue;
53
+ }
54
+ const entries = updated[dependency.field];
55
+ if (entries !== undefined) {
56
+ entries[dependency.name] = rewriteRange(dependency.range, target);
57
+ }
58
+ }
59
+ return updated;
60
+ };
61
+ /**
62
+ * The version the consumer is on.
63
+ *
64
+ * The installed version is the accurate answer, so it wins. The fallback is the
65
+ * lowest version the declared range allows, which is deliberately conservative:
66
+ * being too low can only select _extra_ entries.
67
+ *
68
+ * That is safe because a transform must be harmless against code it has nothing
69
+ * to do with — not because it is idempotent. Idempotency only proves a second
70
+ * pass over its own output changes nothing; it says nothing about an
71
+ * era-specific transform meeting code from a later era.
72
+ * `imports-to-package-root` needed an explicit leave-alone set to earn this.
73
+ */
74
+ export const detectCurrentVersion = (dependencies, readInstalledVersion) => {
75
+ for (const { name } of dependencies) {
76
+ const installed = readInstalledVersion(name);
77
+ if (installed !== undefined && valid(installed) !== null) {
78
+ return installed;
79
+ }
80
+ }
81
+ for (const { range } of dependencies) {
82
+ const lowest = minVersion(range);
83
+ if (lowest !== null) {
84
+ return lowest.version;
85
+ }
86
+ }
87
+ return undefined;
88
+ };
@@ -0,0 +1,4 @@
1
+ import type { MigrationEntry } from "./catalog/types.js";
2
+ /** Every migration, newest first. Bodies live in `src/migrations`. */
3
+ export declare const migrations: Omit<MigrationEntry, "body">[];
4
+ //# sourceMappingURL=migrations.generated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.generated.d.ts","sourceRoot":"","sources":["../src/migrations.generated.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,sEAAsE;AACtE,eAAO,MAAM,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,EAwOpD,CAAC"}
@@ -0,0 +1,213 @@
1
+ // AUTO-GENERATED by `pnpm nx build codemods` — do not edit.
2
+ //
3
+ // Source: packages/codemods/src/migrations/<id>/entry.md
4
+ /** Every migration, newest first. Bodies live in `src/migrations`. */
5
+ export const migrations = [
6
+ {
7
+ id: "segmented-control-deprecated",
8
+ since: "0.2.0-alpha.1056",
9
+ title: "SegmentedControl deprecated",
10
+ kind: "deprecation",
11
+ action: "manual",
12
+ remotePackage: true,
13
+ apply: "Replace `SegmentedControl` with `Tabs` when the selection switches displayed content, or with `RadioGroup` when it sets a value. Pick per usage — this is a structural change, not a rename.",
14
+ },
15
+ {
16
+ id: "align-to-combine",
17
+ since: "0.2.0-alpha.1047",
18
+ title: "Align renamed to Combine",
19
+ kind: "migration",
20
+ action: "codemod",
21
+ remotePackage: true,
22
+ apply: "Rename `Align` to `Combine` and `AlignProps` to `CombineProps`, for named, aliased and namespace imports from a Flow package.",
23
+ },
24
+ {
25
+ id: "button-color-accent-to-success",
26
+ since: "0.2.0-alpha.1046",
27
+ title: "Button: color `accent` renamed to `success`",
28
+ kind: "migration",
29
+ action: "codemod",
30
+ remotePackage: true,
31
+ apply: 'Rename `color="accent"` to `color="success"` on `Button` and `SubmitButton`. Also update the CSS class `flow--button--accent` to `flow--button--success` and every `--button--accent-{solid,plain,soft,outline}-*` design token to its `success` counterpart if you use `@mittwald/flow-stylesheet` or the token CSS variables directly — those have no fallback.',
32
+ },
33
+ {
34
+ id: "tooltip-trigger-delay-type",
35
+ since: "0.2.0-alpha.1016",
36
+ title: "TooltipTrigger changed delay type",
37
+ kind: "migration",
38
+ action: "manual",
39
+ remotePackage: true,
40
+ apply: 'Replace every numeric `delay` value on `TooltipTrigger` with one of the two string literals: `"default"` (400ms) or `"long"` (1500ms). Pick by intent, not by which number is closer — `"default"` is for elements that cannot be understood without the tooltip (icon-only buttons), `"long"` is for supplementary information on elements that are already labeled. A previous numeric value is not a reliable guide: `delay={500}` maps to `"default"` (400ms), not `"long"` (1500ms), if the element still needs the tooltip to be understood.',
41
+ },
42
+ {
43
+ id: "flags-to-component-defaults-provider",
44
+ since: "0.2.0-alpha.1005",
45
+ title: "`flags` is replaced by the ComponentDefaultsProvider",
46
+ kind: "deprecation",
47
+ action: "manual",
48
+ remotePackage: false,
49
+ apply: "Replace assignments to the global `flags` object with an equivalent `<ComponentDefaultsProvider defaults={{ ... }} />` wrapping the app, or the subtree the default should apply to.",
50
+ },
51
+ {
52
+ id: "modal-unsaved-changes-confirmation",
53
+ since: "0.2.0-alpha.1005",
54
+ title: "Closing a Modal with unsaved changes is confirmed by default",
55
+ kind: "migration",
56
+ action: "none",
57
+ remotePackage: true,
58
+ apply: "No code change required — if you had `requireCloseModalConfirmationOnUnsavedChanges` enabled, the new default matches it. To keep the previous behaviour (closing without confirmation), set `Form: { confirmModalCloseOnUnsavedChanges: false }` via `<ComponentDefaultsProvider />`, or its deprecated equivalent, the `flags.requireCloseModalConfirmationOnUnsavedChanges = false` assignment.",
59
+ },
60
+ {
61
+ id: "password-tools-subpath-renamed",
62
+ since: "0.2.0-alpha.1000",
63
+ title: "`password-tools` entry renamed to `mittwald-password-tools-js`",
64
+ kind: "migration",
65
+ action: "codemod",
66
+ remotePackage: false,
67
+ apply: "Replace the import path `@mittwald/flow-react-components/password-tools` with `@mittwald/flow-react-components/mittwald-password-tools-js`.",
68
+ },
69
+ {
70
+ id: "table-column-width-props",
71
+ since: "0.2.0-alpha.956",
72
+ title: "TableColumn: `maxWidth` removed, `width` and `minWidth` retyped",
73
+ kind: "migration",
74
+ action: "manual",
75
+ remotePackage: true,
76
+ apply: "Remove `maxWidth` from every `TableColumn`. Where `width` or `minWidth` was `null`, omit the prop instead — the type no longer accepts `null`, only `number | string`.",
77
+ },
78
+ {
79
+ id: "table-render-prop-removed",
80
+ since: "0.2.0-alpha.866",
81
+ title: "Table: `render` prop removed",
82
+ kind: "migration",
83
+ action: "manual",
84
+ remotePackage: true,
85
+ apply: "Replace the `render` escape hatch on `Table` with a composition of `TableHeader`, `TableColumn`, `TableBody`, `TableRow` and `TableCell`.",
86
+ },
87
+ {
88
+ id: "color-primary-to-default",
89
+ since: "0.2.0-alpha.846",
90
+ title: 'Breadcrumb, HeaderNavigation, Heading, IllustratedMessage, and Link: color property "primary" renamed to "default"',
91
+ kind: "migration",
92
+ action: "codemod",
93
+ remotePackage: true,
94
+ apply: 'Rewrite `color="primary"` to `color="default"` on `Breadcrumb`, `HeaderNavigation`, `Heading`, `IllustratedMessage`, and `Link` only — leave `Button` (and any other component where `"primary"` is still valid) untouched.',
95
+ },
96
+ {
97
+ id: "table-cell-render-prop-removed",
98
+ since: "0.2.0-alpha.846",
99
+ title: "TableCell: `render` prop removed",
100
+ kind: "migration",
101
+ action: "manual",
102
+ remotePackage: true,
103
+ apply: "Provide the cell content as children of `TableCell` instead of a `render` function.",
104
+ },
105
+ {
106
+ id: "password-tools-rule",
107
+ since: "0.2.0-alpha.802",
108
+ title: "password-tools: `AsyncRule` and `SyncRule` replaced by `Rule`",
109
+ kind: "migration",
110
+ action: "codemod",
111
+ remotePackage: false,
112
+ apply: "Replace `AsyncRule` and `SyncRule` imports from `@mittwald/flow-react-components/mittwald-password-tools-js` with `Rule`. Update custom rule classes to extend `Rule` instead.",
113
+ },
114
+ {
115
+ id: "accent-box-color-to-background-color",
116
+ since: "0.2.0-alpha.786",
117
+ title: "AccentBox.color is now a declaration for foreground",
118
+ kind: "migration",
119
+ action: "codemod",
120
+ remotePackage: true,
121
+ apply: 'Move every `color` value that is not one of `"default" | "dark" | "light" | "dark-static" | "light-static"` to `backgroundColor` instead. Review `color={expression}` and any element that already has `backgroundColor` by hand — neither can be decided from the value alone.',
122
+ },
123
+ {
124
+ id: "cartesian-chart-restructured",
125
+ since: "0.2.0-alpha.780",
126
+ title: "CartesianChart",
127
+ kind: "migration",
128
+ action: "manual",
129
+ remotePackage: true,
130
+ apply: "Add `dataKeyLabel` wherever a `dataKey` is a function — a string `dataKey` already sets it automatically. Where a `tickFormatter` or other callback relied on the argument being `any`, add an explicit type check (for example `instanceof Date`), or switch to `typedCartesianChart<T>()` for a chart whose callbacks are typed from your own data shape.",
131
+ },
132
+ {
133
+ id: "code-block-syntax-highlighter-removed",
134
+ since: "0.2.0-alpha.756",
135
+ title: "Removed the underlying react-syntax-highlighter library from CodeBlock",
136
+ kind: "migration",
137
+ action: "manual",
138
+ remotePackage: true,
139
+ apply: "Check every `CodeBlock` usage against the current props (see the [CodeBlock documentation](https://flow.mittwald.de/04-components/content/code-block/overview)) and remove or replace props the new implementation does not support.",
140
+ },
141
+ {
142
+ id: "muted-action-error-to-abort-action-error",
143
+ since: "0.2.0-alpha.712",
144
+ title: "`MutedActionError` renamed to `AbortActionError`",
145
+ kind: "migration",
146
+ action: "codemod",
147
+ remotePackage: false,
148
+ apply: 'Rename `MutedActionError` to `AbortActionError`, `isMutedActionError` to `isAbortActionError`, and `rethrowIfNotMuted` to `rethrowIfNotAborted`. Update any `error.name === "MutedActionError"` comparison to `"AbortActionError"`.',
149
+ },
150
+ {
151
+ id: "overlay-controller-add-on-close-return-type",
152
+ since: "0.2.0-alpha.696",
153
+ title: "OverlayController.addOnClose / addOnOpen return type changed",
154
+ kind: "migration",
155
+ action: "manual",
156
+ remotePackage: true,
157
+ apply: "No type change needed: the return type widened from `() => void` to `() => unknown`, and a `() => void` callback stays assignable. Instead, check every callback passed to `addOnClose`/`addOnOpen` for one that can return `false` — for example an arrow function whose body is an expression evaluating to `false`. `executeHandlers` now treats any handler returning `false` as a veto and cancels the close/open. A callback that returned `false` incidentally, with no intent to block anything, now silently cancels closes.",
158
+ },
159
+ {
160
+ id: "form-resets-after-modal-close",
161
+ since: "0.2.0-alpha.694",
162
+ title: "Form: resets itself after the surrounding modal closes",
163
+ kind: "migration",
164
+ action: "none",
165
+ remotePackage: false,
166
+ apply: "No code change required. To keep the previous behaviour (the form keeping what the user entered), pass `autoReset={false}` (or `autoReset={{ onAfterModalClose: false }}`) to `Form`.",
167
+ },
168
+ {
169
+ id: "cartesian-chart-empty-view",
170
+ since: "0.2.0-alpha.676",
171
+ title: "CartesianChart.emptyView changed",
172
+ kind: "migration",
173
+ action: "manual",
174
+ remotePackage: true,
175
+ apply: "Wrap the `emptyView` value in JSX — `emptyView={<EmptyState />}` instead of `emptyView={EmptyState}`.",
176
+ },
177
+ {
178
+ id: "action-prop-to-on-action",
179
+ since: "0.2.0-alpha.646",
180
+ title: "Action: `action` renamed to `onAction`",
181
+ kind: "migration",
182
+ action: "codemod",
183
+ remotePackage: true,
184
+ apply: "Rename the `action` prop on `Action` to `onAction`.",
185
+ },
186
+ {
187
+ id: "button-props-interfaces",
188
+ since: "0.2.0-alpha.646",
189
+ title: "Removed ResetButton and SubmitButton Interfaces",
190
+ kind: "migration",
191
+ action: "codemod",
192
+ remotePackage: false,
193
+ apply: "Replace `ResetButtonProps`/`SubmitButtonProps` imports from `@mittwald/flow-react-components/react-hook-form` with `ButtonProps` from the package root. Leave `RemoteButtonElementProps` (from `@mittwald/flow-remote-elements`) alone.",
194
+ },
195
+ {
196
+ id: "imports-to-package-root",
197
+ since: "0.2.0-alpha.28",
198
+ title: "Subpath imports moved to the package root",
199
+ kind: "migration",
200
+ action: "codemod",
201
+ remotePackage: false,
202
+ 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`.',
203
+ },
204
+ {
205
+ id: "renamed-css-export",
206
+ since: "0.1.0-alpha.292",
207
+ title: "Renamed CSS export",
208
+ kind: "migration",
209
+ action: "manual",
210
+ remotePackage: false,
211
+ apply: "Replace the import `@mittwald/flow-react-components/styles` with `@mittwald/flow-react-components/all.css`.",
212
+ },
213
+ ];
@@ -0,0 +1,50 @@
1
+ import { type FlowDependency, type Manifest } from "../manifest.js";
2
+ import { fetchVersions } from "./registry.js";
3
+ /**
4
+ * The installed version of `name`, read from `cwd`'s `node_modules`.
5
+ *
6
+ * Lives here rather than in `upgrade.ts` (where it used to) because `list` now
7
+ * resolves a range too, and both commands need the identical "what's actually
8
+ * installed" answer — this is `resolveRange`'s default reader.
9
+ */
10
+ export declare const readInstalledVersion: (cwd: string, name: string) => string | undefined;
11
+ export interface RangeDeps {
12
+ cwd: string;
13
+ fetchVersions: typeof fetchVersions;
14
+ readInstalledVersion: (cwd: string, name: string) => string | undefined;
15
+ }
16
+ export declare const defaultRangeDeps: (cwd: string) => RangeDeps;
17
+ export interface ResolvedRange {
18
+ ok: true;
19
+ manifestPath: string;
20
+ manifestRaw: string;
21
+ manifest: Manifest;
22
+ dependencies: FlowDependency[];
23
+ current: string;
24
+ target: string;
25
+ versions: string[];
26
+ }
27
+ export interface UnresolvedRange {
28
+ ok: false;
29
+ /** Human-readable, ready to print as-is. */
30
+ reason: string;
31
+ }
32
+ export type RangeResult = ResolvedRange | UnresolvedRange;
33
+ /**
34
+ * What `revision` resolves to for the project at `cwd`.
35
+ *
36
+ * Reads the manifest, finds its Flow dependencies, detects the current version,
37
+ * fetches what every dependency has actually published, and resolves `revision`
38
+ * against the intersection — the same sequence `upgrade` always needed, now
39
+ * shared with `list <revision>`, which uses it to answer "what would `upgrade
40
+ * <revision>` touch?" without writing anything.
41
+ *
42
+ * Reports the resolution rather than judging it: an exact version or a stale
43
+ * dist-tag can resolve at or below `current`, and this function returns that
44
+ * target just the same. Whether that is a refusal (`upgrade`, about to write
45
+ * files) or a legitimate answer ("nothing between here and there" — `list`) is
46
+ * for the caller to decide. Two callers judging the same fact differently is
47
+ * fine; two callers computing the fact differently is how they drift.
48
+ */
49
+ export declare const resolveRange: (revision: string, deps: RangeDeps) => Promise<RangeResult>;
50
+ //# sourceMappingURL=range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.d.ts","sourceRoot":"","sources":["../../src/resolve/range.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,QAAQ,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,aAAa,EAEd,MAAM,eAAe,CAAC;AAGvB;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,QAC1B,MAAM,QACL,MAAM,KACX,MAAM,GAAG,SASX,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,oBAAoB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CACzE;AAED,eAAO,MAAM,gBAAgB,QAAS,MAAM,KAAG,SAI7C,CAAC;AAEH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,KAAK,CAAC;IACV,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,eAAe,CAAC;AA2C1D;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY,aACb,MAAM,QACV,SAAS,KACd,OAAO,CAAC,WAAW,CAuHrB,CAAC"}