Skip to content

refactor: standardize source map handling across compressors#2800

Merged
srod merged 3 commits intodevelopfrom
refactor/p3-source-map-utils
Jan 28, 2026
Merged

refactor: standardize source map handling across compressors#2800
srod merged 3 commits intodevelopfrom
refactor/p3-source-map-utils

Conversation

@srod
Copy link
Owner

@srod srod commented Jan 27, 2026

User description

Summary

  • Extract duplicated !!options.sourceMap pattern into shared utilities in @node-minify/utils
  • getSourceMapBoolean() — normalizes sourceMap option to boolean (used by swc, oxc, lightningcss)
  • extractSourceMapOption() — extracts sourceMap boolean + remaining options (used by esbuild)
  • Update .plans/github_action_implementation_plan.md to reflect completed work

Changes

  • New: packages/utils/src/sourceMap.ts + 18 tests
  • Updated: swc, oxc, lightningcss, esbuild compressors to use shared utilities
  • No behavior changes — pure refactoring

PR Type

Enhancement, Tests


Description

  • Extract duplicated sourceMap handling into shared utility functions

  • Add getSourceMapBoolean() and extractSourceMapOption() utilities

  • Update swc, oxc, lightningcss, esbuild compressors to use new utilities

  • Add comprehensive test suite with 18 test cases for sourceMap utilities

  • Update implementation plan to reflect completed GitHub Action work


Diagram Walkthrough

flowchart LR
  A["Duplicated sourceMap<br/>handling in 4 compressors"]
  B["New sourceMap.ts<br/>utility module"]
  C["getSourceMapBoolean()"]
  D["extractSourceMapOption()"]
  E["swc, oxc,<br/>lightningcss, esbuild"]
  F["Consistent sourceMap<br/>normalization"]
  
  A --> B
  B --> C
  B --> D
  C --> E
  D --> E
  E --> F
Loading

File Walkthrough

Relevant files
Enhancement
sourceMap.ts
New sourceMap utility functions for compressors                   

packages/utils/src/sourceMap.ts

  • New utility module with two functions for sourceMap handling
  • getSourceMapBoolean() normalizes sourceMap option to boolean
  • extractSourceMapOption() extracts sourceMap and remaining options
    separately
  • Eliminates duplicated !!options.sourceMap pattern across compressors
+38/-0   
index.ts
Export sourceMap utilities from utils package                       

packages/utils/src/index.ts

  • Import new sourceMap utility functions
  • Export getSourceMapBoolean and extractSourceMapOption from utils
    package
  • Makes utilities available to all compressor packages
+3/-0     
index.ts
Update swc to use sourceMap utility                                           

packages/swc/src/index.ts

  • Import getSourceMapBoolean from utils
  • Replace !!options.sourceMap with getSourceMapBoolean(options) call
  • Improves code consistency and reduces duplication
+3/-2     
index.ts
Update oxc to use sourceMap utility                                           

packages/oxc/src/index.ts

  • Import getSourceMapBoolean from utils
  • Replace !!options.sourceMap with getSourceMapBoolean(options) call
  • Maintains consistent sourceMap handling across compressors
+3/-1     
index.ts
Update lightningcss to use sourceMap utility                         

packages/lightningcss/src/index.ts

  • Import getSourceMapBoolean from utils
  • Replace !!options.sourceMap with getSourceMapBoolean(options) call
  • Standardizes sourceMap normalization pattern
+3/-2     
index.ts
Update esbuild to use sourceMap utility                                   

packages/esbuild/src/index.ts

  • Import extractSourceMapOption from utils
  • Replace destructuring pattern with extractSourceMapOption() call
  • Simplifies sourceMap extraction and option handling
+8/-3     
Tests
sourceMap.test.ts
Complete test coverage for sourceMap utilities                     

packages/utils/tests/sourceMap.test.ts

  • Comprehensive test suite with 18 test cases
  • Tests for getSourceMapBoolean() covering undefined, empty, falsy,
    truthy, and mixed options
  • Tests for extractSourceMapOption() covering extraction, preservation,
    and immutability
  • Validates edge cases like null, undefined, and non-empty strings
