@strapi/upgrade 0.0.0-experimental.a407f3bc8fb79a53cf7975140864526b6ddbac4b → 0.0.0-experimental.d23c1d5b0e45dd06ef09977f526c85468be05403

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 (74) hide show
  1. package/dist/cli.js +1452 -5
  2. package/dist/cli.js.map +1 -1
  3. package/dist/index.js +318 -88
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +319 -89
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/modules/codemod/codemod.d.ts +4 -2
  8. package/dist/modules/codemod/codemod.d.ts.map +1 -1
  9. package/dist/modules/codemod/types.d.ts +8 -1
  10. package/dist/modules/codemod/types.d.ts.map +1 -1
  11. package/dist/modules/codemod-repository/constants.d.ts.map +1 -1
  12. package/dist/modules/codemod-repository/repository.d.ts +6 -5
  13. package/dist/modules/codemod-repository/repository.d.ts.map +1 -1
  14. package/dist/modules/codemod-repository/types.d.ts +7 -3
  15. package/dist/modules/codemod-repository/types.d.ts.map +1 -1
  16. package/dist/modules/codemod-runner/codemod-runner.d.ts +3 -0
  17. package/dist/modules/codemod-runner/codemod-runner.d.ts.map +1 -1
  18. package/dist/modules/codemod-runner/index.d.ts +1 -0
  19. package/dist/modules/codemod-runner/index.d.ts.map +1 -1
  20. package/dist/modules/codemod-runner/types.d.ts +1 -0
  21. package/dist/modules/codemod-runner/types.d.ts.map +1 -1
  22. package/dist/modules/format/formats.d.ts +5 -0
  23. package/dist/modules/format/formats.d.ts.map +1 -1
  24. package/dist/modules/project/constants.d.ts +2 -0
  25. package/dist/modules/project/constants.d.ts.map +1 -1
  26. package/dist/modules/project/index.d.ts +2 -0
  27. package/dist/modules/project/index.d.ts.map +1 -1
  28. package/dist/modules/project/project.d.ts +12 -4
  29. package/dist/modules/project/project.d.ts.map +1 -1
  30. package/dist/modules/project/types.d.ts +1 -11
  31. package/dist/modules/project/types.d.ts.map +1 -1
  32. package/dist/modules/project/utils.d.ts +6 -0
  33. package/dist/modules/project/utils.d.ts.map +1 -0
  34. package/dist/modules/report/report.d.ts.map +1 -1
  35. package/dist/modules/requirement/types.d.ts +2 -2
  36. package/dist/modules/requirement/types.d.ts.map +1 -1
  37. package/dist/modules/upgrader/upgrader.d.ts +3 -3
  38. package/dist/modules/upgrader/upgrader.d.ts.map +1 -1
  39. package/dist/modules/version/range.d.ts +2 -0
  40. package/dist/modules/version/range.d.ts.map +1 -1
  41. package/dist/tasks/codemods/index.d.ts +2 -1
  42. package/dist/tasks/codemods/index.d.ts.map +1 -1
  43. package/dist/tasks/codemods/list-codemods.d.ts +3 -0
  44. package/dist/tasks/codemods/list-codemods.d.ts.map +1 -0
  45. package/dist/tasks/codemods/run-codemods.d.ts +3 -0
  46. package/dist/tasks/codemods/run-codemods.d.ts.map +1 -0
  47. package/dist/tasks/codemods/types.d.ts +9 -3
  48. package/dist/tasks/codemods/types.d.ts.map +1 -1
  49. package/dist/tasks/codemods/utils.d.ts +6 -0
  50. package/dist/tasks/codemods/utils.d.ts.map +1 -0
  51. package/dist/tasks/index.d.ts +1 -1
  52. package/dist/tasks/index.d.ts.map +1 -1
  53. package/dist/tasks/upgrade/upgrade.d.ts.map +1 -1
  54. package/package.json +7 -7
  55. package/resources/codemods/5.0.0/dependency-remove-strapi-plugin-i18n.json.ts +31 -0
  56. package/resources/codemods/5.0.0/dependency-upgrade-react-router-dom.json.ts +59 -0
  57. package/resources/codemods/5.0.0/entity-service-document-service.code.ts +374 -0
  58. package/resources/codemods/5.0.0/s3-keys-wrapped-in-credentials.code.ts +1 -1
  59. package/resources/codemods/5.0.0/sqlite3-to-better-sqlite3.json.ts +5 -2
  60. package/resources/codemods/5.0.0/strapi-public-interface.code.ts +126 -0
  61. package/resources/codemods/5.0.0/use-uid-for-config-namespace.code.ts +45 -0
  62. package/resources/codemods/5.0.0/utils-public-interface.code.ts +320 -0
  63. package/resources/examples/console.log-to-console.info.code.ts +1 -1
  64. package/resources/examples/disable-jsx-buttons.code.ts +42 -0
  65. package/dist/_chunks/codemod-runner-84t8FGQa.js +0 -729
  66. package/dist/_chunks/codemod-runner-84t8FGQa.js.map +0 -1
  67. package/dist/_chunks/codemods-KNF9fcQL.js +0 -108
  68. package/dist/_chunks/codemods-KNF9fcQL.js.map +0 -1
  69. package/dist/_chunks/index-hERDGiiJ.js +0 -103
  70. package/dist/_chunks/index-hERDGiiJ.js.map +0 -1
  71. package/dist/_chunks/upgrade-dU3oQNZk.js +0 -357
  72. package/dist/_chunks/upgrade-dU3oQNZk.js.map +0 -1
  73. package/dist/tasks/codemods/codemods.d.ts +0 -3
  74. package/dist/tasks/codemods/codemods.d.ts.map +0 -1
