@strapi/upgrade 0.0.0-experimental.defd8568ae03ef8d52f86e1f3541979f953c3941 → 0.0.0-experimental.df298029ec6478763dcca7d59fafe8d2ae4ed60a

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 (44) hide show
  1. package/LICENSE +19 -4
  2. package/README.md +1 -1
  3. package/dist/cli.js +444 -318
  4. package/dist/cli.js.map +1 -1
  5. package/dist/index.js +467 -344
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +463 -341
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/modules/error/utils.d.ts +8 -0
  10. package/dist/modules/error/utils.d.ts.map +1 -1
  11. package/dist/modules/file-scanner/scanner.d.ts.map +1 -1
  12. package/dist/modules/format/formats.d.ts +2 -1
  13. package/dist/modules/format/formats.d.ts.map +1 -1
  14. package/dist/modules/project/constants.d.ts +6 -5
  15. package/dist/modules/project/constants.d.ts.map +1 -1
  16. package/dist/modules/project/project.d.ts +16 -2
  17. package/dist/modules/project/project.d.ts.map +1 -1
  18. package/dist/modules/project/types.d.ts +3 -0
  19. package/dist/modules/project/types.d.ts.map +1 -1
  20. package/dist/modules/runner/json/transform.d.ts.map +1 -1
  21. package/dist/modules/upgrader/types.d.ts +6 -0
  22. package/dist/modules/upgrader/types.d.ts.map +1 -1
  23. package/dist/modules/upgrader/upgrader.d.ts +4 -0
  24. package/dist/modules/upgrader/upgrader.d.ts.map +1 -1
  25. package/dist/modules/version/range.d.ts.map +1 -1
  26. package/dist/modules/version/types.d.ts +2 -1
  27. package/dist/modules/version/types.d.ts.map +1 -1
  28. package/dist/tasks/codemods/utils.d.ts.map +1 -1
  29. package/dist/tasks/upgrade/prompts/index.d.ts +2 -0
  30. package/dist/tasks/upgrade/prompts/index.d.ts.map +1 -0
  31. package/dist/tasks/upgrade/prompts/latest.d.ts +9 -0
  32. package/dist/tasks/upgrade/prompts/latest.d.ts.map +1 -0
  33. package/dist/tasks/upgrade/requirements/major.d.ts.map +1 -1
  34. package/dist/tasks/upgrade/upgrade.d.ts.map +1 -1
  35. package/package.json +9 -8
  36. package/resources/codemods/5.0.0/comment-out-lifecycle-files.code.ts +63 -0
  37. package/resources/codemods/5.0.0/dependency-upgrade-react-and-react-dom.json.ts +67 -0
  38. package/resources/codemods/5.0.0/dependency-upgrade-styled-components.json.ts +49 -0
  39. package/resources/codemods/5.0.0/deprecate-helper-plugin.code.ts +192 -0
  40. package/resources/codemods/5.0.0/entity-service-document-service.code.ts +68 -5
  41. package/resources/codemods/5.0.0/sqlite3-to-better-sqlite3.json.ts +0 -1
  42. package/resources/codemods/5.1.0/dependency-better-sqlite3.json.ts +48 -0
  43. package/resources/utils/change-import.ts +118 -0
  44. package/resources/utils/replace-jsx.ts +49 -0
@@ -142,12 +142,39 @@ const objectParam_10 = [...objectParam_10_2];
142
142
 
143
143
  strapi.entityService.findOne(...[...objectParam_10]);
144
144
 
145
+ Case: find, create, update, delete with entityId as first argument
146
+
147
+ strapi.entityService.findMany(uid, {
148
+ fields: ["id", "name", "description"],
149
+ populate: ["author", "comments"],
150
+ publicationState: "preview",
151
+ });
152
+
153
+ strapi.entityService.create(uid, {
154
+ data: {
155
+ name: "John Doe",
156
+ age: 30,
157
+ },
158
+ });
159
+
160
+ strapi.entityService.update(uid, entityId, {
161
+ data: {
162
+ name: "John Doe",
163
+ age: 30,
164
+ },
165
+ });
166
+
167
+ strapi.entityService.delete(uid, entityId);
168
+ strapi.entityService.findOne(uid, entityId);
169
+
145
170
  */
