@clerk/upgrade 2.0.0-snapshot.v20251204175016 → 2.0.0-snapshot.v20251208202852

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 (54) hide show
  1. package/dist/__tests__/fixtures/expo-old-package/package-lock.json +5 -0
  2. package/dist/__tests__/fixtures/expo-old-package/package.json +10 -0
  3. package/dist/__tests__/fixtures/expo-old-package/src/App.tsx +14 -0
  4. package/dist/__tests__/fixtures/nextjs-v6/package.json +9 -0
  5. package/dist/__tests__/fixtures/nextjs-v6/pnpm-lock.yaml +2 -0
  6. package/dist/__tests__/fixtures/nextjs-v6/src/app.tsx +17 -0
  7. package/dist/__tests__/fixtures/nextjs-v7/package.json +9 -0
  8. package/dist/__tests__/fixtures/nextjs-v7/pnpm-lock.yaml +2 -0
  9. package/dist/__tests__/fixtures/nextjs-v7/src/app.tsx +16 -0
  10. package/dist/__tests__/fixtures/no-clerk/package.json +7 -0
  11. package/dist/__tests__/fixtures/react-v6/package.json +8 -0
  12. package/dist/__tests__/fixtures/react-v6/src/App.tsx +19 -0
  13. package/dist/__tests__/fixtures/react-v6/yarn.lock +2 -0
  14. package/dist/__tests__/helpers/create-fixture.js +56 -0
  15. package/dist/__tests__/integration/cli.test.js +230 -0
  16. package/dist/__tests__/integration/config.test.js +76 -0
  17. package/dist/__tests__/integration/detect-sdk.test.js +100 -0
  18. package/dist/__tests__/integration/runner.test.js +79 -0
  19. package/dist/cli.js +159 -45
  20. package/dist/codemods/__tests__/__fixtures__/transform-align-experimental-unstable-prefixes.fixtures.js +68 -0
  21. package/dist/codemods/__tests__/__fixtures__/transform-appearance-layout-to-options.fixtures.js +9 -0
  22. package/dist/codemods/__tests__/__fixtures__/transform-clerk-react-v6.fixtures.js +13 -0
  23. package/dist/codemods/__tests__/__fixtures__/transform-remove-deprecated-appearance-props.fixtures.js +63 -0
  24. package/dist/codemods/__tests__/__fixtures__/transform-themes-to-ui-themes.fixtures.js +41 -0
  25. package/dist/codemods/__tests__/transform-align-experimental-unstable-prefixes.test.js +15 -0
  26. package/dist/codemods/__tests__/transform-appearance-layout-to-options.test.js +15 -0
  27. package/dist/codemods/__tests__/transform-remove-deprecated-appearance-props.test.js +15 -0
  28. package/dist/codemods/__tests__/transform-themes-to-ui-themes.test.js +15 -0
  29. package/dist/codemods/index.js +67 -13
  30. package/dist/codemods/transform-align-experimental-unstable-prefixes.cjs +400 -0
  31. package/dist/codemods/transform-appearance-layout-to-options.cjs +65 -0
  32. package/dist/codemods/transform-clerk-react-v6.cjs +15 -7
  33. package/dist/codemods/transform-remove-deprecated-appearance-props.cjs +109 -0
  34. package/dist/codemods/transform-remove-deprecated-props.cjs +11 -32
  35. package/dist/codemods/transform-themes-to-ui-themes.cjs +65 -0
  36. package/dist/config.js +122 -0
  37. package/dist/render.js +164 -0
  38. package/dist/runner.js +98 -0
  39. package/dist/util/detect-sdk.js +125 -0
  40. package/dist/util/package-manager.js +94 -0
  41. package/dist/versions/core-3/changes/clerk-expo-package-rename.md +23 -0
  42. package/dist/versions/core-3/changes/clerk-react-package-rename.md +23 -0
  43. package/dist/versions/core-3/index.js +40 -0
  44. package/package.json +2 -8
  45. package/dist/app.js +0 -177
  46. package/dist/components/Codemod.js +0 -149
  47. package/dist/components/Command.js +0 -56
  48. package/dist/components/Header.js +0 -11
  49. package/dist/components/SDKWorkflow.js +0 -278
  50. package/dist/components/Scan.js +0 -180
  51. package/dist/components/UpgradeSDK.js +0 -116
  52. package/dist/util/expandable-list.js +0 -173
  53. package/dist/util/get-clerk-version.js +0 -22
  54. package/dist/util/guess-framework.js +0 -69