@@ -0,0 +1,374 @@
1
+ import type { Transform, JSCodeshift, ASTPath, ObjectExpression } from 'jscodeshift';
2
+
3
+ /*
4
+ This codemod transforms entity service calls to match the new document service interface.
5
+ It supports all kind of argument parsing, including spread elements & deeply nested objects.
6
+
7
+ Here is a list of scenarios this was tested against
8
+
9
+ const uid = "api::xxx.xxx";
10
+ const entityId = 1;
11
+
12
+ Case: basic call
13
+
14
+ strapi.entityService.findOne(uid, entityId, {
15
+ fields: ["id", "name", "description"],
16
+ populate: ["author", "comments"],
17
+ publicationState: "preview",
18
+ });
19
+
20
+
21
+ Case: using a variable declared somewhere else
22
+
23
+ const objectParam_2 = {
24
+ fields: ["id", "name", "description"],
25
+ populate: ["author", "comments"],
26
+ publicationState: "preview",
27
+ };
28
+
29
+ strapi.entityService.findOne(uid, entityId, objectParam_2);
30
+
31
+ Case: using a variable declared somewhere else with a spread element
32
+
33
+ const objectParam_3 = {
34
+ fields: ["id", "name", "description"],
35
+ populate: ["author", "comments"],
36
+ publicationState: "preview",
37
+ };
38
+
39
+ strapi.entityService.findOne(uid, entityId, {
40
+ ...objectParam_3,
41
+ });
42
+
43
+
44
+ Case: using a variable declared somewhere else with a spread element and overwritten properties
45
+
46
+ const objectParam_4_1 = {
47
+ fields: ["id", "name", "description"],
48
+ populate: ["author", "comments"],
49
+ publicationState: "preview",
50
+ };
51
+
52
+ const objectParam_4 = {
53
+ publicationState: "live",
54
+ ...objectParam_4_1,
55
+ };
56
+
57
+ strapi.entityService.findOne(uid, entityId, {
58
+ ...objectParam_4,
59
+ });
60
+
61
+ Case: using a variable declared somewhere else with a spread array element while that need its 1st element to be moved
62
+
63
+ const objectParam_5 = [
64
+ uid,
65
+ entityId,
66
+ {
67
+ fields: ["id", "name", "description"],
68
+ populate: ["author", "comments"],
69
+ publicationState: "preview",
70
+ },
71
+ ];
72
+
73
+ strapi.entityService.findOne(...objectParam_5);
74
+
75
+ Case: using a variable declared somewhere else with a partial spread array
76
+
77
+ const objectParam_6 = [
78
+ entityId,
79
+ {
80
+ fields: ["id", "name", "description"],
81
+ populate: ["author", "comments"],
82
+ publicationState: "preview",
83
+ },
84
+ ];
85
+
86
+ strapi.entityService.findOne(uid, ...objectParam_6);
87
+
88
+ Case: using a variable declared somewhere else with a partial & nested spread arrays
89
+
90
+ const objectParam_7_1 = [
91
+ {
92
+ fields: ["id", "name", "description"],
93
+ populate: ["author", "comments"],
94
+ publicationState: "preview",
95
+ },
96
+ ];
97
+
98
+ const objectParam_7 = [entityId, ...objectParam_7_1];
99
+
100
+ strapi.entityService.findOne(uid, ...objectParam_7);
101
+
102
+ Case: using a variable declared somewhere else with a partial & nested spread arrays & objects
103
+
104
+ const objectParam_8_1 = {
105
+ publicationState: "preview",
106
+ };
107
+
108
+ const objectParam_8 = [
109
+ entityId,
110
+ {
111
+ fields: ["id", "name", "description"],
112
+ populate: ["author", "comments"],
113
+ ...objectParam_8_1,
114
+ },
115
+ ];
116
+
117
+ strapi.entityService.findOne(uid, ...objectParam_8);
118
+
119
+
120
+ Case: some sort of mix of all the above
121
+
122
+ const objectParam_9_1 = {
123
+ publicationState: "preview",
124
+ };
125
+
126
+ const objectParam_9 = {
127
+ fields: ["id", "name", "description"],
128
+ populate: ["author", "comments"],
129
+ ...objectParam_9_1,
130
+ };
131
+
132
+ strapi.entityService.findOne(uid, ...[entityId, [objectParam_9]]);
133
+
134
+ Case: even more complex
135
+
136
+ const objectParam_10_1 = {
137
+ publicationState: "preview",
138
+ };
139
+
140
+ const objectParam_10_2 = [uid, ...[12], ...[objectParam_10_1]];
141
+ const objectParam_10 = [...objectParam_10_2];
142
+
143
+ strapi.entityService.findOne(...[...objectParam_10]);
144
+
145
+ */
146
+
147
+ const movedFunctions = ['findOne', 'find', 'count', 'create', 'update', 'delete'];
148
+
149
+ const transformDeclaration = (path: ASTPath<any>, name: any, j: JSCodeshift) => {
150
+ const declaration = findClosesDeclaration(path, name, j);
151
+
152
+ if (!declaration) {
153
+ return;
154
+ }
155
+
156
+ transformElement(path, declaration.init, j);
157
+ };
158
+
159
+ const transformElement = (path: ASTPath<any>, element: any, j: JSCodeshift) => {
160
+ switch (true) {
161
+ case j.ObjectExpression.check(element): {
162
+ transformObjectParam(path, element, j);
163
+ break;
164
+ }
165
+
166
+ case j.Identifier.check(element): {
167
+ transformDeclaration(path, element.name, j);
168
+ break;
169
+ }
170
+
171
+ case j.SpreadElement.check(element): {
172
+ transformElement(path, element.argument, j);
173
+ break;
174
+ }
175
+
176
+ case j.ArrayExpression.check(element): {
177
+ element.elements.forEach((element) => {
178
+ transformElement(path, element, j);
179
+ });
180
+ break;
181
+ }
182
+ default: {
183
+ break;
184
+ }
185
+ }
186
+ };
187
+
188
+ const transformObjectParam = (path: ASTPath<any>, expression: ObjectExpression, j: JSCodeshift) => {
189
+ expression.properties.forEach((prop) => {
190
+ switch (true) {
191
+ case j.ObjectProperty.check(prop): {
192
+ if (!j.Identifier.check(prop.key) && !j.Literal.check(prop.key)) {
193
+ return;
194
+ }
195
+
196
+ if (j.Identifier.check(prop.key) && prop.key.name !== 'publicationState') {
197
+ return;
198
+ }
199
+
200
+ if (j.Literal.check(prop.key) && prop.key.value !== 'publicationState') {
201
+ return;
202
+ }
203
+
204
+ if (j.Identifier.check(prop.key) && prop.key.name === 'publicationState') {
205
+ if (!prop.computed && !prop.shorthand) {
206
+ prop.key.name = 'status';
207
+ }
208
+
209
+ if (prop.shorthand && !prop.computed) {
210
+ prop.shorthand = false;
211
+ prop.key = j.identifier('status');
212
+ prop.value = j.identifier('publicationState');
213
+ }
214
+ } else if (j.Literal.check(prop.key) && prop.key.value === 'publicationState') {
215
+ prop.key.value = 'status';
216
+ }
217
+
218
+ switch (true) {
219
+ case j.Literal.check(prop.value): {
220
+ prop.value = prop.value.value === 'live' ? j.literal('published') : j.literal('draft');
221
+
222
+ break;
223
+ }
224
+ case j.Identifier.check(prop.value): {
225
+ const declaration = findClosesDeclaration(path, prop.value.name, j);
226
+
227
+ if (!declaration) {
228
+ return;
229
+ }
230
+
231
+ if (j.Literal.check(declaration.init)) {
232
+ declaration.init =
233
+ declaration.init.value === 'live' ? j.literal('published') : j.literal('draft');
234
+ }
235
+
236
+ break;
237
+ }
238
+ default: {
239
+ break;
240
+ }
241
+ }
242
+
243
+ break;
244
+ }
245
+ case j.SpreadElement.check(prop): {
246
+ transformElement(path, prop.argument, j);
247
+ break;
248
+ }
249
+ default: {
250
+ break;
251
+ }
252
+ }
253
+ });
254
+ };
255
+
256
+ const findClosesDeclaration = (path: ASTPath<any>, name: string, j) => {
257
+ // find Identifier declaration
258
+ const scope = path.scope.lookup(name);
259
+
260
+ if (!scope) {
261
+ return;
262
+ }
263
+
264
+ return j(scope.path)
265
+ .find(j.VariableDeclarator, { id: { type: 'Identifier', name } })
266
+ .nodes()[0];
267
+ };
268
+
269
+ const transform: Transform = (file, api) => {
270
+ const j = api.jscodeshift;
271
+
272
+ const root = j(file.source);
273
+
274
+ root
275
+ .find(j.CallExpression, {
276
+ callee: {
277
+ type: 'MemberExpression',
278
+ object: {
279
+ type: 'MemberExpression',
280
+ object: {
281
+ type: 'Identifier',
282
+ name: 'strapi',
283
+ },
284
+ property: {
285
+ type: 'Identifier',
286
+ name: 'entityService',
287
+ },
288
+ },
289
+ property: {
290
+ type: 'Identifier',
291
+ name: (name) => movedFunctions.includes(name),
292
+ },
293
+ },
294
+ })
295
+ .replaceWith((path) => {
296
+ if (!j.MemberExpression.check(path.value.callee)) {
297
+ return;
298
+ }
299
+
300
+ const args = path.value.arguments;
301
+
302
+ if (args.length === 0) {
303
+ // we don't know how to transform this
304
+ return;
305
+ }
306
+
307
+ type Args = typeof path.value.arguments;
308
+
309
+ function resolveArgs(args: Args): Args {
310
+ return args.flatMap((arg: Args[number]) => {
311
+ switch (true) {
312
+ case j.Identifier.check(arg):
313
+ case j.Literal.check(arg): {
314
+ return arg;
315
+ }
316
+ case j.SpreadElement.check(arg): {
317
+ switch (true) {
318
+ case j.Identifier.check(arg.argument): {
319
+ const identifier = arg.argument;
320
+
321
+ const declaration = findClosesDeclaration(path, identifier.name, j);
322
+
323
+ if (!declaration) {
324
+ return arg;
325
+ }
326
+
327
+ switch (true) {
328
+ case j.ArrayExpression.check(declaration.init): {
329
+ return resolveArgs(declaration.init.elements);
330
+ }
331
+ default:
332
+ return arg;
333
+ }
334
+ }
335
+ case j.ArrayExpression.check(arg.argument): {
336
+ return resolveArgs(arg.argument.elements as Args);
337
+ }
338
+ default: {
339
+ return arg;
340
+ }
341
+ }
342
+ }
343
+ default: {
344
+ return arg;
345
+ }
346
+ }
347
+ });
348
+ }
349
+
350
+ const resolvedArgs = resolveArgs(args);
351
+
352
+ const [docUID, ...rest] = resolvedArgs;
353
+
354
+ path.value.arguments.forEach((arg) => {
355
+ transformElement(path, arg, j);
356
+ });
357
+
358
+ return j.callExpression(
359
+ j.memberExpression(
360
+ j.callExpression(j.memberExpression(j.identifier('strapi'), j.identifier('documents')), [
361
+ docUID,
362
+ ]),
363
+ path.value.callee.property
364
+ ),
365
+ rest
366
+ );
367
+ });
368
+
369
+ return root.toSource();
370
+ };
371
+
372
+ export const parser = 'tsx';
373
+
374
+ export default transform;
@@ -59,7 +59,7 @@ const transform: Transform = (file, api) => {
59
59
  }
