@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.
Files changed (55) hide show
  1. package/README.md +35 -5
  2. package/dist/__tests__/fixtures/expo-old-package/package-lock.json +5 -0
  3. package/dist/__tests__/fixtures/expo-old-package/package.json +10 -0
  4. package/dist/__tests__/fixtures/expo-old-package/src/App.tsx +14 -0
  5. package/dist/__tests__/fixtures/nextjs-v6/package.json +9 -0
  6. package/dist/__tests__/fixtures/nextjs-v6/pnpm-lock.yaml +2 -0
  7. package/dist/__tests__/fixtures/nextjs-v6/src/app.tsx +17 -0
  8. package/dist/__tests__/fixtures/nextjs-v7/package.json +9 -0
  9. package/dist/__tests__/fixtures/nextjs-v7/pnpm-lock.yaml +2 -0
  10. package/dist/__tests__/fixtures/nextjs-v7/src/app.tsx +16 -0
  11. package/dist/__tests__/fixtures/no-clerk/package.json +7 -0
  12. package/dist/__tests__/fixtures/react-v6/package.json +8 -0
  13. package/dist/__tests__/fixtures/react-v6/src/App.tsx +19 -0
  14. package/dist/__tests__/fixtures/react-v6/yarn.lock +2 -0
  15. package/dist/__tests__/helpers/create-fixture.js +56 -0
  16. package/dist/__tests__/integration/cli.test.js +275 -0
  17. package/dist/__tests__/integration/config.test.js +97 -0
  18. package/dist/__tests__/integration/detect-sdk.test.js +100 -0
  19. package/dist/__tests__/integration/runner.test.js +58 -0
  20. package/dist/cli.js +172 -44
  21. package/dist/codemods/__tests__/__fixtures__/transform-align-experimental-unstable-prefixes.fixtures.js +92 -0
  22. package/dist/codemods/__tests__/__fixtures__/transform-appearance-layout-to-options.fixtures.js +9 -0
  23. package/dist/codemods/__tests__/__fixtures__/transform-clerk-react-v6.fixtures.js +13 -0
  24. package/dist/codemods/__tests__/__fixtures__/transform-remove-deprecated-appearance-props.fixtures.js +63 -0
  25. package/dist/codemods/__tests__/__fixtures__/transform-themes-to-ui-themes.fixtures.js +41 -0
  26. package/dist/codemods/__tests__/transform-align-experimental-unstable-prefixes.test.js +15 -0
  27. package/dist/codemods/__tests__/transform-appearance-layout-to-options.test.js +15 -0
  28. package/dist/codemods/__tests__/transform-remove-deprecated-appearance-props.test.js +15 -0
  29. package/dist/codemods/__tests__/transform-themes-to-ui-themes.test.js +15 -0
  30. package/dist/codemods/index.js +67 -13
  31. package/dist/codemods/transform-align-experimental-unstable-prefixes.cjs +412 -0
  32. package/dist/codemods/transform-appearance-layout-to-options.cjs +65 -0
  33. package/dist/codemods/transform-clerk-react-v6.cjs +15 -7
  34. package/dist/codemods/transform-remove-deprecated-appearance-props.cjs +109 -0
  35. package/dist/codemods/transform-remove-deprecated-props.cjs +11 -32
  36. package/dist/codemods/transform-themes-to-ui-themes.cjs +65 -0
  37. package/dist/config.js +145 -0
  38. package/dist/render.js +170 -0
  39. package/dist/runner.js +98 -0
  40. package/dist/util/detect-sdk.js +125 -0
  41. package/dist/util/package-manager.js +94 -0
  42. package/dist/versions/core-3/changes/clerk-expo-package-rename.md +23 -0
  43. package/dist/versions/core-3/changes/clerk-react-package-rename.md +22 -0
  44. package/dist/versions/core-3/index.js +40 -0
  45. package/package.json +2 -8
  46. package/dist/app.js +0 -177
  47. package/dist/components/Codemod.js +0 -149
  48. package/dist/components/Command.js +0 -56
  49. package/dist/components/Header.js +0 -11
  50. package/dist/components/SDKWorkflow.js +0 -278
  51. package/dist/components/Scan.js +0 -180
  52. package/dist/components/UpgradeSDK.js +0 -116
  53. package/dist/util/expandable-list.js +0 -173
  54. package/dist/util/get-clerk-version.js +0 -22
  55. 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 React from 'react';
5
- import App from './app.js';
6
- import sdks from './constants/sdks.js';
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-upgrade
11
+ $ npx @clerk/upgrade
10
12
 
11
13
  Options
12
- --from Major version number you're upgrading from
13
- --to Major version number you're upgrading to
14
- --sdk Name of the SDK you're upgrading
15
- --dir Directory you'd like to scan for files
16
- --ignore Any files or directories you'd like to ignore
17
- --noWarnings Do not print warnings, only items that must be fixed
18
- --disableTelemetry Do not send anonymous usage telemetry
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-upgrade --sdk=nextjs --dir=src/**
22
- $ clerk-upgrade --ignore=**/public/** --ignore=**/dist/**
23
- $ clerk-upgrade --from=core-1 --to=core-2
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
- from: {
28
- type: 'string'
29
- },
30
- to: {
33
+ sdk: {
31
34
  type: 'string'
32
35
  },
33
- sdk: {
36
+ dir: {
34
37
  type: 'string',
35
- choices: sdks.map(i => i.value)
38
+ default: process.cwd()
36
39
  },
37
- dir: {
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
- yolo: {
45
- type: 'boolean'
48
+ skipUpgrade: {
49
+ type: 'boolean',
50
+ default: false
46
51
  },
47
- noWarnings: {
48
- type: 'boolean'
52
+ release: {
53
+ type: 'string'
54
+ },
55
+ dryRun: {
56
+ type: 'boolean',
57
+ default: false
49
58
  },
50
- disableTelemetry: {
51
- type: 'boolean'
59
+ skipCodemods: {
60
+ type: 'boolean',
61
+ default: false
52
62
  }
53
63
  }
54
64
  });
55
- render(/*#__PURE__*/React.createElement(App, {
56
- dir: cli.flags.dir,
57
- disableTelemetry: cli.flags.disableTelemetry,
58
- fromVersion: cli.flags.from,
59
- ignore: cli.flags.ignore,
60
- noWarnings: cli.flags.noWarnings,
61
- packageManager: cli.flags.packageManager,
62
- sdk: cli.flags.sdk,
63
- toVersion: cli.flags.to,
64
- yolo: cli.flags.yolo
65
- })
66
- // if having issues with errors being swallowed, uncomment this
67
- // { debug: true },
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
+ }];
@@ -0,0 +1,9 @@
1
+ export const fixtures = [{
2
+ name: 'Renames layout inside JSX appearance prop',
3
+ source: `
4
+ <SignIn appearance={{ layout: { socialButtonsPlacement: 'top' } }} />
5
+ `,
6
+ output: `
7
+ <SignIn appearance={{ options: { socialButtonsPlacement: 'top' } }} />
8
+ `
9
+ }];
@@ -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
+ });