Skip to content

fix(deps): update frontend dependencies#788

Open
renovate-sh-app[bot] wants to merge 1 commit into
mainfrom
renovate/frontend-dependencies
Open

fix(deps): update frontend dependencies#788
renovate-sh-app[bot] wants to merge 1 commit into
mainfrom
renovate/frontend-dependencies

Conversation

@renovate-sh-app

@renovate-sh-app renovate-sh-app Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
@babel/core (source) 7.29.67.29.7 age confidence
@changesets/cli (source) 2.31.02.31.1 age confidence
@swc/core (source) 1.15.431.15.46 age confidence
@typescript-eslint/eslint-plugin (source) 8.63.08.65.0 age confidence
@typescript-eslint/parser (source) 8.63.08.65.0 age confidence
dompurify 3.4.113.4.12 age confidence
prettier (source) 3.9.53.9.6 age confidence
sass 1.101.01.101.7 age confidence
webpack 5.108.45.109.0 age confidence

DOMPurify: CUSTOM_ELEMENT_HANDLING bypasses afterSanitizeElements for allowed custom elements.

GHSA-c2j3-45gr-mqc4

More information

Details

Summary

There is a possible hook-policy inconsistency in DOMPurify 3.4.11 involving CUSTOM_ELEMENT_HANDLING.

When a custom element is allowed via CUSTOM_ELEMENT_HANDLING.tagNameCheck, it appears that the element does not go through afterSanitizeElements in the same way as a normal element. As a result, an application that relies on afterSanitizeElements as a security policy layer to strip sensitive attributes from all elements may see those attributes removed from normal elements but preserved on allowed custom elements.

This does not appear to be a direct DOMPurify XSS or a case where DOMPurify directly allows executable payloads. The preserved value is still inert at sanitize time. The issue becomes relevant when the allowed custom element later re-injects that attribute value into an HTML sink such as innerHTML, creating a second-order XSS gadget.

Details

The issue appears to originate from the control flow in src/purify.ts: line 1672~1691

const _sanitizeDisallowedNode = function (
    currentNode: any,
    tagName: string
  ): boolean {
    /* Check if we have a custom element to handle */
    if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
      if (
        CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&
        regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)
      ) {
        return false;
      }

      if (
        CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&
        CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)
      ) {
        return false;
      }
    }

CUSTOM_ELEMENT_HANDLING is parsed from user configuration at src/purify.ts: line 741~748

const customElementHandling =
      objectHasOwnProperty(cfg, 'CUSTOM_ELEMENT_HANDLING') &&
      cfg.CUSTOM_ELEMENT_HANDLING &&
      typeof cfg.CUSTOM_ELEMENT_HANDLING === 'object'
        ? clone(cfg.CUSTOM_ELEMENT_HANDLING)
        : create(null);

    CUSTOM_ELEMENT_HANDLING = create(null);

In particular, tagNameCheck, attributeNameCheck, and allowCustomizedBuiltInElements are copied into the internal CUSTOM_ELEMENT_HANDLING object there.

During element sanitization, _sanitizeElements() checks whether a node is forbidden or not allowlisted at src/purify.ts: line 1805~1814

/* Remove element if anything forbids its presence */
    if (
      FORBID_TAGS[tagName] ||
      (!(
        EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function &&
        EXTRA_ELEMENT_HANDLING.tagCheck(tagName)
      ) &&
        !ALLOWED_TAGS[tagName])
    ) {
      return _sanitizeDisallowedNode(currentNode, tagName);
    }

If so, it immediately delegates to _sanitizeDisallowedNode(currentNode, tagName) and returns its boolean result.

Inside _sanitizeDisallowedNode(), the custom-element-specific allow path is implemented at src/purify.ts: line 1672~1692

const _sanitizeDisallowedNode = function (
    currentNode: any,
    tagName: string
  ): boolean {
    /* Check if we have a custom element to handle */
    if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
      if (
        CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&
        regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)
      ) {
        return false;
      }

      if (
        CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&
        CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)
      ) {
        return false;
      }
    }

If the node is treated as a basic custom element and CUSTOM_ELEMENT_HANDLING.tagNameCheck matches, the function returns false immediately at line 1682 or 1689, meaning “do not remove this node”.

That early return false is significant because control returns directly to _sanitizeElements() via the return _sanitizeDisallowedNode(...) at line 1813. As a result, the later logic in _sanitizeElements() is skipped for that custom element instance, including:

  • the namespace validation at src/purify.ts: line 1816~1826
