@clerk/upgrade 2.0.0-snapshot.v20251204175016 → 2.0.0-snapshot.v20251211120550
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 +35 -5
- package/dist/__tests__/fixtures/expo-old-package/package-lock.json +5 -0
- package/dist/__tests__/fixtures/expo-old-package/package.json +10 -0
- package/dist/__tests__/fixtures/expo-old-package/src/App.tsx +14 -0
- package/dist/__tests__/fixtures/nextjs-v6/package.json +9 -0
- package/dist/__tests__/fixtures/nextjs-v6/pnpm-lock.yaml +2 -0
- package/dist/__tests__/fixtures/nextjs-v6/src/app.tsx +17 -0
- package/dist/__tests__/fixtures/nextjs-v7/package.json +9 -0
- package/dist/__tests__/fixtures/nextjs-v7/pnpm-lock.yaml +2 -0
- package/dist/__tests__/fixtures/nextjs-v7/src/app.tsx +16 -0
- package/dist/__tests__/fixtures/no-clerk/package.json +7 -0
- package/dist/__tests__/fixtures/react-v6/package.json +8 -0
- package/dist/__tests__/fixtures/react-v6/src/App.tsx +19 -0
- package/dist/__tests__/fixtures/react-v6/yarn.lock +2 -0
- package/dist/__tests__/helpers/create-fixture.js +56 -0
- package/dist/__tests__/integration/cli.test.js +275 -0
- package/dist/__tests__/integration/config.test.js +97 -0
- package/dist/__tests__/integration/detect-sdk.test.js +100 -0
- package/dist/__tests__/integration/runner.test.js +58 -0
- package/dist/cli.js +172 -44
- package/dist/codemods/__tests__/__fixtures__/transform-align-experimental-unstable-prefixes.fixtures.js +92 -0
- package/dist/codemods/__tests__/__fixtures__/transform-appearance-layout-to-options.fixtures.js +9 -0
- package/dist/codemods/__tests__/__fixtures__/transform-clerk-react-v6.fixtures.js +13 -0
- package/dist/codemods/__tests__/__fixtures__/transform-remove-deprecated-appearance-props.fixtures.js +63 -0
- package/dist/codemods/__tests__/__fixtures__/transform-themes-to-ui-themes.fixtures.js +41 -0
- package/dist/codemods/__tests__/transform-align-experimental-unstable-prefixes.test.js +15 -0
- package/dist/codemods/__tests__/transform-appearance-layout-to-options.test.js +15 -0
- package/dist/codemods/__tests__/transform-remove-deprecated-appearance-props.test.js +15 -0
- package/dist/codemods/__tests__/transform-themes-to-ui-themes.test.js +15 -0
- package/dist/codemods/index.js +67 -13
- package/dist/codemods/transform-align-experimental-unstable-prefixes.cjs +412 -0
- package/dist/codemods/transform-appearance-layout-to-options.cjs +65 -0
- package/dist/codemods/transform-clerk-react-v6.cjs +15 -7
- package/dist/codemods/transform-remove-deprecated-appearance-props.cjs +109 -0
- package/dist/codemods/transform-remove-deprecated-props.cjs +11 -32
- package/dist/codemods/transform-themes-to-ui-themes.cjs +65 -0
- package/dist/config.js +145 -0
- package/dist/render.js +170 -0
- package/dist/runner.js +98 -0
- package/dist/util/detect-sdk.js +125 -0
- package/dist/util/package-manager.js +94 -0
- package/dist/versions/core-3/changes/clerk-expo-package-rename.md +23 -0
- package/dist/versions/core-3/changes/clerk-react-package-rename.md +22 -0
- package/dist/versions/core-3/index.js +40 -0
- package/package.json +2 -8
- package/dist/app.js +0 -177
- package/dist/components/Codemod.js +0 -149
- package/dist/components/Command.js +0 -56
- package/dist/components/Header.js +0 -11
- package/dist/components/SDKWorkflow.js +0 -278
- package/dist/components/Scan.js +0 -180
- package/dist/components/UpgradeSDK.js +0 -116
- package/dist/util/expandable-list.js +0 -173
- package/dist/util/get-clerk-version.js +0 -22
- package/dist/util/guess-framework.js +0 -69
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { detectSdk, getMajorVersion, getSdkVersion, normalizeSdkName } from '../../util/detect-sdk.js';
|
|
3
|
+
import { detectPackageManager } from '../../util/package-manager.js';
|
|
4
|
+
import { getFixturePath } from '../helpers/create-fixture.js';
|
|
5
|
+
describe('detectSdk', () => {
|
|
6
|
+
it('detects @clerk/nextjs from package.json', () => {
|
|
7
|
+
const sdk = detectSdk(getFixturePath('nextjs-v6'));
|
|
8
|
+
expect(sdk).toBe('nextjs');
|
|
9
|
+
});
|
|
10
|
+
it('detects @clerk/nextjs v7 from package.json', () => {
|
|
11
|
+
const sdk = detectSdk(getFixturePath('nextjs-v7'));
|
|
12
|
+
expect(sdk).toBe('nextjs');
|
|
13
|
+
});
|
|
14
|
+
it('detects @clerk/clerk-react (legacy name) from package.json', () => {
|
|
15
|
+
const sdk = detectSdk(getFixturePath('react-v6'));
|
|
16
|
+
expect(sdk).toBe('react');
|
|
17
|
+
});
|
|
18
|
+
it('detects @clerk/clerk-expo (legacy name) from package.json', () => {
|
|
19
|
+
const sdk = detectSdk(getFixturePath('expo-old-package'));
|
|
20
|
+
expect(sdk).toBe('expo');
|
|
21
|
+
});
|
|
22
|
+
it('returns null when no Clerk SDK is found', () => {
|
|
23
|
+
const sdk = detectSdk(getFixturePath('no-clerk'));
|
|
24
|
+
expect(sdk).toBeNull();
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('getSdkVersion', () => {
|
|
28
|
+
it('returns major version 6 for nextjs-v6 fixture', () => {
|
|
29
|
+
const version = getSdkVersion('nextjs', getFixturePath('nextjs-v6'));
|
|
30
|
+
expect(version).toBe(6);
|
|
31
|
+
});
|
|
32
|
+
it('returns major version 7 for nextjs-v7 fixture', () => {
|
|
33
|
+
const version = getSdkVersion('nextjs', getFixturePath('nextjs-v7'));
|
|
34
|
+
expect(version).toBe(7);
|
|
35
|
+
});
|
|
36
|
+
it('returns major version 5 for clerk-react fixture', () => {
|
|
37
|
+
const version = getSdkVersion('clerk-react', getFixturePath('react-v6'));
|
|
38
|
+
expect(version).toBe(5);
|
|
39
|
+
});
|
|
40
|
+
it('returns major version 2 for clerk-expo fixture', () => {
|
|
41
|
+
const version = getSdkVersion('clerk-expo', getFixturePath('expo-old-package'));
|
|
42
|
+
expect(version).toBe(2);
|
|
43
|
+
});
|
|
44
|
+
it('returns null when SDK is not found', () => {
|
|
45
|
+
const version = getSdkVersion('nextjs', getFixturePath('no-clerk'));
|
|
46
|
+
expect(version).toBeNull();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe('getMajorVersion', () => {
|
|
50
|
+
it('parses ^6.0.0 as version 6', () => {
|
|
51
|
+
expect(getMajorVersion('^6.0.0')).toBe(6);
|
|
52
|
+
});
|
|
53
|
+
it('parses ~7.1.2 as version 7', () => {
|
|
54
|
+
expect(getMajorVersion('~7.1.2')).toBe(7);
|
|
55
|
+
});
|
|
56
|
+
it('parses 5.0.0 as version 5', () => {
|
|
57
|
+
expect(getMajorVersion('5.0.0')).toBe(5);
|
|
58
|
+
});
|
|
59
|
+
it('parses 14.2.3 as version 14', () => {
|
|
60
|
+
expect(getMajorVersion('14.2.3')).toBe(14);
|
|
61
|
+
});
|
|
62
|
+
it('returns null for invalid semver', () => {
|
|
63
|
+
expect(getMajorVersion('invalid')).toBeNull();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('normalizeSdkName', () => {
|
|
67
|
+
it('returns null for null input', () => {
|
|
68
|
+
expect(normalizeSdkName(null)).toBeNull();
|
|
69
|
+
});
|
|
70
|
+
it('strips @clerk/ prefix', () => {
|
|
71
|
+
expect(normalizeSdkName('@clerk/nextjs')).toBe('nextjs');
|
|
72
|
+
});
|
|
73
|
+
it('converts clerk-react to react', () => {
|
|
74
|
+
expect(normalizeSdkName('clerk-react')).toBe('react');
|
|
75
|
+
});
|
|
76
|
+
it('converts clerk-expo to expo', () => {
|
|
77
|
+
expect(normalizeSdkName('clerk-expo')).toBe('expo');
|
|
78
|
+
});
|
|
79
|
+
it('returns name unchanged for standard names', () => {
|
|
80
|
+
expect(normalizeSdkName('nextjs')).toBe('nextjs');
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
describe('detectPackageManager', () => {
|
|
84
|
+
it('detects pnpm from pnpm-lock.yaml', () => {
|
|
85
|
+
const pm = detectPackageManager(getFixturePath('nextjs-v6'));
|
|
86
|
+
expect(pm).toBe('pnpm');
|
|
87
|
+
});
|
|
88
|
+
it('detects yarn from yarn.lock', () => {
|
|
89
|
+
const pm = detectPackageManager(getFixturePath('react-v6'));
|
|
90
|
+
expect(pm).toBe('yarn');
|
|
91
|
+
});
|
|
92
|
+
it('detects npm from package-lock.json', () => {
|
|
93
|
+
const pm = detectPackageManager(getFixturePath('expo-old-package'));
|
|
94
|
+
expect(pm).toBe('npm');
|
|
95
|
+
});
|
|
96
|
+
it('defaults to npm when no lock file exists', () => {
|
|
97
|
+
const pm = detectPackageManager(getFixturePath('no-clerk'));
|
|
98
|
+
expect(pm).toBe('npm');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { loadConfig } from '../../config.js';
|
|
3
|
+
import { runScans } from '../../runner.js';
|
|
4
|
+
import { createTempFixture } from '../helpers/create-fixture.js';
|
|
5
|
+
vi.mock('../../render.js', () => ({
|
|
6
|
+
colors: {
|
|
7
|
+
reset: '',
|
|
8
|
+
bold: '',
|
|
9
|
+
yellow: '',
|
|
10
|
+
gray: ''
|
|
11
|
+
},
|
|
12
|
+
createSpinner: vi.fn(() => ({
|
|
13
|
+
update: vi.fn(),
|
|
14
|
+
stop: vi.fn(),
|
|
15
|
+
success: vi.fn(),
|
|
16
|
+
error: vi.fn()
|
|
17
|
+
})),
|
|
18
|
+
promptText: vi.fn((msg, defaultValue) => defaultValue),
|
|
19
|
+
renderCodemodResults: vi.fn(),
|
|
20
|
+
renderText: vi.fn()
|
|
21
|
+
}));
|
|
22
|
+
describe('runScans', () => {
|
|
23
|
+
let fixture;
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
fixture = createTempFixture('nextjs-v6');
|
|
26
|
+
});
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
fixture?.cleanup();
|
|
29
|
+
});
|
|
30
|
+
it('finds patterns in fixture files', async () => {
|
|
31
|
+
const config = await loadConfig('nextjs', 6);
|
|
32
|
+
const options = {
|
|
33
|
+
dir: fixture.path,
|
|
34
|
+
ignore: []
|
|
35
|
+
};
|
|
36
|
+
const results = await runScans(config, 'nextjs', options);
|
|
37
|
+
expect(results.length).toBeGreaterThan(0);
|
|
38
|
+
});
|
|
39
|
+
it('returns empty array when no matchers match', async () => {
|
|
40
|
+
const config = await loadConfig('nextjs', 6);
|
|
41
|
+
config.changes = [];
|
|
42
|
+
const options = {
|
|
43
|
+
dir: fixture.path,
|
|
44
|
+
ignore: []
|
|
45
|
+
};
|
|
46
|
+
const results = await runScans(config, 'nextjs', options);
|
|
47
|
+
expect(results).toEqual([]);
|
|
48
|
+
});
|
|
49
|
+
it('respects ignore patterns', async () => {
|
|
50
|
+
const config = await loadConfig('nextjs', 6);
|
|
51
|
+
const options = {
|
|
52
|
+
dir: fixture.path,
|
|
53
|
+
ignore: ['**/src/**']
|
|
54
|
+
};
|
|
55
|
+
const results = await runScans(config, 'nextjs', options);
|
|
56
|
+
expect(results).toEqual([]);
|
|
57
|
+
});
|
|
58
|
+
});
|
package/dist/cli.js
CHANGED
|
@@ -1,68 +1,196 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { render } from 'ink';
|
|
3
2
|
import meow from 'meow';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
3
|
+
import { getOldPackageName, getTargetPackageName, loadConfig } from './config.js';
|
|
4
|
+
import { createSpinner, promptConfirm, promptSelect, renderComplete, renderConfig, renderError, renderHeader, renderNewline, renderScanResults, renderSuccess, renderText, renderWarning } from './render.js';
|
|
5
|
+
import { runCodemods, runScans } from './runner.js';
|
|
6
|
+
import { detectSdk, getSdkVersion, getSupportedSdks, normalizeSdkName } from './util/detect-sdk.js';
|
|
7
|
+
import { detectPackageManager, getPackageManagerDisplayName, removePackage, upgradePackage } from './util/package-manager.js';
|
|
8
|
+
const isInteractive = process.stdin.isTTY;
|
|
7
9
|
const cli = meow(`
|
|
8
10
|
Usage
|
|
9
|
-
$ clerk
|
|
11
|
+
$ npx @clerk/upgrade
|
|
10
12
|
|
|
11
13
|
Options
|
|
12
|
-
--
|
|
13
|
-
--to
|
|
14
|
-
--
|
|
15
|
-
--
|
|
16
|
-
--
|
|
17
|
-
--
|
|
18
|
-
--
|
|
14
|
+
--sdk Name of the SDK you're upgrading (e.g., nextjs, react)
|
|
15
|
+
--dir Directory to scan (defaults to current directory)
|
|
16
|
+
--glob Glob pattern for files to transform (defaults to **/*.{js,jsx,ts,tsx,mjs,cjs})
|
|
17
|
+
--ignore Directories/files to ignore (can be used multiple times)
|
|
18
|
+
--skip-upgrade Skip the upgrade step
|
|
19
|
+
--release Name of the release you're upgrading to (e.g. core-3)
|
|
20
|
+
--dry-run Show what would be done without making changes
|
|
19
21
|
|
|
20
22
|
Examples
|
|
21
|
-
$ clerk
|
|
22
|
-
$ clerk
|
|
23
|
-
$ clerk
|
|
24
|
-
|
|
23
|
+
$ npx @clerk/upgrade
|
|
24
|
+
$ npx @clerk/upgrade --sdk=nextjs
|
|
25
|
+
$ npx @clerk/upgrade --dir=./src --ignore=**/test/**
|
|
26
|
+
$ npx @clerk/upgrade --dry-run
|
|
27
|
+
|
|
28
|
+
Non-interactive mode:
|
|
29
|
+
When running in CI or piped environments, --sdk is required if it cannot be auto-detected.
|
|
30
|
+
`, {
|
|
25
31
|
importMeta: import.meta,
|
|
26
32
|
flags: {
|
|
27
|
-
|
|
28
|
-
type: 'string'
|
|
29
|
-
},
|
|
30
|
-
to: {
|
|
33
|
+
sdk: {
|
|
31
34
|
type: 'string'
|
|
32
35
|
},
|
|
33
|
-
|
|
36
|
+
dir: {
|
|
34
37
|
type: 'string',
|
|
35
|
-
|
|
38
|
+
default: process.cwd()
|
|
36
39
|
},
|
|
37
|
-
|
|
38
|
-
type: 'string'
|
|
40
|
+
glob: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
default: '**/*.(js|jsx|ts|tsx|mjs|cjs)'
|
|
39
43
|
},
|
|
40
44
|
ignore: {
|
|
41
45
|
type: 'string',
|
|
42
46
|
isMultiple: true
|
|
43
47
|
},
|
|
44
|
-
|
|
45
|
-
type: 'boolean'
|
|
48
|
+
skipUpgrade: {
|
|
49
|
+
type: 'boolean',
|
|
50
|
+
default: false
|
|
46
51
|
},
|
|
47
|
-
|
|
48
|
-
type: '
|
|
52
|
+
release: {
|
|
53
|
+
type: 'string'
|
|
54
|
+
},
|
|
55
|
+
dryRun: {
|
|
56
|
+
type: 'boolean',
|
|
57
|
+
default: false
|
|
49
58
|
},
|
|
50
|
-
|
|
51
|
-
type: 'boolean'
|
|
59
|
+
skipCodemods: {
|
|
60
|
+
type: 'boolean',
|
|
61
|
+
default: false
|
|
52
62
|
}
|
|
53
63
|
}
|
|
54
64
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
);
|
|
65
|
+
async function main() {
|
|
66
|
+
renderHeader();
|
|
67
|
+
const options = {
|
|
68
|
+
dir: cli.flags.dir,
|
|
69
|
+
glob: cli.flags.glob,
|
|
70
|
+
ignore: cli.flags.ignore,
|
|
71
|
+
skipUpgrade: cli.flags.skipUpgrade,
|
|
72
|
+
release: cli.flags.release,
|
|
73
|
+
dryRun: cli.flags.dryRun,
|
|
74
|
+
skipCodemods: cli.flags.skipCodemods
|
|
75
|
+
};
|
|
76
|
+
if (options.dryRun) {
|
|
77
|
+
renderWarning(' Upgrade running in dry run mode - no changes will be made');
|
|
78
|
+
renderNewline();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Step 1: Detect or prompt for SDK
|
|
82
|
+
let sdk = normalizeSdkName(cli.flags.sdk);
|
|
83
|
+
if (!sdk) {
|
|
84
|
+
sdk = detectSdk(options.dir);
|
|
85
|
+
}
|
|
86
|
+
if (!sdk) {
|
|
87
|
+
if (!isInteractive) {
|
|
88
|
+
renderError('Could not detect Clerk SDK. Please provide --sdk flag in non-interactive mode.');
|
|
89
|
+
renderText('Supported SDKs: ' + getSupportedSdks().map(s => s.value).join(', '));
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const sdkOptions = getSupportedSdks().map(s => ({
|
|
93
|
+
label: s.label,
|
|
94
|
+
value: s.value
|
|
95
|
+
}));
|
|
96
|
+
sdk = await promptSelect('Could not detect Clerk SDK. Please select which SDK you are upgrading:', sdkOptions);
|
|
97
|
+
}
|
|
98
|
+
if (!sdk) {
|
|
99
|
+
renderError('No SDK selected. Exiting.');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Step 2: Get current version and detect package manager
|
|
104
|
+
const currentVersion = getSdkVersion(sdk, options.dir);
|
|
105
|
+
const packageManager = detectPackageManager(options.dir);
|
|
106
|
+
|
|
107
|
+
// Step 3: Load version config
|
|
108
|
+
const config = await loadConfig(sdk, currentVersion, options.release);
|
|
109
|
+
if (!config) {
|
|
110
|
+
renderError(`No upgrade path found for @clerk/${sdk}. Your version may be too old for this upgrade tool.`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Step 4: Display configuration
|
|
115
|
+
renderConfig({
|
|
116
|
+
sdk,
|
|
117
|
+
currentVersion,
|
|
118
|
+
fromVersion: config.sdkVersions?.[sdk]?.from,
|
|
119
|
+
toVersion: config.sdkVersions?.[sdk]?.to,
|
|
120
|
+
versionName: config.name,
|
|
121
|
+
dir: options.dir,
|
|
122
|
+
packageManager: getPackageManagerDisplayName(packageManager)
|
|
123
|
+
});
|
|
124
|
+
if (isInteractive && !(await promptConfirm('Ready to upgrade?', true))) {
|
|
125
|
+
renderError('Upgrade cancelled. Exiting...');
|
|
126
|
+
process.exit(0);
|
|
127
|
+
}
|
|
128
|
+
console.log('');
|
|
129
|
+
|
|
130
|
+
// Step 5: Handle upgrade status
|
|
131
|
+
if (options.skipUpgrade) {
|
|
132
|
+
renderText('Skipping package upgrade (--skip-upgrade flag)', 'yellow');
|
|
133
|
+
renderNewline();
|
|
134
|
+
} else if (config.alreadyUpgraded) {
|
|
135
|
+
renderSuccess(`You're already on the latest major version of @clerk/${sdk}`);
|
|
136
|
+
} else if (config.needsUpgrade) {
|
|
137
|
+
await performUpgrade(sdk, packageManager, config, options);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Step 6: Run codemods
|
|
141
|
+
if (config.codemods?.length > 0) {
|
|
142
|
+
renderText(`Running ${config.codemods.length} codemod(s)...`, 'blue');
|
|
143
|
+
await runCodemods(config, sdk, options);
|
|
144
|
+
renderSuccess('All codemods applied');
|
|
145
|
+
renderNewline();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Step 7: Run scans
|
|
149
|
+
if (config.changes?.length > 0) {
|
|
150
|
+
renderText('Scanning for additional breaking changes...', 'blue');
|
|
151
|
+
const results = await runScans(config, sdk, options);
|
|
152
|
+
renderScanResults(results, config.docsUrl);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Step 8: Done
|
|
156
|
+
renderComplete(sdk, config.docsUrl);
|
|
157
|
+
}
|
|
158
|
+
async function performUpgrade(sdk, packageManager, config, options) {
|
|
159
|
+
const targetPackage = getTargetPackageName(sdk);
|
|
160
|
+
const oldPackage = getOldPackageName(sdk);
|
|
161
|
+
const targetVersion = config.sdkVersions?.[sdk]?.to;
|
|
162
|
+
if (options.dryRun) {
|
|
163
|
+
renderText(`[dry run] Would upgrade ${targetPackage} to version ${targetVersion}`, 'yellow');
|
|
164
|
+
if (oldPackage) {
|
|
165
|
+
renderText(`[dry run] Would remove old package ${oldPackage}`, 'yellow');
|
|
166
|
+
}
|
|
167
|
+
renderNewline();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Remove old package if this is a rename (clerk-react -> react, clerk-expo -> expo)
|
|
172
|
+
if (oldPackage) {
|
|
173
|
+
const removeSpinner = createSpinner(`Removing ${oldPackage}...`);
|
|
174
|
+
try {
|
|
175
|
+
await removePackage(packageManager, oldPackage, options.dir);
|
|
176
|
+
removeSpinner.success(`Removed ${oldPackage}`);
|
|
177
|
+
} catch {
|
|
178
|
+
removeSpinner.error(`Failed to remove ${oldPackage}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Upgrade to the new version
|
|
183
|
+
const spinner = createSpinner(`Upgrading ${targetPackage} to version ${targetVersion}...`);
|
|
184
|
+
try {
|
|
185
|
+
await upgradePackage(packageManager, targetPackage, targetVersion, options.dir);
|
|
186
|
+
spinner.success(`Upgraded ${targetPackage} to version ${targetVersion}`);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
spinner.error(`Failed to upgrade ${targetPackage}`);
|
|
189
|
+
renderError(error.message);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
main().catch(error => {
|
|
194
|
+
renderError(error.message);
|
|
195
|
+
process.exit(1);
|
|
196
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export const fixtures = [{
|
|
2
|
+
name: 'Renames unstable hooks and handlers to internal',
|
|
3
|
+
source: `
|
|
4
|
+
const clerk = useClerk();
|
|
5
|
+
clerk.__unstable__updateProps({});
|
|
6
|
+
window.__unstable__onAfterSetActive = () => {};
|
|
7
|
+
const opts = { __unstable_invokeMiddlewareOnAuthStateChange: true };
|
|
8
|
+
const handler = client['__unstable__onAfterResponse'];
|
|
9
|
+
`,
|
|
10
|
+
output: `
|
|
11
|
+
const clerk = useClerk();
|
|
12
|
+
clerk.__internal_updateProps({});
|
|
13
|
+
window.__internal_onAfterSetActive = () => {};
|
|
14
|
+
const opts = { __internal_invokeMiddlewareOnAuthStateChange: true };
|
|
15
|
+
const handler = client["__internal_onAfterResponse"];
|
|
16
|
+
`
|
|
17
|
+
}, {
|
|
18
|
+
name: 'Moves UI theme helpers to experimental path and renames identifiers',
|
|
19
|
+
source: `
|
|
20
|
+
import { __experimental_createTheme, experimental__simple, Button } from '@clerk/ui';
|
|
21
|
+
|
|
22
|
+
const theme = __experimental_createTheme();
|
|
23
|
+
const kind = experimental__simple;
|
|
24
|
+
`,
|
|
25
|
+
output: `
|
|
26
|
+
import { Button } from '@clerk/ui';
|
|
27
|
+
|
|
28
|
+
import { createTheme, simple } from "@clerk/ui/themes/experimental";
|
|
29
|
+
|
|
30
|
+
const theme = createTheme();
|
|
31
|
+
const kind = simple;
|
|
32
|
+
`
|
|
33
|
+
}, {
|
|
34
|
+
name: 'Moves UI theme helpers required from root to experimental path',
|
|
35
|
+
source: `
|
|
36
|
+
const { __experimental_createTheme, experimental__simple, Card } = require('@clerk/ui');
|
|
37
|
+
`,
|
|
38
|
+
output: `
|
|
39
|
+
const {
|
|
40
|
+
Card
|
|
41
|
+
} = require('@clerk/ui');
|
|
42
|
+
|
|
43
|
+
const {
|
|
44
|
+
createTheme,
|
|
45
|
+
simple
|
|
46
|
+
} = require("@clerk/ui/themes/experimental");
|
|
47
|
+
`
|
|
48
|
+
}, {
|
|
49
|
+
name: 'Moves chrome extension client creation to background path',
|
|
50
|
+
source: `
|
|
51
|
+
import { __unstable__createClerkClient } from '@clerk/chrome-extension';
|
|
52
|
+
|
|
53
|
+
__unstable__createClerkClient();
|
|
54
|
+
`,
|
|
55
|
+
output: `
|
|
56
|
+
import { createClerkClient } from "@clerk/chrome-extension/background";
|
|
57
|
+
|
|
58
|
+
createClerkClient();
|
|
59
|
+
`
|
|
60
|
+
}, {
|
|
61
|
+
name: 'Removes deprecated billing props from JSX',
|
|
62
|
+
source: `
|
|
63
|
+
<OrganizationProfile __unstable_manageBillingUrl="url" experimental__forceOauthFirst />;
|
|
64
|
+
`,
|
|
65
|
+
output: `
|
|
66
|
+
<OrganizationProfile />;
|
|
67
|
+
`
|
|
68
|
+
}, {
|
|
69
|
+
name: 'Does not rename class constructors',
|
|
70
|
+
source: `
|
|
71
|
+
export class AppError extends Error {
|
|
72
|
+
constructor(
|
|
73
|
+
message: string,
|
|
74
|
+
public readonly code: string,
|
|
75
|
+
public readonly statusCode: number = 500
|
|
76
|
+
) {
|
|
77
|
+
super(message);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
`,
|
|
81
|
+
output: `
|
|
82
|
+
export class AppError extends Error {
|
|
83
|
+
constructor(
|
|
84
|
+
message: string,
|
|
85
|
+
public readonly code: string,
|
|
86
|
+
public readonly statusCode: number = 500
|
|
87
|
+
) {
|
|
88
|
+
super(message);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
`
|
|
92
|
+
}];
|
|
@@ -104,4 +104,17 @@ const clerk = require("@clerk/clerk-react")
|
|
|
104
104
|
output: `
|
|
105
105
|
const clerk = require("@clerk/react")
|
|
106
106
|
`
|
|
107
|
+
}, {
|
|
108
|
+
name: 'Handles directives with mixed legacy imports without double semicolons',
|
|
109
|
+
source: `"use client";
|
|
110
|
+
|
|
111
|
+
import { ClerkProvider, useSignIn, useSignUp } from "@clerk/nextjs";
|
|
112
|
+
|
|
113
|
+
export const dynamic = "force-dynamic";
|
|
114
|
+
`,
|
|
115
|
+
output: `"use client";
|
|
116
|
+
import { ClerkProvider } from "@clerk/nextjs";
|
|
117
|
+
import { useSignIn, useSignUp } from "@clerk/nextjs/legacy";
|
|
118
|
+
|
|
119
|
+
export const dynamic = "force-dynamic";`
|
|
107
120
|
}];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export const fixtures = [{
|
|
2
|
+
name: 'Renames baseTheme to theme in JSX appearance',
|
|
3
|
+
source: `
|
|
4
|
+
<SignIn appearance={{ baseTheme: dark }} />
|
|
5
|
+
`,
|
|
6
|
+
output: `
|
|
7
|
+
<SignIn appearance={{ theme: dark }} />
|
|
8
|
+
`
|
|
9
|
+
}, {
|
|
10
|
+
name: 'Renames baseTheme and variable keys when appearance object is referenced',
|
|
11
|
+
source: `
|
|
12
|
+
const appearance = {
|
|
13
|
+
baseTheme: [dark, light],
|
|
14
|
+
variables: {
|
|
15
|
+
colorText: '#000',
|
|
16
|
+
colorTextSecondary: '#111',
|
|
17
|
+
colorInputText: '#222',
|
|
18
|
+
colorInputBackground: '#333',
|
|
19
|
+
colorTextOnPrimaryBackground: '#444',
|
|
20
|
+
spacingUnit: '1rem',
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
<SignUp appearance={appearance} />
|
|
25
|
+
`,
|
|
26
|
+
output: `
|
|
27
|
+
const appearance = {
|
|
28
|
+
theme: [dark, light],
|
|
29
|
+
variables: {
|
|
30
|
+
colorForeground: '#000',
|
|
31
|
+
colorMutedForeground: '#111',
|
|
32
|
+
colorInputForeground: '#222',
|
|
33
|
+
colorInput: '#333',
|
|
34
|
+
colorPrimaryForeground: '#444',
|
|
35
|
+
spacing: '1rem',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
<SignUp appearance={appearance} />
|
|
40
|
+
`
|
|
41
|
+
}, {
|
|
42
|
+
name: 'Handles string literal keys',
|
|
43
|
+
source: `
|
|
44
|
+
const appearance = {
|
|
45
|
+
'baseTheme': dark,
|
|
46
|
+
variables: {
|
|
47
|
+
'colorText': '#000',
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
<SignIn appearance={appearance} />
|
|
52
|
+
`,
|
|
53
|
+
output: `
|
|
54
|
+
const appearance = {
|
|
55
|
+
"theme": dark,
|
|
56
|
+
variables: {
|
|
57
|
+
"colorForeground": '#000',
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
<SignIn appearance={appearance} />
|
|
62
|
+
`
|
|
63
|
+
}];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export const fixtures = [{
|
|
2
|
+
name: 'Renames root import',
|
|
3
|
+
source: `
|
|
4
|
+
import { dark, light } from '@clerk/themes';
|
|
5
|
+
`,
|
|
6
|
+
output: `
|
|
7
|
+
import { dark, light } from "@clerk/ui/themes";
|
|
8
|
+
`
|
|
9
|
+
}, {
|
|
10
|
+
name: 'Renames subpath import',
|
|
11
|
+
source: `
|
|
12
|
+
import palette from '@clerk/themes/palette';
|
|
13
|
+
`,
|
|
14
|
+
output: `
|
|
15
|
+
import palette from "@clerk/ui/themes/palette";
|
|
16
|
+
`
|
|
17
|
+
}, {
|
|
18
|
+
name: 'Renames require call',
|
|
19
|
+
source: `
|
|
20
|
+
const themes = require('@clerk/themes');
|
|
21
|
+
`,
|
|
22
|
+
output: `
|
|
23
|
+
const themes = require("@clerk/ui/themes");
|
|
24
|
+
`
|
|
25
|
+
}, {
|
|
26
|
+
name: 'Renames dynamic import',
|
|
27
|
+
source: `
|
|
28
|
+
const mod = await import('@clerk/themes/foo');
|
|
29
|
+
`,
|
|
30
|
+
output: `
|
|
31
|
+
const mod = await import("@clerk/ui/themes/foo");
|
|
32
|
+
`
|
|
33
|
+
}, {
|
|
34
|
+
name: 'Renames export source',
|
|
35
|
+
source: `
|
|
36
|
+
export * from '@clerk/themes';
|
|
37
|
+
`,
|
|
38
|
+
output: `
|
|
39
|
+
export * from "@clerk/ui/themes";
|
|
40
|
+
`
|
|
41
|
+
}];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { applyTransform } from 'jscodeshift/dist/testUtils';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import transformer from '../transform-align-experimental-unstable-prefixes.cjs';
|
|
4
|
+
import { fixtures } from './__fixtures__/transform-align-experimental-unstable-prefixes.fixtures';
|
|
5
|
+
describe('transform-align-experimental-unstable-prefixes', () => {
|
|
6
|
+
it.each(fixtures)('$name', ({
|
|
7
|
+
source,
|
|
8
|
+
output
|
|
9
|
+
}) => {
|
|
10
|
+
const result = applyTransform(transformer, {}, {
|
|
11
|
+
source
|
|
12
|
+
}) || source.trim();
|
|
13
|
+
expect(result).toEqual(output.trim());
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { applyTransform } from 'jscodeshift/dist/testUtils';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import transformer from '../transform-appearance-layout-to-options.cjs';
|
|
4
|
+
import { fixtures } from './__fixtures__/transform-appearance-layout-to-options.fixtures';
|
|
5
|
+
describe('transform-appearance-layout-to-options', () => {
|
|
6
|
+
it.each(fixtures)('$name', ({
|
|
7
|
+
source,
|
|
8
|
+
output
|
|
9
|
+
}) => {
|
|
10
|
+
const result = applyTransform(transformer, {}, {
|
|
11
|
+
source
|
|
12
|
+
});
|
|
13
|
+
expect(result).toEqual(output.trim());
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { applyTransform } from 'jscodeshift/dist/testUtils';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import transformer from '../transform-remove-deprecated-appearance-props.cjs';
|
|
4
|
+
import { fixtures } from './__fixtures__/transform-remove-deprecated-appearance-props.fixtures';
|
|
5
|
+
describe('transform-remove-deprecated-appearance-props', () => {
|
|
6
|
+
it.each(fixtures)('$name', ({
|
|
7
|
+
source,
|
|
8
|
+
output
|
|
9
|
+
}) => {
|
|
10
|
+
const result = applyTransform(transformer, {}, {
|
|
11
|
+
source
|
|
12
|
+
});
|
|
13
|
+
expect(result).toEqual(output.trim());
|
|
14
|
+
});
|
|
15
|
+
});
|