@clerk/upgrade 0.1.1 → 0.2.1

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 (132) hide show
  1. package/dist/app.js +20 -12
  2. package/dist/cli.js +13 -8
  3. package/dist/scan.js +61 -18
  4. package/dist/util/expandable-list.js +5 -4
  5. package/dist/util/generate-changelog.js +1 -1
  6. package/dist/util/generate-export-change.js +0 -3
  7. package/dist/util/guess-framework.js +47 -11
  8. package/dist/util/load-change.js +1 -1
  9. package/dist/versions/v5/backend/api-url-value-changed.md +1 -0
  10. package/dist/versions/v5/backend/clerk-import.md +2 -2
  11. package/dist/versions/v5/backend/createclerkclient-frontendapi.md +1 -1
  12. package/dist/versions/v5/backend/pkgversion.md +3 -3
  13. package/dist/versions/v5/common/afterswitchorganizationurl.md +3 -6
  14. package/dist/versions/v5/common/getorganizationinvitationlist-return-type-change.md +14 -0
  15. package/dist/versions/v5/common/getorganizationlist-return-type-change.md +14 -0
  16. package/dist/versions/v5/common/getorganizationmembershiplist-return-type-change.md +14 -0
  17. package/dist/versions/v5/common/getroles-pagination.md +15 -0
  18. package/dist/versions/v5/common/handlemagiclinkverification.md +1 -1
  19. package/dist/versions/v5/common/min-react-version.md +6 -0
  20. package/dist/versions/v5/common/navigate-to-routerpush-routerreplace.md +8 -6
  21. package/dist/versions/v5/common/organization-getdomains-arguments-change.md +1 -6
  22. package/dist/versions/v5/common/organization-getinvitations-arguments-changed.md +15 -0
  23. package/dist/versions/v5/common/organization-getmembershiprequests-arguments-changed.md +1 -6
  24. package/dist/versions/v5/common/organization-getmemberships-arguments-changed.md +15 -0
  25. package/dist/versions/v5/common/organization-getroles-arguments-changed.md +1 -6
  26. package/dist/versions/v5/common/setsession.md +1 -0
  27. package/dist/versions/v5/common/usemagiclink.md +1 -1
  28. package/dist/versions/v5/common/user-getorganizationinvitations-arguments-chanaged.md +15 -0
  29. package/dist/versions/v5/common/user-getorganizationmemberships-arguments-chanaged.md +15 -0
  30. package/dist/versions/v5/common/user-getorganizationsuggestions-arguments-chanaged.md +15 -0
  31. package/dist/versions/v5/common/userprofile-prop.md +6 -1
  32. package/dist/versions/v5/expo/clerkprovider-frontendapi.md +4 -7
  33. package/dist/versions/v5/fastify/api-url-value-change.md +3 -1
  34. package/dist/versions/v5/fastify/clerk-import-change.md +12 -0
  35. package/dist/versions/v5/fastify/clerkplugin-frontendapi.md +3 -6
  36. package/dist/versions/v5/fastify/createclerkclient-apikey.md +4 -7
  37. package/dist/versions/v5/fastify/createclerkclient-frontendapi.md +4 -7
  38. package/dist/versions/v5/gatsby/api-url-value-change.md +3 -1
  39. package/dist/versions/v5/gatsby/clerk-import-change.md +12 -0
  40. package/dist/versions/v5/gatsby/createclerkclient-apikey.md +4 -7
  41. package/dist/versions/v5/gatsby/createclerkclient-frontendapi.md +4 -7
  42. package/dist/versions/v5/index.js +8 -8
  43. package/dist/versions/v5/js/organization-create-string.md +3 -6
  44. package/dist/versions/v5/js/organization-getdomains-arguments-change.md +1 -6
  45. package/dist/versions/v5/js/organization-getinvitations-arguments-changed.md +1 -6
  46. package/dist/versions/v5/js/organization-getmembershiprequests-arguments-changed.md +1 -6
  47. package/dist/versions/v5/js/organization-getmemberships-arguments-changed.md +1 -6
  48. package/dist/versions/v5/js/organization-getpendinginvitations.md +3 -6
  49. package/dist/versions/v5/js/organization-getroles-arguments-changed.md +1 -6
  50. package/dist/versions/v5/js/redirecttohome.md +1 -1
  51. package/dist/versions/v5/js/router-navigate-push-replace.md +18 -0
  52. package/dist/versions/v5/js/signup-attemptweb3walletverification-generatedsignature.md +2 -1
  53. package/dist/versions/v5/js/user-createexternalaccount-redirecturl.md +1 -1
  54. package/dist/versions/v5/js/user-getorganizationinvitations-arguments-chanaged.md +1 -6
  55. package/dist/versions/v5/js/user-getorganizationmemberships-arguments-chanaged.md +1 -6
  56. package/dist/versions/v5/js/user-getorganizationsuggestions-arguments-chanaged.md +1 -6
  57. package/dist/versions/v5/js/user-update-password.md +1 -1
  58. package/dist/versions/v5/next/api-url-value-change.md +1 -0
  59. package/dist/versions/v5/next/authmiddleware-frontendapi.md +7 -2
  60. package/dist/versions/v5/next/constants-import-change.md +1 -1
  61. package/dist/versions/v5/next/createclerkclient-apikey.md +3 -6
  62. package/dist/versions/v5/next/createclerkclient-frontendapi.md +3 -6
  63. package/dist/versions/v5/next/getauth-apikey.md +5 -2
  64. package/dist/versions/v5/next/import-nextjs-api.md +0 -2
  65. package/dist/versions/v5/next/redirect-import-change.md +1 -1
  66. package/dist/versions/v5/next/redirecttosignin-import-path.md +12 -0
  67. package/dist/versions/v5/next/redirecttosignin-removed.md +6 -0
  68. package/dist/versions/v5/next/redirecttosignup-import-path.md +12 -0
  69. package/dist/versions/v5/next/redirecttosignup-removed.md +6 -0
  70. package/dist/versions/v5/next/with-clerk-middleware-removed.md +2 -2
  71. package/dist/versions/v5/node/api-url-value-change.md +4 -2
  72. package/dist/versions/v5/node/cjs-esm-instance.md +6 -9
  73. package/dist/versions/v5/node/clerk-import-change.md +12 -0
  74. package/dist/versions/v5/node/clerkexpressrequireauth-apikey.md +4 -7
  75. package/dist/versions/v5/node/clerkexpressrequireauth-frontendapi.md +4 -7
  76. package/dist/versions/v5/node/clerkexpresswithauth-apikey.md +4 -7
  77. package/dist/versions/v5/node/clerkexpresswithauth-frontendapi.md +4 -7
  78. package/dist/versions/v5/node/createclerkclient-apikey.md +4 -7
  79. package/dist/versions/v5/node/createclerkclient-frontendapi.md +4 -7
  80. package/dist/versions/v5/node/createclerkexpressrequireauth-apikey.md +4 -7
  81. package/dist/versions/v5/node/createclerkexpressrequireauth-frontendapi.md +4 -7
  82. package/dist/versions/v5/node/createclerkexpresswithauth-apikey.md +4 -7
  83. package/dist/versions/v5/node/createclerkexpresswithauth-frontendapi.md +4 -7
  84. package/dist/versions/v5/node/legacyauthobject-removed.md +6 -6
  85. package/dist/versions/v5/node/setclerkapikey.md +4 -6
  86. package/dist/versions/v5/node/setclerkapiversion.md +4 -6
  87. package/dist/versions/v5/node/setclerkhttpoptions.md +4 -6
  88. package/dist/versions/v5/node/setclerkserverapiurl.md +7 -9
  89. package/dist/versions/v5/react/api-url-value-change.md +3 -1
  90. package/dist/versions/v5/remix/clerk-import-change.md +12 -0
  91. package/dist/versions/v5/remix/clerkerrorboundary-removed.md +1 -0
  92. package/package.json +52 -61
  93. package/dist/test.js +0 -100
  94. package/dist/util/test.js +0 -100
  95. package/dist/versions/v5/backend/return-signature-change.md +0 -14
  96. package/dist/versions/v5/common/aftersigninouturl-behavior-change.md +0 -7
  97. package/dist/versions/v5/common/aftersigninurl-behavior-change +0 -7
  98. package/dist/versions/v5/common/aftersigninurl-behavior-change.md +0 -7
  99. package/dist/versions/v5/common/clerkprovider-frontendapi.md +0 -7
  100. package/dist/versions/v5/common/external-account-avatarurl.md +0 -7
  101. package/dist/versions/v5/common/multi-session-ui-changes.md +0 -0
  102. package/dist/versions/v5/common/organization-getroles-return-type.md +0 -0
  103. package/dist/versions/v5/common/organizationprofile-general.md +0 -0
  104. package/dist/versions/v5/common/userbuttonpopoveractionbuttontext.md +0 -7
  105. package/dist/versions/v5/common/withuser-removed.md +0 -16
  106. package/dist/versions/v5/js/aftersigninout-behavior-change.md +0 -7
  107. package/dist/versions/v5/js/aftersigninouturl-behavior-change.md +0 -7
  108. package/dist/versions/v5/js/aftersigninurl-behavior-change.md +0 -0
  109. package/dist/versions/v5/js/afterswitchorganizationurl.md +0 -15
  110. package/dist/versions/v5/js/appearance-organizationpreview-organizationswitcher.md +0 -8
  111. package/dist/versions/v5/js/useorganization-invitationlist.md +0 -25
  112. package/dist/versions/v5/js/useorganization-membershiplist.md +0 -24
  113. package/dist/versions/v5/js/useorganizations.md +0 -26
  114. package/dist/versions/v5/js/user-getorganizationmemberships-arguments-chanaged +0 -0
  115. package/dist/versions/v5/js/userprofile-prop.md +0 -7
  116. package/dist/versions/v5/next/verify +0 -0
  117. package/dist/versions/v5/next/withclerk-removed.md +0 -15
  118. package/dist/versions/v5/next/withsession-removed.md +0 -15
  119. package/dist/versions/v5/next/withuser-removed.md +0 -0
  120. package/dist/versions/v5/node/package-rename.md +0 -6
  121. package/dist/versions/v5/react/afterswitchorganizationurl.md +0 -15
  122. package/dist/versions/v5/react/appearance-organizationpreview-organizationswitcher.md +0 -8
  123. package/dist/versions/v5/react/signoutcallback-to- +0 -0
  124. package/dist/versions/v5/react/signoutcallback-to-redirecturl.md +0 -22
  125. package/dist/versions/v5/react/useorganization-invitationlist.md +0 -25
  126. package/dist/versions/v5/react/useorganization-membershiplist.md +0 -24
  127. package/dist/versions/v5/react/useorganizations.md +0 -26
  128. package/dist/versions/v5/react/userprofile-prop.md +0 -7
  129. package/dist/versions/v5/remix/clerkprovider-frontendapi.md +0 -0
  130. package/dist/versions/v5/shared/buildrequesturl.md +0 -12
  131. /package/dist/versions/v5/backend/{signjwt-import-path-move → clerkoptions-type.md} +0 -0
  132. /package/dist/versions/v5/backend/{decodeJwt-import-path-move.md → decodejwt-import-path-move.md} +0 -0
