@automattic/vip 3.5.1 → 3.7.0

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.
@@ -1,13 +1,118 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
- exports.summaryLogs = exports.logErrorsForInvalidFilenames = exports.logErrorsForInvalidFileTypes = exports.logErrorsForIntermediateImages = exports.isFileSanitized = exports.folderStructureValidation = exports.findNestedDirectories = exports.doesImageHaveExistingSource = exports.acceptedExtensions = void 0;
4
+ exports.summaryLogs = exports.logErrors = exports.isFileSanitized = exports.folderStructureValidation = exports.findNestedDirectories = exports.doesImageHaveExistingSource = exports.ValidateFilesErrors = void 0;
5
+ exports.validateFiles = validateFiles;
5
6
  var _chalk = _interopRequireDefault(require("chalk"));
6
7
  var _fs = _interopRequireDefault(require("fs"));
7
8
  var _path = _interopRequireDefault(require("path"));
8
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
- // Accepted media file extensions
10
- const acceptedExtensions = exports.acceptedExtensions = ['jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'svg', 'tiff', 'tif', 'ico', 'asf', 'asx', 'wmv', 'wmx', 'wm', 'avi', 'divx', 'mov', 'qt', 'mpeg', 'mpg', 'mpe', 'mp4', 'm4v', 'ogv', 'webm', 'mkv', '3gp', '3gpp', '3g2', '3gp2', 'txt', 'asc', 'c', 'cc', 'h', 'srt', 'csv', 'tsv', 'ics', 'rtx', 'css', 'vtt', 'dfxp', 'mp3', 'm4a', 'm4b', 'ra', 'ram', 'wav', 'ogg', 'oga', 'mid', 'midi', 'wma', 'wax', 'mka', 'rtf', 'js', 'pdf', 'class', 'psd', 'xcf', 'doc', 'pot', 'pps', 'ppt', 'wri', 'xla', 'xls', 'xlt', 'xlw', 'mdb', 'mpp', 'docx', 'docm', 'dotx', 'dotm', 'xlsx', 'xlsm', 'xlsb', 'xltx', 'xltm', 'xlam', 'pptx', 'pptm', 'ppsx', 'ppsm', 'potx', 'potm', 'ppam', 'sldx', 'sldm', 'onetoc', ' onetoc2', 'onetmp', 'onepkg', 'oxps', 'xps', 'odt', 'odp', 'ods', 'odg', 'odc', 'odb', 'odf', 'webp', 'wp', 'wpd', 'key', 'numbers', 'pages'];
10
+ /**
11
+ * External dependencies
12
+ */
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ let ValidateFilesErrors = exports.ValidateFilesErrors = /*#__PURE__*/function (ValidateFilesErrors) {
17
+ ValidateFilesErrors["INVALID_TYPES"] = "invalid_types";
18
+ ValidateFilesErrors["INTERMEDIATE_IMAGES"] = "intermediate_images";
19
+ ValidateFilesErrors["INVALID_SIZES"] = "invalid_sizes";
20
+ ValidateFilesErrors["INVALID_NAMES"] = "invalid_names";
21
+ ValidateFilesErrors["INVALID_NAME_CHARACTER_COUNTS"] = "invalid_name_character_counts";
22
+ return ValidateFilesErrors;
23
+ }({});
24
+ /**
25
+ * File info validation
26
+ *
27
+ * Validate the file info for media files
28
+ */
29
+ async function validateFiles(files, mediaImportConfig) {
30
+ const validationResult = {
31
+ intermediateImagesTotal: 0,
32
+ errorFileTypes: [],
33
+ errorFileNames: [],
34
+ errorFileSizes: [],
35
+ errorFileNamesCharCount: [],
36
+ intermediateImages: {}
37
+ };
38
+ const fileValidationPromises = files.map(async file => {
39
+ const isFolder = await isDirectory(file);
40
+ const fileExtType = getFileExtType(file,
41
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
42
+ mediaImportConfig.allowedFileTypes);
43
+ if (isInvalidFile(fileExtType, isFolder)) {
44
+ validationResult.errorFileTypes.push(file);
45
+ }
46
+
47
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
48
+ if (!isFileSizeValid(file, mediaImportConfig.fileSizeLimitInBytes)) {
49
+ validationResult.errorFileSizes.push(file);
50
+ }
51
+ if (isFileSanitized(file)) {
52
+ validationResult.errorFileNames.push(file);
53
+ }
54
+
55
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
56
+ if (!isFileNameCharCountValid(file, mediaImportConfig?.fileNameCharCount)) {
57
+ validationResult.errorFileNamesCharCount.push(file);
58
+ }
59
+ const original = doesImageHaveExistingSource(file);
60
+ if (original) {
61
+ validationResult.intermediateImagesTotal++;
62
+ if (validationResult.intermediateImages[original]) {
63
+ validationResult.intermediateImages[original] += `, ${file}`;
64
+ } else {
65
+ validationResult.intermediateImages[original] = file;
66
+ }
67
+ }
68
+ });
69
+ await Promise.all(fileValidationPromises);
70
+ return validationResult;
71
+ }
72
+ const isDirectory = async file => {
73
+ const stats = await _fs.default.promises.stat(file);
74
+ return stats.isDirectory();
75
+ };
76
+ const getFileExtType = (file, allowedFileTypes) => {
77
+ if (!allowedFileTypes) return {
78
+ ext: null,
79
+ type: null
80
+ };
81
+ return getExtAndType(file, allowedFileTypes);
82
+ };
83
+ const isInvalidFile = (fileExtType, isFolder) => {
84
+ return !fileExtType.type || !fileExtType.ext || isFolder;
85
+ };
86
+ const getExtAndType = (filePath, allowedFileTypes) => {
87
+ const extType = {
88
+ ext: null,
89
+ type: null
90
+ };
91
+ for (const [key, value] of Object.entries(allowedFileTypes)) {
92
+ // Create a regular expression to match the file extension
93
+ // eslint-disable-next-line security/detect-non-literal-regexp
94
+ const regex = new RegExp(`(?:\\.)(${key})$`, 'i');
95
+ const matches = regex.exec(filePath);
96
+ if (matches) {
97
+ extType.type = value;
98
+ extType.ext = matches[1];
99
+ break;
100
+ }
101
+ }
102
+ return extType;
103
+ };
104
+ const isFileSizeValid = (filePathOnDisk, fileSizeLimitInBytes) => {
105
+ const fileStat = _fs.default.statSync(filePathOnDisk);
106
+ return fileSizeLimitInBytes >= fileStat.size;
107
+ };
108
+ const isFileNameCharCountValid = (file, fileNameCharCount) => {
109
+ const filename = _path.default.basename(file);
110
+ return filename.length <= fileNameCharCount;
111
+ };
112
+
113
+ /**
114
+ * End file info validation
115
+ */
11
116
 
12
117
  /**
13
118
  * Character validation global variables
@@ -38,8 +143,8 @@ const recommendedFileStructure = () => {
38
143
  };
39
144
 
40
145
  // Recommend accepted file types
41
- const recommendAcceptableFileTypes = () => {
42
- console.log('Accepted file types: \n\n' + _chalk.default.magenta(`${acceptedExtensions.join(', ')}`));
146
+ const recommendAcceptableFileTypes = allowedFileTypesString => {
147
+ console.log('Accepted file types: \n\n' + _chalk.default.magenta(`${allowedFileTypesString}`));
43
148
  console.log();
44
149
  };
45
150
 
@@ -392,8 +497,8 @@ const isFileSanitized = file => {
392
497
  sanitizedFile = sanitizedFile.replace(regexSpaces, ' ');
393
498
 
394
499
  // Check if the filename has been sanitized
395
- const checkFile = sanitizedFile !== filename;
396
- return checkFile;
500
+
501
+ return sanitizedFile !== filename;
397
502
  };
398
503
 
399
504
  /**
@@ -449,45 +554,50 @@ const doesImageHaveExistingSource = file => {
449
554
  *
450
555
  * Log errors for invalid folders or files
451
556
  */
452
-
453
- // Log errors for files with invalid file extensions and recommend accepted file types
454
557
  exports.doesImageHaveExistingSource = doesImageHaveExistingSource;
455
- const logErrorsForInvalidFileTypes = invalidFiles => {
456
- invalidFiles.forEach(file => {
457
- console.error(_chalk.default.red('✕'), 'File extensions: Invalid file type for file: ', _chalk.default.cyan(`${file}`));
458
- });
459
- console.log();
460
- recommendAcceptableFileTypes();
461
- console.log('------------------------------------------------------------');
462
- console.log();
463
- };
464
-
465
- // Log errors for files with invalid filenames and show a list of accepted/prohibited chars
466
- exports.logErrorsForInvalidFileTypes = logErrorsForInvalidFileTypes;
467
- const logErrorsForInvalidFilenames = invalidFiles => {
558
+ const logErrors = ({
559
+ errorType,
560
+ invalidFiles,
561
+ limit
562
+ }) => {
563
+ if (invalidFiles.length === 0) {
564
+ return;
565
+ }
468
566
  invalidFiles.forEach(file => {
469
- console.error(_chalk.default.red('✕'), 'Character validation: Invalid filename for file: ', _chalk.default.cyan(`${file}`));
567
+ switch (errorType) {
568
+ case ValidateFilesErrors.INVALID_TYPES:
569
+ console.error(_chalk.default.red('✕'), 'File extensions: Invalid file type for file: ', _chalk.default.cyan(`${file}`));
570
+ console.log();
571
+ recommendAcceptableFileTypes(limit);
572
+ break;
573
+ case ValidateFilesErrors.INTERMEDIATE_IMAGES:
574
+ console.error(_chalk.default.red('✕'), 'Intermediate images: Duplicate files found:\n' + 'Original file: ' + _chalk.default.blue(`${file}\n`) + 'Intermediate images: ' + _chalk.default.cyan(`${limit[file]}\n`));
575
+ break;
576
+ case ValidateFilesErrors.INVALID_SIZES:
577
+ console.error(_chalk.default.red('✕'), `File size cannot be more than ${limit / 1024 / 1024 / 1024} GB`, _chalk.default.cyan(`${file}`));
578
+ console.log();
579
+ break;
580
+ case ValidateFilesErrors.INVALID_NAME_CHARACTER_COUNTS:
581
+ console.error(_chalk.default.red('✕'), `File name cannot have more than ${limit} characters`, _chalk.default.cyan(`${file}`));
582
+ break;
583
+ case ValidateFilesErrors.INVALID_NAMES:
584
+ console.error(_chalk.default.red('✕'), 'Character validation: Invalid filename for file: ', _chalk.default.cyan(`${file}`));
585
+ recommendAcceptableFileNames();
586
+ break;
587
+ default:
588
+ console.error(_chalk.default.red('✕'), 'Unknown error type:', errorType);
589
+ }
470
590
  });
471
591
  console.log();
472
- recommendAcceptableFileNames();
473
- console.log('------------------------------------------------------------');
474
- console.log();
475
- };
476
-
477
- // Log errors for intermediate image file duplicates
478
- exports.logErrorsForInvalidFilenames = logErrorsForInvalidFilenames;
479
- const logErrorsForIntermediateImages = obj => {
480
- for (const original in obj) {
481
- console.error(_chalk.default.red('✕'), 'Intermediate images: Duplicate files found:\n' + 'Original file: ' + _chalk.default.blue(`${original}\n`) + 'Intermediate images: ' + _chalk.default.cyan(`${obj[original]}\n`));
482
- }
483
- console.log('------------------------------------------------------------');
484
592
  };
485
- exports.logErrorsForIntermediateImages = logErrorsForIntermediateImages;
593
+ exports.logErrors = logErrors;
486
594
  const summaryLogs = ({
487
595
  folderErrorsLength,
488
596
  intImagesErrorsLength,
489
597
  fileTypeErrorsLength,
598
+ fileErrorFileSizesLength,
490
599
  filenameErrorsLength,
600
+ fileNameCharCountErrorsLength,
491
601
  totalFiles,
492
602
  totalFolders
493
603
  }) => {
@@ -507,11 +617,21 @@ const summaryLogs = ({
507
617
  } else {
508
618
  messages.push(_chalk.default.white.bgGreen(' PASS ') + _chalk.default.green(` ${fileTypeErrorsLength} invalid file extensions`) + `, ${totalFiles} files total`);
509
619
  }
620
+ if (fileErrorFileSizesLength > 0) {
621
+ messages.push(_chalk.default.white.bgRed(' ERROR ') + _chalk.default.red(` ${fileTypeErrorsLength} invalid file sizes`) + `, ${totalFiles} files total`);
622
+ } else {
623
+ messages.push(_chalk.default.white.bgGreen(' PASS ') + _chalk.default.green(` ${fileTypeErrorsLength} invalid file sizes`) + `, ${totalFiles} files total`);
624
+ }
510
625
  if (filenameErrorsLength) {
511
626
  messages.push(_chalk.default.white.bgRed(' ERROR ') + _chalk.default.red(` ${filenameErrorsLength} invalid filenames`) + `, ${totalFiles} files total`);
512
627
  } else {
513
628
  messages.push(_chalk.default.bgGreen(' PASS ') + _chalk.default.green(` ${filenameErrorsLength} invalid filenames`) + `, ${totalFiles} files total`);
514
629
  }
630
+ if (fileNameCharCountErrorsLength) {
631
+ messages.push(_chalk.default.white.bgRed(' ERROR ') + _chalk.default.red(` ${filenameErrorsLength} file names reached the maximum character count limit `) + `, ${totalFiles} files total`);
632
+ } else {
633
+ messages.push(_chalk.default.bgGreen(' PASS ') + _chalk.default.green(` ${filenameErrorsLength} file names reached the maximum character count limit`) + `, ${totalFiles} files total`);
634
+ }
515
635
  console.log(`\n${messages.join('\n')}\n`);
516
636
  };
517
637
  exports.summaryLogs = summaryLogs;
package/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  ## Changelog
2
2
 
3
+ ## 3.6.0
4
+
5
+ * build(deps-dev): bump rimraf from 5.0.7 to 5.0.8
6
+ * feat(dev-env): add DNS check to health check to ensure domains resolve correctly
7
+
8
+ **Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.5.1...3.6.0
9
+
10
+ ## 3.5.1
11
+
12
+ * fix(dev-env): display cron status in `vip dev-env info --extended`
13
+ * build(deps-dev): bump typescript from 5.5.2 to 5.5.3
14
+ * fix: case mismatch in environment identifier matcher
15
+
16
+ **Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.5.0...3.5.1
17
+
3
18
  ### 3.5.0
4
19
 
5
20
  * feat(dev-env): add support for cron