@strapi/upgrade 5.0.0-beta.0 → 5.0.0-beta.10
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.
- package/dist/cli.js +1452 -5
- package/dist/cli.js.map +1 -1
- package/dist/index.js +318 -89
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +319 -90
- package/dist/index.mjs.map +1 -1
- package/dist/modules/codemod/codemod.d.ts +4 -2
- package/dist/modules/codemod/codemod.d.ts.map +1 -1
- package/dist/modules/codemod/types.d.ts +8 -1
- package/dist/modules/codemod/types.d.ts.map +1 -1
- package/dist/modules/codemod-repository/constants.d.ts.map +1 -1
- package/dist/modules/codemod-repository/repository.d.ts +6 -5
- package/dist/modules/codemod-repository/repository.d.ts.map +1 -1
- package/dist/modules/codemod-repository/types.d.ts +7 -3
- package/dist/modules/codemod-repository/types.d.ts.map +1 -1
- package/dist/modules/codemod-runner/codemod-runner.d.ts +3 -0
- package/dist/modules/codemod-runner/codemod-runner.d.ts.map +1 -1
- package/dist/modules/codemod-runner/index.d.ts +1 -0
- package/dist/modules/codemod-runner/index.d.ts.map +1 -1
- package/dist/modules/codemod-runner/types.d.ts +1 -0
- package/dist/modules/codemod-runner/types.d.ts.map +1 -1
- package/dist/modules/format/formats.d.ts +5 -0
- package/dist/modules/format/formats.d.ts.map +1 -1
- package/dist/modules/project/constants.d.ts +2 -0
- package/dist/modules/project/constants.d.ts.map +1 -1
- package/dist/modules/project/index.d.ts +2 -0
- package/dist/modules/project/index.d.ts.map +1 -1
- package/dist/modules/project/project.d.ts +12 -4
- package/dist/modules/project/project.d.ts.map +1 -1
- package/dist/modules/project/types.d.ts +1 -11
- package/dist/modules/project/types.d.ts.map +1 -1
- package/dist/modules/project/utils.d.ts +6 -0
- package/dist/modules/project/utils.d.ts.map +1 -0
- package/dist/modules/report/report.d.ts.map +1 -1
- package/dist/modules/requirement/types.d.ts +2 -2
- package/dist/modules/requirement/types.d.ts.map +1 -1
- package/dist/modules/upgrader/upgrader.d.ts +3 -3
- package/dist/modules/upgrader/upgrader.d.ts.map +1 -1
- package/dist/modules/version/range.d.ts +2 -0
- package/dist/modules/version/range.d.ts.map +1 -1
- package/dist/tasks/codemods/index.d.ts +2 -1
- package/dist/tasks/codemods/index.d.ts.map +1 -1
- package/dist/tasks/codemods/list-codemods.d.ts +3 -0
- package/dist/tasks/codemods/list-codemods.d.ts.map +1 -0
- package/dist/tasks/codemods/run-codemods.d.ts +3 -0
- package/dist/tasks/codemods/run-codemods.d.ts.map +1 -0
- package/dist/tasks/codemods/types.d.ts +9 -3
- package/dist/tasks/codemods/types.d.ts.map +1 -1
- package/dist/tasks/codemods/utils.d.ts +6 -0
- package/dist/tasks/codemods/utils.d.ts.map +1 -0
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/upgrade/upgrade.d.ts.map +1 -1
- package/package.json +9 -8
- package/resources/codemods/5.0.0/dependency-remove-strapi-plugin-i18n.json.ts +31 -0
- package/resources/codemods/5.0.0/dependency-upgrade-react-router-dom.json.ts +59 -0
- package/resources/codemods/5.0.0/entity-service-document-service.code.ts +437 -0
- package/resources/codemods/5.0.0/s3-keys-wrapped-in-credentials.code.ts +1 -1
- package/resources/codemods/5.0.0/sqlite3-to-better-sqlite3.json.ts +5 -2
- package/resources/codemods/5.0.0/strapi-public-interface.code.ts +126 -0
- package/resources/codemods/5.0.0/use-uid-for-config-namespace.code.ts +1 -1
- package/resources/codemods/5.0.0/utils-public-interface.code.ts +320 -0
- package/resources/examples/console.log-to-console.info.code.ts +1 -1
- package/resources/examples/disable-jsx-buttons.code.ts +42 -0
- package/dist/_chunks/codemod-runner-gNmBzH6-.js +0 -730
- package/dist/_chunks/codemod-runner-gNmBzH6-.js.map +0 -1
- package/dist/_chunks/codemods--eBNi-jZ.js +0 -105
- package/dist/_chunks/codemods--eBNi-jZ.js.map +0 -1
- package/dist/_chunks/index-oO2o1y7M.js +0 -103
- package/dist/_chunks/index-oO2o1y7M.js.map +0 -1
- package/dist/_chunks/upgrade-9ZLeKVLU.js +0 -354
- package/dist/_chunks/upgrade-9ZLeKVLU.js.map +0 -1
- package/dist/tasks/codemods/codemods.d.ts +0 -3
- package/dist/tasks/codemods/codemods.d.ts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import simpleGit from "simple-git";
|
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import semver from "semver";
|
|
5
5
|
import { packageManager } from "@strapi/utils";
|
|
6
|
-
import { cloneDeep, get, has, merge, set, omit, isEqual } from "lodash/fp";
|
|
6
|
+
import { cloneDeep, get, has, merge, set, omit, isEqual, groupBy, size } from "lodash/fp";
|
|
7
7
|
import fse from "fs-extra";
|
|
8
8
|
import assert from "node:assert";
|
|
9
9
|
import { glob } from "glob";
|
|
@@ -253,13 +253,19 @@ const rangeFromVersions = (currentVersion, target) => {
|
|
|
253
253
|
}
|
|
254
254
|
throw new Error(`Invalid target set: ${target}`);
|
|
255
255
|
};
|
|
256
|
+
const isValidStringifiedRange = (str) => semver.validRange(str) !== null;
|
|
257
|
+
const isRangeInstance = (range) => {
|
|
258
|
+
return range instanceof semver.Range;
|
|
259
|
+
};
|
|
256
260
|
const index$e = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
257
261
|
__proto__: null,
|
|
258
262
|
Version: types,
|
|
259
263
|
isLiteralSemVer,
|
|
264
|
+
isRangeInstance,
|
|
260
265
|
isSemVerReleaseType,
|
|
261
266
|
isSemverInstance,
|
|
262
267
|
isValidSemVer,
|
|
268
|
+
isValidStringifiedRange,
|
|
263
269
|
rangeFactory,
|
|
264
270
|
rangeFromReleaseType,
|
|
265
271
|
rangeFromVersions,
|
|
@@ -366,7 +372,20 @@ const index$b = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
|
|
|
366
372
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
367
373
|
const PROJECT_PACKAGE_JSON = "package.json";
|
|
368
374
|
const PROJECT_DEFAULT_ALLOWED_ROOT_PATHS = ["src", "config", "public"];
|
|
369
|
-
const
|
|
375
|
+
const PROJECT_DEFAULT_CODE_EXTENSIONS = [
|
|
376
|
+
// Source files
|
|
377
|
+
"js",
|
|
378
|
+
"mjs",
|
|
379
|
+
"ts",
|
|
380
|
+
// React files
|
|
381
|
+
"jsx",
|
|
382
|
+
"tsx"
|
|
383
|
+
];
|
|
384
|
+
const PROJECT_DEFAULT_JSON_EXTENSIONS = ["json"];
|
|
385
|
+
const PROJECT_DEFAULT_ALLOWED_EXTENSIONS = [
|
|
386
|
+
...PROJECT_DEFAULT_CODE_EXTENSIONS,
|
|
387
|
+
...PROJECT_DEFAULT_JSON_EXTENSIONS
|
|
388
|
+
];
|
|
370
389
|
const PROJECT_DEFAULT_PATTERNS = ["package.json"];
|
|
371
390
|
const SCOPED_STRAPI_PACKAGE_PREFIX = "@strapi/";
|
|
372
391
|
const STRAPI_DEPENDENCY_NAME = `${SCOPED_STRAPI_PACKAGE_PREFIX}strapi`;
|
|
@@ -374,6 +393,8 @@ const constants$3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
|
|
|
374
393
|
__proto__: null,
|
|
375
394
|
PROJECT_DEFAULT_ALLOWED_EXTENSIONS,
|
|
376
395
|
PROJECT_DEFAULT_ALLOWED_ROOT_PATHS,
|
|
396
|
+
PROJECT_DEFAULT_CODE_EXTENSIONS,
|
|
397
|
+
PROJECT_DEFAULT_JSON_EXTENSIONS,
|
|
377
398
|
PROJECT_DEFAULT_PATTERNS,
|
|
378
399
|
PROJECT_PACKAGE_JSON,
|
|
379
400
|
SCOPED_STRAPI_PACKAGE_PREFIX,
|
|
@@ -385,7 +406,6 @@ class Project {
|
|
|
385
406
|
files;
|
|
386
407
|
packageJSONPath;
|
|
387
408
|
packageJSON;
|
|
388
|
-
strapiVersion;
|
|
389
409
|
constructor(cwd) {
|
|
390
410
|
if (!fse.pathExistsSync(cwd)) {
|
|
391
411
|
throw new Error(`ENOENT: no such file or directory, access '${cwd}'`);
|
|
@@ -401,14 +421,13 @@ class Project {
|
|
|
401
421
|
}
|
|
402
422
|
refresh() {
|
|
403
423
|
this.refreshPackageJSON();
|
|
404
|
-
this.refreshStrapiVersion();
|
|
405
424
|
this.refreshProjectFiles();
|
|
406
425
|
return this;
|
|
407
426
|
}
|
|
408
|
-
async runCodemods(
|
|
427
|
+
async runCodemods(codemods, options) {
|
|
409
428
|
const runners = this.createProjectCodemodsRunners(options.dry);
|
|
410
429
|
const reports2 = [];
|
|
411
|
-
for (const codemod of
|
|
430
|
+
for (const codemod of codemods) {
|
|
412
431
|
for (const runner of runners) {
|
|
413
432
|
if (runner.valid(codemod)) {
|
|
414
433
|
const report = await runner.run(codemod);
|
|
@@ -419,17 +438,24 @@ class Project {
|
|
|
419
438
|
return reports2;
|
|
420
439
|
}
|
|
421
440
|
createProjectCodemodsRunners(dry = false) {
|
|
422
|
-
const
|
|
423
|
-
|
|
441
|
+
const jsonExtensions = PROJECT_DEFAULT_JSON_EXTENSIONS.map(
|
|
442
|
+
(ext) => `.${ext}`
|
|
443
|
+
);
|
|
444
|
+
const codeExtensions = PROJECT_DEFAULT_CODE_EXTENSIONS.map(
|
|
445
|
+
(ext) => `.${ext}`
|
|
446
|
+
);
|
|
447
|
+
const jsonFiles = this.getFilesByExtensions(jsonExtensions);
|
|
448
|
+
const codeFiles = this.getFilesByExtensions(codeExtensions);
|
|
424
449
|
const codeRunner = codeRunnerFactory(codeFiles, {
|
|
425
450
|
dry,
|
|
426
|
-
|
|
427
|
-
silent: true,
|
|
428
|
-
extensions: "js,ts",
|
|
451
|
+
parser: "ts",
|
|
429
452
|
runInBand: true,
|
|
430
|
-
verbose: 0,
|
|
431
453
|
babel: true,
|
|
432
|
-
|
|
454
|
+
extensions: PROJECT_DEFAULT_CODE_EXTENSIONS.join(","),
|
|
455
|
+
// Don't output any log coming from the runner
|
|
456
|
+
print: false,
|
|
457
|
+
silent: true,
|
|
458
|
+
verbose: 0
|
|
433
459
|
});
|
|
434
460
|
const jsonRunner = jsonRunnerFactory(jsonFiles, { dry, cwd: this.cwd });
|
|
435
461
|
return [codeRunner, jsonRunner];
|
|
@@ -457,6 +483,19 @@ class Project {
|
|
|
457
483
|
const scanner = fileScannerFactory(this.cwd);
|
|
458
484
|
this.files = scanner.scan(patterns);
|
|
459
485
|
}
|
|
486
|
+
}
|
|
487
|
+
class AppProject extends Project {
|
|
488
|
+
strapiVersion;
|
|
489
|
+
type = "application";
|
|
490
|
+
constructor(cwd) {
|
|
491
|
+
super(cwd);
|
|
492
|
+
this.refreshStrapiVersion();
|
|
493
|
+
}
|
|
494
|
+
refresh() {
|
|
495
|
+
super.refresh();
|
|
496
|
+
this.refreshStrapiVersion();
|
|
497
|
+
return this;
|
|
498
|
+
}
|
|
460
499
|
refreshStrapiVersion() {
|
|
461
500
|
this.strapiVersion = // First try to get the strapi version from the package.json dependencies
|
|
462
501
|
this.findStrapiVersionFromProjectPackageJSON() ?? // If the version found is not a valid SemVer, get the Strapi version from the installed package
|
|
@@ -502,10 +541,50 @@ const formatGlobCollectionPattern = (collection) => {
|
|
|
502
541
|
);
|
|
503
542
|
return collection.length === 1 ? collection[0] : `{${collection}}`;
|
|
504
543
|
};
|
|
505
|
-
|
|
544
|
+
class PluginProject extends Project {
|
|
545
|
+
type = "plugin";
|
|
546
|
+
}
|
|
547
|
+
const isPlugin = (cwd) => {
|
|
548
|
+
const packageJSONPath = path$1.join(cwd, PROJECT_PACKAGE_JSON);
|
|
549
|
+
try {
|
|
550
|
+
fse.accessSync(packageJSONPath);
|
|
551
|
+
} catch {
|
|
552
|
+
throw new Error(`Could not find a ${PROJECT_PACKAGE_JSON} file in ${cwd}`);
|
|
553
|
+
}
|
|
554
|
+
const packageJSONBuffer = fse.readFileSync(packageJSONPath);
|
|
555
|
+
const packageJSON = JSON.parse(packageJSONBuffer.toString());
|
|
556
|
+
return packageJSON?.strapi?.kind === "plugin";
|
|
557
|
+
};
|
|
558
|
+
const projectFactory = (cwd) => {
|
|
559
|
+
fse.accessSync(cwd);
|
|
560
|
+
if (isPlugin(cwd)) {
|
|
561
|
+
return new PluginProject(cwd);
|
|
562
|
+
}
|
|
563
|
+
return new AppProject(cwd);
|
|
564
|
+
};
|
|
565
|
+
const isPluginProject = (project) => {
|
|
566
|
+
return project instanceof PluginProject;
|
|
567
|
+
};
|
|
568
|
+
function assertPluginProject(project) {
|
|
569
|
+
if (!isPluginProject(project)) {
|
|
570
|
+
throw new Error("Project is not a plugin");
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
const isApplicationProject = (project) => {
|
|
574
|
+
return project instanceof AppProject;
|
|
575
|
+
};
|
|
576
|
+
function assertAppProject(project) {
|
|
577
|
+
if (!isApplicationProject(project)) {
|
|
578
|
+
throw new Error("Project is not an application");
|
|
579
|
+
}
|
|
580
|
+
}
|
|
506
581
|
const index$a = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
507
582
|
__proto__: null,
|
|
583
|
+
assertAppProject,
|
|
584
|
+
assertPluginProject,
|
|
508
585
|
constants: constants$3,
|
|
586
|
+
isApplicationProject,
|
|
587
|
+
isPluginProject,
|
|
509
588
|
projectFactory
|
|
510
589
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
511
590
|
class UnexpectedError extends Error {
|
|
@@ -531,7 +610,11 @@ const path = (path2) => chalk.blue(path2);
|
|
|
531
610
|
const version = (version2) => {
|
|
532
611
|
return chalk.italic.yellow(`v${version2}`);
|
|
533
612
|
};
|
|
534
|
-
const
|
|
613
|
+
const codemodUID = (uid) => {
|
|
614
|
+
return chalk.bold.cyan(uid);
|
|
615
|
+
};
|
|
616
|
+
const projectType = (type) => chalk.cyan(type);
|
|
617
|
+
const versionRange = (range) => chalk.italic.yellow(range.raw);
|
|
535
618
|
const transform = (transformFilePath) => chalk.cyan(transformFilePath);
|
|
536
619
|
const highlight = (arg) => chalk.bold.underline(arg);
|
|
537
620
|
const upgradeStep = (text, step) => {
|
|
@@ -563,15 +646,40 @@ const reports = (reports2) => {
|
|
|
563
646
|
table.push(...rows);
|
|
564
647
|
return table.toString();
|
|
565
648
|
};
|
|
649
|
+
const codemodList = (codemods) => {
|
|
650
|
+
const rows = codemods.map((codemod, index2) => {
|
|
651
|
+
const fIndex = chalk.grey(index2);
|
|
652
|
+
const fVersion = chalk.magenta(codemod.version);
|
|
653
|
+
const fKind = chalk.yellow(codemod.kind);
|
|
654
|
+
const fName = chalk.blue(codemod.format());
|
|
655
|
+
const fUID = codemodUID(codemod.uid);
|
|
656
|
+
return [fIndex, fVersion, fKind, fName, fUID];
|
|
657
|
+
});
|
|
658
|
+
const table = new CliTable3({
|
|
659
|
+
style: { compact: true },
|
|
660
|
+
head: [
|
|
661
|
+
chalk.bold.grey("N°"),
|
|
662
|
+
chalk.bold.magenta("Version"),
|
|
663
|
+
chalk.bold.yellow("Kind"),
|
|
664
|
+
chalk.bold.blue("Name"),
|
|
665
|
+
chalk.bold.cyan("UID")
|
|
666
|
+
]
|
|
667
|
+
});
|
|
668
|
+
table.push(...rows);
|
|
669
|
+
return table.toString();
|
|
670
|
+
};
|
|
566
671
|
const durationMs = (elapsedMs) => {
|
|
567
672
|
const elapsedSeconds = (elapsedMs / ONE_SECOND_MS).toFixed(3);
|
|
568
673
|
return `${elapsedSeconds}s`;
|
|
569
674
|
};
|
|
570
675
|
const index$8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
571
676
|
__proto__: null,
|
|
677
|
+
codemodList,
|
|
678
|
+
codemodUID,
|
|
572
679
|
durationMs,
|
|
573
680
|
highlight,
|
|
574
681
|
path,
|
|
682
|
+
projectType,
|
|
575
683
|
reports,
|
|
576
684
|
transform,
|
|
577
685
|
upgradeStep,
|
|
@@ -594,6 +702,7 @@ const constants$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
|
|
|
594
702
|
CODEMOD_JSON_SUFFIX
|
|
595
703
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
596
704
|
class Codemod {
|
|
705
|
+
uid;
|
|
597
706
|
kind;
|
|
598
707
|
version;
|
|
599
708
|
baseDirectory;
|
|
@@ -605,9 +714,27 @@ class Codemod {
|
|
|
605
714
|
this.baseDirectory = options.baseDirectory;
|
|
606
715
|
this.filename = options.filename;
|
|
607
716
|
this.path = path$1.join(this.baseDirectory, this.version.raw, this.filename);
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
717
|
+
this.uid = this.createUID();
|
|
718
|
+
}
|
|
719
|
+
createUID() {
|
|
720
|
+
const name = this.format({ stripExtension: true, stripKind: true, stripHyphens: false });
|
|
721
|
+
const kind = this.kind;
|
|
722
|
+
const version2 = this.version.raw;
|
|
723
|
+
return `${version2}-${name}-${kind}`;
|
|
724
|
+
}
|
|
725
|
+
format(options) {
|
|
726
|
+
const { stripExtension = true, stripKind = true, stripHyphens = true } = options ?? {};
|
|
727
|
+
let formatted = this.filename;
|
|
728
|
+
if (stripExtension) {
|
|
729
|
+
formatted = formatted.replace(new RegExp(`\\.${CODEMOD_EXTENSION}$`, "i"), "");
|
|
730
|
+
}
|
|
731
|
+
if (stripKind) {
|
|
732
|
+
formatted = formatted.replace(`.${CODEMOD_CODE_SUFFIX}`, "").replace(`.${CODEMOD_JSON_SUFFIX}`, "");
|
|
733
|
+
}
|
|
734
|
+
if (stripHyphens) {
|
|
735
|
+
formatted = formatted.replaceAll("-", " ");
|
|
736
|
+
}
|
|
737
|
+
return formatted;
|
|
611
738
|
}
|
|
612
739
|
}
|
|
613
740
|
const codemodFactory = (options) => new Codemod(options);
|
|
@@ -616,6 +743,20 @@ const index$7 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
|
|
|
616
743
|
codemodFactory,
|
|
617
744
|
constants: constants$2
|
|
618
745
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
746
|
+
const INTERNAL_CODEMODS_DIRECTORY = path$1.join(
|
|
747
|
+
__dirname,
|
|
748
|
+
// upgrade/dist
|
|
749
|
+
"..",
|
|
750
|
+
// upgrade
|
|
751
|
+
"resources",
|
|
752
|
+
// upgrade/resources
|
|
753
|
+
"codemods"
|
|
754
|
+
// upgrade/resources/codemods
|
|
755
|
+
);
|
|
756
|
+
const constants$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
757
|
+
__proto__: null,
|
|
758
|
+
INTERNAL_CODEMODS_DIRECTORY
|
|
759
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
619
760
|
class CodemodRepository {
|
|
620
761
|
groups;
|
|
621
762
|
versions;
|
|
@@ -634,23 +775,48 @@ class CodemodRepository {
|
|
|
634
775
|
count(version2) {
|
|
635
776
|
return this.findByVersion(version2).length;
|
|
636
777
|
}
|
|
637
|
-
|
|
638
|
-
return this.findByRange(range).length;
|
|
639
|
-
}
|
|
640
|
-
exists(version2) {
|
|
778
|
+
versionExists(version2) {
|
|
641
779
|
return version2.raw in this.groups;
|
|
642
780
|
}
|
|
643
|
-
|
|
781
|
+
has(uid) {
|
|
782
|
+
const result = this.find({ uids: [uid] });
|
|
783
|
+
if (result.length !== 1) {
|
|
784
|
+
return false;
|
|
785
|
+
}
|
|
786
|
+
const { codemods } = result[0];
|
|
787
|
+
return codemods.length === 1 && codemods[0].uid === uid;
|
|
788
|
+
}
|
|
789
|
+
find(q) {
|
|
644
790
|
const entries = Object.entries(this.groups);
|
|
645
|
-
return entries.filter(
|
|
791
|
+
return entries.filter(maybeFilterByRange).map(([version2, codemods]) => ({
|
|
646
792
|
version: semVerFactory(version2),
|
|
647
|
-
|
|
648
|
-
|
|
793
|
+
// Filter by UID if provided in the query
|
|
794
|
+
codemods: codemods.filter(maybeFilterByUIDs)
|
|
795
|
+
})).filter(({ codemods }) => codemods.length > 0);
|
|
796
|
+
function maybeFilterByRange([version2]) {
|
|
797
|
+
if (!isRangeInstance(q.range)) {
|
|
798
|
+
return true;
|
|
799
|
+
}
|
|
800
|
+
return q.range.test(version2);
|
|
801
|
+
}
|
|
802
|
+
function maybeFilterByUIDs(codemod) {
|
|
803
|
+
if (q.uids === void 0) {
|
|
804
|
+
return true;
|
|
805
|
+
}
|
|
806
|
+
return q.uids.includes(codemod.uid);
|
|
807
|
+
}
|
|
649
808
|
}
|
|
650
809
|
findByVersion(version2) {
|
|
651
810
|
const literalVersion = version2.raw;
|
|
652
|
-
const
|
|
653
|
-
return
|
|
811
|
+
const codemods = this.groups[literalVersion];
|
|
812
|
+
return codemods ?? [];
|
|
813
|
+
}
|
|
814
|
+
findAll() {
|
|
815
|
+
const entries = Object.entries(this.groups);
|
|
816
|
+
return entries.map(([version2, codemods]) => ({
|
|
817
|
+
version: semVerFactory(version2),
|
|
818
|
+
codemods
|
|
819
|
+
}));
|
|
654
820
|
}
|
|
655
821
|
refreshAvailableVersions() {
|
|
656
822
|
this.versions = fse.readdirSync(this.cwd).filter((filename) => fse.statSync(path$1.join(this.cwd, filename)).isDirectory()).filter((filename) => semver.valid(filename) !== null).map((version2) => semVerFactory(version2)).sort(semver.compare);
|
|
@@ -681,18 +847,9 @@ const parseCodemodKindFromFilename = (filename) => {
|
|
|
681
847
|
assert(CODEMOD_ALLOWED_SUFFIXES.includes(kind));
|
|
682
848
|
return kind;
|
|
683
849
|
};
|
|
684
|
-
const codemodRepositoryFactory = (cwd) =>
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
"..",
|
|
688
|
-
"..",
|
|
689
|
-
"resources",
|
|
690
|
-
"codemods"
|
|
691
|
-
);
|
|
692
|
-
const constants$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
693
|
-
__proto__: null,
|
|
694
|
-
INTERNAL_CODEMODS_DIRECTORY
|
|
695
|
-
}, Symbol.toStringTag, { value: "Module" }));
|
|
850
|
+
const codemodRepositoryFactory = (cwd = INTERNAL_CODEMODS_DIRECTORY) => {
|
|
851
|
+
return new CodemodRepository(cwd);
|
|
852
|
+
};
|
|
696
853
|
const index$6 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
697
854
|
__proto__: null,
|
|
698
855
|
codemodRepositoryFactory,
|
|
@@ -727,34 +884,59 @@ class CodemodRunner {
|
|
|
727
884
|
this.isDry = enabled;
|
|
728
885
|
return this;
|
|
729
886
|
}
|
|
730
|
-
|
|
887
|
+
createRepository(codemodsDirectory) {
|
|
731
888
|
const repository = codemodRepositoryFactory(
|
|
732
889
|
codemodsDirectory ?? INTERNAL_CODEMODS_DIRECTORY
|
|
733
890
|
);
|
|
734
891
|
repository.refresh();
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
if (
|
|
739
|
-
this.logger?.
|
|
740
|
-
|
|
892
|
+
return repository;
|
|
893
|
+
}
|
|
894
|
+
async safeRunAndReport(codemods) {
|
|
895
|
+
if (this.isDry) {
|
|
896
|
+
this.logger?.warn?.(
|
|
897
|
+
"Running the codemods in dry mode. No files will be modified during the process."
|
|
898
|
+
);
|
|
741
899
|
}
|
|
742
|
-
this.logger?.debug(
|
|
743
|
-
`Found codemods for ${highlight(
|
|
744
|
-
versionedCodemods.length
|
|
745
|
-
)} version(s) using ${versionRange(this.range)}`
|
|
746
|
-
);
|
|
747
|
-
versionedCodemods.forEach(
|
|
748
|
-
({ version: version$1, codemods: codemods22 }) => this.logger?.debug(`- ${version(version$1)} (${codemods22.length})`)
|
|
749
|
-
);
|
|
750
|
-
const codemods2 = versionedCodemods.map(({ codemods: codemods22 }) => codemods22).flat();
|
|
751
900
|
try {
|
|
752
|
-
const reports$1 = await this.project.runCodemods(
|
|
753
|
-
this.logger?.raw(reports(reports$1));
|
|
901
|
+
const reports$1 = await this.project.runCodemods(codemods, { dry: this.isDry });
|
|
902
|
+
this.logger?.raw?.(reports(reports$1));
|
|
903
|
+
if (!this.isDry) {
|
|
904
|
+
const nbAffectedTotal = reports$1.flatMap((report) => report.report.ok).reduce((acc, nb) => acc + nb, 0);
|
|
905
|
+
this.logger?.debug?.(
|
|
906
|
+
`Successfully ran ${highlight(codemods.length)} codemod(s), ${highlight(nbAffectedTotal)} change(s) have been detected`
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
return successReport$1();
|
|
754
910
|
} catch (e) {
|
|
755
911
|
return erroredReport$1(unknownToError(e));
|
|
756
912
|
}
|
|
757
|
-
|
|
913
|
+
}
|
|
914
|
+
async runByUID(uid, codemodsDirectory) {
|
|
915
|
+
const repository = this.createRepository(codemodsDirectory);
|
|
916
|
+
if (!repository.has(uid)) {
|
|
917
|
+
throw new Error(`Unknown codemod UID provided: ${uid}`);
|
|
918
|
+
}
|
|
919
|
+
const codemods = repository.find({ uids: [uid] }).flatMap(({ codemods: codemods2 }) => codemods2);
|
|
920
|
+
return this.safeRunAndReport(codemods);
|
|
921
|
+
}
|
|
922
|
+
async run(codemodsDirectory) {
|
|
923
|
+
const repository = this.createRepository(codemodsDirectory);
|
|
924
|
+
const codemodsInRange = repository.find({ range: this.range });
|
|
925
|
+
const selectedCodemods = this.selectCodemodsCallback ? await this.selectCodemodsCallback(codemodsInRange) : codemodsInRange;
|
|
926
|
+
if (selectedCodemods.length === 0) {
|
|
927
|
+
this.logger?.debug?.(`Found no codemods to run for ${versionRange(this.range)}`);
|
|
928
|
+
return successReport$1();
|
|
929
|
+
}
|
|
930
|
+
const codemods = selectedCodemods.flatMap(({ codemods: codemods2 }) => codemods2);
|
|
931
|
+
const codemodsByVersion = groupBy("version", codemods);
|
|
932
|
+
const fRange = versionRange(this.range);
|
|
933
|
+
this.logger?.debug?.(
|
|
934
|
+
`Found ${highlight(codemods.length)} codemods for ${highlight(size(codemodsByVersion))} version(s) using ${fRange}`
|
|
935
|
+
);
|
|
936
|
+
for (const [version$1, codemods2] of Object.entries(codemodsByVersion)) {
|
|
937
|
+
this.logger?.debug?.(`- ${version(semVerFactory(version$1))} (${codemods2.length})`);
|
|
938
|
+
}
|
|
939
|
+
return this.safeRunAndReport(codemods);
|
|
758
940
|
}
|
|
759
941
|
}
|
|
760
942
|
const codemodRunnerFactory = (project, range) => {
|
|
@@ -793,7 +975,7 @@ class Upgrader {
|
|
|
793
975
|
this.codemodsTarget = semVerFactory(
|
|
794
976
|
`${this.target.major}.${this.target.minor}.${this.target.patch}`
|
|
795
977
|
);
|
|
796
|
-
this.logger?.debug(
|
|
978
|
+
this.logger?.debug?.(
|
|
797
979
|
`The codemods target has been synced with the upgrade target. The codemod runner will now look for ${version(
|
|
798
980
|
this.codemodsTarget
|
|
799
981
|
)}`
|
|
@@ -802,7 +984,7 @@ class Upgrader {
|
|
|
802
984
|
}
|
|
803
985
|
overrideCodemodsTarget(target) {
|
|
804
986
|
this.codemodsTarget = target;
|
|
805
|
-
this.logger?.debug(
|
|
987
|
+
this.logger?.debug?.(
|
|
806
988
|
`Overriding the codemods target. The codemod runner will now look for ${version(target)}`
|
|
807
989
|
);
|
|
808
990
|
return this;
|
|
@@ -822,38 +1004,40 @@ class Upgrader {
|
|
|
822
1004
|
addRequirement(requirement) {
|
|
823
1005
|
this.requirements.push(requirement);
|
|
824
1006
|
const fRequired = requirement.isRequired ? "(required)" : "(optional)";
|
|
825
|
-
this.logger?.debug(
|
|
1007
|
+
this.logger?.debug?.(
|
|
826
1008
|
`Added a new requirement to the upgrade: ${highlight(requirement.name)} ${fRequired}`
|
|
827
1009
|
);
|
|
828
1010
|
return this;
|
|
829
1011
|
}
|
|
830
1012
|
async upgrade() {
|
|
831
|
-
this.logger?.info(
|
|
1013
|
+
this.logger?.info?.(
|
|
832
1014
|
`Upgrading from ${version(this.project.strapiVersion)} to ${version(this.target)}`
|
|
833
1015
|
);
|
|
834
1016
|
if (this.isDry) {
|
|
835
|
-
this.logger?.warn(
|
|
1017
|
+
this.logger?.warn?.(
|
|
836
1018
|
"Running the upgrade in dry mode. No files will be modified during the process."
|
|
837
1019
|
);
|
|
838
1020
|
}
|
|
839
1021
|
const range = rangeFromVersions(this.project.strapiVersion, this.target);
|
|
840
1022
|
const codemodsRange = rangeFromVersions(this.project.strapiVersion, this.codemodsTarget);
|
|
841
1023
|
const npmVersionsMatches = this.npmPackage?.findVersionsInRange(range) ?? [];
|
|
842
|
-
this.logger?.debug(
|
|
1024
|
+
this.logger?.debug?.(
|
|
843
1025
|
`Found ${highlight(npmVersionsMatches.length)} versions satisfying ${versionRange(range)}`
|
|
844
1026
|
);
|
|
845
1027
|
try {
|
|
846
|
-
this.logger?.info(upgradeStep("Checking requirement", [1, 4]));
|
|
1028
|
+
this.logger?.info?.(upgradeStep("Checking requirement", [1, 4]));
|
|
847
1029
|
await this.checkRequirements(this.requirements, {
|
|
848
1030
|
npmVersionsMatches,
|
|
849
1031
|
project: this.project,
|
|
850
1032
|
target: this.target
|
|
851
1033
|
});
|
|
852
|
-
this.logger?.info(upgradeStep("Applying the latest code modifications", [2, 4]));
|
|
1034
|
+
this.logger?.info?.(upgradeStep("Applying the latest code modifications", [2, 4]));
|
|
853
1035
|
await this.runCodemods(codemodsRange);
|
|
854
|
-
this.logger?.
|
|
1036
|
+
this.logger?.debug?.("Refreshing project information...");
|
|
1037
|
+
this.project.refresh();
|
|
1038
|
+
this.logger?.info?.(upgradeStep("Upgrading Strapi dependencies", [3, 4]));
|
|
855
1039
|
await this.updateDependencies();
|
|
856
|
-
this.logger?.info(upgradeStep("Installing dependencies", [4, 4]));
|
|
1040
|
+
this.logger?.info?.(upgradeStep("Installing dependencies", [4, 4]));
|
|
857
1041
|
await this.installDependencies();
|
|
858
1042
|
} catch (e) {
|
|
859
1043
|
return erroredReport(unknownToError(e));
|
|
@@ -886,7 +1070,7 @@ class Upgrader {
|
|
|
886
1070
|
if (requirement.isRequired) {
|
|
887
1071
|
throw error;
|
|
888
1072
|
}
|
|
889
|
-
this.logger?.warn(warningMessage);
|
|
1073
|
+
this.logger?.warn?.(warningMessage);
|
|
890
1074
|
const response = await this.confirmationCallback?.(confirmationMessage);
|
|
891
1075
|
if (!response) {
|
|
892
1076
|
throw error;
|
|
@@ -897,9 +1081,11 @@ class Upgrader {
|
|
|
897
1081
|
const json = createJSONTransformAPI(packageJSON);
|
|
898
1082
|
const dependencies = json.get("dependencies", {});
|
|
899
1083
|
const strapiDependencies = this.getScopedStrapiDependencies(dependencies);
|
|
900
|
-
this.logger?.debug(
|
|
1084
|
+
this.logger?.debug?.(
|
|
1085
|
+
`Found ${highlight(strapiDependencies.length)} dependency(ies) to update`
|
|
1086
|
+
);
|
|
901
1087
|
strapiDependencies.forEach(
|
|
902
|
-
(dependency) => this.logger?.debug(`- ${dependency[0]} (${dependency[1]} -> ${this.target})`)
|
|
1088
|
+
(dependency) => this.logger?.debug?.(`- ${dependency[0]} (${dependency[1]} -> ${this.target})`)
|
|
903
1089
|
);
|
|
904
1090
|
if (strapiDependencies.length === 0) {
|
|
905
1091
|
return;
|
|
@@ -907,7 +1093,7 @@ class Upgrader {
|
|
|
907
1093
|
strapiDependencies.forEach(([name]) => json.set(`dependencies.${name}`, this.target.raw));
|
|
908
1094
|
const updatedPackageJSON = json.root();
|
|
909
1095
|
if (this.isDry) {
|
|
910
|
-
this.logger?.debug(`Skipping dependencies update (${chalk.italic("dry mode")})`);
|
|
1096
|
+
this.logger?.debug?.(`Skipping dependencies update (${chalk.italic("dry mode")})`);
|
|
911
1097
|
return;
|
|
912
1098
|
}
|
|
913
1099
|
await saveJSON(packageJSONPath, updatedPackageJSON);
|
|
@@ -927,9 +1113,9 @@ class Upgrader {
|
|
|
927
1113
|
async installDependencies() {
|
|
928
1114
|
const projectPath = this.project.cwd;
|
|
929
1115
|
const packageManagerName = await packageManager.getPreferred(projectPath);
|
|
930
|
-
this.logger?.debug(`Using ${highlight(packageManagerName)} as package manager`);
|
|
1116
|
+
this.logger?.debug?.(`Using ${highlight(packageManagerName)} as package manager`);
|
|
931
1117
|
if (this.isDry) {
|
|
932
|
-
this.logger?.debug(`Skipping dependencies installation (${chalk.italic("dry mode")}`);
|
|
1118
|
+
this.logger?.debug?.(`Skipping dependencies installation (${chalk.italic("dry mode")}`);
|
|
933
1119
|
return;
|
|
934
1120
|
}
|
|
935
1121
|
await packageManager.installDependencies(projectPath, packageManagerName, {
|
|
@@ -1028,6 +1214,11 @@ const upgrade = async (options) => {
|
|
|
1028
1214
|
const { logger, codemodsTarget } = options;
|
|
1029
1215
|
const cwd = path$1.resolve(options.cwd ?? process.cwd());
|
|
1030
1216
|
const project = projectFactory(cwd);
|
|
1217
|
+
if (!isApplicationProject(project)) {
|
|
1218
|
+
throw new Error(
|
|
1219
|
+
`The "${options.target}" upgrade can only be run on a Strapi project; for plugins, please use "codemods".`
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1031
1222
|
const npmPackage = npmPackageFactory(STRAPI_PACKAGE_NAME);
|
|
1032
1223
|
await npmPackage.refresh();
|
|
1033
1224
|
const upgrader = upgraderFactory(project, options.target, npmPackage).dry(options.dry ?? false).onConfirm(options.confirm ?? null).setLogger(logger);
|
|
@@ -1045,20 +1236,7 @@ const upgrade = async (options) => {
|
|
|
1045
1236
|
timer.stop();
|
|
1046
1237
|
logger.info(`Completed in ${durationMs(timer.elapsedMs)}`);
|
|
1047
1238
|
};
|
|
1048
|
-
const
|
|
1049
|
-
const timer = timerFactory();
|
|
1050
|
-
const { logger } = options;
|
|
1051
|
-
const cwd = path$1.resolve(options.cwd ?? process.cwd());
|
|
1052
|
-
const project = projectFactory(cwd);
|
|
1053
|
-
const range = getRangeFromTarget(project.strapiVersion, options.target);
|
|
1054
|
-
const codemodRunner = codemodRunnerFactory(project, range).dry(options.dry ?? false).onSelectCodemods(options.selectCodemods ?? null).setLogger(logger);
|
|
1055
|
-
const executionReport = await codemodRunner.run();
|
|
1056
|
-
if (!executionReport.success) {
|
|
1057
|
-
throw executionReport.error;
|
|
1058
|
-
}
|
|
1059
|
-
timer.stop();
|
|
1060
|
-
logger.info(`Completed in ${timer.elapsedMs}`);
|
|
1061
|
-
};
|
|
1239
|
+
const resolvePath = (cwd) => path$1.resolve(cwd ?? process.cwd());
|
|
1062
1240
|
const getRangeFromTarget = (currentVersion, target) => {
|
|
1063
1241
|
if (isSemverInstance(target)) {
|
|
1064
1242
|
return rangeFactory(target);
|
|
@@ -1075,9 +1253,60 @@ const getRangeFromTarget = (currentVersion, target) => {
|
|
|
1075
1253
|
throw new Error(`Invalid target set: ${target}`);
|
|
1076
1254
|
}
|
|
1077
1255
|
};
|
|
1256
|
+
const findRangeFromTarget = (project, target) => {
|
|
1257
|
+
if (isRangeInstance(target)) {
|
|
1258
|
+
return target;
|
|
1259
|
+
}
|
|
1260
|
+
if (isApplicationProject(project)) {
|
|
1261
|
+
return getRangeFromTarget(project.strapiVersion, target);
|
|
1262
|
+
}
|
|
1263
|
+
return rangeFactory("*");
|
|
1264
|
+
};
|
|
1265
|
+
const runCodemods = async (options) => {
|
|
1266
|
+
const timer = timerFactory();
|
|
1267
|
+
const { logger, uid } = options;
|
|
1268
|
+
const cwd = resolvePath(options.cwd);
|
|
1269
|
+
const project = projectFactory(cwd);
|
|
1270
|
+
const range = findRangeFromTarget(project, options.target);
|
|
1271
|
+
logger.debug(`Project: ${projectType(project.type)} found in ${path(cwd)}`);
|
|
1272
|
+
logger.debug(`Range: set to ${versionRange(range)}`);
|
|
1273
|
+
const codemodRunner = codemodRunnerFactory(project, range).dry(options.dry ?? false).onSelectCodemods(options.selectCodemods ?? null).setLogger(logger);
|
|
1274
|
+
let report;
|
|
1275
|
+
if (uid !== void 0) {
|
|
1276
|
+
logger.debug(`Running a single codemod: ${codemodUID(uid)}`);
|
|
1277
|
+
report = await codemodRunner.runByUID(uid);
|
|
1278
|
+
} else {
|
|
1279
|
+
report = await codemodRunner.run();
|
|
1280
|
+
}
|
|
1281
|
+
if (!report.success) {
|
|
1282
|
+
throw report.error;
|
|
1283
|
+
}
|
|
1284
|
+
timer.stop();
|
|
1285
|
+
logger.info(`Completed in ${timer.elapsedMs}`);
|
|
1286
|
+
};
|
|
1287
|
+
const listCodemods = async (options) => {
|
|
1288
|
+
const { logger, target } = options;
|
|
1289
|
+
const cwd = resolvePath(options.cwd);
|
|
1290
|
+
const project = projectFactory(cwd);
|
|
1291
|
+
const range = findRangeFromTarget(project, target);
|
|
1292
|
+
logger.debug(`Project: ${projectType(project.type)} found in ${path(cwd)}`);
|
|
1293
|
+
logger.debug(`Range: set to ${versionRange(range)}`);
|
|
1294
|
+
const repo = codemodRepositoryFactory();
|
|
1295
|
+
repo.refresh();
|
|
1296
|
+
const groups = repo.find({ range });
|
|
1297
|
+
const codemods = groups.flatMap((collection) => collection.codemods);
|
|
1298
|
+
logger.debug(`Found ${highlight(codemods.length)} codemods`);
|
|
1299
|
+
if (codemods.length === 0) {
|
|
1300
|
+
logger.info(`Found no codemods matching ${versionRange(range)}`);
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
const fCodemods = codemodList(codemods);
|
|
1304
|
+
logger.raw(fCodemods);
|
|
1305
|
+
};
|
|
1078
1306
|
const index$4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1079
1307
|
__proto__: null,
|
|
1080
|
-
|
|
1308
|
+
listCodemods,
|
|
1309
|
+
runCodemods,
|
|
1081
1310
|
upgrade
|
|
1082
1311
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1083
1312
|
class Logger {
|