@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.
- package/dist/cli.js +1452 -5
- package/dist/cli.js.map +1 -1
- package/dist/index.js +318 -88
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +319 -89
- 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 +7 -7
- 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 +374 -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 +45 -0
- 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-84t8FGQa.js +0 -729
- package/dist/_chunks/codemod-runner-84t8FGQa.js.map +0 -1
- package/dist/_chunks/codemods-KNF9fcQL.js +0 -108
- package/dist/_chunks/codemods-KNF9fcQL.js.map +0 -1
- package/dist/_chunks/index-hERDGiiJ.js +0 -103
- package/dist/_chunks/index-hERDGiiJ.js.map +0 -1
- package/dist/_chunks/upgrade-dU3oQNZk.js +0 -357
- package/dist/_chunks/upgrade-dU3oQNZk.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,16 +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,
|
|
451
|
+
parser: "ts",
|
|
452
|
+
runInBand: true,
|
|
453
|
+
babel: true,
|
|
454
|
+
extensions: PROJECT_DEFAULT_CODE_EXTENSIONS.join(","),
|
|
455
|
+
// Don't output any log coming from the runner
|
|
426
456
|
print: false,
|
|
427
457
|
silent: true,
|
|
428
|
-
|
|
429
|
-
runInBand: true,
|
|
430
|
-
verbose: 0,
|
|
431
|
-
babel: true
|
|
458
|
+
verbose: 0
|
|
432
459
|
});
|
|
433
460
|
const jsonRunner = jsonRunnerFactory(jsonFiles, { dry, cwd: this.cwd });
|
|
434
461
|
return [codeRunner, jsonRunner];
|
|
@@ -456,6 +483,19 @@ class Project {
|
|
|
456
483
|
const scanner = fileScannerFactory(this.cwd);
|
|
457
484
|
this.files = scanner.scan(patterns);
|
|
458
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
|
+
}
|
|
459
499
|
refreshStrapiVersion() {
|
|
460
500
|
this.strapiVersion = // First try to get the strapi version from the package.json dependencies
|
|
461
501
|
this.findStrapiVersionFromProjectPackageJSON() ?? // If the version found is not a valid SemVer, get the Strapi version from the installed package
|
|
@@ -501,10 +541,50 @@ const formatGlobCollectionPattern = (collection) => {
|
|
|
501
541
|
);
|
|
502
542
|
return collection.length === 1 ? collection[0] : `{${collection}}`;
|
|
503
543
|
};
|
|
504
|
-
|
|
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
|
+
}
|
|
505
581
|
const index$a = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
506
582
|
__proto__: null,
|
|
583
|
+
assertAppProject,
|
|
584
|
+
assertPluginProject,
|
|
507
585
|
constants: constants$3,
|
|
586
|
+
isApplicationProject,
|
|
587
|
+
isPluginProject,
|
|
508
588
|
projectFactory
|
|
509
589
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
510
590
|
class UnexpectedError extends Error {
|
|
@@ -530,7 +610,11 @@ const path = (path2) => chalk.blue(path2);
|
|
|
530
610
|
const version = (version2) => {
|
|
531
611
|
return chalk.italic.yellow(`v${version2}`);
|
|
532
612
|
};
|
|
533
|
-
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);
|
|
534
618
|
const transform = (transformFilePath) => chalk.cyan(transformFilePath);
|
|
535
619
|
const highlight = (arg) => chalk.bold.underline(arg);
|
|
536
620
|
const upgradeStep = (text, step) => {
|
|
@@ -562,15 +646,40 @@ const reports = (reports2) => {
|
|
|
562
646
|
table.push(...rows);
|
|
563
647
|
return table.toString();
|
|
564
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
|
+
};
|
|
565
671
|
const durationMs = (elapsedMs) => {
|
|
566
672
|
const elapsedSeconds = (elapsedMs / ONE_SECOND_MS).toFixed(3);
|
|
567
673
|
return `${elapsedSeconds}s`;
|
|
568
674
|
};
|
|
569
675
|
const index$8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
570
676
|
__proto__: null,
|
|
677
|
+
codemodList,
|
|
678
|
+
codemodUID,
|
|
571
679
|
durationMs,
|
|
572
680
|
highlight,
|
|
573
681
|
path,
|
|
682
|
+
projectType,
|
|
574
683
|
reports,
|
|
575
684
|
transform,
|
|
576
685
|
upgradeStep,
|
|
@@ -593,6 +702,7 @@ const constants$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineP
|
|
|
593
702
|
CODEMOD_JSON_SUFFIX
|
|
594
703
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
595
704
|
class Codemod {
|
|
705
|
+
uid;
|
|
596
706
|
kind;
|
|
597
707
|
version;
|
|
598
708
|
baseDirectory;
|
|
@@ -604,9 +714,27 @@ class Codemod {
|
|
|
604
714
|
this.baseDirectory = options.baseDirectory;
|
|
605
715
|
this.filename = options.filename;
|
|
606
716
|
this.path = path$1.join(this.baseDirectory, this.version.raw, this.filename);
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
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;
|
|
610
738
|
}
|
|
611
739
|
}
|
|
612
740
|
const codemodFactory = (options) => new Codemod(options);
|
|
@@ -615,6 +743,20 @@ const index$7 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
|
|
|
615
743
|
codemodFactory,
|
|
616
744
|
constants: constants$2
|
|
617
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" }));
|
|
618
760
|
class CodemodRepository {
|
|
619
761
|
groups;
|
|
620
762
|
versions;
|
|
@@ -633,23 +775,48 @@ class CodemodRepository {
|
|
|
633
775
|
count(version2) {
|
|
634
776
|
return this.findByVersion(version2).length;
|
|
635
777
|
}
|
|
636
|
-
|
|
637
|
-
return this.findByRange(range).length;
|
|
638
|
-
}
|
|
639
|
-
exists(version2) {
|
|
778
|
+
versionExists(version2) {
|
|
640
779
|
return version2.raw in this.groups;
|
|
641
780
|
}
|
|
642
|
-
|
|
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) {
|
|
643
790
|
const entries = Object.entries(this.groups);
|
|
644
|
-
return entries.filter(
|
|
791
|
+
return entries.filter(maybeFilterByRange).map(([version2, codemods]) => ({
|
|
645
792
|
version: semVerFactory(version2),
|
|
646
|
-
|
|
647
|
-
|
|
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
|
+
}
|
|
648
808
|
}
|
|
649
809
|
findByVersion(version2) {
|
|
650
810
|
const literalVersion = version2.raw;
|
|
651
|
-
const
|
|
652
|
-
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
|
+
}));
|
|
653
820
|
}
|
|
654
821
|
refreshAvailableVersions() {
|
|
655
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);
|
|
@@ -680,18 +847,9 @@ const parseCodemodKindFromFilename = (filename) => {
|
|
|
680
847
|
assert(CODEMOD_ALLOWED_SUFFIXES.includes(kind));
|
|
681
848
|
return kind;
|
|
682
849
|
};
|
|
683
|
-
const codemodRepositoryFactory = (cwd) =>
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
"..",
|
|
687
|
-
"..",
|
|
688
|
-
"resources",
|
|
689
|
-
"codemods"
|
|
690
|
-
);
|
|
691
|
-
const constants$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
692
|
-
__proto__: null,
|
|
693
|
-
INTERNAL_CODEMODS_DIRECTORY
|
|
694
|
-
}, Symbol.toStringTag, { value: "Module" }));
|
|
850
|
+
const codemodRepositoryFactory = (cwd = INTERNAL_CODEMODS_DIRECTORY) => {
|
|
851
|
+
return new CodemodRepository(cwd);
|
|
852
|
+
};
|
|
695
853
|
const index$6 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
696
854
|
__proto__: null,
|
|
697
855
|
codemodRepositoryFactory,
|
|
@@ -726,34 +884,59 @@ class CodemodRunner {
|
|
|
726
884
|
this.isDry = enabled;
|
|
727
885
|
return this;
|
|
728
886
|
}
|
|
729
|
-
|
|
887
|
+
createRepository(codemodsDirectory) {
|
|
730
888
|
const repository = codemodRepositoryFactory(
|
|
731
889
|
codemodsDirectory ?? INTERNAL_CODEMODS_DIRECTORY
|
|
732
890
|
);
|
|
733
891
|
repository.refresh();
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
if (
|
|
738
|
-
this.logger?.
|
|
739
|
-
|
|
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
|
+
);
|
|
740
899
|
}
|
|
741
|
-
this.logger?.debug(
|
|
742
|
-
`Found codemods for ${highlight(
|
|
743
|
-
versionedCodemods.length
|
|
744
|
-
)} version(s) using ${versionRange(this.range)}`
|
|
745
|
-
);
|
|
746
|
-
versionedCodemods.forEach(
|
|
747
|
-
({ version: version$1, codemods: codemods22 }) => this.logger?.debug(`- ${version(version$1)} (${codemods22.length})`)
|
|
748
|
-
);
|
|
749
|
-
const codemods2 = versionedCodemods.map(({ codemods: codemods22 }) => codemods22).flat();
|
|
750
900
|
try {
|
|
751
|
-
const reports$1 = await this.project.runCodemods(
|
|
752
|
-
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();
|
|
753
910
|
} catch (e) {
|
|
754
911
|
return erroredReport$1(unknownToError(e));
|
|
755
912
|
}
|
|
756
|
-
|
|
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);
|
|
757
940
|
}
|
|
758
941
|
}
|
|
759
942
|
const codemodRunnerFactory = (project, range) => {
|
|
@@ -792,7 +975,7 @@ class Upgrader {
|
|
|
792
975
|
this.codemodsTarget = semVerFactory(
|
|
793
976
|
`${this.target.major}.${this.target.minor}.${this.target.patch}`
|
|
794
977
|
);
|
|
795
|
-
this.logger?.debug(
|
|
978
|
+
this.logger?.debug?.(
|
|
796
979
|
`The codemods target has been synced with the upgrade target. The codemod runner will now look for ${version(
|
|
797
980
|
this.codemodsTarget
|
|
798
981
|
)}`
|
|
@@ -801,7 +984,7 @@ class Upgrader {
|
|
|
801
984
|
}
|
|
802
985
|
overrideCodemodsTarget(target) {
|
|
803
986
|
this.codemodsTarget = target;
|
|
804
|
-
this.logger?.debug(
|
|
987
|
+
this.logger?.debug?.(
|
|
805
988
|
`Overriding the codemods target. The codemod runner will now look for ${version(target)}`
|
|
806
989
|
);
|
|
807
990
|
return this;
|
|
@@ -821,38 +1004,40 @@ class Upgrader {
|
|
|
821
1004
|
addRequirement(requirement) {
|
|
822
1005
|
this.requirements.push(requirement);
|
|
823
1006
|
const fRequired = requirement.isRequired ? "(required)" : "(optional)";
|
|
824
|
-
this.logger?.debug(
|
|
1007
|
+
this.logger?.debug?.(
|
|
825
1008
|
`Added a new requirement to the upgrade: ${highlight(requirement.name)} ${fRequired}`
|
|
826
1009
|
);
|
|
827
1010
|
return this;
|
|
828
1011
|
}
|
|
829
1012
|
async upgrade() {
|
|
830
|
-
this.logger?.info(
|
|
1013
|
+
this.logger?.info?.(
|
|
831
1014
|
`Upgrading from ${version(this.project.strapiVersion)} to ${version(this.target)}`
|
|
832
1015
|
);
|
|
833
1016
|
if (this.isDry) {
|
|
834
|
-
this.logger?.warn(
|
|
1017
|
+
this.logger?.warn?.(
|
|
835
1018
|
"Running the upgrade in dry mode. No files will be modified during the process."
|
|
836
1019
|
);
|
|
837
1020
|
}
|
|
838
1021
|
const range = rangeFromVersions(this.project.strapiVersion, this.target);
|
|
839
1022
|
const codemodsRange = rangeFromVersions(this.project.strapiVersion, this.codemodsTarget);
|
|
840
1023
|
const npmVersionsMatches = this.npmPackage?.findVersionsInRange(range) ?? [];
|
|
841
|
-
this.logger?.debug(
|
|
1024
|
+
this.logger?.debug?.(
|
|
842
1025
|
`Found ${highlight(npmVersionsMatches.length)} versions satisfying ${versionRange(range)}`
|
|
843
1026
|
);
|
|
844
1027
|
try {
|
|
845
|
-
this.logger?.info(upgradeStep("Checking requirement", [1, 4]));
|
|
1028
|
+
this.logger?.info?.(upgradeStep("Checking requirement", [1, 4]));
|
|
846
1029
|
await this.checkRequirements(this.requirements, {
|
|
847
1030
|
npmVersionsMatches,
|
|
848
1031
|
project: this.project,
|
|
849
1032
|
target: this.target
|
|
850
1033
|
});
|
|
851
|
-
this.logger?.info(upgradeStep("Applying the latest code modifications", [2, 4]));
|
|
1034
|
+
this.logger?.info?.(upgradeStep("Applying the latest code modifications", [2, 4]));
|
|
852
1035
|
await this.runCodemods(codemodsRange);
|
|
853
|
-
this.logger?.
|
|
1036
|
+
this.logger?.debug?.("Refreshing project information...");
|
|
1037
|
+
this.project.refresh();
|
|
1038
|
+
this.logger?.info?.(upgradeStep("Upgrading Strapi dependencies", [3, 4]));
|
|
854
1039
|
await this.updateDependencies();
|
|
855
|
-
this.logger?.info(upgradeStep("Installing dependencies", [4, 4]));
|
|
1040
|
+
this.logger?.info?.(upgradeStep("Installing dependencies", [4, 4]));
|
|
856
1041
|
await this.installDependencies();
|
|
857
1042
|
} catch (e) {
|
|
858
1043
|
return erroredReport(unknownToError(e));
|
|
@@ -885,7 +1070,7 @@ class Upgrader {
|
|
|
885
1070
|
if (requirement.isRequired) {
|
|
886
1071
|
throw error;
|
|
887
1072
|
}
|
|
888
|
-
this.logger?.warn(warningMessage);
|
|
1073
|
+
this.logger?.warn?.(warningMessage);
|
|
889
1074
|
const response = await this.confirmationCallback?.(confirmationMessage);
|
|
890
1075
|
if (!response) {
|
|
891
1076
|
throw error;
|
|
@@ -896,9 +1081,11 @@ class Upgrader {
|
|
|
896
1081
|
const json = createJSONTransformAPI(packageJSON);
|
|
897
1082
|
const dependencies = json.get("dependencies", {});
|
|
898
1083
|
const strapiDependencies = this.getScopedStrapiDependencies(dependencies);
|
|
899
|
-
this.logger?.debug(
|
|
1084
|
+
this.logger?.debug?.(
|
|
1085
|
+
`Found ${highlight(strapiDependencies.length)} dependency(ies) to update`
|
|
1086
|
+
);
|
|
900
1087
|
strapiDependencies.forEach(
|
|
901
|
-
(dependency) => this.logger?.debug(`- ${dependency[0]} (${dependency[1]} -> ${this.target})`)
|
|
1088
|
+
(dependency) => this.logger?.debug?.(`- ${dependency[0]} (${dependency[1]} -> ${this.target})`)
|
|
902
1089
|
);
|
|
903
1090
|
if (strapiDependencies.length === 0) {
|
|
904
1091
|
return;
|
|
@@ -906,7 +1093,7 @@ class Upgrader {
|
|
|
906
1093
|
strapiDependencies.forEach(([name]) => json.set(`dependencies.${name}`, this.target.raw));
|
|
907
1094
|
const updatedPackageJSON = json.root();
|
|
908
1095
|
if (this.isDry) {
|
|
909
|
-
this.logger?.debug(`Skipping dependencies update (${chalk.italic("dry mode")})`);
|
|
1096
|
+
this.logger?.debug?.(`Skipping dependencies update (${chalk.italic("dry mode")})`);
|
|
910
1097
|
return;
|
|
911
1098
|
}
|
|
912
1099
|
await saveJSON(packageJSONPath, updatedPackageJSON);
|
|
@@ -926,9 +1113,9 @@ class Upgrader {
|
|
|
926
1113
|
async installDependencies() {
|
|
927
1114
|
const projectPath = this.project.cwd;
|
|
928
1115
|
const packageManagerName = await packageManager.getPreferred(projectPath);
|
|
929
|
-
this.logger?.debug(`Using ${highlight(packageManagerName)} as package manager`);
|
|
1116
|
+
this.logger?.debug?.(`Using ${highlight(packageManagerName)} as package manager`);
|
|
930
1117
|
if (this.isDry) {
|
|
931
|
-
this.logger?.debug(`Skipping dependencies installation (${chalk.italic("dry mode")}`);
|
|
1118
|
+
this.logger?.debug?.(`Skipping dependencies installation (${chalk.italic("dry mode")}`);
|
|
932
1119
|
return;
|
|
933
1120
|
}
|
|
934
1121
|
await packageManager.installDependencies(projectPath, packageManagerName, {
|
|
@@ -1027,6 +1214,11 @@ const upgrade = async (options) => {
|
|
|
1027
1214
|
const { logger, codemodsTarget } = options;
|
|
1028
1215
|
const cwd = path$1.resolve(options.cwd ?? process.cwd());
|
|
1029
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
|
+
}
|
|
1030
1222
|
const npmPackage = npmPackageFactory(STRAPI_PACKAGE_NAME);
|
|
1031
1223
|
await npmPackage.refresh();
|
|
1032
1224
|
const upgrader = upgraderFactory(project, options.target, npmPackage).dry(options.dry ?? false).onConfirm(options.confirm ?? null).setLogger(logger);
|
|
@@ -1044,20 +1236,7 @@ const upgrade = async (options) => {
|
|
|
1044
1236
|
timer.stop();
|
|
1045
1237
|
logger.info(`Completed in ${durationMs(timer.elapsedMs)}`);
|
|
1046
1238
|
};
|
|
1047
|
-
const
|
|
1048
|
-
const timer = timerFactory();
|
|
1049
|
-
const { logger } = options;
|
|
1050
|
-
const cwd = path$1.resolve(options.cwd ?? process.cwd());
|
|
1051
|
-
const project = projectFactory(cwd);
|
|
1052
|
-
const range = getRangeFromTarget(project.strapiVersion, options.target);
|
|
1053
|
-
const codemodRunner = codemodRunnerFactory(project, range).dry(options.dry ?? false).onSelectCodemods(options.selectCodemods ?? null).setLogger(logger);
|
|
1054
|
-
const executionReport = await codemodRunner.run();
|
|
1055
|
-
if (!executionReport.success) {
|
|
1056
|
-
throw executionReport.error;
|
|
1057
|
-
}
|
|
1058
|
-
timer.stop();
|
|
1059
|
-
logger.info(`Completed in ${timer.elapsedMs}`);
|
|
1060
|
-
};
|
|
1239
|
+
const resolvePath = (cwd) => path$1.resolve(cwd ?? process.cwd());
|
|
1061
1240
|
const getRangeFromTarget = (currentVersion, target) => {
|
|
1062
1241
|
if (isSemverInstance(target)) {
|
|
1063
1242
|
return rangeFactory(target);
|
|
@@ -1074,9 +1253,60 @@ const getRangeFromTarget = (currentVersion, target) => {
|
|
|
1074
1253
|
throw new Error(`Invalid target set: ${target}`);
|
|
1075
1254
|
}
|
|
1076
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
|
+
};
|
|
1077
1306
|
const index$4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1078
1307
|
__proto__: null,
|
|
1079
|
-
|
|
1308
|
+
listCodemods,
|
|
1309
|
+
runCodemods,
|
|
1080
1310
|
upgrade
|
|
1081
1311
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1082
1312
|
class Logger {
|