* Check whether element has a valid namespace.
       Realm-safe check (GHSA-hpcv-96wg-7vj8): use the cached Node.prototype
       nodeType getter rather than `instanceof Element`, which is realm-
       bound and short-circuits to false for any node minted in a different
       realm  letting a foreign-realm element with a forbidden namespace
       slip past the namespace check entirely. */
    const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;
    if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
      _forceRemove(currentNode);
      return true;
    }
  • the fallback-tag mXSS check at src/purify.ts: line 1828~1837
/* Make sure that older browsers don't get fallback-tag mXSS */
    if (
      (tagName === 'noscript' ||
        tagName === 'noembed' ||
        tagName === 'noframes') &&
      regExpTest(EXPRESSIONS.FALLBACK_TAG_CLOSE, currentNode.innerHTML)
    ) {
      _forceRemove(currentNode);
      return true;
    }
  • most importantly for this report, the afterSanitizeElements hook dispatch at src/purify.ts: line 1850~1851.
   /* Execute a hook if present */
    _executeHooks(hooks.afterSanitizeElements, currentNode, null);

In other words, a normal allowlisted element continues through _sanitizeElements() and reaches hooks.afterSanitizeElements, but a disallowed-by-default element that is revived by the CUSTOM_ELEMENT_HANDLING.tagNameCheck path does not. This creates a policy inconsistency: an application that relies on afterSanitizeElements to remove an attribute from all elements will observe that the policy is applied to normal elements but not to custom elements allowed through CUSTOM_ELEMENT_HANDLING.

In the PoC, the application hook removes data-bio from ordinary elements, but the same attribute remains on <x-bio> because the custom-element keep path bypasses afterSanitizeElements. The attribute itself is inert at sanitize time and DOMPurify is not directly allowing executable SVG/HTML through. The security impact appears when the application-defined custom element later reads the preserved data-bio value in connectedCallback() and writes it to innerHTML, turning the preserved attribute into a second-order XSS gadget.

PoC

Reproduced on DOMPurify 3.4.11.

Steps
  1. Save the following HTML to a file, for example poc.html.
  2. Open it in a browser.
  3. Observe that the div control loses data-bio, while the allowed custom element keeps it.
  4. Observe that after connectedCallback() runs, the candidate payload is reinserted into the DOM and executes through the custom element’s own sink.
HTML PoC
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.4.11/purify.min.js"></script>
</head>
<body>
<pre id="result"></pre>

<script>
window.__controlFired = false;
window.__candidateFired = false;

customElements.define("x-bio", class extends HTMLElement {
  connectedCallback() {
    const bio = this.getAttribute("data-bio");
    if (bio) this.innerHTML = bio;
  }
});

DOMPurify.addHook("afterSanitizeElements", node => {
  if (node.hasAttribute && node.hasAttribute("data-bio")) {
    node.removeAttribute("data-bio");
  }
});

const config = {
  CUSTOM_ELEMENT_HANDLING: {
    tagNameCheck: /^x-/
  }
};

const controlInput =
  '<div data-bio="&lt;img src=x onerror=window.__controlFired=true&gt;"></div>';

const candidateInput =
  '<x-bio data-bio="&lt;img src=x onerror=window.__candidateFired=true&gt;"></x-bio>';

const cleanControl = DOMPurify.sanitize(controlInput, config);
const cleanCandidate = DOMPurify.sanitize(candidateInput, config);

const container = document.createElement("div");
container.innerHTML = cleanCandidate;
document.body.appendChild(container);

setTimeout(() => {
  document.getElementById("result").textContent =
    "This is not direct DOMPurify XSS.\n" +
    "The payload becomes executable only after x-bio writes data-bio into innerHTML.\n\n" +
    "control: " + cleanControl + "\n" +
    "candidate: " + cleanCandidate + "\n" +
    "after connectedCallback: " + container.innerHTML + "\n" +
    "control fired: " + window.__controlFired + "\n" +
    "candidate fired: " + window.__candidateFired;
}, 100);
</script>
</body>
</html>
Expected result
control: <div></div>
candidate: <x-bio data-bio="<img src=x onerror=window.__candidateFired=true>"></x-bio>
after connectedCallback: <x-bio data-bio="..."><img src="x" onerror="window.__candidateFired=true"></x-bio>
control fired: false
candidate fired: true