package/dist/app.js CHANGED
@@ -1,13 +1,12 @@
1
+ import { MultiSelect, Select, TextInput } from '@inkjs/ui';
2
+ import { Newline, Text } from 'ink';
3
+ import BigText from 'ink-big-text';
4
+ import Gradient from 'ink-gradient';
1
5
  import React, { useState } from 'react';
2
- import { Text, Newline } from 'ink';
3
- import { Select, MultiSelect, TextInput } from '@inkjs/ui';
4
6
  import SDKS from './constants/sdks.js';
5
- import VERSIONS from './constants/versions.js';
6
7
  import Scan from './scan.js';
7
- import guessFrameworks from './util/guess-framework.js';
8
8
  import getClerkMajorVersion from './util/get-clerk-version.js';
9
- import Gradient from 'ink-gradient';
10
- import BigText from 'ink-big-text';
9
+ import guessFrameworks from './util/guess-framework.js';
11
10
  export default function App({
12
11
  _fromVersion,
13
12
  _toVersion,
@@ -15,7 +14,8 @@ export default function App({
15
14
  _dir = false,
16
15
  _ignore = [],
17
16
  _yolo = false,
18
- noWarnings = false
17
+ noWarnings = false,
18
+ disableTelemetry = false
19
19
  }) {
20
20
  const [yolo, setYolo] = useState(_yolo);
21
21
  const [sdks, setSdks] = useState(_sdk ? [_sdk] : []);
@@ -23,12 +23,13 @@ export default function App({
23
23
  const [sdkGuessConfirmed, setSdkGuessConfirmed] = useState(false);
24
24
  const [sdkGuessAttempted, setSdkGuessAttempted] = useState(false);
25
25
  const [fromVersion, setFromVersion] = useState(_fromVersion);
26
- const [fromVersionGuessAttempted, fromVersionSdkGuessAttempted] = useState(false);
26
+ const [fromVersionGuessAttempted, setFromVersionGuessAttempted] = useState(false);
27
27
  const [toVersion, setToVersion] = useState(_toVersion);
28
28
  const [dir, setDir] = useState(_dir);
29
29
  const [ignore, setIgnore] = useState(_ignore);
30
30
  const [configComplete, setConfigComplete] = useState(false);
31
31
  const [configVerified, setConfigVerified] = useState(false);
32
+ const [uuid, setUuid] = useState();
32
33
  let fromVersionGuess = false;
33
34
  if (yolo) {
34
35
  setSdks(SDKS.map(s => s.value));
@@ -38,7 +39,12 @@ export default function App({
38
39
  // We try to guess which SDK they are using
39
40
  if (isEmpty(sdks) && isEmpty(sdkGuesses) && !sdkGuessAttempted) {
40
41
  if (!dir) return setDir(process.cwd());
41
- setSdkGuesses(guessFrameworks(dir)); // this is the suspect line
42
+ const {
43
+ guesses,
44
+ _uuid
45
+ } = guessFrameworks(dir, disableTelemetry);
46
+ setUuid(_uuid);
47
+ setSdkGuesses(guesses);
42
48
  setSdkGuessAttempted(true);
43
49
  }
44
50
 
@@ -128,14 +134,16 @@ export default function App({
128
134
  setConfigVerified(true);
129
135
  }
130
136
  }
131
- })), configVerified && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Scan, {
137
+ })), configVerified && /*#__PURE__*/React.createElement(Scan, {
132
138
  fromVersion,
133
139
  toVersion,
134
140
  sdks,
135
141
  dir,
136
142
  ignore,
137
- noWarnings
138
- })));
143
+ noWarnings,
144
+ uuid,
145
+ disableTelemetry
146
+ }));
139
147
  }