146
171
 
147
- const movedFunctions = ['findOne', 'find', 'count', 'create', 'update', 'delete'];
172
+ const movedFunctions = ['findOne', 'findMany', 'count', 'create', 'update', 'delete'];
173
+
174
+ const functionsWithEntityId = ['findOne', 'update', 'delete'];
148
175
 
149
176
  const transformDeclaration = (path: ASTPath<any>, name: any, j: JSCodeshift) => {
150
- const declaration = findClosesDeclaration(path, name, j);
177
+ const declaration = findClosestDeclaration(path, name, j);
151
178
 
152
179
  if (!declaration) {
153
180
  return;
@@ -222,7 +249,7 @@ const transformObjectParam = (path: ASTPath<any>, expression: ObjectExpression,
222
249
  break;
223
250
  }
224
251
  case j.Identifier.check(prop.value): {
225
- const declaration = findClosesDeclaration(path, prop.value.name, j);
252
+ const declaration = findClosestDeclaration(path, prop.value.name, j);
226
253
 
227
254
  if (!declaration) {
228
255
  return;
@@ -253,7 +280,7 @@ const transformObjectParam = (path: ASTPath<any>, expression: ObjectExpression,
253
280
  });
254
281
  };
255
282
 
256
- const findClosesDeclaration = (path: ASTPath<any>, name: string, j) => {
283
+ const findClosestDeclaration = (path: ASTPath<any>, name: string, j) => {
257
284
  // find Identifier declaration
258
285
  const scope = path.scope.lookup(name);
259
286
 
@@ -318,7 +345,7 @@ const transform: Transform = (file, api) => {
318
345
  case j.Identifier.check(arg.argument): {
319
346
  const identifier = arg.argument;
320
347
 
321
- const declaration = findClosesDeclaration(path, identifier.name, j);
348
+ const declaration = findClosestDeclaration(path, identifier.name, j);
322
349
 
323
350
  if (!declaration) {
324
351
  return arg;
@@ -351,6 +378,42 @@ const transform: Transform = (file, api) => {
351
378
 
352
379
  const [docUID, ...rest] = resolvedArgs;
353
380
 
381
+ // function with entityId as first argument
382
+ if (
383
+ j.Identifier.check(path.value.callee.property) &&
384
+ functionsWithEntityId.includes(path.value.callee.property.name)
385
+ ) {
386
+ rest.splice(0, 1);
387
+
388
+ // in case no extra params are passed in the function e.g delete(uid, entityId)
389
+ if (rest.length === 0) {
390
+ rest.push(
391
+ j.objectExpression.from({
392
+ properties: [],
393
+ })
394
+ );
395
+ }
396
+
397
+ const params = rest[0];
398
+
399
+ const placeholder = j.objectProperty(j.identifier('documentId'), j.literal('__TODO__'));
400
+
401
+ // add documentId to params with a placeholder
402
+ if (j.ObjectExpression.check(params)) {
403
+ params.properties.unshift(placeholder);
404
+ } else if (j.Identifier.check(params)) {
405
+ const declaration = findClosestDeclaration(path, params.name, j);
406
+
407
+ if (!declaration) {
408
+ return;
409
+ }
410
+
411
+ if (j.ObjectExpression.check(declaration.init)) {
412
+ declaration.init.properties.unshift(placeholder);
413
+ }
414
+ }
415
+ }
416
+
354
417
  path.value.arguments.forEach((arg) => {
355
418
  transformElement(path, arg, j);
356
419
  });
@@ -30,7 +30,6 @@ const transform: modules.runner.json.JSONTransform = (file, params) => {
30
30
  });
31
31
 
32
32
  if (removed && !j.has('dependencies.better-sqlite3')) {
33
- // TODO check this version when releasing V5
34
33
  j.set('dependencies.better-sqlite3', '9.4.3');
35
34
  }
36
35
 
@@ -0,0 +1,48 @@
1
+ import path from 'path';
2
+ import semver from 'semver';
3
+ import type { modules } from '../../../dist';
4
+
5
+ const DEP_NAME = 'better-sqlite3';
6
+ const DEP_PATH = `dependencies.${DEP_NAME}`;
7
+ const DEP_VERSION = '11.3.0';
8
+
9
+ /**
10
+ *
11
+ */
12
+ const transform: modules.runner.json.JSONTransform = (file, params) => {
13
+ return upgradeIfExists(file, params, DEP_PATH, DEP_VERSION);
14
+ };
15
+
16
+ export default transform;
17
+
18
+ // TODO: move this to a utility once we solve the issue where codemods are not transpiled properly
19
+ const upgradeIfExists = (
20
+ file: modules.runner.json.JSONSourceFile,
21
+ params: modules.runner.json.JSONTransformParams,
22
+ packagePath: string,
23
+ targetVersion: string
24
+ ) => {
25
+ const { cwd, json } = params;
26
+
27
+ // Return early if the file path is not the root package.json
28
+ if (file.path !== path.join(cwd, 'package.json')) {
29
+ return file.json;
30
+ }
31
+
32
+ const packageJson = json(file.json);
33
+
34
+ // Check if the package exists
35
+ if (packageJson.has(packagePath)) {
36
+ const currentVersion = packageJson.get(packagePath);
37
+ // ensure we only upgrade, not downgrade
38
+ if (
39
+ typeof currentVersion === 'string' &&
40
+ semver.valid(currentVersion) &&
41
+ semver.lt(currentVersion, targetVersion)
42
+ ) {
43
+ packageJson.set(packagePath, targetVersion);
44
+ }
45
+ }
46
+
47
+ return packageJson.root();
48
+ };
@@ -0,0 +1,118 @@
1
+ import type { ImportDeclaration, JSCodeshift, Collection } from 'jscodeshift';
2
+
3
+ export const changeImportSpecifier = (
4
+ root: Collection,
5
+ j: JSCodeshift,
6
+ options: {
7
+ oldDependency: string;
8
+ newDependency: string;
9
+ oldMethodName: string;
10
+ newMethodName?: string;
11
+ }
12
+ ): void => {
13
+ const { oldMethodName, newMethodName, oldDependency, newDependency } = options;
14
+ const methodNameToReplace = newMethodName ?? oldMethodName;
15
+
16
+ // Flag to check if the method was imported from the old dependency
17
+ let methodImportedFromOldDependency = false;
18
+ const methodAliases: string[] = [];
19
+
20
+ // Remove the method from the old dependency and check if it was imported
21
+ root
22
+ .find(j.ImportDeclaration)
23
+ .filter((path) => path.node.source.value === oldDependency)
24
+ .forEach((path) => {
25
+ const importDeclaration: ImportDeclaration = path.node;
26
+
27
+ // Check if the method is imported from the old dependency
28
+ const methodSpecifiers = importDeclaration.specifiers?.filter(
29
+ (specifier) =>
30
+ specifier.type === 'ImportSpecifier' && specifier.imported.name === oldMethodName
31
+ );
32
+
33
+ if (methodSpecifiers && methodSpecifiers.length > 0) {
34
+ methodImportedFromOldDependency = true;
35
+
36
+ // Collect all aliases for the method
37
+ methodSpecifiers.forEach((specifier) => {
38
+ if (specifier.local && specifier.local.name !== oldMethodName) {
39
+ methodAliases.push(specifier.local.name);
40
+ } else {
41
+ methodAliases.push(methodNameToReplace);
42
+ }
43
+ });
44
+
45
+ // Remove the method specifiers from the old import
46
+ const updatedSpecifiers = importDeclaration.specifiers?.filter(
47
+ (specifier) =>
48
+ specifier.type !== 'ImportSpecifier' || specifier.imported.name !== oldMethodName
49
+ );
50
+
51
+ if (updatedSpecifiers && updatedSpecifiers.length > 0) {
52
+ // Replace the import with the updated specifiers if there are other imports left
53
+ j(path).replaceWith(j.importDeclaration(updatedSpecifiers, j.literal(oldDependency)));
54
+ } else {
55
+ // Remove the entire import statement if the specified method was the only import
56
+ j(path).remove();
57
+ }
58
+ }
59
+ });
60
+
61
+ // Add new import dependency if the method was imported from the old dependency
62
+ if (methodImportedFromOldDependency) {
63
+ const dependencies = root
64
+ .find(j.ImportDeclaration)
65
+ .filter((path) => path.node.source.value === newDependency);
66
+
67
+ if (dependencies.length > 0) {
68
+ // we have to use a flag to prevent adding the method to multiple imports
69
+ let methodAdded = false;
70
+ dependencies.forEach((path) => {
71
+ const importDeclaration: ImportDeclaration = path.node;
72
+ if (!methodAdded) {
73
+ methodAliases.forEach((alias) => {
74
+ // Check if the methodNameToReplace or its alias is already imported
75
+ const specifiersArray = importDeclaration.specifiers || [];
76
+ const methodAlreadyExists = specifiersArray.some(
77
+ (specifier) =>
78
+ specifier.type === 'ImportSpecifier' &&
79
+ specifier.imported.name === methodNameToReplace && // Check if imported method matches
80
+ specifier.local?.name === alias // Check if local alias matches
81
+ );
82
+
83
+ if (!methodAlreadyExists) {
84
+ // If method does not exist, add it
85
+ const newSpecifier = j.importSpecifier(
86
+ j.identifier(methodNameToReplace),
87
+ j.identifier(alias)
88
+ );
89
+ path.get('specifiers').replace([...specifiersArray, newSpecifier]);
90
+ methodAdded = true;
91
+ }
92
+ });
93
+ }
94
+ });
95
+ } else {
96
+ const newSpecifiers = methodAliases.map((alias) =>
97
+ j.importSpecifier(j.identifier(methodNameToReplace), j.identifier(alias))
98
+ );
99
+
100
+ const newImportDeclaration = j.importDeclaration(newSpecifiers, j.literal(newDependency));
101
+
102
+ // Find the index of the first non-import declaration
103
+ const body = root.get().node.program.body;
104
+ const lastImportIndex = body.findIndex((node) => node.type !== 'ImportDeclaration');
105
+
106
+ if (lastImportIndex > -1) {
107
+ // Insert the new import declaration just before the first non-import node
108
+ body.splice(lastImportIndex, 0, newImportDeclaration);
109
+ } else {
110
+ // Check if 'use strict' exists at the beginning
111
+ const hasUseStrict =
112
+ body[0]?.type === 'ExpressionStatement' && body[0]?.expression?.value === 'use strict';
113
+ // Add the new import after 'use strict' if it exists, otherwise at the beginning
114
+ body.splice(hasUseStrict ? 1 : 0, 0, newImportDeclaration);
115
+ }
116
+ }
117
+ }
118
+ };
@@ -0,0 +1,49 @@
1
+ import type { JSCodeshift, Collection } from 'jscodeshift';
2
+
3
+ export const replaceJSXElement = (
4
+ root: Collection,
5
+ j: JSCodeshift,
6
+ {
7
+ oldElementName,
8
+ newElementName,
9
+ oldDependency,
10
+ }: {
11
+ oldElementName: string;
12
+ newElementName: string;
13
+ oldDependency: string;
14
+ }
15
+ ) => {
16
+ // Find the import declaration for the old dependency
17
+ const importDeclaration = root.find(j.ImportDeclaration, {
18
+ source: { value: oldDependency },
19
+ });
20
+
21
+ if (importDeclaration.size() === 0) {
22
+ return;
23
+ }
24
+
25
+ // Get the local name of the imported element
26
+ const localName = importDeclaration
27
+ .find(j.ImportSpecifier, {
28
+ imported: { name: oldElementName },
29
+ })
30
+ .nodes()[0]?.local?.name;
31
+
32
+ if (!localName) {
33
+ return;
34
+ }
35
+
36
+ // Replace JSX elements
37
+ root.findJSXElements(localName).forEach((path) => {
38
+ const openingElement = path.node.openingElement;
39
+ const closingElement = path.node.closingElement;
40
+
41
+ if (j.JSXIdentifier.check(openingElement.name)) {
42
+ openingElement.name.name = newElementName;
43
+ }
44
+
45
+ if (closingElement && j.JSXIdentifier.check(closingElement.name)) {
46
+ closingElement.name.name = newElementName;
47
+ }
48
+ });
49
+ };