60
60
 
61
61
  const { j } = api;
62
- const root = j(file.source);
62
+ const root = j.withParser('tsx')(file.source);
63
63
 
64
64
  root
65
65
  .find(j.ArrowFunctionExpression)
@@ -17,18 +17,21 @@ const transform: modules.runner.json.JSONTransform = (file, params) => {
17
17
 
18
18
  const j = json(file.json);
19
19
 
20
+ let removed = false;
21
+
20
22
  const targetProperties = ['sqlite3', '@vscode/sqlite3'];
21
23
 
22
24
  targetProperties.forEach((targetProperty) => {
23
25
  const oldSqliteDependency = `dependencies.${targetProperty}`;
24
26
  if (j.has(oldSqliteDependency)) {
25
27
  j.remove(oldSqliteDependency);
28
+ removed = true;
26
29
  }
27
30
  });
28
31
 
29
- if (!j.has('dependencies.better-sqlite3')) {
32
+ if (removed && !j.has('dependencies.better-sqlite3')) {
30
33
  // TODO check this version when releasing V5
31
- j.set('dependencies.better-sqlite3', '9.0.0');
34
+ j.set('dependencies.better-sqlite3', '9.4.3');
32
35
  }
33
36
 
34
37
  return j.root();
@@ -0,0 +1,126 @@
1
+ import { Transform, JSCodeshift, Collection } from 'jscodeshift';
2
+
3
+ /*
4
+ This codemod transforms @strapi/strapi imports to use the new public interface.
5
+
6
+ ESM
7
+ Before:
8
+
9
+ import strapi from '@strapi/strapi';
10
+ strapi();
11
+
12
+ After:
13
+
14
+ import { createStrapi } from '@strapi/strapi'; // keeps the default import
15
+ createStrapi();
16
+
17
+ ---
18
+
19
+ Common JS
20
+ Before:
21
+
22
+ const strapi = require('@strapi/strapi');
23
+ strapi();
24
+
25
+ After:
26
+
27
+ const strapi = require('@strapi/strapi');
28
+ strapi.createStrapi();
29
+
30
+ */
31
+
32
+ const transformStrapiImport = (root: Collection, j: JSCodeshift) => {
33
+ root.find(j.ImportDefaultSpecifier).forEach((path) => {
34
+ if (path.parent.value.source.value === '@strapi/strapi') {
35
+ const newSpecifiers = path.parent.value.specifiers.filter(
36
+ (specifier) => specifier.type !== 'ImportDefaultSpecifier'
37
+ );
38
+
39
+ j(path.parent).replaceWith(
40
+ j.importDeclaration(
41
+ [...newSpecifiers, j.importSpecifier(j.identifier('createStrapi'))],
42
+ j.literal('@strapi/strapi')
43
+ )
44
+ );
45
+
46
+ transformFunctionCalls(path.value.local.name, root, j);
47
+ }
48
+ });
49
+ };
50
+
51
+ const transformRequireImport = (root: Collection, j: JSCodeshift) => {
52
+ root
53
+ .find(j.VariableDeclarator, {
54
+ init: {
55
+ callee: {
56
+ name: 'require',
57
+ },
58
+ arguments: [{ value: '@strapi/strapi' }],
59
+ },
60
+ })
61
+ .forEach((path) => {
62
+ if (path.value.id.type === 'Identifier') {
63
+ const identifier = path.value.id.name;
64
+
65
+ root
66
+ .find(j.CallExpression, {
67
+ callee: {
68
+ type: 'Identifier',
69
+ name: identifier,
70
+ },
71
+ })
72
+ .forEach((callExpressionPath) => {
73
+ j(callExpressionPath).replaceWith(
74
+ j.callExpression(
75
+ j.memberExpression(j.identifier(identifier), j.identifier('createStrapi')),
76
+ callExpressionPath.value.arguments
77
+ )
78
+ );
79
+ });
80
+ }
81
+ });
82
+ };
83
+
84
+ const transformFunctionCalls = (identifier: string, root: Collection, j: JSCodeshift) => {
85
+ root
86
+ .find(j.CallExpression, {
87
+ callee: {
88
+ type: 'Identifier',
89
+ name: identifier,
90
+ },
91
+ })
92
+ .forEach((path) => {
93
+ // we a type guard again to avoid ts issues
94
+ if (path.value.callee.type === 'Identifier') {
95
+ path.value.callee.name = 'createStrapi';
96
+ }
97
+ });
98
+ };
99
+
100
+ /**
101
+ * Transformations
102
+ *
103
+ * With ESM imports
104
+ *
105
+ * import strapi from '@strapi/strapi'; => import strapi, { createStrapi } from '@strapi/strapi';
106
+ * strapi() => createStrapi()
107
+ *
108
+ * With CJS imports
109
+ *
110
+ * const strapi = require('@strapi/strapi'); => no transform
111
+ * strapi() => strapi.createStrapi()
112
+ */
113
+ const transform: Transform = (file, api) => {
114
+ const j = api.jscodeshift;
115
+
116
+ const root = j(file.source);
117
+
118
+ transformStrapiImport(root, j);
119
+ transformRequireImport(root, j);
120
+
121
+ return root.toSource();
122
+ };
123
+
124
+ export const parser = 'tsx';
125
+
126
+ export default transform;
@@ -0,0 +1,45 @@
1
+ import { Transform } from 'jscodeshift';
2
+
3
+ /**
4
+ * Replaces string dot format for config get/set/has with uid format for 'plugin' and 'api' namespace where possible
5
+ * For example, `strapi.config.get('plugin.anyString')` will become `strapi.config.get('plugin::anyString')`
6
+ * Ignores api followed by 'rest' or 'responses' because those are the valid Strapi api config values in v4
7
+ */
8
+ const transform: Transform = (file, api) => {
9
+ const j = api.jscodeshift;
10
+ const root = j.withParser('tsx')(file.source);
11
+
12
+ const ignoreList = ['api.rest', 'api.responses'];
13
+
14
+ ['get', 'has', 'set'].forEach((configMethod) => {
15
+ root
16
+ .find(j.CallExpression, {
17
+ callee: {
18
+ type: 'MemberExpression',
19
+ object: {
20
+ type: 'MemberExpression',
21
+ object: { type: 'Identifier', name: 'strapi' },
22
+ property: { type: 'Identifier', name: 'config' },
23
+ },
24
+ property: { type: 'Identifier', name: configMethod },
25
+ },
26
+ // Note: we can't filter by arguments because it won't find them in typescript files
27
+ })
28
+ .forEach((path) => {
29
+ const argumentNode = path.node.arguments[0];
30
+ if (j.StringLiteral.check(argumentNode)) {
31
+ const value = argumentNode.value;
32
+ const isTargeted = value.startsWith('plugin.') || value.startsWith('api.');
33
+ const isIgnored = ignoreList.some((ignoreItem) => value.startsWith(ignoreItem));
34
+ if (!isTargeted || isIgnored) {
35
+ return;
36
+ }
37
+ argumentNode.value = value.replace('.', '::');
38
+ }
39
+ });
40
+ });
41
+
42
+ return root.toSource();
43
+ };
44
+
45
+ export default transform;