+124/-0 
Documentation
github_action_implementation_plan.md
Update implementation plan with completion status               

.plans/github_action_implementation_plan.md

  • Mark overall status as complete with publication date
  • Update Phase 2 checklist items from unchecked to checked
  • Note Phase 1 was skipped in favor of direct JavaScript Action
  • Update file references to reflect actual implementation structure
+25/-23 

Summary by CodeRabbit

  • New Features

    • Completed GitHub Action (Phase 2) with marketplace-ready action and docs site page
    • Added source-map utilities to normalize source map option handling
  • Refactor

    • Standardized source-map handling across minifier integrations for consistent behavior
  • Tests

    • Added comprehensive tests covering source-map utilities and edge cases

✏️ Tip: You can customize this high-level summary in your review settings.

srod added 2 commits January 27, 2026 19:24
- Create sourceMap.ts utility with getSourceMapBoolean and extractSourceMapOption
- Add comprehensive tests for source map utilities
- Update swc, oxc, lightningcss, esbuild to use new utilities
- Reduces duplication and improves consistency across compressors
- Mark P3 source map utilities as completed in github_action_implementation_plan.md
@changeset-bot
Copy link

changeset-bot bot commented Jan 27, 2026

⚠️ No Changeset found

Latest commit: 5ece1b1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 27, 2026

📝 Walkthrough

Walkthrough

Refactors sourceMap option handling into two new utilities and applies them across compressor packages; implements a JavaScript GitHub Action with associated files, docs and tests, and adds tests for the new utilities.

Changes