@@ -0,0 +1,94 @@
1
+ import { spawn } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ export function detectPackageManager(dir) {
5
+ if (fs.existsSync(path.join(dir, 'pnpm-lock.yaml'))) {
6
+ return 'pnpm';
7
+ }
8
+ if (fs.existsSync(path.join(dir, 'yarn.lock'))) {
9
+ return 'yarn';
10
+ }
11
+ if (fs.existsSync(path.join(dir, 'bun.lockb')) || fs.existsSync(path.join(dir, 'bun.lock'))) {
12
+ return 'bun';
13
+ }
14
+ if (fs.existsSync(path.join(dir, 'package-lock.json'))) {
15
+ return 'npm';
16
+ }
17
+ return 'npm';
18
+ }
19
+ export function getInstallCommand(packageManager, packageName, version = 'latest') {
20
+ const pkg = version === 'latest' ? packageName : `${packageName}@${version}`;
21
+ switch (packageManager) {
22
+ case 'pnpm':
23
+ return ['pnpm', ['add', pkg]];
24
+ case 'yarn':
25
+ return ['yarn', ['add', pkg]];
26
+ case 'bun':
27
+ return ['bun', ['add', pkg]];
28
+ case 'npm':
29
+ default:
30
+ return ['npm', ['install', pkg]];
31
+ }
32
+ }
33
+ export function getUninstallCommand(packageManager, packageName) {
34
+ switch (packageManager) {
35
+ case 'pnpm':
36
+ return ['pnpm', ['remove', packageName]];
37
+ case 'yarn':
38
+ return ['yarn', ['remove', packageName]];
39
+ case 'bun':
40
+ return ['bun', ['remove', packageName]];
41
+ case 'npm':
42
+ default:
43
+ return ['npm', ['uninstall', packageName]];
44
+ }
45
+ }
46
+ export async function runPackageManagerCommand(command, args, cwd) {
47
+ return new Promise((resolve, reject) => {
48
+ const child = spawn(command, args, {
49
+ cwd,
50
+ stdio: 'pipe',
51
+ shell: process.platform === 'win32'
52
+ });
53
+ let stdout = '';
54
+ let stderr = '';
55
+ child.stdout?.on('data', data => {
56
+ stdout += data.toString();
57
+ });
58
+ child.stderr?.on('data', data => {
59
+ stderr += data.toString();
60
+ });
61
+ child.on('close', code => {
62
+ if (code === 0) {
63
+ resolve({
64
+ stdout,
65
+ stderr
66
+ });
67
+ } else {
68
+ reject(new Error(`Command failed with code ${code}: ${stderr || stdout}`));
69
+ }
70
+ });
71
+ child.on('error', reject);
72
+ });
73
+ }
74
+ export async function upgradePackage(packageManager, packageName, version, cwd) {
75
+ const [cmd, args] = getInstallCommand(packageManager, packageName, version);
76
+ return runPackageManagerCommand(cmd, args, cwd);
77
+ }
78
+ export async function removePackage(packageManager, packageName, cwd) {
79
+ const [cmd, args] = getUninstallCommand(packageManager, packageName);
80
+ return runPackageManagerCommand(cmd, args, cwd);
81
+ }
82
+ export function getPackageManagerDisplayName(packageManager) {
83
+ switch (packageManager) {
84
+ case 'pnpm':
85
+ return 'pnpm';
86
+ case 'yarn':
87
+ return 'Yarn';
88
+ case 'bun':
89
+ return 'Bun';
90
+ case 'npm':
91
+ default:
92
+ return 'npm';
93
+ }
94
+ }
@@ -0,0 +1,23 @@
1
+ ---
2
+ title: '`@clerk/clerk-expo` renamed to `@clerk/expo`'
3
+ packages: ['expo']
4
+ matcher: '@clerk/clerk-expo'
5
+ category: 'breaking'
6
+ docsAnchor: 'clerk-expo-rename'
7
+ ---
8
+
9
+ The `@clerk/clerk-expo` package has been renamed to `@clerk/expo`.
10
+
11
+ Update your imports:
12
+
13
+ ```diff
14
+ - import { ClerkProvider, useUser } from '@clerk/clerk-expo';
15
+ + import { ClerkProvider, useUser } from '@clerk/expo';
16
+ ```
17
+
18
+ And update your package.json:
19
+
20
+ ```diff
21
+ - "@clerk/clerk-expo": "^2.0.0",
22
+ + "@clerk/expo": "^3.0.0",
23
+ ```
@@ -0,0 +1,23 @@
1
+ ---
2
+ title: '`@clerk/clerk-react` renamed to `@clerk/react`'
3
+ packages: ['react']
4
+ matcher: '@clerk/clerk-react'
5
+ category: 'breaking'
6
+ docsAnchor: 'clerk-react-rename'
7
+ ---
8
+
9
+ The `@clerk/clerk-react` package has been renamed to `@clerk/react`.
10
+
11
+ Update your imports:
12
+
13
+ ```diff
14
+ - import { ClerkProvider, useUser } from '@clerk/clerk-react';
15
+ + import { ClerkProvider, useUser } from '@clerk/react';
16
+ ```
17
+
18
+ And update your package.json:
19
+
20
+ ```diff
21
+ - "@clerk/clerk-react": "^5.0.0",
22
+ + "@clerk/react": "^7.0.0",
23
+ ```
@@ -0,0 +1,40 @@
1
+ export default {
2
+ id: 'core-3',
3
+ name: 'Core 3',
4
+ docsUrl: 'https://clerk.com/docs/upgrade-guides/core-3',
5
+ sdkVersions: {
6
+ nextjs: {
7
+ from: 6,
8
+ to: 7
9
+ },
10
+ react: {
11
+ from: 5,
12
+ to: 7
13
+ },
14
+ expo: {
15
+ from: 2,
16
+ to: 3
17
+ },
18
+ 'react-router': {
19
+ from: 2,
20
+ to: 3
21
+ },
22
+ 'tanstack-react-start': {
23
+ from: 0,
24
+ to: 1
25
+ },
26
+ astro: {
27
+ from: 2,
28
+ to: 3
29
+ },
30
+ nuxt: {
31
+ from: 2,
32
+ to: 3
33
+ },
34
+ vue: {
35
+ from: 2,
36
+ to: 3
37
+ }
38
+ },
39
+ codemods: ['transform-clerk-react-v6', 'transform-remove-deprecated-props', 'transform-remove-deprecated-appearance-props', 'transform-appearance-layout-to-options', 'transform-themes-to-ui-themes', 'transform-align-experimental-unstable-prefixes']
40
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerk/upgrade",
3
- "version": "2.0.0-snapshot.v20251204175016",
3
+ "version": "2.0.0-snapshot.v20251208202852",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/clerk/javascript.git",
@@ -21,21 +21,15 @@
21
21
  ]
22
22
  },
23
23
  "dependencies": {
24
- "@inkjs/ui": "^2.0.0",
25
- "@jescalan/ink-markdown": "^2.0.0",
24
+ "chalk": "^5.3.0",
26
25
  "ejs": "3.1.10",
27
26
  "execa": "9.4.1",
28
27
  "globby": "^14.0.1",
29
28
  "gray-matter": "^4.0.3",
30
29
  "index-to-position": "^0.1.2",
31
- "ink": "^5.0.1",
32
- "ink-big-text": "^2.0.0",
33
- "ink-gradient": "^3.0.0",
34
- "ink-link": "^4.1.0",
35
30
  "jscodeshift": "^17.0.0",
36
31
  "marked": "^11.1.1",
37
32
  "meow": "^11.0.0",
38
- "react": "18.3.1",
39
33
  "read-pkg": "^9.0.1",
40
34
  "semver-regex": "^4.0.5",
41
35
  "temp-dir": "^3.0.0"
package/dist/app.js DELETED
@@ -1,177 +0,0 @@
1
- import { MultiSelect, Select, TextInput } from '@inkjs/ui';
2
- import { Newline, Text, useApp } from 'ink';
3
- import React, { useEffect, useState } from 'react';
4
- import { Header } from './components/Header.js';
5
- import { Scan } from './components/Scan.js';
6
- import { SDKWorkflow } from './components/SDKWorkflow.js';
7
- import SDKS from './constants/sdks.js';
8
- import guessFrameworks from './util/guess-framework.js';
9
-
10
- /**
11
- * Main CLI application component for handling Clerk SDK upgrades.
12
- *
13
- * @param {Object} props - The `props` object.
14
- * @param {string} [props.dir] - The directory to scan for files.
15
- * @param {boolean} [props.disableTelemetry=false] - Flag to disable telemetry.
16
- * @param {string} [props.fromVersion] - The current version of the SDK.
17
- * @param {Array<string>} [props.ignore] - List of files or directories to ignore.
18
- * @param {boolean} [props.noWarnings=false] - Flag to disable warnings.
19
- * @param {string} [props.sdk] - The SDK to upgrade.
20
- * @param {string} [props.toVersion] - The target version of the SDK.
21
- * @param {boolean} [props.yolo=false] - Flag to enable YOLO mode.
22
- *
23
- * @returns {JSX.Element} The rendered component.
24
- */
25
- export default function App(props) {
26
- const {
27
- noWarnings = false,
28
- disableTelemetry = false
29
- } = props;
30
- const {
31
- exit
32
- } = useApp();
33
- const [yolo, setYolo] = useState(props.yolo ?? false);
34
- const [sdks, setSdks] = useState(props.sdk ? [props.sdk] : []);
35
- const [sdkGuesses, setSdkGuesses] = useState([]);
36
- const [sdkGuessConfirmed, setSdkGuessConfirmed] = useState(false);
37
- const [sdkGuessAttempted, setSdkGuessAttempted] = useState(false);
38
- const [fromVersion, setFromVersion] = useState(props.fromVersion);
39
- const [toVersion, setToVersion] = useState(props.toVersion);
40
- const [dir, setDir] = useState(props.dir);
41
- const [ignore, setIgnore] = useState(props.ignore ?? []);
42
- const [configComplete, setConfigComplete] = useState(false);
43
- const [configVerified, setConfigVerified] = useState(false);
44
- const [uuid, setUuid] = useState();
45
- if (yolo) {
46
- setSdks(SDKS.map(s => s.value));
47
- setYolo(false);
48
- }
49
- useEffect(() => {
50
- if (toVersion === 'core-2') {
51
- setFromVersion('core-1');
52
- }
53
- }, [toVersion]);
54
- useEffect(() => {
55
- if (fromVersion === 'core-1') {
56
- setToVersion('core-2');
57
- }
58
- }, [fromVersion]);
59
-
60
- // Handle the individual SDK upgrade
61
- if (!fromVersion && !toVersion && ['nextjs', 'clerk-react', 'clerk-expo', 'react-router', 'tanstack-react-start'].includes(sdks[0])) {
62
- return /*#__PURE__*/React.createElement(SDKWorkflow, {
63
- sdk: sdks[0]
64
- });
65
- }
66
-
67
- // We try to guess which SDK they are using
68
- if (isEmpty(sdks) && isEmpty(sdkGuesses) && !sdkGuessAttempted) {
69
- if (!dir) {
70
- return setDir(process.cwd());
71
- }
72
- const {
73
- guesses,
74
- _uuid
75
- } = guessFrameworks(dir, disableTelemetry);
76
- setUuid(_uuid);
77
- setSdkGuesses(guesses);
78
- setSdkGuessAttempted(true);
79
- }
80
-
81
- // No support for v3 or below, sadly
82
- if (parseInt(fromVersion) < 4) {
83
- return /*#__PURE__*/React.createElement(Text, {
84
- color: "red"
85
- }, "We're so sorry, but this tool only supports migration from version 4 and above.");
86
- }
87
-
88
- // If they are trying to/from the same version, that's an error
89
- if (parseInt(fromVersion) === parseInt(toVersion)) {
90
- return /*#__PURE__*/React.createElement(Text, {
91
- color: "red"
92
- }, "You are already on version ", toVersion, ", so there's no need to migrate!");
93
- }
94
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Header, null), !configComplete && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement(Text, {
95
- color: "blue"
96
- }, "Hello friend!"), " We're excited to help you upgrade Clerk modules. Before we get started, a couple questions..."), /*#__PURE__*/React.createElement(Newline, null)), isEmpty(sdks) && !isEmpty(sdkGuesses) && !sdkGuessConfirmed && /*#__PURE__*/React.createElement(React.Fragment, null, sdkGuesses.length > 1 ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, "It looks like you are using the following Clerk SDKs in your project:"), sdkGuesses.map(guess => /*#__PURE__*/React.createElement(Text, {
97
- key: guess.value
98
- }, ' ', "- ", guess.label)), /*#__PURE__*/React.createElement(Text, null, "Is that right?")) : /*#__PURE__*/React.createElement(Text, null, "It looks like you are using the ", /*#__PURE__*/React.createElement(Text, {
99
- bold: true
100
- }, sdkGuesses[0].label), " Clerk SDK in your project. Is that right?"), /*#__PURE__*/React.createElement(Select, {
101
- options: [{
102
- label: 'yes',
103
- value: 'yes'
104
- }, {
105
- label: 'no',
106
- value: 'no'
107
- }],
108
- onChange: item => {
109
- setSdkGuessConfirmed(true);
110
- // if true, we were right so we set the sdk
111
- if (item === 'yes') {
112
- setSdks(sdkGuesses.map(guess => guess.value));
113
- } else {
114
- setSdkGuesses([]);
115
- }
116
- }
117
- })), isEmpty(sdks) && isEmpty(sdkGuesses) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, "Please select which Clerk SDK(s) you're using for your app:"), /*#__PURE__*/React.createElement(Text, {
118
- color: "gray"
119
- }, "(select with space bar, multiple can be selected, press enter when finished)"), /*#__PURE__*/React.createElement(MultiSelect, {
120
- options: SDKS,
121
- onSubmit: value => setSdks(value),
122
- visibleOptionCount: SDKS.length
123
- })), !isEmpty(sdks) && fromVersion && toVersion && !dir && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, "Where would you like for us to scan for files in your project?"), /*#__PURE__*/React.createElement(Text, {
124
- color: "gray"
125
- }, "(globstar syntax supported)"), /*#__PURE__*/React.createElement(TextInput, {
126
- defaultValue: "**/*",
127
- onSubmit: val => setDir(val)
128
- })), !isEmpty(sdks) && fromVersion && toVersion && dir && isEmpty(ignore) && !configComplete && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, "Are there any files or directories you'd like to ignore? If so, you can add them below, separated by commas. We ignore \"node_modules\" and \".git\" by default."), /*#__PURE__*/React.createElement(Text, {
129
- color: "gray"
130
- }, "(globstar syntax supported)"), /*#__PURE__*/React.createElement(TextInput, {
131
- placeholder: "**/public/**, **/docs/**",
132
- defaultValue: ignore,
133
- onSubmit: val => {
134
- setIgnore(val.includes(',') ? val.split(/\s*,\s*/) : [].concat(val));
135
- setConfigComplete(true);
136
- }
137
- })), configComplete && !configVerified && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, "Ok, here's our configuration:"), /*#__PURE__*/React.createElement(Newline, null), /*#__PURE__*/React.createElement(Text, null, "Clerk ", sdks.length > 1 ? 'SDKs' : 'SDK', " used:", /*#__PURE__*/React.createElement(Text, {
138
- color: "green"
139
- }, " ", sdks.toString())), /*#__PURE__*/React.createElement(Text, null, "Migrating from", /*#__PURE__*/React.createElement(Text, {
140
- color: "green"
141
- }, " ", fromVersion, " "), "to", /*#__PURE__*/React.createElement(Text, {
142
- color: "green"
143
- }, " ", toVersion)), /*#__PURE__*/React.createElement(Text, null, "Looking in the directory", /*#__PURE__*/React.createElement(Text, {
144
- color: "green"
145
- }, " ", dir, " "), ignore.length > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, "and ignoring", /*#__PURE__*/React.createElement(Text, {
146
- color: "green"
147
- }, " ", ignore.join(', ')))), /*#__PURE__*/React.createElement(Newline, null), /*#__PURE__*/React.createElement(Text, null, "Does this look right?"), /*#__PURE__*/React.createElement(Select, {
148
- options: [{
149
- label: 'yes',
150
- value: 'yes'
151
- }, {
152
- label: 'no - exit, and I will try again',
153
- value: 'no'
154
- }],
155
- onChange: value => {
156
- if (!value || value === 'no') {
157
- exit();
158
- } else {
159
- setConfigVerified(true);
160
- }
161
- }
162
- })), configVerified && /*#__PURE__*/React.createElement(Scan, {
163
- fromVersion,
164
- toVersion,
165
- sdks,
166
- dir,
167
- ignore,
168
- noWarnings,
169
- uuid,
170
- disableTelemetry
171
- }));
172
- }
173
-
174
- // small util to make the logic blocks easier to visually parse
175
- function isEmpty(arr) {
176
- return !arr.length;
177
- }
@@ -1,149 +0,0 @@
1
- import { Spinner, StatusMessage, TextInput } from '@inkjs/ui';
2
- import { Newline, Text } from 'ink';
3
- import React, { useEffect, useState } from 'react';
4
- import { runCodemod } from '../codemods/index.js';
5
-
6
- /**
7
- * Codemod component that allows users to run a codemod transformation on their project files.
8
- *
9
- * @param {Object} props
10
- * @param {Function} props.callback - The callback function to be called after the codemod is run.
11
- * @param {string|string[]} [props.glob] - Optional glob(s) to scan for files. When provided, the
12
- * codemod will use this glob directly instead of prompting.
13
- * @param {Function} [props.onGlobResolved] - Optional callback invoked with the resolved glob array
14
- * when the user provides it via the prompt.
15
- * @param {string} props.sdk - The SDK name to be used in the codemod.
16
- * @param {string} props.transform - The transformation to be applied by the codemod.
17
- *
18
- * @returns {JSX.Element} The rendered Codemod component.
19
- */
20
- export function Codemod(props) {
21
- const {
22
- callback,
23
- sdk,
24
- transform,
25
- glob: initialGlob,
26
- onGlobResolved
27
- } = props;
28
- const [error, setError] = useState();
29
- const [glob, setGlob] = useState(initialGlob);
30
- const [result, setResult] = useState();
31
-
32
- // If a glob is later provided via props (e.g. from a previous codemod run),
33
- // adopt it so we can run without re-prompting.
34
- useEffect(() => {
35
- if (initialGlob && !glob) {
36
- setGlob(initialGlob);
37
- }
38
- }, [initialGlob, glob]);
39
- useEffect(() => {
40
- if (!glob) {
41
- return;
42
- }
43
- runCodemod(transform, glob).then(res => {
44
- setResult(res);
45
- }).catch(err => {
46
- setError(err);
47
- }).finally(() => {
48
- callback(true);
49
- });
50
- }, [callback, glob, transform]);
51
- return /*#__PURE__*/React.createElement(React.Fragment, null, glob ? /*#__PURE__*/React.createElement(StatusMessage, {
52
- variant: "success"
53
- }, "Scanning for files in your project... ", glob.toString()) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, "Where would you like for us to scan for files in your project?"), /*#__PURE__*/React.createElement(Text, {
54
- color: "gray"
55
- }, "(globstar syntax supported)"), glob ? /*#__PURE__*/React.createElement(Text, null, glob.toString()) : /*#__PURE__*/React.createElement(TextInput, {
56
- defaultValue: "**/*.(js|jsx|ts|tsx|mjs|cjs)",
57
- onSubmit: val => {
58
- const parsed = val.split(/[ ,]/).filter(Boolean);
59
- setGlob(parsed);
60
- if (onGlobResolved) {
61
- onGlobResolved(parsed);
62
- }
63
- }
64
- })), !result && !error && glob && /*#__PURE__*/React.createElement(Spinner, {
65
- label: `Running @clerk/${sdk} codemod... ${transform}`
66
- }), result && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(StatusMessage, {
67
- variant: "success"
68
- }, "Running ", /*#__PURE__*/React.createElement(Text, {
69
- bold: true
70
- }, "@clerk/", sdk), " codemod... ", transform, " complete!"), /*#__PURE__*/React.createElement(Newline, null), /*#__PURE__*/React.createElement(Text, {
71
- bold: true
72
- }, "Codemod results:"), /*#__PURE__*/React.createElement(Text, {
73
- color: "red"
74
- }, result.error ?? 0, " errors"), /*#__PURE__*/React.createElement(Text, {
75
- color: "green"
76
- }, result.ok ?? 0, " ok"), /*#__PURE__*/React.createElement(Text, {
77
- color: "yellow"
78
- }, result.skip ?? 0, " skipped"), /*#__PURE__*/React.createElement(Text, {
79
- color: "gray"
80
- }, result.nochange ?? 0, " unmodified"), result.timeElapsed && /*#__PURE__*/React.createElement(Text, null, "Time elapsed: ", result.timeElapsed), transform === 'transform-remove-deprecated-props' && /*#__PURE__*/React.createElement(ManualInterventionSummary, {
81
- stats: result.clerkUpgradeStats
82
- }), /*#__PURE__*/React.createElement(Newline, null)), error && /*#__PURE__*/React.createElement(Text, {
83
- color: "red"
84
- }, error.message));
85
- }
86
- function ManualInterventionSummary({
87
- stats
88
- }) {
89
- if (!stats) {
90
- return null;
91
- }
92
- const hasUserButtonChanges = stats.userbuttonAfterSignOutPropsRemoved > 0;
93
- const hasHideSlugChanges = stats.hideSlugRemoved > 0;
94
- const hasBeforeEmitChanges = stats.beforeEmitTransformed > 0;
95
- if (!hasUserButtonChanges && !hasHideSlugChanges && !hasBeforeEmitChanges) {
96
- return null;
97
- }
98
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Newline, null), /*#__PURE__*/React.createElement(Text, {
99
- bold: true,
100
- color: "yellow"
101
- }, "\u26A0\uFE0F Manual intervention may be required:"), hasUserButtonChanges && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Newline, null), /*#__PURE__*/React.createElement(Text, {
102
- color: "yellow"
103
- }, "\u2022 Removed ", stats.userbuttonAfterSignOutPropsRemoved, " ", /*#__PURE__*/React.createElement(Text, {
104
- bold: true
105
- }, "UserButton"), " sign-out redirect prop(s)"), /*#__PURE__*/React.createElement(Text, {
106
- color: "gray"
107
- }, ' ', "Configure redirects via ", /*#__PURE__*/React.createElement(Text, {
108
- italic: true
109
- }, "ClerkProvider afterSignOutUrl"), " or", ' ', /*#__PURE__*/React.createElement(Text, {
110
- italic: true
111
- }, "SignOutButton redirectUrl")), /*#__PURE__*/React.createElement(FileList, {
112
- files: stats.userbuttonFilesAffected
113
- })), hasHideSlugChanges && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Newline, null), /*#__PURE__*/React.createElement(Text, {
114
- color: "yellow"
115
- }, "\u2022 Removed ", stats.hideSlugRemoved, " ", /*#__PURE__*/React.createElement(Text, {
116
- bold: true
117
- }, "hideSlug"), " prop(s)"), /*#__PURE__*/React.createElement(Text, {
118
- color: "gray"
119
- }, ' ', "This prop has been removed. Slug visibility is now controlled differently."), /*#__PURE__*/React.createElement(FileList, {
120
- files: stats.hideSlugFiles
121
- })), hasBeforeEmitChanges && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Newline, null), /*#__PURE__*/React.createElement(Text, {
122
- color: "yellow"
123
- }, "\u2022 Transformed ", stats.beforeEmitTransformed, " ", /*#__PURE__*/React.createElement(Text, {
124
- bold: true
125
- }, "setActive beforeEmit"), " to", ' ', /*#__PURE__*/React.createElement(Text, {
126
- bold: true
127
- }, "navigate")), /*#__PURE__*/React.createElement(Text, {
128
- color: "gray"
129
- }, ' ', "Callback signature changed: now receives ", /*#__PURE__*/React.createElement(Text, {
130
- italic: true
131
- }, "params"), " object instead of", ' ', /*#__PURE__*/React.createElement(Text, {
132
- italic: true
133
- }, "session"), " directly. Review the transformed code."), /*#__PURE__*/React.createElement(FileList, {
134
- files: stats.beforeEmitFiles
135
- })));
136
- }
137
- function FileList({
138
- files
139
- }) {
140
- if (!files?.length) {
141
- return null;
142
- }
143
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, {
144
- color: "gray"
145
- }, ' ', "Files:"), files.map((file, index) => /*#__PURE__*/React.createElement(Text, {
146
- key: index,
147
- color: "gray"
148
- }, ' ', "- ", file)));
149
- }
@@ -1,56 +0,0 @@
1
- import { Spinner, StatusMessage } from '@inkjs/ui';
2
- import { execa } from 'execa';
3
- import { Text } from 'ink';
4
- import React, { useEffect, useState } from 'react';
5
-
6
- /**
7
- * Component that runs a command and handles the result.
8
- *
9
- * @component
10
- * @param {Object} props
11
- * @param {Function} props.callback - The callback function to be called after the command execution.
12
- * @param {string} props.cmd - The command to execute.
13
- * @param {string} props.message - The message to display while the command is running.
14
- * @returns {JSX.Element} The rendered component.
15
- *
16
- * @example
17
- * <Command cmd="echo 'hello world'" />
18
- */
19
- export function Command({
20
- cmd,
21
- message,
22
- onError,
23
- onSuccess
24
- }) {
25
- const [error, setError] = useState();
26
- const [result, setResult] = useState();
27
- useEffect(() => {
28
- execa({
29
- shell: true
30
- })`${cmd}`.then(res => {
31
- setResult(res);
32
- }).catch(err => {
33
- setError(err);
34
- });
35
- }, [cmd]);
36
- return /*#__PURE__*/React.createElement(React.Fragment, null, !result && !error && /*#__PURE__*/React.createElement(Loading, {
37
- cmd: cmd,
38
- message: message
39
- }), result ? onSuccess ? onSuccess() : /*#__PURE__*/React.createElement(StatusMessage, {
40
- variant: "success"
41
- }, "Successfully ran: ", /*#__PURE__*/React.createElement(Text, {
42
- bold: true
43
- }, cmd)) : null, error ? onError ? onError() : /*#__PURE__*/React.createElement(StatusMessage, {
44
- variant: "error"
45
- }, "Failed running: ", /*#__PURE__*/React.createElement(Text, {
46
- bold: true
47
- }, cmd)) : null);
48
- }
49
- function Loading({
50
- cmd,
51
- message
52
- }) {
53
- return message ? message : /*#__PURE__*/React.createElement(Spinner, {
54
- label: `Running command: ${cmd}`
55
- });
56
- }
@@ -1,11 +0,0 @@
1
- import BigText from 'ink-big-text';
2
- import Gradient from 'ink-gradient';
3
- import React from 'react';
4
- export function Header() {
5
- return /*#__PURE__*/React.createElement(Gradient, {
6
- name: "vice"
7
- }, /*#__PURE__*/React.createElement(BigText, {
8
- text: "Clerk Upgrade",
9
- font: "tiny"
10
- }));
11
- }