Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/real-boats-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/upgrade": minor
---

Enhancing error handling throughout the SDK upgrade flow
7 changes: 1 addition & 6 deletions packages/upgrade/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,7 @@ export default function App(props) {

// Handle the individual SDK upgrade
if (!fromVersion && !toVersion && sdks[0] === 'nextjs') {
return (
<SDKWorkflow
packageManager={props.packageManager}
sdk={sdks[0]}
/>
);
return <SDKWorkflow sdk={sdks[0]} />;
}

// We try to guess which SDK they are using
Expand Down
2 changes: 0 additions & 2 deletions packages/upgrade/src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const cli = meow(
--sdk Name of the SDK you're upgrading
--dir Directory you'd like to scan for files
--ignore Any files or directories you'd like to ignore
--packageManager The package manager you're using (npm, yarn, pnpm)
--noWarnings Do not print warnings, only items that must be fixed
--disableTelemetry Do not send anonymous usage telemetry

Expand All @@ -34,7 +33,6 @@ const cli = meow(
sdk: { type: 'string', choices: sdks.map(i => i.value) },
dir: { type: 'string' },
ignore: { type: 'string', isMultiple: true },
packageManager: { type: 'string' },
yolo: { type: 'boolean' },
noWarnings: { type: 'boolean' },
disableTelemetry: { type: 'boolean' },
Expand Down
2 changes: 1 addition & 1 deletion packages/upgrade/src/components/Codemod.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function Codemod(props) {
</>
)}

{!result && !error && glob && <Spinner label={`Running @clerk/${sdk}</Text> codemod... ${transform}`} />}
{!result && !error && glob && <Spinner label={`Running @clerk/${sdk} codemod... ${transform}`} />}
{result && (
<>
<StatusMessage variant='success'>
Expand Down
4 changes: 1 addition & 3 deletions packages/upgrade/src/components/SDKWorkflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ import { UpgradeSDK } from './UpgradeSDK.js';
*
* @component
* @param {Object} props
* @param {string} props.packageManager - The package manager to use for the upgrade, if needed.
* @param {string} props.sdk - The SDK to be upgraded.
*
* @returns {JSX.Element} The rendered component.
*/
export function SDKWorkflow(props) {
const { packageManager, sdk } = props;
const { sdk } = props;

const [done, setDone] = useState(false);
const [runCodemod, setRunCodemod] = useState(false);
Expand Down Expand Up @@ -59,7 +58,6 @@ export function SDKWorkflow(props) {
<>
<UpgradeSDK
callback={setUpgradeComplete}
packageManager={packageManager}
sdk={sdk}
/>
{upgradeComplete ? (
Expand Down
71 changes: 58 additions & 13 deletions packages/upgrade/src/components/UpgradeSDK.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Spinner, StatusMessage } from '@inkjs/ui';
import { Select, Spinner, StatusMessage } from '@inkjs/ui';
import { execa } from 'execa';
import { existsSync } from 'fs';
import { Text } from 'ink';
import { Newline, Text } from 'ink';
import React, { useEffect, useState } from 'react';

function detectPackageManager() {
Expand All @@ -11,13 +11,12 @@ function detectPackageManager() {
return 'yarn';
} else if (existsSync('pnpm-lock.yaml')) {
return 'pnpm';
} else {
return 'npm';
}
return undefined;
}

function upgradeCommand(sdk, packageManager) {
switch (packageManager || detectPackageManager()) {
switch (packageManager) {
case 'yarn':
return `yarn add @clerk/${sdk}@latest`;
case 'pnpm':
Expand All @@ -33,39 +32,85 @@ function upgradeCommand(sdk, packageManager) {
* @component
* @param {Object} props
* @param {Function} props.callback - The callback function to be called after the command execution.
* @param {string} props.packageManager - The package manager used in the project in case we cannot detect it automatically.
* @param {string} props.sdk - The SDK for which the upgrade command is run.
* @returns {JSX.Element} The rendered component.
*
* @example
* <UpgradeCommand sdk="example-sdk" callback={handleUpgrade} />
*/
export function UpgradeSDK({ callback, packageManager, sdk }) {
export function UpgradeSDK({ callback, sdk }) {
const [command, setCommand] = useState();
const [error, setError] = useState();
const [packageManager, setPackageManager] = useState(detectPackageManager());
const [result, setResult] = useState();

const command = upgradeCommand(sdk, packageManager);

useEffect(() => {
if (!packageManager) {
return;
}
setCommand(previous => {
if (previous) {
return previous;
}
return upgradeCommand(sdk, packageManager);
});
if (!command) {
return;
}

execa({ shell: true })`${command}`
.then(res => {
setResult(res);
callback(true);
})
.catch(err => {
setError(err);
})
.finally(() => {
callback(true);
});
}, [command]);
}, [command, packageManager, sdk]);

return (
<>
{!result && !error && <Spinner label={`Running upgrade command: ${command}`} />}
{packageManager ? null : (
<>
<Text>
We could not detect the package manager used in your project. Please select the package manager you are
using
</Text>
<Select
options={[
{ label: 'npm', value: 'npm' },
{ label: 'pnpm', value: 'pnpm' },
{ label: 'yarn', value: 'yarn' },
]}
onChange={setPackageManager}
/>
</>
)}
{packageManager && !result && !error && <Spinner label={`Running upgrade command: ${command}`} />}
{result && (
<StatusMessage variant='success'>
<Text bold>@clerk/{sdk}</Text> upgraded successfully to <Text bold>latest!</Text>
</StatusMessage>
)}
{error && <StatusMessage variant='error'>Upgrade failed!</StatusMessage>}
{error && (
<>
<StatusMessage variant='error'>
Running the upgrade command failed:{' '}
<Text
bold
color='red'
>
{command}
</Text>
</StatusMessage>
<StatusMessage variant='info'>
Please manually upgrade <Text bold>@clerk/{sdk}</Text> to <Text bold>latest</Text> in your project.
</StatusMessage>
<Newline />
</>
)}
</>
);
}
Loading