140
148
 
141
149
  // small util to make the logic blocks easier to visually parse
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import React from 'react';
3
2
  import { render } from 'ink';
4
3
  import meow from 'meow';
4
+ import React from 'react';
5
5
  import App from './app.js';
6
6
  import sdks from './constants/sdks.js';
7
7
  const cli = meow(`
@@ -9,12 +9,13 @@ const cli = meow(`
9
9
  $ clerk-upgrade
10
10
 
11
11
  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
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
18
19
 
19
20
  Examples
20
21
  $ clerk-upgrade --sdk=nextjs --dir=src/**
@@ -45,6 +46,9 @@ const cli = meow(`
45
46
  },
46
47
  noWarnings: {
47
48
  type: 'boolean'
49
+ },
50
+ disableTelemetry: {
51
+ type: 'boolean'
48
52
  }
49
53
  }
50
54
  });
@@ -54,7 +58,8 @@ render( /*#__PURE__*/React.createElement(App, {
54
58
  _sdk: cli.flags.sdk,
55
59
  _dir: cli.flags.dir,
56
60
  _yolo: cli.flags.yolo,
57
- noWarnings: cli.flags.noWarnings
61
+ noWarnings: cli.flags.noWarnings,
62
+ disableTelemetry: cli.flags.disableTelemetry
58
63
  })
59
64
  // { debug: true }, if having issues with errors being swallowed, uncomment this
60
65
  );
