Skip to content

Feat: bulk optimization#34

Open
bfintal wants to merge 5 commits intodevelopfrom
feat/bulk-optimization
Open

Feat: bulk optimization#34
bfintal wants to merge 5 commits intodevelopfrom
feat/bulk-optimization

Conversation

@bfintal
Copy link
Contributor

@bfintal bfintal commented Mar 17, 2026

fixes #26

Summary by CodeRabbit

Release Notes

  • New Features

    • Bulk media optimization interface with progress tracking, sortable image list, and real-time statistics updates
    • Enhanced image conversion with configurable format selection and compression options
    • Improved file upload processing with enhanced error detection and reporting
  • Chores

    • Added image compression and conversion dependencies
    • Updated platform compatibility testing

@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2026

📝 Walkthrough

Walkthrough

The pull request introduces bulk image optimization functionality with dependencies for image compression and format conversion. Backend changes add stats tracking for bulk operations, metadata handling, and admin UI configuration. Frontend enhancements include a new bulk optimizer component with comprehensive styling, refactored image converter with options support, and improved error handling in file processing pipelines.

Changes

Cohort / File(s) Summary
Dependencies & Version
package.json, readme.txt
Adds runtime dependencies for image compression (browser-image-compression, heic2any), utility libraries (classnames, mime), and testing (resemblejs). Version compatibility updated to 6.9.1.
Backend Infrastructure
src/admin/class-admin.php, src/admin/class-metadata.php, src/admin/class-stats.php
Extends admin localization with isPremium flag and uploadsUrl. Adds optimized_during_upload metadata flag and early return in preserve_cimo_metadata. Introduces bulk_optimization stats parsing and two new public methods (update_stats_bulk_optimized, update_stats_bulk_restored) for tracking bulk operation impact.
Frontend UI & Styling
src/admin/css/admin-page.css, src/admin/js/page/admin-settings.js
Implements comprehensive bulk optimizer UI with grid layouts, table styling, image list sections, progress animations, and responsive behavior. Adds BulkOptimizationComponent filter hook, premium conditional rendering, Learn More buttons, and admin wrapper premium styling.
File Processing & Error Handling
src/admin/js/media-manager/drop-zone.js, src/admin/js/media-manager/select-files.js, src/shared/converters/image-converter.js
Enhances converter error inspection with per-result logging in drop-zone and select-files. Refactors ImageConverter.convert() signature to accept force and options parameters; adds formatTo resolution, early exits for unsupported formats and unchanged images, animated GIF detection, PNG compression via dynamic import, and new optimize() method with filter support.

Sequence Diagram

sequenceDiagram
    actor User
    participant UI as Bulk Optimizer UI
    participant FileProc as File Processor
    participant Converter as Image Converter
    participant Stats as Stats Manager
    participant Admin as Admin Backend

    User->>UI: Select files for bulk optimization
    UI->>FileProc: Process selected files
    FileProc->>Converter: Convert file with options
    alt Error in conversion
        Converter-->>FileProc: Return error result
        FileProc-->>FileProc: Log error, set hasError
    else Conversion successful
        Converter-->>FileProc: Return converted result
    end
    FileProc->>Admin: Store optimized_during_upload flag
    FileProc->>Stats: Call update_stats_bulk_optimized
    Stats-->>Admin: Persist updated stats via option
    UI->>UI: Update progress bar/animation
    UI-->>User: Display optimization results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hoppy hearts for bulk compress!
Files shrunk, images blessed,
Progress bars that blink and glow,
Optimization steals the show!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat: bulk optimization' directly describes the main feature being implemented, which is evident from all file changes related to bulk optimization UI, components, stats handling, and image conversion.
Linked Issues check ✅ Passed The PR implements bulk optimization of images as required by #26, adding UI components, stats tracking, image conversion logic, and supporting infrastructure for bulk image optimization.
Out of Scope Changes check ✅ Passed All changes are scoped to bulk optimization implementation: UI components, stats handling, image converter updates, and admin infrastructure. No unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/bulk-optimization
📝 Coding Plan
  • Generate coding plan for human review comments

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Stylelint (17.4.0)
src/admin/css/admin-page.css

ConfigurationError: Could not find "@wordpress/stylelint-config". Do you need to install the package or use the "configBasedir" option?
at getModulePath (file:///usr/local/lib/node_modules/stylelint/lib/utils/getModulePath.mjs:29:9)
at loadExtendedConfig (file:///usr/local/lib/node_modules/stylelint/lib/augmentConfig.mjs:241:21)
at extendConfig (file:///usr/local/lib/node_modules/stylelint/lib/augmentConfig.mjs:208:25)
at augmentConfigBasic (file:///usr/local/lib/node_modules/stylelint/lib/augmentConfig.mjs:73:26)
at augmentConfigFull (file:///usr/local/lib/node_modules/stylelint/lib/augmentConfig.mjs:126:30)
at getConfigForFile (file:///usr/local/lib/node_modules/stylelint/lib/getConfigForFile.mjs:102:32)
at async resolveOptionValue (file:///usr/local/lib/node_modules/stylelint/lib/utils/resolveOptionValue.mjs:27:24)
at async standalone (file:///usr/local/lib/node_modules/stylelint/lib/standalone.mjs:202:19)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.

Change the reviews.profile setting to assertive to make CodeRabbit's nitpick more issues in your PRs.

@github-actions
Copy link

🤖 Pull request artifacts

file commit
pr34-cimo-34-merge.zip a7762b0

github-actions bot added a commit that referenced this pull request Mar 17, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (3)
src/admin/class-stats.php (2)

183-189: Minor: Unused $attachment_id parameter.

Static analysis notes this parameter is unused. If reserved for future tracking, prefix with underscore to silence warnings.

-	public static function update_stats_bulk_optimized( $attachment_id, $original_size, $optimized_size ) {
+	public static function update_stats_bulk_optimized( $_attachment_id, $original_size, $optimized_size ) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/admin/class-stats.php` around lines 183 - 189, The parameter
$attachment_id in the static method update_stats_bulk_optimized is unused and
triggers static-analysis warnings; to silence them, rename the parameter to
$_attachment_id (or otherwise prefix it with an underscore) in the method
signature and any callers, leaving the body unchanged; reference:
update_stats_bulk_optimized and its parameter $attachment_id.

93-93: Minor: Unused loop variable $size.

Static analysis flagged that $size is unused in the loop body. If it's not needed, use $_ or just iterate values.

-				foreach ( $cimo_data['bulk_optimization'] as $size => $data ) {
+				foreach ( $cimo_data['bulk_optimization'] as $data ) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/admin/class-stats.php` at line 93, The foreach over
$cimo_data['bulk_optimization'] declares an unused loop key $size; update the
loop in src/admin/class-stats.php to avoid the unused variable by iterating only
values (e.g., change the foreach signature that currently uses $size to use just
$data) or explicitly use an underscore key (e.g., $_ => $data) so static
analysis no longer flags $size as unused while preserving the existing loop body
that references $data.
src/shared/converters/image-converter.js (1)

360-363: Consider documenting the expected filter contract.

The optimize() method delegates to a WordPress filter, but the expected return type and filter behavior are undocumented. Consider adding a JSDoc comment explaining what filters should return.

📝 Suggested documentation
+	/**
+	 * Optimize the image using registered filters.
+	 * Filters receive this ImageConverter instance and should return
+	 * an object with { file, metadata } or the original instance if no optimization is performed.
+	 * `@return` {Promise<Object>} Promise resolving to optimization result.
+	 */
 	async optimize() {
 		return await applyFiltersAsync( 'cimo.imageConverter.optimize', this )
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/converters/image-converter.js` around lines 360 - 363, The
optimize() method delegates to the WordPress filter
'cimo.imageConverter.optimize' via applyFiltersAsync(this), but there is no
JSDoc describing the expected filter contract; add a JSDoc block above the
optimize() method that documents the expected input (this ImageConverter
instance), the expected return type (e.g. a Promise resolving to void, an
updated ImageConverter, or a specific result object), whether filters should
mutate the instance or return a new one, and any error/exception behavior;
reference the optimize() method name and the filter hook
'cimo.imageConverter.optimize' in the comment so implementers know what to
implement when hooking into applyFiltersAsync.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/admin/class-metadata.php`:
- Around line 162-164: You added an associative key 'optimized_during_upload' =>
true into $sanitized_metadata (a numerically-indexed array), which mixes array
types and breaks consumers like add_attachment_metadata() that expect each item
to be an array with a 'filename' key; instead, either (A) push a properly
structured metadata entry into $sanitized_metadata (e.g., an array with
'filename' and a flag field) so iteration still yields arrays, or (B) keep the
boolean flag separate (e.g., set it on the attachment post meta or a separate
variable/property) and do not inject an associative key into
$sanitized_metadata; update any usages in add_attachment_metadata(),
class-meta-box.php, and class-stats.php to read the flag from the new location.

In `@src/admin/class-stats.php`:
- Around line 198-204: In update_stats_bulk_restored, the two size fields are
using the wrong parameters: swap the size arithmetic so total_optimized_size
subtracts $optimized_size/1024 and total_original_size is adjusted only
according to how originals were tracked during optimization (e.g. subtract
$restored_size/1024 if originals were previously added, otherwise leave
unchanged) — update the lines in update_stats_bulk_restored to use
$optimized_size and $restored_size in the correct places (reference function
update_stats_bulk_restored and variables $optimized_size, $restored_size,
$stats['total_original_size'], $stats['total_optimized_size']); also address the
unused $attachment_id by either prefixing it with an underscore or adding a //
phpcs:ignore comment.
- Around line 87-106: The code double-counts media_optimized_num because it
increments inside the foreach over $cimo_data['bulk_optimization'] and then
unconditionally again after that block; update the logic around $cimo_data and
$updated_stats so the final $updated_stats['media_optimized_num']++ only runs
for individually optimized images (i.e., when bulk_optimization is not present
or empty). Concretely, use an if/else or guard that checks
isset($cimo_data['bulk_optimization']) (and non-empty if appropriate) and only
perform the standalone increment when no bulk_optimization entries were
processed, leaving the increments inside the foreach unchanged.

In `@src/shared/converters/image-converter.js`:
- Around line 229-231: The format normalization can leave formatTo as an
unsupported string (e.g., "jpeg") which causes formatInfo to be undefined later;
update the logic around formatTo (derived from options.format and
this.options?.format) to canonicalize common aliases (e.g., "jpeg" -> "jpg")
and/or map "image/..." MIME types to supportedFormats values, then look up
supportedFormats to get formatInfo and if lookup returns undefined fall back to
a safe default like 'webp' (and log or throw a clear error if appropriate) so
that any subsequent use of formatInfo.mimeType in the image conversion flow
cannot dereference undefined.

---

Nitpick comments:
In `@src/admin/class-stats.php`:
- Around line 183-189: The parameter $attachment_id in the static method
update_stats_bulk_optimized is unused and triggers static-analysis warnings; to
silence them, rename the parameter to $_attachment_id (or otherwise prefix it
with an underscore) in the method signature and any callers, leaving the body
unchanged; reference: update_stats_bulk_optimized and its parameter
$attachment_id.
- Line 93: The foreach over $cimo_data['bulk_optimization'] declares an unused
loop key $size; update the loop in src/admin/class-stats.php to avoid the unused
variable by iterating only values (e.g., change the foreach signature that
currently uses $size to use just $data) or explicitly use an underscore key
(e.g., $_ => $data) so static analysis no longer flags $size as unused while
preserving the existing loop body that references $data.

In `@src/shared/converters/image-converter.js`:
- Around line 360-363: The optimize() method delegates to the WordPress filter
'cimo.imageConverter.optimize' via applyFiltersAsync(this), but there is no
JSDoc describing the expected filter contract; add a JSDoc block above the
optimize() method that documents the expected input (this ImageConverter
instance), the expected return type (e.g. a Promise resolving to void, an
updated ImageConverter, or a specific result object), whether filters should
mutate the instance or return a new one, and any error/exception behavior;
reference the optimize() method name and the filter hook
'cimo.imageConverter.optimize' in the comment so implementers know what to
implement when hooking into applyFiltersAsync.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3daa2999-3f41-463c-a3d5-042f6c705705

📥 Commits

Reviewing files that changed from the base of the PR and between 7f63e64 and a7762b0.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • package.json
  • readme.txt
  • src/admin/class-admin.php
  • src/admin/class-metadata.php
  • src/admin/class-stats.php
  • src/admin/css/admin-page.css
  • src/admin/js/media-manager/drop-zone.js
  • src/admin/js/media-manager/select-files.js
  • src/admin/js/page/admin-settings.js
  • src/shared/converters/image-converter.js

Comment on lines +162 to +164
// Add our metadata key to note that this was optimized during upload.
$sanitized_metadata['optimized_during_upload'] = true;

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Data structure inconsistency: mixing non-numeric key into a numerically-indexed array.

$sanitized_metadata is a numerically-indexed array of metadata entries. Adding 'optimized_during_upload' => true as an associative key creates a mixed array that will cause issues downstream:

  1. In add_attachment_metadata() (line 215), the foreach iterates expecting each $item to be an array with a 'filename' key. When it encounters the boolean true value, isset($item['filename']) will fail or produce unexpected behavior.

  2. This could also affect consumers in class-meta-box.php and class-stats.php that expect consistent data structures.

Consider storing this flag separately or restructuring to avoid mixing numeric and associative keys:

Proposed fix
-		// Add our metadata key to note that this was optimized during upload.
-		$sanitized_metadata['optimized_during_upload'] = true;
-
 		// Save to a transient queue for metadata waiting for attachment creation
 		$transient_key = 'cimo_metadata_queue';
 		$queue = get_transient( $transient_key );
 		if ( ! is_array( $queue ) ) {
 			$queue = [];
 		}

 		// Append new metadata to the queue
-		$queue = array_merge( $queue, $sanitized_metadata );
+		// Mark each entry as optimized during upload
+		foreach ( $sanitized_metadata as &$entry ) {
+			$entry['optimized_during_upload'] = true;
+		}
+		$queue = array_merge( $queue, $sanitized_metadata );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/admin/class-metadata.php` around lines 162 - 164, You added an
associative key 'optimized_during_upload' => true into $sanitized_metadata (a
numerically-indexed array), which mixes array types and breaks consumers like
add_attachment_metadata() that expect each item to be an array with a 'filename'
key; instead, either (A) push a properly structured metadata entry into
$sanitized_metadata (e.g., an array with 'filename' and a flag field) so
iteration still yields arrays, or (B) keep the boolean flag separate (e.g., set
it on the attachment post meta or a separate variable/property) and do not
inject an associative key into $sanitized_metadata; update any usages in
add_attachment_metadata(), class-meta-box.php, and class-stats.php to read the
flag from the new location.

Comment on lines +87 to 106

/**
* This data comes from bulk optimizing media in the Media Library:
*/

if ( isset( $cimo_data['bulk_optimization'] ) ) {
foreach ( $cimo_data['bulk_optimization'] as $size => $data ) {
$updated_stats['media_optimized_num']++;
$original_size_b = isset( $data['originalFilesize'] ) ? (int) $data['originalFilesize'] : 0;
$converted_size_b = isset( $data['convertedFilesize'] ) ? (int) $data['convertedFilesize'] : 0;
$updated_stats['total_original_size'] += $original_size_b / 1024;
$updated_stats['total_optimized_size'] += $converted_size_b / 1024;
}
}

/**
* This data comes from individually optimized images from the user uploading media:
*/

$updated_stats['media_optimized_num']++;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Double-counting issue: media_optimized_num is incremented both inside and outside the bulk optimization loop.

When bulk_optimization data exists, the code increments media_optimized_num for each entry inside the loop (line 94), but then also unconditionally increments it again at line 106. This results in double-counting.

Proposed fix: only count individually optimized images when bulk_optimization is absent
 				if ( isset( $cimo_data['bulk_optimization'] ) ) {
 					foreach ( $cimo_data['bulk_optimization'] as $size => $data ) {
 						$updated_stats['media_optimized_num']++;
 						$original_size_b = isset( $data['originalFilesize'] ) ? (int) $data['originalFilesize'] : 0;
 						$converted_size_b = isset( $data['convertedFilesize'] ) ? (int) $data['convertedFilesize'] : 0;
 						$updated_stats['total_original_size'] += $original_size_b / 1024;
 						$updated_stats['total_optimized_size'] += $converted_size_b / 1024;
 					}
-				}
-
-				/**
-				 * This data comes from individually optimized images from the user uploading media:
-				 */
-
-				$updated_stats['media_optimized_num']++;
-
-				// Extract file sizes (bytes) and add to KB totals
-				$original_size_b = isset( $cimo_data['originalFilesize'] ) ? (int) $cimo_data['originalFilesize'] : 0;
-				$converted_size_b = isset( $cimo_data['convertedFilesize'] ) ? (int) $cimo_data['convertedFilesize'] : 0;
-
-				$updated_stats['total_original_size'] += $original_size_b / 1024;
-				$updated_stats['total_optimized_size'] += $converted_size_b / 1024;
+				} else {
+					/**
+					 * This data comes from individually optimized images from the user uploading media:
+					 */
+					$updated_stats['media_optimized_num']++;
+
+					// Extract file sizes (bytes) and add to KB totals
+					$original_size_b = isset( $cimo_data['originalFilesize'] ) ? (int) $cimo_data['originalFilesize'] : 0;
+					$converted_size_b = isset( $cimo_data['convertedFilesize'] ) ? (int) $cimo_data['convertedFilesize'] : 0;
+
+					$updated_stats['total_original_size'] += $original_size_b / 1024;
+					$updated_stats['total_optimized_size'] += $converted_size_b / 1024;
+				}
🧰 Tools
🪛 PHPMD (2.15.0)

[warning] 93-93: Avoid unused local variables such as '$size'. (undefined)

(UnusedLocalVariable)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/admin/class-stats.php` around lines 87 - 106, The code double-counts
media_optimized_num because it increments inside the foreach over
$cimo_data['bulk_optimization'] and then unconditionally again after that block;
update the logic around $cimo_data and $updated_stats so the final
$updated_stats['media_optimized_num']++ only runs for individually optimized
images (i.e., when bulk_optimization is not present or empty). Concretely, use
an if/else or guard that checks isset($cimo_data['bulk_optimization']) (and
non-empty if appropriate) and only perform the standalone increment when no
bulk_optimization entries were processed, leaving the increments inside the
foreach unchanged.

Comment on lines +198 to +204
public static function update_stats_bulk_restored( $attachment_id, $optimized_size, $restored_size ) {
$stats = self::get_stats();
$stats['media_optimized_num']--;
$stats['total_original_size'] -= $optimized_size / 1024;
$stats['total_optimized_size'] -= $restored_size / 1024;
update_option( self::OPTION_KEY, $stats, false );
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Verify the restore stats logic: parameter usage appears inverted.

The subtraction logic seems backwards:

  • total_original_size -= $optimized_size — but when restoring, the original size should remain unchanged or increase
  • total_optimized_size -= $restored_size — this should subtract the optimized size being removed

Also, $attachment_id is unused per static analysis. If it's reserved for future use, consider adding a // phpcs:ignore comment or prefixing with underscore.

Suggested fix (verify intended behavior)
-	public static function update_stats_bulk_restored( $attachment_id, $optimized_size, $restored_size ) {
+	public static function update_stats_bulk_restored( $_attachment_id, $optimized_size, $restored_size ) {
 		$stats = self::get_stats();
 		$stats['media_optimized_num']--;
-		$stats['total_original_size'] -= $optimized_size / 1024;
-		$stats['total_optimized_size'] -= $restored_size / 1024;
+		$stats['total_original_size'] -= $restored_size / 1024;
+		$stats['total_optimized_size'] -= $optimized_size / 1024;
 		update_option( self::OPTION_KEY, $stats, false );
 	}
🧰 Tools
🪛 PHPMD (2.15.0)

[warning] 198-198: Avoid unused parameters such as '$attachment_id'. (undefined)

(UnusedFormalParameter)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/admin/class-stats.php` around lines 198 - 204, In
update_stats_bulk_restored, the two size fields are using the wrong parameters:
swap the size arithmetic so total_optimized_size subtracts $optimized_size/1024
and total_original_size is adjusted only according to how originals were tracked
during optimization (e.g. subtract $restored_size/1024 if originals were
previously added, otherwise leave unchanged) — update the lines in
update_stats_bulk_restored to use $optimized_size and $restored_size in the
correct places (reference function update_stats_bulk_restored and variables
$optimized_size, $restored_size, $stats['total_original_size'],
$stats['total_optimized_size']); also address the unused $attachment_id by
either prefixing it with an underscore or adding a // phpcs:ignore comment.

Comment on lines +229 to +231
let formatTo = options.format || this.options?.format || ''
formatTo = ( formatTo.startsWith( 'image/' ) ? supportedFormats.find( f => f.mimeType === formatTo )?.value : formatTo ) ||
'webp'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Potential null dereference when formatTo is an unsupported format string.

If a caller passes formatTo = 'jpeg' (rather than 'jpg' or 'image/jpeg'), the normalization logic preserves it unchanged. Then at line 243, formatInfo becomes undefined since supportedFormats uses 'jpg' as the value. This causes a crash at line 336 when accessing formatInfo.mimeType.

Consider adding early validation:

🛡️ Proposed fix to validate formatTo
 let formatTo = options.format || this.options?.format || ''
 formatTo = ( formatTo.startsWith( 'image/' ) ? supportedFormats.find( f => f.mimeType === formatTo )?.value : formatTo ) ||
     'webp'
+
+ // Normalize 'jpeg' to 'jpg' for consistency
+ if ( formatTo === 'jpeg' ) {
+     formatTo = 'jpg'
+ }
+
+ // Validate formatTo is a supported format
+ const formatInfo = supportedFormats.find( f => f.value === formatTo )
+ if ( ! formatInfo ) {
+     return {
+         file,
+         metadata: null,
+         reason: 'unsupported-format',
+         error: `Unsupported output format: ${ formatTo }`,
+     }
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let formatTo = options.format || this.options?.format || ''
formatTo = ( formatTo.startsWith( 'image/' ) ? supportedFormats.find( f => f.mimeType === formatTo )?.value : formatTo ) ||
'webp'
let formatTo = options.format || this.options?.format || ''
formatTo = ( formatTo.startsWith( 'image/' ) ? supportedFormats.find( f => f.mimeType === formatTo )?.value : formatTo ) ||
'webp'
// Normalize 'jpeg' to 'jpg' for consistency
if ( formatTo === 'jpeg' ) {
formatTo = 'jpg'
}
// Validate formatTo is a supported format
const formatInfo = supportedFormats.find( f => f.value === formatTo )
if ( ! formatInfo ) {
return {
file,
metadata: null,
reason: 'unsupported-format',
error: `Unsupported output format: ${ formatTo }`,
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/converters/image-converter.js` around lines 229 - 231, The format
normalization can leave formatTo as an unsupported string (e.g., "jpeg") which
causes formatInfo to be undefined later; update the logic around formatTo
(derived from options.format and this.options?.format) to canonicalize common
aliases (e.g., "jpeg" -> "jpg") and/or map "image/..." MIME types to
supportedFormats values, then look up supportedFormats to get formatInfo and if
lookup returns undefined fall back to a safe default like 'webp' (and log or
throw a clear error if appropriate) so that any subsequent use of
formatInfo.mimeType in the image conversion flow cannot dereference undefined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Support for Bulk Optimization of Images

1 participant