Files
thelounge/package.json
renovate[bot] 7ba5cf9382 Update dependency postcss to v8.5.18 [SECURITY] (#5128)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [postcss](https://postcss.org/)
([source](https://redirect.github.com/postcss/postcss)) | [`8.5.10` →
`8.5.18`](https://renovatebot.com/diffs/npm/postcss/8.5.10/8.5.18) |
![age](https://developer.mend.io/api/mc/badges/age/npm/postcss/8.5.18?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/postcss/8.5.10/8.5.18?slim=true)
|

---

### PostCSS has XSS via Unescaped </style> in its CSS Stringify Output
[CVE-2026-41305](https://nvd.nist.gov/vuln/detail/CVE-2026-41305) /
[GHSA-qx2v-qp2m-jg93](https://redirect.github.com/advisories/GHSA-qx2v-qp2m-jg93)

<details>
<summary>More information</summary>

#### Details
##### PostCSS: XSS via Unescaped `</style>` in CSS Stringify Output

##### Summary

PostCSS v8.5.5 (latest) does not escape `</style>` sequences when
stringifying CSS ASTs. When user-submitted CSS is parsed and
re-stringified for embedding in HTML `<style>` tags, `</style>` in CSS
values breaks out of the style context, enabling XSS.

##### Proof of Concept

```javascript
const postcss = require('postcss');

// Parse user CSS and re-stringify for page embedding
const userCSS = 'body { content: "</style><script>alert(1)</script><style>"; }';
const ast = postcss.parse(userCSS);
const output = ast.toResult().css;
const html = `<style>${output}</style>`;

console.log(html);
// <style>body { content: "</style><script>alert(1)</script><style>"; }</style>
//
// Browser: </style> closes the style tag, <script> executes
```

**Tested output** (Node.js v22, postcss v8.5.5):
```
Input: body { content: "</style><script>alert(1)</script><style>"; }
Output: body { content: "</style><script>alert(1)</script><style>"; }
Contains </style>: true
```

##### Impact

Impact non-bundler use cases since bundlers for XSS on their own.
Requires some PostCSS plugin to have malware code, which can inject XSS
to website.

##### Suggested Fix

Escape `</style` in all stringified output values:
```javascript
output = output.replace(/<\/(style)/gi, '<\\/$1');
```

##### Credits
Discovered and reported by [Sunil Kumar](https://tharvid.in)
([@&#8203;TharVid](https://redirect.github.com/TharVid))

#### Severity
- CVSS Score: 6.1 / 10 (Medium)
- Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N`

#### References
-
[https://github.com/postcss/postcss/security/advisories/GHSA-qx2v-qp2m-jg93](https://redirect.github.com/postcss/postcss/security/advisories/GHSA-qx2v-qp2m-jg93)
-
[https://nvd.nist.gov/vuln/detail/CVE-2026-41305](https://nvd.nist.gov/vuln/detail/CVE-2026-41305)
-
[https://github.com/postcss/postcss/releases/tag/8.5.10](https://redirect.github.com/postcss/postcss/releases/tag/8.5.10)
-
[https://github.com/advisories/GHSA-qx2v-qp2m-jg93](https://redirect.github.com/advisories/GHSA-qx2v-qp2m-jg93)

This data is provided by the [GitHub Advisory
Database](https://redirect.github.com/advisories/GHSA-qx2v-qp2m-jg93)
([CC-BY
4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).
</details>

---

### PostCSS: Arbitrary file read and information disclosure via
attacker-controlled sourceMappingURL in CSS comments
[CVE-2026-45623](https://nvd.nist.gov/vuln/detail/CVE-2026-45623) /
[GHSA-6g55-p6wh-862q](https://redirect.github.com/advisories/GHSA-6g55-p6wh-862q)

<details>
<summary>More information</summary>

#### Details
##### Summary

PostCSS's `PreviousMap` parses the `/*# sourceMappingURL=PATH */`
comment from any CSS string passed to `process()` and dereferences
`PATH` against the local filesystem with no scheme, allowlist, or
traversal check. An attacker who controls the CSS input can cause the
host process to read any file readable by Node and leak the first ~10
bytes of its content through the resulting `JSON.parse` `SyntaxError`
message. The bug also yields a precise file-existence oracle and a
controllable-read primitive that may be combined with large-file targets
for DoS. The behaviour is triggered with PostCSS's default options — no
`from`, no `map`, no plugins required — and is therefore reachable from
any pipeline that runs untrusted CSS through PostCSS (CMS themes,
user-uploaded styles, browser-extension/userstyle processors, build
pipelines for third-party packages, blog comment renderers, etc.).

##### Details

The dangerous chain lives in `lib/previous-map.js` and is wired into
every `Input` construction at `lib/input.js:70-77`.

`Input` constructor (`lib/input.js:70-77`):

```js
if (pathAvailable && sourceMapAvailable) {
  let map = new PreviousMap(this.css, opts)
  if (map.text) {
    this.map = map
    let file = map.consumer().file
    if (!this.file && file) this.file = this.mapResolve(file)
  }
}
```

`PreviousMap` constructor (`lib/previous-map.js:17-29`):

```js
constructor(css, opts) {
  if (opts.map === false) return
  this.loadAnnotation(css)
  this.inline = this.startWith(this.annotation, 'data:')

  let prev = opts.map ? opts.map.prev : undefined
  let text = this.loadMap(opts.from, prev)
  ...
}
```

Note `opts.map === false` is the only short-circuit. With default
options (`opts.map === undefined`), the rest of the constructor —
including the filesystem read — executes.

`loadAnnotation` (`lib/previous-map.js:72-84`) extracts the URL
**without sanitisation**:

```js
loadAnnotation(css) {
  let comments = css.match(/\/\*\s*# sourceMappingURL=/g)
  if (!comments) return
  let start = css.lastIndexOf(comments.pop())
  let end = css.indexOf('*/', start)
  if (start > -1 && end > -1) {
    this.annotation = this.getAnnotationURL(css.substring(start, end))
  }
}
```

`getAnnotationURL` (`lib/previous-map.js:59-61`) only strips the `/*#
sourceMappingURL=` prefix and trims whitespace — no scheme check, no
path normalisation, no allowlist.

`loadMap` (`lib/previous-map.js:124-128`) — when `prev` is absent and
the annotation is not an inline `data:` URI:

```js
} else if (this.annotation) {
  let map = this.annotation
  if (file) map = join(dirname(file), map)
  return this.loadFile(map)
}
```

* If `opts.from` is unset, `file` is undefined and the raw
attacker-supplied path (e.g. `/etc/passwd`) is used directly.
* If `opts.from` is set, `path.join(dirname(file), attackerPath)` is
used. `path.join` does **not** block `..` segments, so
`../../../../../etc/passwd` resolves outside the intended directory.

`loadFile` (`lib/previous-map.js:86-92`) is the sink:

```js
loadFile(path) {
  this.root = dirname(path)
  if (existsSync(path)) {
    this.mapFile = path
    return readFileSync(path, 'utf-8').toString().trim()
  }
}
```

The bytes are stored in `this.text`. `Input` immediately invokes
`map.consumer()` (`lib/input.js:74`), which constructs a
`SourceMapConsumer` (`lib/previous-map.js:33`). When the file is not
valid source-map JSON (the common case), `source-map-js` calls
`JSON.parse`, and V8's `SyntaxError` message embeds the first ~10 bytes
of the file content:

```
Unexpected token 'r', "root:x:0:0"... is not valid JSON
```

This error is propagated back to the caller. Any application that
surfaces PostCSS errors (logs, HTTP 500 responses, build-tool output,
debug pages) discloses those bytes to the attacker.

Trust-boundary analysis:
* Attacker controls: CSS input passed to `postcss().process(css,
opts?)`.
* Server resources: any file readable by the Node process — typically
including app config, environment files, SSH keys, `/etc/passwd`,
`/proc/self/environ`, etc.
* No mitigations: there is no path validation, scheme allowlist,
traversal check, or symlink check. The only relevant check
(`startWith(annotation, 'data:')`) routes inline URIs to `decodeInline`;
everything else hits `loadFile`.

Primitives obtained:
* (a) **Arbitrary file read** — bytes loaded into Node memory.
* (b) **Information disclosure** — first ~10 bytes leaked via
`JSON.parse` `SyntaxError` message.
* (c) **File-existence oracle** — non-existent paths return silently
from `loadFile` (`existsSync` is false → returns undefined → no map text
→ no consumer call → no error). Existent non-JSON paths throw. Existent
JSON paths succeed silently. Three distinguishable states.
* (d) **DoS primitive** — directing the read at `/dev/zero`, very large
files, or device files can stall or crash the process.

##### PoC

All commands executed against this repository's HEAD (postcss 8.5.10) on
Node v22.12.0.

**Vector 1 — Absolute path, default options (no `from`, no `map`):**

```bash
$ node -e 'const p=require("postcss"); \
  try { p().process("a{color:red}\n/*# sourceMappingURL=/etc/passwd */"); } \
  catch(e){console.log(e.message)}'
Unexpected token 'r', "root:x:0:0"... is not valid JSON
```

The first 10 bytes of `/etc/passwd` (`root:x:0:0`) are leaked.

**Vector 2 — Relative `..` traversal with `opts.from` set (simulates a
build pipeline that pins `from` to the source file):**

```bash
$ node -e 'const p=require("postcss"); \
  p().process("a{color:red}\n/*# sourceMappingURL=../../../../../etc/passwd */", \
              {from:"/var/www/html/styles/main.css", map:{inline:false}}) \
   .catch(e=>console.log(e.message))'
Unexpected token 'r', "root:x:0:0"... is not valid JSON
```

`path.join('/var/www/html/styles', '../../../../../etc/passwd')`
resolves to `/etc/passwd`.

**Vector 3 — File-existence oracle:**

```bash

##### Existing non-JSON file → throws (file confirmed to exist)
$ node -e 'require("postcss")().process("a{}\n/*# sourceMappingURL=/etc/passwd */")'
SyntaxError: Unexpected token 'r', "root:x:0:0"... is not valid JSON

##### Non-existent file → returns silently (file confirmed absent)
$ node -e 'r=require("postcss")().process("a{}\n/*# sourceMappingURL=/no/such/file */"); console.log("ok")'
ok
```

**Vector 4 — Custom file-content leak:**

```bash
$ printf 'API_KEY=sk-secret-12345\n' > /tmp/server-secret.env
$ node -e 'require("postcss")().process("a{}\n/*# sourceMappingURL=/tmp/server-secret.env */")' 2>&1 | head -1
SyntaxError: Unexpected token 'A', "API_KEY=sk"... is not valid JSON
```

The first 10 bytes of `/tmp/server-secret.env` (`API_KEY=sk`) are leaked
— sufficient to confirm a token's presence and, in many cases, recover
its prefix.

**Filesystem-call trace** (proves the read happens with no opts at all):

```js
const fs = require('fs');
const orig = fs.readFileSync;
fs.readFileSync = function(p){
  if (typeof p==='string' && p.startsWith('/etc')) console.log('[FILE READ]:', p);
  return orig.apply(this, arguments);
};
require('postcss')().process('a{}\n/*# sourceMappingURL=/etc/hostname */');
// → [FILE READ]: /etc/hostname
// → SyntaxError: Unexpected token 'D', "Debian-tri"... is not valid JSON
```

##### Impact

* **Arbitrary file read** of any file readable by the Node process from
any CSS-processing context that accepts attacker-influenced CSS. PostCSS
has hundreds of millions of weekly npm downloads and is the standard CSS
processor for build tools (webpack `postcss-loader`, vite, parcel,
Next.js, Gatsby, etc.) and for runtime CSS-handling libraries (CSS
Modules tools, CSS minifiers, theme processors). Any pipeline that runs
untrusted user CSS — CMS theme uploads, user-styled blog posts,
browser-extension/userstyle services, multi-tenant build farms,
third-party-package build pipelines — is exposed.
* **Confidentiality leak** of the first ~10 bytes of the targeted file
via `JSON.parse` `SyntaxError`. This is enough to recover SSH-key
headers, environment-variable prefixes (`API_KEY=sk…`), `/etc/passwd`
records, the start of `/proc/self/environ`, and other high-value
secrets, and to fingerprint the host (`Debian-tri…` from
`/etc/hostname`).
* **File-existence oracle** with three distinguishable response states
(silent success, `JSON.parse` error, no-such-file silence), enabling
reconnaissance of the host filesystem layout and confirmation of
installed software, user accounts, and configuration files.
* **DoS** by targeting `/dev/zero`, `/proc/kcore`, very large files, or
named pipes — `readFileSync` is a synchronous, unbounded read.
* **Default-on**: triggered with `postcss().process(css)` and no
options. The only configuration that disables the bug is the explicit,
undocumented-for-this-purpose `{ map: false }`.

##### Recommended Fix

The root cause is that `loadFile` accepts any path the attacker supplies
inside a CSS comment. The annotation is meant for tooling, not for
production CSS processing of untrusted input. Two layered fixes:

1. **Refuse traversal/absolute paths in `loadMap`** (defence-in-depth):

   ```js
   // lib/previous-map.js
   loadMap(file, prev) {
     if (prev === false) return false
     if (prev) { /* unchanged */ }
     else if (this.inline) {
       return this.decodeInline(this.annotation)
     } else if (this.annotation) {
       let annotation = this.annotation
// Reject schemes (other than data:, handled above) and absolute paths.
       if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(annotation)) return
       if (require('path').isAbsolute(annotation)) return
       if (!file) return  // No base path → cannot safely resolve.
const base = require('path').resolve(require('path').dirname(file))
       const resolved = require('path').resolve(base, annotation)
       // Refuse anything that escapes the base directory.
if (resolved !== base && !resolved.startsWith(base +
require('path').sep)) {
         return
       }
       return this.loadFile(resolved)
     }
   }
   ```

2. **Require explicit opt-in to follow on-disk source-map annotations**:
gate the `loadFile(map)` call in `loadMap` behind an option such as
`opts.map.annotation === true` or `opts.map.followAnnotation === true`.
Today, the only way to opt out is `{ map: false }`, which also disables
in-memory previous-map handling. Inverting the default — only follow
disk-resident annotations when explicitly asked — eliminates the entire
attack surface for callers that pass untrusted CSS, while preserving
build-tool use cases where the annotation is trusted.

A user-facing changelog entry should warn that
`postcss().process(untrustedCss)` previously read attacker-controlled
paths, and recommend auditing applications that surfaced PostCSS errors
to end users.

#### Severity
- CVSS Score: 7.5 / 10 (High)
- Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`

#### References
-
[https://github.com/postcss/postcss/security/advisories/GHSA-6g55-p6wh-862q](https://redirect.github.com/postcss/postcss/security/advisories/GHSA-6g55-p6wh-862q)
-
[aaec7b78b3)
-
[c64b7488d2)
-
[https://github.com/postcss/postcss/releases/tag/8.5.12](https://redirect.github.com/postcss/postcss/releases/tag/8.5.12)
-
[https://github.com/advisories/GHSA-6g55-p6wh-862q](https://redirect.github.com/advisories/GHSA-6g55-p6wh-862q)

This data is provided by the [GitHub Advisory
Database](https://redirect.github.com/advisories/GHSA-6g55-p6wh-862q)
([CC-BY
4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).
</details>

---

### PostCSS: Path Traversal in Previous Source Map Auto-Loading
(sourceMappingURL) leads to Arbitrary .map File Disclosure

[GHSA-r28c-9q8g-f849](https://redirect.github.com/advisories/GHSA-r28c-9q8g-f849)

<details>
<summary>More information</summary>

#### Details
##### Vulnerability Details

**File**: `lib/previous-map.js`
**Line**: 87-98 (`loadFile`), 129-144 (`loadMap`)

##### Root Cause
PostCSS auto-detects a `/*# sourceMappingURL=... */` comment inside the
CSS text it is asked to parse and, unless the caller explicitly passes
`map: false`, attempts to load that path from disk as a "previous source
map." This happens on every `postcss.parse()` / `postcss().process()`
call by default (opt-out, not opt-in).

`loadMap()` builds the candidate path via `join(dirname(opts.from),
annotation)`, where `annotation` is the raw, attacker-controlled string
from the CSS comment. `path.join()` normalizes but does not sandbox `..`
segments, so a `../../../` prefix walks the resolved path outside the
intended directory. If `opts.from` is not set at all, the annotation is
used completely unmodified — an absolute path in the CSS comment is read
verbatim.

8.5.12 already fixed a strictly worse variant of this (any file, any
extension, could be read) by requiring the resolved path to end in
`.map` (`loadFile()`). That fix did not address the traversal itself,
only the target extension. Since the `join(dirname(file), map)` logic
has existed unchanged since PostCSS 8.0.0 (Feb 2020), any file ending in
`.map` remains readable through this path in the current release
(8.5.16).

Once loaded, `MapGenerator.isMap()` treats the mere presence of a loaded
"previous map" as an implicit request to generate `result.map`, even
when the caller never set the `map` option. If the loaded map has a
`sourcesContent` field (common for maps emitted by
bundlers/transpilers), that content is merged into `result.map` and
returned to the caller — disclosing the traversed-to file's content to
whoever supplied the CSS.

##### Attack Scenario
1. A service accepts user-submitted CSS and runs it through PostCSS to
lint/format/transform it, e.g. `postcss().process(userCss, { from:
'/app/uploads/user123/input.css', to: '/app/uploads/user123/output.css'
})` — idiomatic usage; `map` option untouched.
2. Attacker submits CSS containing `/*#
sourceMappingURL=../../../../some/other/app/dist/bundle.js.map */` (or
an absolute path if `from` is unset).
3. PostCSS reads that `.map` file and folds its `sourcesContent` into
`result.map`.
4. The service does what most build pipelines do with a truthy
`result.map` — writes it next to the CSS output or returns it via API
(source maps are meant to be consumed by browser devtools, so this is
commonly public/served).
5. Attacker retrieves the emitted map and reads out the traversed file's
content.

##### Impact
Disclosure of the contents of arbitrary `.map` files reachable via path
traversal (or absolute path when `from` is unset) from the process's
filesystem. Affects any application processing CSS it does not fully
trust without explicitly passing `map: false`. No authentication or user
interaction beyond submitting CSS text is required.

##### Vulnerable Code
```js
loadFile(path, cssFile, trusted) {
  if (!trusted && !this.unsafeMap) {
    if (!/\.map$/i.test(path)) {
      return undefined
    }
  }
  this.root = dirname(path)
  if (existsSync(path)) {
    this.mapFile = path
    return readFileSync(path, 'utf-8').toString().trim()
  }
}

loadMap(file, prev) {
  ...
  } else if (this.annotation) {
    let map = this.annotation
    if (file) map = join(dirname(file), map)
    let unknown = this.loadFile(map, file, false)
    ...
  }
}
```

##### Recommended Fix
Constrain the resolved path to remain inside the CSS file's own
directory instead of relying solely on a filename-extension check:
```js
loadFile(path, cssFile, trusted) {
  if (!trusted && !this.unsafeMap) {
    if (!/\.map$/i.test(path)) {
      return undefined
    }
    if (!cssFile) return undefined
    let root = resolve(dirname(cssFile))
    let resolvedPath = resolve(root, path)
    if (resolvedPath !== root && !resolvedPath.startsWith(root + sep)) {
      return undefined
    }
  }
  this.root = dirname(path)
  if (existsSync(path)) {
    this.mapFile = path
    return readFileSync(path, 'utf-8').toString().trim()
  }
}
```
I've implemented, tested (full existing test suite — 660/660 passing,
plus new PoC-based regression checks for both the traversal and
legitimate same-directory cases), and can share this fix on request or
via a private fork if invited.

##### Verification
Dynamically confirmed on v8.5.16 (current npm release / repo HEAD) via a
standalone Node.js harness against `lib/postcss.js`: a "secret" `.map`
file placed two directories outside a simulated project directory was
read via a crafted `sourceMappingURL` comment in otherwise-innocuous
CSS, with its `sourcesContent` appearing verbatim in
`result.map.toString()` — with no `map` option set by the caller. A
second harness confirmed the simpler no-`from` case reads an absolute
path directly. A third harness confirmed `map: false` is the only
current workaround. The attached fix branch closes both vectors while
keeping all 660 existing unit tests green.

#### Severity
- CVSS Score: 7.5 / 10 (High)
- Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`

#### References
-
[https://github.com/postcss/postcss/security/advisories/GHSA-r28c-9q8g-f849](https://redirect.github.com/postcss/postcss/security/advisories/GHSA-r28c-9q8g-f849)
-
[95663d3eb7)
-
[https://github.com/postcss/postcss/releases/tag/8.5.18](https://redirect.github.com/postcss/postcss/releases/tag/8.5.18)
-
[https://github.com/advisories/GHSA-r28c-9q8g-f849](https://redirect.github.com/advisories/GHSA-r28c-9q8g-f849)

This data is provided by the [GitHub Advisory
Database](https://redirect.github.com/advisories/GHSA-r28c-9q8g-f849)
([CC-BY
4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).
</details>

---

### Release Notes

<details>
<summary>postcss/postcss (postcss)</summary>

###
[`v8.5.18`](https://redirect.github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8518)

[Compare
Source](https://redirect.github.com/postcss/postcss/compare/8.5.17...8.5.18)

- Restricted loading previous source maps file to the `opts.from` folder
for security reasons (use `unsafeMap: true` to disable the check).

###
[`v8.5.17`](https://redirect.github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8517)

[Compare
Source](https://redirect.github.com/postcss/postcss/compare/8.5.16...8.5.17)

- Fixed `Maximum call stack size exceeded` error.
- Fixed Prototype hijacking for `postcss.fromJSON()`.
- Fixed `Input#origin()` for unmapped end position (by
[@&#8203;chatman-media](https://redirect.github.com/chatman-media)).

###
[`v8.5.16`](https://redirect.github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8516)

[Compare
Source](https://redirect.github.com/postcss/postcss/compare/8.5.15...8.5.16)

- Fixed `Input#origin()` position (by
[@&#8203;mizdra](https://redirect.github.com/mizdra)).
- Fixed `raws` after rehydrating a JSON AST (by
[@&#8203;sarathfrancis90](https://redirect.github.com/sarathfrancis90)).
- Fixed putting parent-less node in `nodes` of new node (by
[@&#8203;MahinAnowar](https://redirect.github.com/MahinAnowar)).
- Fixed computing `offset` in `positionBy()` (by
[@&#8203;greymoth-jp](https://redirect.github.com/greymoth-jp)).
- Fixed `rangeBy()` on `index: 0` (by
[@&#8203;sarathfrancis90](https://redirect.github.com/sarathfrancis90)).

###
[`v8.5.15`](https://redirect.github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8515)

[Compare
Source](https://redirect.github.com/postcss/postcss/compare/8.5.14...8.5.15)

- Fixed declaration parsing performance (by
[@&#8203;homanp](https://redirect.github.com/homanp)).

###
[`v8.5.14`](https://redirect.github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8514)

[Compare
Source](https://redirect.github.com/postcss/postcss/compare/8.5.13...8.5.14)

- Fixed custom syntax regression (by
[@&#8203;43081j](https://redirect.github.com/43081j)).

###
[`v8.5.13`](https://redirect.github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8513)

[Compare
Source](https://redirect.github.com/postcss/postcss/compare/8.5.12...8.5.13)

- Fixed `postcss-scss` commend regression.

###
[`v8.5.12`](https://redirect.github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8512)

[Compare
Source](https://redirect.github.com/postcss/postcss/compare/8.5.11...8.5.12)

- Fixed reading any file via user-generated CSS.
- Added `opts.unsafeMap` to disable checks.

###
[`v8.5.11`](https://redirect.github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8511)

[Compare
Source](https://redirect.github.com/postcss/postcss/compare/8.5.10...8.5.11)

- Fixed nested brackets parsing performance (by
[@&#8203;offset](https://redirect.github.com/offset)).

</details>

---

### Configuration

📅 **Schedule**: (UTC)

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

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

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

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/thelounge/thelounge).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbIlR5cGU6IFNlY3VyaXR5Il19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-01 07:33:42 -07:00

144 lines
4.1 KiB
JSON

{
"name": "thelounge",
"description": "The self-hosted Web IRC client",
"version": "4.6.0-pre.1",
"type": "commonjs",
"preferGlobal": true,
"bin": {
"thelounge": "index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/thelounge/thelounge.git"
},
"homepage": "https://thelounge.chat/",
"scripts": {
"build:client": "vite build",
"build:server": "tsc -p server/tsconfig.json",
"build": "run-p --aggregate-output build:client build:server",
"coverage": "vitest run --coverage",
"dev": "cross-env NODE_ENV=development ts-node --project server/tsconfig.json server/index.ts start --dev",
"format:prettier": "prettier --write \"**/*.*\"",
"generate:config:doc": "ts-node scripts/generate-config-doc.js",
"lint:check-eslint": "eslint-config-prettier .eslintrc.cjs",
"lint:eslint": "eslint . --report-unused-disable-directives --color",
"lint:prettier": "prettier --list-different \"**/*.*\"",
"lint:stylelint": "stylelint --color \"client/**/*.css\"",
"lint": "run-p --aggregate-output --continue-on-error lint:*",
"start": "node index start",
"test": "run-p --aggregate-output --continue-on-error lint:* test:vitest",
"test:vitest": "vitest run",
"watch": "vite build --watch",
"githooks-install": "git config core.hooksPath scripts/git-hooks"
},
"keywords": [
"lounge",
"browser",
"web",
"chat",
"client",
"irc",
"server",
"thelounge"
],
"license": "MIT",
"engines": {
"node": ">=22.0.0"
},
"files": [
"./.thelounge_home",
"./index.js",
"./yarn.lock",
"./dist/package.json",
"./dist/**/*.js",
"./public/**"
],
"dependencies": {
"@fastify/busboy": "1.0.0",
"bcryptjs": "2.4.3",
"chalk": "4.1.2",
"cheerio": "1.0.0",
"commander": "9.0.0",
"content-disposition": "0.5.4",
"express": "4.20.0",
"file-type": "16.5.4",
"filenamify": "4.3.0",
"got": "11.8.6",
"irc-framework": "github:kiwiirc/irc-framework#69d47d1",
"ldapjs": "2.3.3",
"linkify-it": "5.0.2",
"lodash": "4.17.21",
"mime-types": "2.1.35",
"node-forge": "1.3.1",
"package-json": "7.0.0",
"read": "1.0.7",
"semver": "7.5.2",
"socket.io": "4.6.2",
"tlds": "1.228.0",
"ua-parser-js": "1.0.39",
"web-push-neo": "0.1.2",
"yarn": "1.22.22"
},
"devDependencies": {
"@fortawesome/fontawesome-free": "5.15.4",
"@textcomplete/core": "0.1.10",
"@textcomplete/textarea": "0.1.10",
"@types/bcryptjs": "2.4.6",
"@types/cheerio": "0.22.35",
"@types/content-disposition": "0.5.8",
"@types/express": "4.17.21",
"@types/ldapjs": "2.2.5",
"@types/linkify-it": "3.0.5",
"@types/lodash": "4.14.202",
"@types/mime-types": "2.1.4",
"@types/mousetrap": "1.6.15",
"@types/node": "24.13.3",
"@types/read": "0.0.32",
"@types/semver": "7.3.9",
"@types/sortablejs": "1.15.8",
"@types/ua-parser-js": "0.7.39",
"@types/ws": "8.5.12",
"@typescript-eslint/eslint-plugin": "7.8.0",
"@typescript-eslint/parser": "7.8.0",
"@vitejs/plugin-vue": "6.0.5",
"@vitest/coverage-istanbul": "4.1.4",
"@vue/runtime-dom": "3.2.33",
"@vue/test-utils": "2.4.6",
"cross-env": "7.0.3",
"cssnano": "5.0.17",
"dayjs": "1.10.8",
"emoji-regex": "10.2.1",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-define-config": "2.1.0",
"eslint-plugin-vue": "9.25.0",
"fuzzy": "0.1.3",
"jsdom": "29.0.2",
"mousetrap": "1.6.5",
"normalize.css": "8.0.1",
"npm-run-all2": "5.0.0",
"postcss": "8.5.18",
"postcss-import": "14.0.2",
"postcss-preset-env": "7.3.0",
"prettier": "2.5.1",
"pretty-quick": "3.1.3",
"primer-tooltips": "2.0.0",
"sinon": "13.0.2",
"socket.io-client": "4.5.0",
"sortablejs": "1.15.2",
"stylelint": "14.3.0",
"stylelint-config-standard": "24.0.0",
"ts-node": "10.9.2",
"ts-sinon": "2.0.2",
"tsx": "4.21.0",
"typescript": "6.0.2",
"undate": "0.3.0",
"vite": "8.0.16",
"vitest": "4.1.4",
"vue": "3.2.35",
"vue-eslint-parser": "9.4.3",
"vue-router": "4.0.15",
"vuex": "4.0.2"
}
}