package/dist/scan.js CHANGED
@@ -1,10 +1,10 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { Text, Newline, Box } from 'ink';
3
- import { globby } from 'globby';
4
- import fs from 'fs/promises';
5
- import path from 'path';
6
1
  import { ProgressBar } from '@inkjs/ui';
2
+ import fs from 'fs/promises';
3
+ import { globby } from 'globby';
7
4
  import indexToPosition from 'index-to-position';
5
+ import { Newline, Text } from 'ink';
6
+ import path from 'path';
7
+ import React, { useEffect, useState } from 'react';
8
8
  import ExpandableList from './util/expandable-list.js';
9
9
  export default function Scan({
10
10
  fromVersion,
@@ -12,7 +12,9 @@ export default function Scan({
12
12
  sdks,
13
13
  dir,
14
14
  ignore,
15
- noWarnings
15
+ noWarnings,
16
+ uuid,
17
+ disableTelemetry
16
18
  }) {
17
19
  // NOTE: if the difference between fromVersion and toVersion is greater than 1
18
20
  // we need to do a little extra work here and import two matchers,
@@ -40,7 +42,7 @@ export default function Scan({
40
42
  return m;
41
43
  }, {}));
42
44
  });
43
- }, [toVersion]);
45
+ }, [toVersion, sdks]);
44
46
 
45
47
  // Get all files from the glob matcher
46
48
  // -----------------------------------
@@ -62,7 +64,6 @@ export default function Scan({
62
64
  // Read files and scan regexes
63
65
  // ---------------------------
64
66
  // result = `results` set to format
65
- //
66
67
  useEffect(() => {
67
68
  if (!matchers || !files) return;
68
69
  const allResults = {};
@@ -87,21 +88,28 @@ export default function Scan({
87
88
  }
88
89
  if (matches.length < 1) return;
89
90
 
90
- // for each match, add to `instances` array of a key, create if not exists
91
+ // for each match, add to `instances` array
91
92
  matches.map(match => {
92
93
  if (noWarnings && matcherConfig.warning) return;
94
+
95
+ // create if not exists
93
96
  if (!allResults[matcherConfig.title]) allResults[matcherConfig.title] = {
94
97
  instances: [],
95
98
  ...matcherConfig
96
99
  };
100
+ const position = indexToPosition(content, match.index, {
101
+ oneBased: true
102
+ });
103
+ const fileRelative = path.relative(process.cwd(), file);
97
104
 
98
- // TODO: there's a small bug where we can see multiple instances of the same position
105
+ // when scanning for multiple SDKs, you can get a double match, this logic ensures you don't
106
+ if (allResults[matcherConfig.title].instances.filter(i => {
107
+ return i.position.line === position.line && i.position.column === position.column && i.file === fileRelative;
108
+ }).length > 0) return;
99
109
  allResults[matcherConfig.title].instances.push({
100
110
  sdk,
101
- file: path.relative(process.cwd(), file),
102
- position: indexToPosition(content, match.index, {
103
- oneBased: true
104
- })
111
+ position,
112
+ file: fileRelative
105
113
  });
106
114
  });
107
115
  });
@@ -109,7 +117,42 @@ export default function Scan({
109
117
  setStatus(`Scanning ${file}`);
110
118
  setProgress(Math.ceil(idx / files.length * 100));
111
119
  })).then(() => {
112
- setResults([...results, ...Object.keys(allResults).map(k => allResults[k])]);
120
+ const newResults = [...results, ...Object.keys(allResults).map(k => allResults[k])];
121
+ setResults(newResults);
122
+
123
+ // Anonymously track how many instances of each breaking change item were encountered.
124
+ // This only tracks the name of the breaking change found, and how many instances of it
125
+ // were found. It does not send any part of the scanned codebase or any PII.
126
+ // It is used internally to help us understand what the most common sticking points are
127
+ // for our users so we can appropriate prioritize support/guidance/docs around them.
128
+ if (!disableTelemetry) {
129
+ fetch('https://api.segment.io/v1/batch', {
130
+ method: 'POST',
131
+ headers: {
132
+ Authorization: `Basic ${Buffer.from('5TkC1SM87VX2JRJcIGBBmL7sHLRWaIvc:').toString('base64')}`,
133
+ 'Content-Type': 'application/json'
134
+ },
135
+ body: JSON.stringify({
136
+ batch: newResults.map(item => {
137
+ return {
138
+ type: 'track',
139
+ userId: 'clerk-upgrade-tool',
140
+ event: 'Clerk Migration Tool_CLI_Breaking Change Found',
141
+ properties: {
142
+ appId: `cmt_${uuid}`,
143
+ surface: 'Clerk Migration Tool',
144
+ location: 'CLI',
145
+ title: item.title,
146
+ instances: item.instances.length,
147
+ fromVersion,
148
+ toVersion
149
+ },
150
+ timestamp: new Date().toISOString()
151
+ };
152
+ })
153
+ })
154
+ });
155
+ }
113
156
  setComplete(true);
114
157
  if (Object.keys(allResults).length < 1) {
115
158
  setStatus('It looks like you have nothing you need to change, upgrade away!');
@@ -119,12 +162,12 @@ export default function Scan({
119
162
  }).catch(err => {
120
163
  console.error(err);
121
164
  });
122
- }, [matchers, files]);
123
- return /*#__PURE__*/React.createElement(React.Fragment, null, complete ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, {
165
+ }, [matchers, files, noWarnings]);
166
+ return complete ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, {
124
167
  color: "green"
125
168
  }, "\u2713 ", status), /*#__PURE__*/React.createElement(Newline, null), !!results.length && /*#__PURE__*/React.createElement(ExpandableList, {
126
169
  items: results
127
170
  })) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ProgressBar, {
128
171
  value: progress
129
- }), /*#__PURE__*/React.createElement(Text, null, status)));
172
+ }), /*#__PURE__*/React.createElement(Text, null, status));
130
173
  }
@@ -1,7 +1,6 @@
1
- import React, { useReducer, useMemo } from 'react';
2
- import { Text, Newline, useInput, Box } from 'ink';
3
- import Link from 'ink-link';
4
1
  import Markdown from '@jescalan/ink-markdown';
2
+ import { Box, Newline, Text, useInput } from 'ink';
3
+ import React, { useReducer } from 'react';
5
4
 
6
5
  // A listing of items which can be navigated with arrow keys and expanded/contracted
7
6
  // with space bar. Limits the number visible at a time to prevent rendering issues with
@@ -59,7 +58,9 @@ export default function ExpandableList({
59
58
  borderColor: item.focused ? 'blue' : 'white',
60
59
  paddingX: 1,
61
60
  key: item.title
62
- }, /*#__PURE__*/React.createElement(Markdown, null, item.title), locations.length > 1 ? /*#__PURE__*/React.createElement(Text, null, "Found ", locations.length, " instances, expand for detail") : /*#__PURE__*/React.createElement(Text, null, "Location: ", locations[0]), item.expanded && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Line, null), locations.length > 1 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, "Locations:"), locations.map(loc => /*#__PURE__*/React.createElement(Text, null, ' ', "- ", loc)), /*#__PURE__*/React.createElement(Line, null)), item.warning && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, {
61
+ }, /*#__PURE__*/React.createElement(Markdown, null, item.title), locations.length > 1 ? /*#__PURE__*/React.createElement(Text, null, "Found ", locations.length, " instances, expand for detail") : /*#__PURE__*/React.createElement(Text, null, "Location: ", locations[0]), item.expanded && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Line, null), locations.length > 1 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, null, "Locations:"), locations.map(loc => /*#__PURE__*/React.createElement(Text, {
62
+ key: loc
63
+ }, ' ', "- ", loc)), /*#__PURE__*/React.createElement(Line, null)), item.warning && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, {
63
64
  color: "yellow"
64
65
  }, "\u26A0\uFE0F This is a WARNING and will still match even if you corrected the issue or if no correction is necessary. To dismiss warnings, pass the `--noWarnings` flag to the CLI when running."), /*#__PURE__*/React.createElement(Line, null)), /*#__PURE__*/React.createElement(Newline, null), /*#__PURE__*/React.createElement(Markdown, null, item.content))));
65
66
  return memo;
@@ -1,5 +1,5 @@
1
- import SDKS from '../constants/sdks.js';
2
1
  import { parseInline } from 'marked';
2
+ import SDKS from '../constants/sdks.js';
3
3
  const VERSION = 'v5';