This is output of HTML PoC.

poc
Impact

This does not appear to affect DOMPurify’s default configuration as a direct sanitizer bypass.

The impact is limited to applications that:

  • enable CUSTOM_ELEMENT_HANDLING,
  • rely on afterSanitizeElements as a security policy layer,
  • expect that hook to apply uniformly to all surviving elements,
  • and have allowed custom elements that later re-inject preserved attribute values into innerHTML or another HTML sink.

In that situation, the behavior can become a second-order XSS gadget because a security-relevant attribute is removed from normal elements but remains on allowed custom elements.

Possible fixes or mitigations might include

  • ensuring that allowed custom elements also consistently pass through afterSanitizeElements
  • documenting clearly that elements preserved via CUSTOM_ELEMENT_HANDLING may not participate in the same post-element hook flow as normal allowlisted elements.

Severity

  • CVSS Score: 2.1 / 10 (Low)
  • Vector String: CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


DOMPurify: CUSTOM_ELEMENT_HANDLING bypasses afterSanitizeElements for allowed custom elements.

CVE-2026-66010 / GHSA-c2j3-45gr-mqc4

More information

Details

Summary

There is a possible hook-policy inconsistency in DOMPurify 3.4.11 involving CUSTOM_ELEMENT_HANDLING.

When a custom element is allowed via CUSTOM_ELEMENT_HANDLING.tagNameCheck, it appears that the element does not go through afterSanitizeElements in the same way as a normal element. As a result, an application that relies on afterSanitizeElements as a security policy layer to strip sensitive attributes from all elements may see those attributes removed from normal elements but preserved on allowed custom elements.

This does not appear to be a direct DOMPurify XSS or a case where DOMPurify directly allows executable payloads. The preserved value is still inert at sanitize time. The issue becomes relevant when the allowed custom element later re-injects that attribute value into an HTML sink such as innerHTML, creating a second-order XSS gadget.

Details

The issue appears to originate from the control flow in src/purify.ts: line 1672~1691

const _sanitizeDisallowedNode = function (
    currentNode: any,
    tagName: string
  ): boolean {
    /* Check if we have a custom element to handle */
    if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
      if (
        CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&
        regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)
      ) {
        return false;
      }

      if (
        CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&
        CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)
      ) {
        return false;
      }
    }

CUSTOM_ELEMENT_HANDLING is parsed from user configuration at src/purify.ts: line 741~748

const customElementHandling =
      objectHasOwnProperty(cfg, 'CUSTOM_ELEMENT_HANDLING') &&
      cfg.CUSTOM_ELEMENT_HANDLING &&
      typeof cfg.CUSTOM_ELEMENT_HANDLING === 'object'
        ? clone(cfg.CUSTOM_ELEMENT_HANDLING)
        : create(null);

    CUSTOM_ELEMENT_HANDLING = create(null);

In particular, tagNameCheck, attributeNameCheck, and allowCustomizedBuiltInElements are copied into the internal CUSTOM_ELEMENT_HANDLING object there.

During element sanitization, _sanitizeElements() checks whether a node is forbidden or not allowlisted at src/purify.ts: line 1805~1814

/* Remove element if anything forbids its presence */
    if (
      FORBID_TAGS[tagName] ||
      (!(
        EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function &&
        EXTRA_ELEMENT_HANDLING.tagCheck(tagName)
      ) &&
        !ALLOWED_TAGS[tagName])
    ) {
      return _sanitizeDisallowedNode(currentNode, tagName);
    }

If so, it immediately delegates to _sanitizeDisallowedNode(currentNode, tagName) and returns its boolean result.

Inside _sanitizeDisallowedNode(), the custom-element-specific allow path is implemented at src/purify.ts: line 1672~1692

const _sanitizeDisallowedNode = function (
    currentNode: any,
    tagName: string
  ): boolean {
    /* Check if we have a custom element to handle */
    if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
      if (
        CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&
        regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)
      ) {
        return false;
      }

      if (
        CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&
        CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)
      ) {
        return false;
      }
    }

If the node is treated as a basic custom element and CUSTOM_ELEMENT_HANDLING.tagNameCheck matches, the function returns false immediately at line 1682 or 1689, meaning “do not remove this node”.

That early return false is significant because control returns directly to _sanitizeElements() via the return _sanitizeDisallowedNode(...) at line 1813. As a result, the later logic in _sanitizeElements() is skipped for that custom element instance, including:

  • the namespace validation at src/purify.ts: line 1816~1826
* Check whether element has a valid namespace.
       Realm-safe check (GHSA-hpcv-96wg-7vj8): use the cached Node.prototype
       nodeType getter rather than `instanceof Element`, which is realm-
       bound and short-circuits to false for any node minted in a different
       realm  letting a foreign-realm element with a forbidden namespace
       slip past the namespace check entirely. */
    const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;
    if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
      _forceRemove(currentNode);
      return true;
    }
  • the fallback-tag mXSS check at src/purify.ts: line 1828~1837
/* Make sure that older browsers don't get fallback-tag mXSS */
    if (
      (tagName === 'noscript' ||
        tagName === 'noembed' ||
        tagName === 'noframes') &&
      regExpTest(EXPRESSIONS.FALLBACK_TAG_CLOSE, currentNode.innerHTML)
    ) {
      _forceRemove(currentNode);
      return true;
    }
  • most importantly for this report, the afterSanitizeElements hook dispatch at src/purify.ts: line 1850~1851.
   /* Execute a hook if present */
    _executeHooks(hooks.afterSanitizeElements, currentNode, null);

In other words, a normal allowlisted element continues through _sanitizeElements() and reaches hooks.afterSanitizeElements, but a disallowed-by-default element that is revived by the CUSTOM_ELEMENT_HANDLING.tagNameCheck path does not. This creates a policy inconsistency: an application that relies on afterSanitizeElements to remove an attribute from all elements will observe that the policy is applied to normal elements but not to custom elements allowed through CUSTOM_ELEMENT_HANDLING.

In the PoC, the application hook removes data-bio from ordinary elements, but the same attribute remains on <x-bio> because the custom-element keep path bypasses afterSanitizeElements. The attribute itself is inert at sanitize time and DOMPurify is not directly allowing executable SVG/HTML through. The security impact appears when the application-defined custom element later reads the preserved data-bio value in connectedCallback() and writes it to innerHTML, turning the preserved attribute into a second-order XSS gadget.

PoC

Reproduced on DOMPurify 3.4.11.

Steps
  1. Save the following HTML to a file, for example poc.html.
  2. Open it in a browser.
  3. Observe that the div control loses data-bio, while the allowed custom element keeps it.
  4. Observe that after connectedCallback() runs, the candidate payload is reinserted into the DOM and executes through the custom element’s own sink.
HTML PoC
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.4.11/purify.min.js"></script>
</head>
<body>
<pre id="result"></pre>

<script>
window.__controlFired = false;
window.__candidateFired = false;

customElements.define("x-bio", class extends HTMLElement {
  connectedCallback() {
    const bio = this.getAttribute("data-bio");
    if (bio) this.innerHTML = bio;
  }
});

DOMPurify.addHook("afterSanitizeElements", node => {
  if (node.hasAttribute && node.hasAttribute("data-bio")) {
    node.removeAttribute("data-bio");
  }
});

const config = {
  CUSTOM_ELEMENT_HANDLING: {
    tagNameCheck: /^x-/
  }
};

const controlInput =
  '<div data-bio="&lt;img src=x onerror=window.__controlFired=true&gt;"></div>';

const candidateInput =
  '<x-bio data-bio="&lt;img src=x onerror=window.__candidateFired=true&gt;"></x-bio>';

const cleanControl = DOMPurify.sanitize(controlInput, config);
const cleanCandidate = DOMPurify.sanitize(candidateInput, config);

const container = document.createElement("div");
container.innerHTML = cleanCandidate;
document.body.appendChild(container);

setTimeout(() => {
  document.getElementById("result").textContent =
    "This is not direct DOMPurify XSS.\n" +
    "The payload becomes executable only after x-bio writes data-bio into innerHTML.\n\n" +
    "control: " + cleanControl + "\n" +
    "candidate: " + cleanCandidate + "\n" +
    "after connectedCallback: " + container.innerHTML + "\n" +
    "control fired: " + window.__controlFired + "\n" +
    "candidate fired: " + window.__candidateFired;
}, 100);
</script>
</body>
</html>
Expected result
control: <div></div>
candidate: <x-bio data-bio="<img src=x onerror=window.__candidateFired=true>"></x-bio>
after connectedCallback: <x-bio data-bio="..."><img src="x" onerror="window.__candidateFired=true"></x-bio>
control fired: false
candidate fired: true

This is output of HTML PoC.

poc
Impact

This does not appear to affect DOMPurify’s default configuration as a direct sanitizer bypass.

The impact is limited to applications that:

  • enable CUSTOM_ELEMENT_HANDLING,
  • rely on afterSanitizeElements as a security policy layer,
  • expect that hook to apply uniformly to all surviving elements,
  • and have allowed custom elements that later re-inject preserved attribute values into innerHTML or another HTML sink.

In that situation, the behavior can become a second-order XSS gadget because a security-relevant attribute is removed from normal elements but remains on allowed custom elements.

Possible fixes or mitigations might include

  • ensuring that allowed custom elements also consistently pass through afterSanitizeElements
  • documenting clearly that elements preserved via CUSTOM_ELEMENT_HANDLING may not participate in the same post-element hook flow as normal allowlisted elements.

Severity

  • CVSS Score: 2.1 / 10 (Low)
  • Vector String: CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N

References

This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).


Release Notes

babel/babel (@​babel/core)

v7.29.7

Compare Source

v7.29.7 (2026-05-25)

Re-release all packages with npm provenance attestations

changesets/changesets (@​changesets/cli)

v2.31.1

Compare Source

Patch Changes
  • #​2159 15cf592 Thanks @​ingvaldlorentzen! - Fixed already-published version detection with npm 12, which always wraps successful npm info --json output in an array. The unwrapped output made changeset publish treat every package as unpublished and fail attempting to republish existing versions.
swc-project/swc (@​swc/core)

v1.15.46

Compare Source

Bug Fixes
Documentation
Features
Refactor
Testing
  • (react-compiler) Add build-pass fixtures for wrapped assignment targets (#​11967) (58d9b53)
Build
Ci
typescript-eslint/typescript-eslint (@​typescript-eslint/eslint-plugin)

v8.65.0

Compare Source

🚀 Features
  • eslint-plugin: [no-shadow] specialized error on enum declaration and member shadowing (#​12578)
  • add warning when TS 7 is detected (#​12529)
  • eslint-plugin: [no-restricted-imports] deprecate extension rule (#​12527, #​19562, #​11889)
🩹 Fixes
  • eslint-plugin: [no-unnecessary-parameter-property-assignment] don't flag computed assignments with a variable key (#​12568)
  • eslint-plugin: [unbound-method] report unbound methods accessed via member expression on union types (#​12448)
  • eslint-plugin: [prefer-string-starts-ends-with] handle escaped $ ending regex literals (#​12515)
❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

v8.64.0

Compare Source

🚀 Features
  • eslint-plugin: [no-loop-func] support using / await using declarations and deprecate the rule (#​12500)
  • typescript-estree: throw for invalid definite assignment in class properties (#​12543)
🩹 Fixes
  • eslint-plugin: [require-array-sort-compare] handle constrained arrays (#​12512)
❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

typescript-eslint/typescript-eslint (@​typescript-eslint/parser)

v8.65.0

Compare Source

🚀 Features
  • add warning when TS 7 is detected (#​12529)
  • parser: add onUnsupportedTypeScriptVersion option to error on unsupported TypeScript versions (#​12465)
❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

v8.64.0

Compare Source

This was a version bump only for parser to align it with other projects, there were no code changes.

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

cure53/DOMPurify (dompurify)

v3.4.12: DOMPurify 3.4.12

Compare Source

  • Fixed an issue where a hook would not get called for custom elements, thanks @​Rikuxx0
  • Hardened the handling of hooks removing elements, @​mkrause-bee360
  • Added support for a few new SVG attributes, thanks @​cbn-falias & @​Develop-KIM
  • Hardened the handling of declarative partial updates
  • Updated the documentation is several spots, README, wiki, etc.
  • Bumped several dependencies where possible
prettier/prettier (prettier)

v3.9.6

Compare Source

diff

TypeScript: Preserve quotes for methods named new (#​19621 by @​kovsu)
// Input
interface Container {
  "new"(id: string): number;
}

// Prettier 3.9.5
interface Container {
  new(id: string): number;
}

// Prettier 3.9.6
interface Container {
  "new"(id: string): number;
}
TypeScript: Support import defer (#​19624, #​19675 by @​fisker)
// Input
import defer * as foo from "foo";

// Prettier 3.9.5
import * as foo from "foo";

// Prettier 3.9.6
import defer * as foo from "foo";
JavaScript: Added a new official plugin @prettier/plugin-yuku (#​19628, #​19629 by @​fisker)

@prettier/plugin-yuku is powered by Yuku (A high-performance JavaScript/TypeScript compiler toolchain written in Zig).

This plugin includes two new parsers: yuku (JavaScript syntax) and yuku-ts (TypeScript syntax).

To use this plugin:

  1. Install the plugin:

    yarn add --dev prettier @&#8203;prettier/plugin-yuku
  2. Add it to your .prettierrc:

    plugins:
      - "@&#8203;prettier/plugin-yuku"

Due to package size limitations, this plugin is not bundled with the main prettier package and must be installed separately.

For more information, check the package homepage.

Big thanks to @​arshad-yaseen for his excellent work.

sass/dart-sass (sass)

v1.101.7

Compare Source

  • No user-visible changes.

v1.101.6

Compare Source

  • No user-visible changes.

v1.101.5

Compare Source

  • No user-visible changes.

v1.101.4

Compare Source

  • Avoid emitting rgb() or rgba() functions with non-percent decimal
    channels. Older browsers only support integer values or (potentially decimal)
    percentages for these functions, so in order to preserve
    backwards-compatibility while retaining full precision for modern browsers,
    legacy colors that contain at least one non-integer channel will now use
    percentages for their channels (for example, rgb(0%, 100%, 50%) rather than
    rgb(0, 255, 127.5)).

  • Fix a bug where the values of plain-CSS if() expressions were emitted using
    their meta.inspect() format rather than their CSS serialization format.

v1.101.3

Compare Source

  • No user-visible changes.
webpack/webpack (webpack)

v5.109.0

Compare Source

Minor Changes
  • Default experiments.typescript to "auto", enabling built-in TypeScript support on Node.js >= 22.6 when no TypeScript loader is registered. (by @​alexander-akait in #​21477)

  • Default experiments.css, experiments.html and experiments.asyncWebAssembly to "auto", enabling built-in support unless a loader is registered for those files; modules with inline or hook-injected loaders (e.g. html-webpack-plugin templates) keep being parsed as JavaScript. (by @​alexander-akait in #​21477)

  • Add output.resourceHints to emit resource hints (preload/prefetch/modulepreload/preconnect), on by default for ESM output, plus module.parser.<type>.urlHints, css.fontPreload and javascript.dynamicImportCssPreload. (by @​alexander-akait in #​21477)

  • Add built-in build progress via infrastructureLogging.progress, plus estimatedTime, phaseTimings, progress bar width and progressBar: "auto" on ProgressPlugin. (by @​alexander-akait in #​21477)

  • Concatenate CommonJS modules with statically analyzable exports; opt out via optimization.concatenateModules: { commonjs: false }. (by @​alexander-akait in #​21477)

  • Wrap "weird" CommonJS modules into module concatenation instead of bailing out. (by @​alexander-akait in #​21477)

  • Add output.html.inline (true | "script" | "style") and the webpackInline magic comment to inline chunk content into HTML. (by @​alexander-akait in #​21477)

  • Add output.html.inject to control where chunk tags are injected. (by @​alexander-akait in #​21477)

  • Add output.html.title, output.html.meta and output.html.base options for head generation. (by @​alexander-akait in #​21477)

  • Support per-icon link attributes (sizes, media, color, type, crossorigin) and arrays in output.html.favicon. (by @​alexander-akait in #​21487)

  • Add output.html.manifest to generate and link a web app manifest with hashed icons. (by @​alexander-akait in #​21487)

  • Add output.html.csp to inject a Content-Security-Policy meta with inline-content hashes and an optional nonce. (by @​alexander-akait in #​21487)

  • Add the output.html injectTags compilation hook to inject tags (script/link/meta/…) with injectTo placement. (by @​alexander-akait in #​21487)

  • Add the output.html transformTags compilation hook to mutate, remove, or move (between <head> and <body>) a page's existing <script>/<link>/<style>/<meta> tags. (by @​alexander-akait in #​21487)

  • Extend the HTML pipeline with html link sources (bundled as their own emitted page) and rel="preload"/"prefetch" links bundled as chunks. (by @​alexander-akait in #​21477)

  • Recognize more asset-bearing HTML sources: the twitter:player:stream meta, legacy SVG references, and Web App Manifest icons/screenshots/shortcuts URLs. (by @​alexander-akait in #​21477)

  • Add module.parser.html.as to parse HTML as a document or an element fragment. (by @​alexander-akait in #​21477)

  • Allow disabling a built-in HTML parser source via type: false in sources. (by @​alexander-akait in #​21477)

  • Export webpack.html.HtmlModulesPlugin with transformHtml/htmlEmitted compilation hooks. (by @​alexander-akait in #​21477)

  • Resolve @custom-media (including media-type values) and @custom-selector in native CSS. (by @​alexander-akait in #​21477)

  • Scope view-transition-name/-group/-class names and ::view-transition-*() pseudo references in CSS modules under customIdents. (by @​alexander-akait in #​21486)

  • Add import.meta.glob support, with a caseSensitive option and consistent hidden/node_modules matching. (by @​alexander-akait in #​21477)

  • Resolve import.meta.resolve("./asset") to the emitted asset URL via the importMeta.resolve parser option. (by @​alexander-akait in #​21477)

  • Add import.meta.env defaults: MODE, DEV, PROD, SSR and BASE_URL. (by @​alexander-akait in #​21477)

  • Add fine-grained import.meta parser options. (by @​alexander-akait in #​21477)

  • Deprecate the importMetaContext parser option in favor of importMeta.webpackContext. (by @​alexander-akait in #​21477)

  • Emit analyzable new URL(…, import.meta.url), worker/worklet URL and import() references with literal specifiers for ESM module output. (by @​alexander-akait in #​21477)

  • Compile async modules to generators for targets without async/await. (by @​alexander-akait in #​21477)

  • Evaluate and validate the second argument of dynamic import(specifier, options). (by @​alexander-akait in #​21477)

  • Add module.parser.javascript.worklet to bundle Worklet addModule() entries. (by @​alexander-akait in #​21477)

  • Add ?raw, ?url, ?inline and ?no-inline asset query suffixes under experiments.futureDefaults. (by @​alexander-akait in #​21477)

  • Add an interop ("default" | "esModule") hint for object externals to control default-export interop. (by @​alexander-akait in #​21477)

  • Add an amd-async externals type that loads AMD externals without an AMD library wrapper. (by @​alexander-akait in #​21477)

  • Support cache.compression: "zstd" for the filesystem cache. (by @​alexander-akait in #​21477)

  • Warn on strict-mode-only syntax and semantic hazards in ES module output, configurable via the strictModeViolations parser option. (by @​alexander-akait in #​21477)

  • Support parsers without location APIs: locations derive from node offsets and AST nodes no longer carry loc. (by @​alexander-akait in #​21477)

  • Attach the original DOM event to ChunkLoadError and ScriptExternalLoadError as error.event. (by [@​alexander-akait](https://redire

Note

PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

Need help?

You can ask for more help in the following Slack channel: #proj-renovate-self-hosted. In that channel you can also find ADR and FAQ docs in the Resources section.

@renovate-sh-app
renovate-sh-app Bot requested a review from a team as a code owner July 21, 2026 22:02
@renovate-sh-app
renovate-sh-app Bot force-pushed the renovate/frontend-dependencies branch 5 times, most recently from 4af2acb to 74bbeea Compare July 24, 2026 10:01
@renovate-sh-app
renovate-sh-app Bot enabled auto-merge (squash) July 24, 2026 10:01
@renovate-sh-app
renovate-sh-app Bot force-pushed the renovate/frontend-dependencies branch 2 times, most recently from b2c304d to aeaa429 Compare July 26, 2026 01:01
| datasource | package                          | from    | to      |
| ---------- | -------------------------------- | ------- | ------- |
| npm        | @babel/core                      | 7.29.6  | 7.29.7  |
| npm        | @changesets/cli                  | 2.31.0  | 2.31.1  |
| npm        | @swc/core                        | 1.15.43 | 1.15.46 |
| npm        | @typescript-eslint/eslint-plugin | 8.63.0  | 8.65.0  |
| npm        | @typescript-eslint/parser        | 8.63.0  | 8.65.0  |
| npm        | dompurify                        | 3.4.11  | 3.4.12  |
| npm        | prettier                         | 3.9.5   | 3.9.6   |
| npm        | sass                             | 1.101.0 | 1.101.7 |
| npm        | webpack                          | 5.108.4 | 5.109.0 |


Signed-off-by: renovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com>
@renovate-sh-app
renovate-sh-app Bot force-pushed the renovate/frontend-dependencies branch from aeaa429 to 03788e7 Compare July 26, 2026 22:02
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