@strapi/upgrade 5.0.0-rc.1 → 5.0.0-rc.11

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.
@@ -0,0 +1,67 @@
1
+ import path from 'node:path';
2
+ import semver from 'semver';
3
+
4
+ import type { modules } from '../../../dist';
5
+
6
+ const REACT_DEP_NAME = 'react';
7
+ const REACT_DEP_PATH = `dependencies.${REACT_DEP_NAME}`;
8
+
9
+ const REACT_DOM_DEP_NAME = 'react-dom';
10
+ const REACT_DOM_DEP_PATH = `dependencies.${REACT_DOM_DEP_NAME}`;
11
+
12
+ const DEP_NEW_VERSION_RANGE = '^18.0.0';
13
+
14
+ /**
15
+ * Specifically targets the root package.json and updates the react and react-dom dependency version.
16
+ *
17
+ * We first check if the react and react-dom dependency is listed in the package.json. If the dependency is
18
+ * found, we verify its version.
19
+ *
20
+ * If the detected version does not satisfy the new version range, we replace it with the new one.
21
+ *
22
+ * Conversely, if no react or react-dom dependency is listed, we add it with the new version range.
23
+ */
24
+ const transform: modules.runner.json.JSONTransform = (file, params) => {
25
+ const { cwd, json } = params;
26
+
27
+ const rootPackageJsonPath = path.join(cwd, 'package.json');
28
+
29
+ if (file.path !== rootPackageJsonPath) {
30
+ return file.json;
31
+ }
32
+
33
+ const j = json(file.json);
34
+
35
+ if (j.has(REACT_DEP_PATH) && j.has(REACT_DOM_DEP_PATH)) {
36
+ const currentReactVersion = j.get(REACT_DEP_PATH);
37
+ const currentReactDOMVersion = j.get(REACT_DOM_DEP_PATH);
38
+
39
+ // If the current version is not a string, then something is wrong, abort
40
+ if (typeof currentReactVersion !== 'string' || typeof currentReactDOMVersion !== 'string') {
41
+ return j.root();
42
+ }
43
+
44
+ const currentSatisfiesNew =
45
+ semver.satisfies(currentReactVersion, DEP_NEW_VERSION_RANGE) &&
46
+ semver.satisfies(currentReactDOMVersion, DEP_NEW_VERSION_RANGE);
47
+
48
+ // if the current version satisfies the new range, keep it as is and abort
49
+ if (currentSatisfiesNew) {
50
+ return j.root();
51
+ }
52
+
53
+ // else, update the version with the new one
54
+ j.set(REACT_DEP_PATH, DEP_NEW_VERSION_RANGE);
55
+ j.set(REACT_DOM_DEP_PATH, DEP_NEW_VERSION_RANGE);
56
+ }
57
+
58
+ // If the dependency is not listed yet, add it
59
+ else {
60
+ j.set(REACT_DEP_PATH, DEP_NEW_VERSION_RANGE);
61
+ j.set(REACT_DOM_DEP_PATH, DEP_NEW_VERSION_RANGE);
62
+ }
63
+
64
+ return j.root();
65
+ };
66
+
67
+ export default transform;
@@ -0,0 +1,49 @@
1
+ import path from 'node:path';
2
+ import semver from 'semver';
3
+
4
+ import type { modules } from '../../../dist';
5
+
6
+ const DEP_NAME = 'styled-components';
7
+ const DEP_PATH = `dependencies.${DEP_NAME}`;
8
+
9
+ const DEP_NEW_VERSION_RANGE = '^6.0.0';
10
+
11
+ const transform: modules.runner.json.JSONTransform = (file, params) => {
12
+ const { cwd, json } = params;
13
+
14
+ const rootPackageJsonPath = path.join(cwd, 'package.json');
15
+
16
+ if (file.path !== rootPackageJsonPath) {
17
+ return file.json;
18
+ }
19
+
20
+ const j = json(file.json);
21
+
22
+ if (j.has(DEP_PATH)) {
23
+ const currentVersion = j.get(DEP_PATH);
24
+
25
+ // If the current version is not a string, then something is wrong, abort
26
+ if (typeof currentVersion !== 'string') {
27
+ return j.root();
28
+ }
29
+
30
+ const currentSatisfiesNew = semver.satisfies(currentVersion, DEP_NEW_VERSION_RANGE);
31
+
32
+ // if the current version satisfies the new range, keep it as is and abort
33
+ if (currentSatisfiesNew) {
34
+ return j.root();
35
+ }
36
+
37
+ // else, update the version with the new one
38
+ j.set(DEP_PATH, DEP_NEW_VERSION_RANGE);
39
+ }
40
+
41
+ // If the dependency is not listed yet, add it
42
+ else {
43
+ j.set(DEP_PATH, DEP_NEW_VERSION_RANGE);
44
+ }
45
+
46
+ return j.root();
47
+ };
48
+
49
+ export default transform;
@@ -0,0 +1,21 @@
1
+ import type { Transform } from 'jscodeshift';
2
+ import { changeImportSpecifier } from '../../utils/change-import';
3
+
4
+ /**
5
+ * change useRBAC import from '@strapi/helper-plugin' to '@strapi/strapi/admin'
6
+ */
7
+ const transform: Transform = (file, api) => {
8
+ const { j } = api;
9
+
10
+ const root = j.withParser('tsx')(file.source);
11
+
12
+ changeImportSpecifier(root, j, {
13
+ methodName: 'useRBAC',
14
+ oldDependency: '@strapi/helper-plugin',
15
+ newDependency: '@strapi/strapi/admin',
16
+ });
17
+
18
+ return root.toSource();
19
+ };
20
+
21
+ export default transform;
@@ -0,0 +1,96 @@
1
+ import type { ImportDeclaration, JSCodeshift, Collection } from 'jscodeshift';
2
+
3
+ export const changeImportSpecifier = (
4
+ root: Collection,
5
+ j: JSCodeshift,
6
+ options: { methodName: string; oldDependency: string; newDependency: string }
7
+ ): void => {
8
+ const { methodName, oldDependency, newDependency } = options;
9
+
10
+ // Flag to check if the method was imported from the old dependency
11
+ let methodImportedFromOldDependency = false;
12
+ const methodAliases: string[] = [];
13
+
14
+ // Remove the method from the old dependency and check if it was imported
15
+ root
16
+ .find(j.ImportDeclaration)
17
+ .filter((path) => path.node.source.value === oldDependency)
18
+ .forEach((path) => {
19
+ const importDeclaration: ImportDeclaration = path.node;
20
+
21
+ // Check if the method is imported from the old dependency
22
+ const methodSpecifiers = importDeclaration.specifiers?.filter(
23
+ (specifier) =>
24
+ specifier.type === 'ImportSpecifier' && specifier.imported.name === methodName
25
+ );
26
+
27
+ if (methodSpecifiers && methodSpecifiers.length > 0) {
28
+ methodImportedFromOldDependency = true;
29
+
30
+ // Collect all aliases for the method
31
+ methodSpecifiers.forEach((specifier) => {
32
+ if (specifier.local && specifier.local.name !== methodName) {
33
+ methodAliases.push(specifier.local.name);
34
+ } else {
35
+ methodAliases.push(methodName);
36
+ }
37
+ });
38
+
39
+ // Remove the method specifiers from the old import
40
+ const updatedSpecifiers = importDeclaration.specifiers?.filter(
41
+ (specifier) =>
42
+ specifier.type !== 'ImportSpecifier' || specifier.imported.name !== methodName
43
+ );
44
+
45
+ if (updatedSpecifiers && updatedSpecifiers.length > 0) {
46
+ // Replace the import with the updated specifiers if there are other imports left
47
+ j(path).replaceWith(j.importDeclaration(updatedSpecifiers, j.literal(oldDependency)));
48
+ } else {
49
+ // Remove the entire import statement if the specified method was the only import
50
+ j(path).remove();
51
+ }
52
+ }
53
+ });
54
+
55
+ // Add new import dependency if the method was imported from the old dependency
56
+ if (methodImportedFromOldDependency) {
57
+ const dependencies = root
58
+ .find(j.ImportDeclaration)
59
+ .filter((path) => path.node.source.value === newDependency);
60
+
61
+ if (dependencies.length > 0) {
62
+ dependencies.forEach((path) => {
63
+ const importDeclaration: ImportDeclaration = path.node;
64
+
65
+ methodAliases.forEach((alias) => {
66
+ const newSpecifier = j.importSpecifier(j.identifier(methodName), j.identifier(alias));
67
+ const specifiersArray = importDeclaration.specifiers || [];
68
+ j(path).replaceWith(
69
+ j.importDeclaration([...specifiersArray, newSpecifier], j.literal(newDependency))
70
+ );
71
+ });
72
+ });
73
+ } else {
74
+ const newSpecifiers = methodAliases.map((alias) =>
75
+ j.importSpecifier(j.identifier(methodName), j.identifier(alias))
76
+ );
77
+
78
+ const newImportDeclaration = j.importDeclaration(newSpecifiers, j.literal(newDependency));
79
+
80
+ // Find the index of the first non-import declaration
81
+ const body = root.get().node.program.body;
82
+ const lastImportIndex = body.findIndex((node) => node.type !== 'ImportDeclaration');
83
+
84
+ if (lastImportIndex > -1) {
85
+ // Insert the new import declaration just before the first non-import node
86
+ body.splice(lastImportIndex, 0, newImportDeclaration);
87
+ } else {
88
+ // Check if 'use strict' exists at the beginning
89
+ const hasUseStrict =
90
+ body[0]?.type === 'ExpressionStatement' && body[0]?.expression?.value === 'use strict';
91
+ // Add the new import after 'use strict' if it exists, otherwise at the beginning
92
+ body.splice(hasUseStrict ? 1 : 0, 0, newImportDeclaration);
93
+ }
94
+ }
95
+ }
96
+ };