4
4
  async function generate() {
5
5
  let output = '';
@@ -1,6 +1,3 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
-
4
1
  // WIP, a util script used for quickly generating a large number of nearly identical change files
5
2
  const movedToServer = ['MultisessionAppSupport', 'auth', 'currentUser', 'authMiddleware',
6
3
  // deprecated
@@ -1,27 +1,63 @@
1
+ import { randomUUID } from 'crypto';
2
+ import fs from 'fs';
3
+ import md5 from 'md5';
4
+ import path from 'path';
1
5
  import { readPackageSync } from 'read-pkg';
6
+ import tempDir from 'temp-dir';
2
7
  import SDKS from '../constants/sdks.js';
3
- export default function guessFrameworks(dir) {
8
+
9
+ // Telemetry Note
10
+ // --------------
11
+ // We collect fully anonymous telemetry as part of this tool. The only data we send is which
12
+ // breaking changes were detected in your app scan. This data helps us to know what the most often
13
+ // encountered issues are so that we can prioritize documentation and support for these areas.
14
+ // We do not send any information from your source code or any PII as part of the telemetry.
15
+
16
+ export default function guessFrameworks(dir, disableTelemetry) {
4
17
  let pkg;
5
18
  try {
6
19
  pkg = readPackageSync({
7
20
  cwd: dir
8
21
  });
9
22
  } catch (err) {
10
- return [];
23
+ const tmpPath = path.join(tempDir, 'clerk-upgrade-uuid');
24
+ let uuid;
25
+ if (!disableTelemetry) {
26
+ // if there's no package.json, create a uuid in tempfile so that multiple runs on the same app can be consolidated
27
+ if (fs.existsSync(tmpPath)) {
28
+ uuid = fs.readFileSync(tmpPath, 'utf8');
29
+ } else {
30
+ uuid = randomUUID();
31
+ fs.writeFileSync(tmpPath, uuid);
32
+ }
33
+ }
34
+ return {
35
+ guesses: [],
36
+ _uuid: uuid
37
+ };
11
38
  }
12
39
 
40
+ // if there is a package.json
41
+ const _uuid = md5(pkg);
42
+
13
43
  // no guessing if there are no deps
14
- if (!pkg.dependencies && !pkg.devDependencies) return [];
44
+ if (!pkg.dependencies && !pkg.devDependencies) return {
45
+ guesses: [],
46
+ _uuid
47
+ };
15
48
  const deps = pkg.dependencies ? Object.keys(pkg.dependencies) : [];
16
49
  const devDeps = pkg.devDependencies ? Object.keys(pkg.devDependencies) : [];
17
- return SDKS.reduce((m, {
18
- label,
19
- value
20
- }) => {
21
- if (deps.includes(label) || devDeps.includes(label)) m.push({
50
+ return {
51
+ _uuid,
52
+ guesses: SDKS.reduce((m, {
22
53
  label,
23
54
  value
24
- });
25
- return m;
26
- }, []);
55
+ }) => {
56
+ if (deps.includes(label) || devDeps.includes(label)) m.push({
57
+ label,
58
+ value
59
+ });
60
+ return m;
61
+ }, [])
62
+ };
27
63
  }
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs';
2
- import path from 'path';
3
2
  import matter from 'gray-matter';
3
+ import path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
6
  export default function createLoader({
@@ -2,6 +2,7 @@
2
2
  title: '`API_URL` value has changed'
3
3
  matcher: "API_URL[\\s\\S]*?from\\s+['\"]@clerk\\/backend\\/constants['\"]"
4
4
  matcherFlags: 'm'
5
+ warning: true
5
6
  ---
6
7
 
7
8
  The value of this export has changed from `https://api.clerk.dev` to `https://api.clerk.com`. If you were relying on the text content of this value not changing, you may need to make adjustments.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: '`Clerk` -> `createClerkClient`'
3
- matcher: "import\\s+{*[\\s\\S]*?Clerk[\\s\\S]*?}*\\s+from\\s+['\"]@clerk\\/backend['\"]"
3
+ matcher: "import\\s+{[\\s\\S]*?Clerk[\\s\\S]*?}\\s+from\\s+['\"]@clerk/backend['\"]"
4
4
  matcherFlags: 'm'
5
5
  ---
6
6
 
@@ -8,7 +8,7 @@ The top level `Clerk` import was renamed to `createClerkClient`. This is just a
8
8
 
9
9
  ```js
10
10
  // before
11
- import Clerk from '@clerk/backend';
11
+ import { Clerk } from '@clerk/backend';
12
12
 
13
13
  // after
14
14
  import { createClerkClient } from '@clerk/backend';
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: '`frontendApi` -> `publishableKey` as param to createClerkClient'
3
- matcher: "[createClerkClient|Clerk]\\(\\s*{[\\s\\S]*?frontendApi:[\\s\\S]*?\\)"
3
+ matcher: "(?:createClerkClient|Clerk)\\(\\s*{[\\s\\S]*?frontendApi:[\\s\\S]*?\\)"
4
4
  matcherFlags: 'm'
5
5
  ---
6
6
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  title: '`pkgVersion` -> `clerkJSVersion`'
3
3
  matcher:
4
- - "loadInterstitialFromLocal\\([\\s\\S]*?pkgVersion:"
5
- - "loadInterstitialFromBAPI\\([\\s\\S]*?pkgVersion:"
6
- - "buildPublicInterstitialUrl\\([\\s\\S]*?pkgVersion:"
4
+ - "loadInterstitialFromLocal\\([\\s\\S]*?pkgVersion:[\\s\\S]*?\\)"
5
+ - "loadInterstitialFromBAPI\\([\\s\\S]*?pkgVersion:[\\s\\S]*?\\)"
6
+ - "buildPublicInterstitialUrl\\([\\s\\S]*?pkgVersion:[\\s\\S]*?\\)"
7
7
  matcherFlags: 'm'
8
8
  ---
9
9
 
@@ -7,10 +7,7 @@ replaceWithString: 'afterSelectOrganizationUrl'
7
7
 
8
8
  The `afterSwitchOrganizationUrl` prop on the `<OrganizationSwitcher />` component has been renamed to `afterSelectOrganizationUrl`. This is a quick and simple rename.
9
9
 
10
- ```js
11
- // before
12
- <OrganizationSwitcher afterSwitchOrganizationUrl='...' />
13
-
14
- // after
15
- <OrganizationSwitcher afterSelectOrganizationUrl='...' />
10
+ ```diff
11
+ - <OrganizationSwitcher afterSwitchOrganizationUrl='...' />
12
+ + <OrganizationSwitcher afterSelectOrganizationUrl='...' />
16
13
  ```
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: '`Organization.getOrganizationInvitationList()` return type changed'
3
+ matcher: "\\.getOrganizationInvitationList\\("
4
+ ---
5
+
6
+ The return type for this function was previously `[Items]` but has now been updated to `{ data: [Items], totalCount: number }`. Since Clerk's API responses are paginated, the `totalCount` property is helpful in determining the total number of items in the response easily. A before/after code example can be seen below:
7
+
8
+ ```diff
9
+ const { organization } = useOrganization()
10
+ const inviteList = organization.getOrganizationInvitationList()
11
+
12
+ - inviteList.forEach(() => {})
13
+ + inviteList.data.forEach(() => {})
14
+ ```
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: '`Organization.getOrganizationList()` return type changed'
3
+ matcher: "\\.getOrganizationList\\("
4
+ ---
5
+
6
+ The return type for this function was previously `[Items]` but has now been updated to `{ data: [Items], totalCount: number }`. Since Clerk's API responses are paginated, the `totalCount` property is helpful in determining the total number of items in the response easily. A before/after code example can be seen below:
7
+
8
+ ```diff
9
+ const { organization } = useOrganization()
10
+ const orgList = organization.getOrganizationList()
11
+
12
+ - orgList.forEach(() => {})
13
+ + orgList.data.forEach(() => {})
14
+ ```
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: '`User.getOrganizationMembershipList()` return type changed'
3
+ matcher: "\\.getOrganizationMembershipList\\("
4
+ ---
5
+
6
+ The return type for this function was previously `[Items]` but has now been updated to `{ data: [Items], totalCount: number }`. Since Clerk's API responses are paginated, the `totalCount` property is helpful in determining the total number of items in the response easily. A before/after code example can be seen below:
7
+
8
+ ```diff
9
+ const { user } = useUser()
10
+ const membershipList = user.getOrganizationMembershipList()
11
+
12
+ - membershipList.forEach(() => {})
13
+ + membershipList.data.forEach(() => {})
14
+ ```
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: 'Pagination parameters changed for `Organization.getRoles()`'
3
+ matcher: ".getRoles\\("
4
+ ---
5
+
6
+ There have been a couple changes to the pagination arguments that can be passed into this function - `limit` has been renamed to `pageSize`, and `offset` has been renamed to `initialPage`. This will help to make it more clear and simple to reason about pagination control. Example of how changes might look below:
7
+
8
+ ```diff
9
+ const { data } = await organization.getRoles({
10
+ - limit: 10,
11
+ + pageSize: 10,
12
+ - offset: 10,
13
+ + initialPage: 2,
14
+ })
15
+ ```
@@ -4,4 +4,4 @@ matcher: 'handleMagicLinkVerification'
4
4
  replaceWithString: 'handleMagicLinkVerification'
5
5
  ---
6
6
 
7
- Across Clerk's documentation and codebases the term "magic link" was changed to "email link" as it more accurately reflects the functionality.
7
+ Across Clerk's documentation and codebases the term "magic link" was changed to "email link" as it more accurately reflects functionality.
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: 'Upgrade react to v18 or higher'
3
+ matcher: "dependencies\":\\s*{[\\s\\S]*?\"react\":\\s*\"(?:^|~|>|=|\\s)*(?:12|13|14|15|16|17)\\..*?"
4
+ ---
5
+
6
+ If you're using `react`, you will need to update your Next.js project to `v18` or later to ensure that the latest version of Clerk's SDKs work properly.
@@ -1,16 +1,18 @@
1
1
  ---
2
- title: '`navigate` prop replaced by `routerPush` and `routerReplace`'
2
+ title: '`navigate` prop to `ClerkProvider` replaced by `routerPush` and `routerReplace`'
3
3
  matcher: "<ClerkProvider[\\s\\S]*?navigate=[\\s\\S]*?>"
4
4
  matcherFlags: 'm'
5
5
  ---
6
6
 
7
- The `navigate` prop on `<ClerkProvider>` allowed developers to override the default navigation behavior with a custom function. However, `navigate` was only able to push, not replace routes. The router is now able to do both, and as such, the props for `<ClerkProvider>` were updated. The `routerPush` and `routerReplace` props replace the old `navigate` prop.
7
+ The `navigate` prop on ClerkProvider allowed developers to override the default navigation behavior with a custom function. However, navigate was only able to push, not replace routes. We have now added the capability for the router to push or replace, and as such, upgraded the provider prop so that it can handle either depending on the circumstance.
8
8
 
9
- For more information on what push and replace mean in relation to the browser history api, check out the ["Working with the History API"](https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API) docs.
9
+ Two new props have been added to `ClerkProvider` that replace the single `navigate` prop, and can be used to override the default navigation behavior for either a push or replace navigation. For more information on what push and replace mean in relation to the browser history api, [check out these wonderful MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/History_API/Working_with_the_History_API).
10
10
 
11
- If you’d like to keep the same behavior as you had with the single `navigate` prop, pass the exact same function to both `routerPush` and `routerReplace`. For example:
11
+ If you’d like to keep the same behavior as you had with the single `navigate` prop, pass the exact same function to both `routerPush` and `routerReplace` and the behavior will be identical. For example:
12
12
 
13
13
  ```diff
14
- - <ClerkProvider navigate={x => x} />
15
- + <ClerkProvider routerPush={x => x} routerReplace={x => x} />
14
+ - <ClerkProvider navigate={ x => x } />
15
+ + <ClerkProvider routerPush={ x => x } routerReplace={ x => x } />
16
16
  ```
17
+
18
+ However, you now have the option to differentiate behavior based on whether the navigation will be a push or replace.
@@ -6,12 +6,7 @@ matcher: "\\.getDomains\\("
6
6
  There have been a couple changes to the pagination arguments that can be passed into this function - `limit` has been renamed to `pageSize`, and `offset` has been renamed to `initialPage`. This will help to make it more clear and simple to reason about pagination control. Example of how changes might look below:
7
7
 
8
8
  ```diff
9
- import Clerk from "@clerk/clerk-js"
10
-
11
- const clerk = new Clerk()
12
- await clerk.load()
13
-
14
- const { data: orgs } = await clerk.organization.getDomains({
9
+ const { data } = await organization.getDomains({
15
10
  - limit: 10,
16
11
  + pageSize: 10,
17
12
  - offset: 10,
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: '`Organization.getInvitations` arguments changed'
3
+ matcher: "\\.getInvitations\\("
4
+ ---
5
+
6
+ There have been a couple changes to the pagination arguments that can be passed into this function - `limit` has been renamed to `pageSize`, and `offset` has been renamed to `initialPage`. This will help to make it more clear and simple to reason about pagination control. Example of how changes might look below:
7
+
8
+ ```diff
9
+ const { data } = await organization.getInvitations({
10
+ - limit: 10,
11
+ + pageSize: 10,
12
+ - offset: 10,
13
+ + initialPage: 2,
14
+ })
15
+ ```
@@ -6,12 +6,7 @@ matcher: "\\.getMembershipRequests\\("
6
6
  There have been a couple changes to the pagination arguments that can be passed into this function - `limit` has been renamed to `pageSize`, and `offset` has been renamed to `initialPage`. This will help to make it more clear and simple to reason about pagination control. Example of how changes might look below:
7
7
 
8
8
  ```diff
9
- import Clerk from "@clerk/clerk-js"
10
-
11
- const clerk = new Clerk()
12
- await clerk.load()
13
-
14
- const { data: orgs } = await clerk.organization.getMembershipRequests({
9
+ const { data } = await organization.getMembershipRequests({
15
10
  - limit: 10,
16
11
  + pageSize: 10,
17
12
  - offset: 10,
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: '`Organization.getMemberships` arguments changed'
3
+ matcher: "\\.getMemberships\\("
4
+ ---
5
+
6
+ There have been a couple changes to the pagination arguments that can be passed into this function - `limit` has been renamed to `pageSize`, and `offset` has been renamed to `initialPage`. This will help to make it more clear and simple to reason about pagination control. Example of how changes might look below:
7
+
8
+ ```diff
9
+ const { data } = await organization.getMemberships({
10
+ - limit: 10,
11
+ + pageSize: 10,
12
+ - offset: 10,
13
+ + initialPage: 2,
14
+ })
15
+ ```
@@ -6,12 +6,7 @@ matcher: "\\.getRoles\\("
6
6
  There have been a couple changes to the pagination arguments that can be passed into this function - `limit` has been renamed to `pageSize`, and `offset` has been renamed to `initialPage`. This will help to make it more clear and simple to reason about pagination control. Example of how changes might look below:
7
7
 
8
8
  ```diff
9
- import Clerk from "@clerk/clerk-js"
10
-
11
- const clerk = new Clerk()
12
- await clerk.load()
13
-
14
- const { data: orgs } = await clerk.organization.getRoles({
9
+ const { data } = await organization.getRoles({
15
10
  - limit: 10,
16
11
  + pageSize: 10,
17
12
  - offset: 10,
@@ -24,6 +24,7 @@ await setActive({
24
24
  organization: 'orgID',
25
25
  beforeEmit: () => void
26
26
  })
27
+
27
28
  await setActive({
28
29
  session: sessionObj,
29
30
  organization: orgObj,