Cohort / File(s) Summary
Planning & Action
\.plans/github_action_implementation_plan.md, packages/action/*, .github/workflows/test-action.yml, docs/github-action.md
Updated plan metadata; implemented Phase 2 as a JavaScript GitHub Action with action package files, workflows, docs, and tests.
New Utilities
packages/utils/src/sourceMap.ts
Added getSourceMapBoolean() and extractSourceMapOption() to normalize sourceMap flag extraction.
Utils Exports
packages/utils/src/index.ts
Exported the new sourceMap utilities.
Utils Tests
packages/utils/__tests__/sourceMap.test.ts
New comprehensive tests for sourceMap utilities covering many input variants and immutability.
Compressor Integrations
packages/esbuild/src/index.ts, packages/lightningcss/src/index.ts, packages/oxc/src/index.ts, packages/swc/src/index.ts
Replaced inline !!options.sourceMap handling with extractSourceMapOption() / getSourceMapBoolean() and forwarded extracted options to respective minifiers.

Sequence Diagram(s)

sequenceDiagram
  participant Runner as Runner
  participant Action as Action (packages/action)
  participant Minifiers as Minifier Modules
  participant Reporters as Reporters (summary/comment/annotations)
  participant GH as GitHub API

  Runner->>Action: trigger with inputs
  Action->>Minifiers: discover files & call minifier (uses extractSourceMapOption)
  Minifiers-->>Action: return code + optional map
  Action->>Reporters: build reports (summary/comment/annotations)
  Reporters->>GH: post comments/annotations & update summary
  GH-->>Runner: workflow status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

Review effort 3/5

Poem

🐰 Hiccup-hop, I parsed each line,

I nudged the maps, made flags align,
Compressors hum, reporters sing,
A tiny action takes to wing,
I twitch my nose—new tests, refined!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor: standardize source map handling across compressors' directly and accurately describes the main change: extracting duplicated source map logic into shared utilities and standardizing its use across multiple compressor packages (swc, oxc, lightningcss, esbuild).
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

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.

@qodo-code-review
Copy link

qodo-code-review bot commented Jan 27, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@greptile-apps
Copy link

greptile-apps bot commented Jan 27, 2026

Greptile Overview

Greptile Summary

This refactoring extracts duplicated !!options.sourceMap logic into two shared utilities in @node-minify/utils. The changes are purely structural with zero behavior changes.

  • Created getSourceMapBoolean() for normalizing sourceMap to boolean (used by swc, oxc, lightningcss)
  • Created extractSourceMapOption() for extracting sourceMap + remaining options (used by esbuild)
  • Updated all four compressors to use the shared utilities instead of inline logic
  • Added comprehensive test coverage (18 tests) covering edge cases and immutability
  • No runtime behavior changes - this is a pure refactoring for maintainability

Confidence Score: 5/5

  • This PR is safe to merge with no risk
  • Pure refactoring with comprehensive test coverage, no behavior changes, and all tests pass
  • No files require special attention

Important Files Changed

Filename Overview
packages/utils/src/sourceMap.ts Added two utility functions to normalize sourceMap options - well-documented with JSDoc
packages/utils/tests/sourceMap.test.ts Comprehensive test coverage with 18 tests covering all edge cases and immutability
packages/swc/src/index.ts Replaced inline !!options.sourceMap with getSourceMapBoolean() utility
packages/oxc/src/index.ts Replaced inline !!options.sourceMap with getSourceMapBoolean() utility
packages/lightningcss/src/index.ts Replaced inline !!options.sourceMap with getSourceMapBoolean() utility
packages/esbuild/src/index.ts Replaced manual destructuring with extractSourceMapOption() utility, removed redundant !! cast

Sequence Diagram

sequenceDiagram
    participant User
    participant Compressor as Compressor<br/>(swc/oxc/lightningcss/esbuild)
    participant Utils as @node-minify/utils
    participant MinifyLib as Minify Library<br/>(swc/oxc/lightningcss/esbuild)

    User->>Compressor: minify({ settings, content })
    Note over Compressor: settings.options = { sourceMap: true, ... }
    
    alt esbuild compressor
        Compressor->>Utils: extractSourceMapOption(options)
        Utils-->>Compressor: { sourceMap: true, restOptions: {...} }
        Compressor->>MinifyLib: transform(content, { sourcemap: true, ...restOptions })
    else swc/oxc/lightningcss
        Compressor->>Utils: getSourceMapBoolean(options)
        Utils-->>Compressor: true
        Compressor->>MinifyLib: minify(content, { sourceMap: true, ...options })
    end
    
    MinifyLib-->>Compressor: { code, map }
    Compressor-->>User: { code, map }
Loading

@qodo-code-review
Copy link

qodo-code-review bot commented Jan 27, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Avoid sourceMap override in transform
Suggestion Impact:The commit replaced getSourceMapBoolean/options spreading with extractSourceMapOption, and passed sourceMap plus the remaining options (restOptions) to transform, preventing sourceMap override.

code diff:

-import { ensureStringContent, getSourceMapBoolean } from "@node-minify/utils";
+import {
+    ensureStringContent,
+    extractSourceMapOption,
+} from "@node-minify/utils";
 import { transform } from "lightningcss";
 
 /**
@@ -21,15 +24,16 @@
 }: MinifierOptions): Promise<CompressorResult> {
     const contentStr = ensureStringContent(content, "lightningcss");
 
-    const options = settings?.options ?? {};
-    const enableSourceMap = getSourceMapBoolean(options);
+    const { sourceMap, restOptions } = extractSourceMapOption(
+        settings?.options
+    );
 
     const result = transform({
         filename: "input.css",
         code: Buffer.from(contentStr),
         minify: true,
-        sourceMap: enableSourceMap,
-        ...options,
+        sourceMap,
+        ...restOptions,
     });

In lightningcss/src/index.ts, use extractSourceMapOption to separate the
sourceMap property and avoid it being overridden when passing options to the
transform function.

packages/lightningcss/src/index.ts [24-33]

-const options = settings?.options ?? {};
-const enableSourceMap = getSourceMapBoolean(options);
+const { sourceMap, restOptions } = extractSourceMapOption(settings?.options);
 
 const result = transform({
     filename: "input.css",
     code: Buffer.from(contentStr),
     minify: true,
-    sourceMap: enableSourceMap,
-    ...options,
+    sourceMap,
+    ...restOptions,
 });

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a bug where spreading ...options after setting sourceMap would override the intended boolean value, and proposes a robust fix using a utility function introduced in this PR.

Medium
Prevent sourcemap override
Suggestion Impact:Replaced getSourceMapBoolean/options spreading with extractSourceMapOption, and spread restOptions after explicitly setting sourcemap to sourceMap, preventing an override.

code diff:

@@ -7,7 +7,7 @@
 import type { CompressorResult, MinifierOptions } from "@node-minify/types";
 import {
     ensureStringContent,
-    getSourceMapBoolean,
+    extractSourceMapOption,
     validateMinifyResult,
     wrapMinificationError,
 } from "@node-minify/utils";
@@ -25,13 +25,14 @@
     content,
 }: MinifierOptions): Promise<CompressorResult> {
     const contentStr = ensureStringContent(content, "oxc");
-    const options = settings?.options ?? {};
-    const enableSourceMap = getSourceMapBoolean(options);
+    const { sourceMap, restOptions } = extractSourceMapOption(
+        settings?.options
+    );
 
     try {
         const result = await oxcMinify("input.js", contentStr, {
-            sourcemap: enableSourceMap,
-            ...options,
+            sourcemap: sourceMap,
+            ...restOptions,
         });

In oxc/src/index.ts, use extractSourceMapOption to separate the sourceMap
property and avoid it being overridden when passing options to oxcMinify.

packages/oxc/src/index.ts [28-35]

-const options = settings?.options ?? {};
-const enableSourceMap = getSourceMapBoolean(options);
+const { sourceMap, restOptions } = extractSourceMapOption(settings?.options);
 
 try {
     const result = await oxcMinify("input.js", contentStr, {
-        sourcemap: enableSourceMap,
-        ...options,
+        sourcemap: sourceMap,
+        ...restOptions,
     });

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a bug where spreading ...options after setting sourcemap would override the intended boolean value, and proposes a robust fix using a utility function introduced in this PR.

Medium
Honor normalized sourceMap flag
Suggestion Impact:Replaced getSourceMapBoolean/options spreading with extractSourceMapOption, passing sourceMap explicitly and spreading restOptions so sourceMap cannot be overridden.

code diff:

-import { ensureStringContent, getSourceMapBoolean } from "@node-minify/utils";
+import {
+    ensureStringContent,
+    extractSourceMapOption,
+} from "@node-minify/utils";
 import { minify as swcMinify } from "@swc/core";
 
 /**
@@ -21,14 +24,15 @@
 }: MinifierOptions): Promise<CompressorResult> {
     const contentStr = ensureStringContent(content, "swc");
 
-    const options = settings?.options ?? {};
-    const enableSourceMap = getSourceMapBoolean(options);
+    const { sourceMap, restOptions } = extractSourceMapOption(
+        settings?.options
+    );
 
     const result = await swcMinify(contentStr, {
         compress: true,
         mangle: true,
-        sourceMap: enableSourceMap,
-        ...options,
+        sourceMap,
+        ...restOptions,
     });

In swc/src/index.ts, use extractSourceMapOption to separate the sourceMap
property and avoid it being overridden when passing options to swcMinify.

packages/swc/src/index.ts [24-32]

-const options = settings?.options ?? {};
-const enableSourceMap = getSourceMapBoolean(options);
+const { sourceMap, restOptions } = extractSourceMapOption(settings?.options);
 
 const result = await swcMinify(contentStr, {
     compress: true,
     mangle: true,
-    sourceMap: enableSourceMap,
-    ...options,
+    sourceMap,
+    ...restOptions,
 });

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a bug where spreading ...options after setting sourceMap would override the intended boolean value, and proposes a robust fix using a utility function introduced in this PR.

Medium
  • Update

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 8 files

Use extractSourceMapOption to separate sourceMap from restOptions,
preventing user-provided sourceMap from overriding normalized boolean.
@srod srod merged commit 9b0b0f5 into develop Jan 28, 2026
9 checks passed
@srod srod deleted the refactor/p3-source-map-utils branch January 28, 2026 17:10
@codecov
Copy link

codecov bot commented Jan 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.09%. Comparing base (c99370c) to head (5ece1b1).
⚠️ Report is 4 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #2800      +/-   ##
===========================================
+ Coverage    95.07%   95.09%   +0.02%     
===========================================
  Files           72       73       +1     
  Lines         1686     1693       +7     
  Branches       512      509       -3     
===========================================
+ Hits          1603     1610       +7     
  Misses          83       83              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant