Compare commits

...
104 Commits
Author SHA1 Message Date
Justin Lin 0467bf8d3f chore(deps): bump the npm_and_yarn group across 2 directories with 2 updates (#223)
Bumps the npm_and_yarn group with 1 update in the /app directory:
[vue-i18n](https://github.com/intlify/vue-i18n/tree/HEAD/packages/vue-i18n).
Bumps the npm_and_yarn group with 1 update in the /packages/constants
directory: [zod](https://github.com/colinhacks/zod).

Updates `vue-i18n` from 11.3.0 to 11.4.14
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/intlify/vue-i18n/releases">vue-i18n's
releases</a>.</em></p>
<blockquote>
<h2>v11.4.14</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>🔒 Security Fixes</h3>
<ul>
<li>fix(shared): neutralize srcdoc attribute in sanitizeTranslatedHtml
by <a href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2679">intlify/vue-i18n#2679</a></li>
<li>fix(core-base): escape both list and named values with
escapeParameter by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2680">intlify/vue-i18n#2680</a></li>
<li>fix: ignore locales named after Object.prototype properties by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2681">intlify/vue-i18n#2681</a></li>
</ul>
<h3>👕 Refactoring</h3>
<ul>
<li>refactor(core-base): extract the resolved message format check by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2674">intlify/vue-i18n#2674</a></li>
<li>refactor(vue-i18n-core): remove dead branches in getCoreContext() by
<a href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2675">intlify/vue-i18n#2675</a></li>
<li>refactor(vue-i18n-core): share the fallbackContext handling in the
composer by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2676">intlify/vue-i18n#2676</a></li>
<li>refactor(vue-i18n-core): simplify flat JSON handling in
setLocaleMessage / mergeLocaleMessage by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2677">intlify/vue-i18n#2677</a></li>
<li>refactor(core-base): give the compile cache a proper type by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2678">intlify/vue-i18n#2678</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/intlify/vue-i18n/compare/v11.4.13...v11.4.14">https://github.com/intlify/vue-i18n/compare/v11.4.13...v11.4.14</a></p>
<h2>v11.4.13</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>⚡ Improvement Features</h3>
<ul>
<li>fix(core-base): map locale unions without the UnionToTuple
round-trip by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2651">intlify/vue-i18n#2651</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/intlify/vue-i18n/compare/v11.4.12...v11.4.13">https://github.com/intlify/vue-i18n/compare/v11.4.12...v11.4.13</a></p>
<h2>v11.4.12</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>fix(core-base): cache locale chains by fallback identity by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2635">intlify/vue-i18n#2635</a></li>
<li>fix(vue-i18n-core): sync the core context when inheritLocale is
enabled by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2636">intlify/vue-i18n#2636</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/intlify/vue-i18n/compare/v11.4.10...v11.4.12">https://github.com/intlify/vue-i18n/compare/v11.4.10...v11.4.12</a></p>
<h2>v11.4.10</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>fix(core-base): avoid throwing on AST keys in devtools groupId by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2603">intlify/vue-i18n#2603</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/intlify/vue-i18n/compare/v11.4.9...v11.4.10">https://github.com/intlify/vue-i18n/compare/v11.4.9...v11.4.10</a></p>
<h2>v11.4.9</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/intlify/vue-i18n/blob/v11.4.14/CHANGELOG.md">vue-i18n's
changelog</a>.</em></p>
<blockquote>
<h1>v11.4.14 (2026-10-10T11:06:13.502Z)</h1>
<p>This changelog is generated by <a
href="https://github.com/intlify/vue-i18n/releases/tag/v11.4.14">GitHub
Releases</a></p>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>🔒 Security Fixes</h3>
<ul>
<li>fix(shared): neutralize srcdoc attribute in sanitizeTranslatedHtml
by <a href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2679">intlify/vue-i18n#2679</a></li>
<li>fix(core-base): escape both list and named values with
escapeParameter by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2680">intlify/vue-i18n#2680</a></li>
<li>fix: ignore locales named after Object.prototype properties by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2681">intlify/vue-i18n#2681</a></li>
</ul>
<h3>👕 Refactoring</h3>
<ul>
<li>refactor(core-base): extract the resolved message format check by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2674">intlify/vue-i18n#2674</a></li>
<li>refactor(vue-i18n-core): remove dead branches in getCoreContext() by
<a href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2675">intlify/vue-i18n#2675</a></li>
<li>refactor(vue-i18n-core): share the fallbackContext handling in the
composer by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2676">intlify/vue-i18n#2676</a></li>
<li>refactor(vue-i18n-core): simplify flat JSON handling in
setLocaleMessage / mergeLocaleMessage by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2677">intlify/vue-i18n#2677</a></li>
<li>refactor(core-base): give the compile cache a proper type by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2678">intlify/vue-i18n#2678</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/intlify/vue-i18n/compare/v11.4.13...v11.4.14">https://github.com/intlify/vue-i18n/compare/v11.4.13...v11.4.14</a></p>
<h1>v11.4.13 (2026-10-02T11:01:59.781Z)</h1>
<p>This changelog is generated by <a
href="https://github.com/intlify/vue-i18n/releases/tag/v11.4.13">GitHub
Releases</a></p>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>⚡ Improvement Features</h3>
<ul>
<li>fix(core-base): map locale unions without the UnionToTuple
round-trip by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2651">intlify/vue-i18n#2651</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/intlify/vue-i18n/compare/v11.4.12...v11.4.13">https://github.com/intlify/vue-i18n/compare/v11.4.12...v11.4.13</a></p>
<h1>v11.4.12 (2026-09-16T14:30:30.396Z)</h1>
<p>This changelog is generated by <a
href="https://github.com/intlify/vue-i18n/releases/tag/v11.4.12">GitHub
Releases</a></p>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>fix(core-base): cache locale chains by fallback identity by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2635">intlify/vue-i18n#2635</a></li>
<li>fix(vue-i18n-core): sync the core context when inheritLocale is
enabled by <a
href="https://github.com/kazupon"><code>@​kazupon</code></a> in <a
href="https://redirect.github.com/intlify/vue-i18n/pull/2636">intlify/vue-i18n#2636</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/intlify/vue-i18n/commit/6bb9ebdeae4955cafb53e82bc461199f6186f573"><code>6bb9ebd</code></a>
release: v11.4.14</li>
<li><a
href="https://github.com/intlify/vue-i18n/commit/f6b3e75a16f43f4d9a7a567b1b36cd638e880831"><code>f6b3e75</code></a>
release: v11.4.13</li>
<li><a
href="https://github.com/intlify/vue-i18n/commit/87f3745072ca15cbd2d1eb8d030aed10639b0e3e"><code>87f3745</code></a>
release: v11.4.12</li>
<li><a
href="https://github.com/intlify/vue-i18n/commit/87510e2f9344e0734bfe9fbc7e0a2c509042e159"><code>87510e2</code></a>
release: v11.4.10</li>
<li><a
href="https://github.com/intlify/vue-i18n/commit/5128bf00a1e23fb1defb01ea80622dd6fedd1e21"><code>5128bf0</code></a>
release: v11.4.9</li>
<li><a
href="https://github.com/intlify/vue-i18n/commit/de2393bae16676a8a7c293bb493415e3085a521a"><code>de2393b</code></a>
release: v11.4.8</li>
<li><a
href="https://github.com/intlify/vue-i18n/commit/ceb0548cb421b8aaf237fecda0394d8fd3d75da7"><code>ceb0548</code></a>
release: v11.4.7</li>
<li><a
href="https://github.com/intlify/vue-i18n/commit/913bbfee3d0fe1b0ff321f9670ee7de5c0a5ae51"><code>913bbfe</code></a>
release: v11.4.6</li>
<li><a
href="https://github.com/intlify/vue-i18n/commit/6b97bfd57387b440d31e76af665cea4a5cdbd8d3"><code>6b97bfd</code></a>
release: v11.4.5</li>
<li><a
href="https://github.com/intlify/vue-i18n/commit/99fd4bcaf9e38b39857653eecf53b5038a6e8a49"><code>99fd4bc</code></a>
release: v11.4.4</li>
<li>Additional commits viewable in <a
href="https://github.com/intlify/vue-i18n/commits/v11.4.14/packages/vue-i18n">compare
view</a></li>
</ul>
</details>
<br />

Updates `zod` from 3.25.76 to 4.6.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/colinhacks/zod/releases">zod's
releases</a>.</em></p>
<blockquote>
<h2>v4.6.7</h2>
<h2>Commits:</h2>
<ul>
<li>b500a2ee95134f81d74da7911d7378dd2853d042 4.6.7</li>
</ul>
<h2>v4.6.6</h2>
<blockquote>
<p>Six malicious commits pushed to <code>main</code> on September 21
with a compromised git credential were reverted the same day in <a
href="https://redirect.github.com/colinhacks/zod/issues/6620">#6620</a>
and have since been removed from the history of <code>main</code>. None
were ever published to npm. The npm provenance for 4.6.6 names 284243fb,
the pre-rewrite copy of 9c219833 with identical contents.</p>
</blockquote>
<h2>Commits:</h2>
<ul>
<li>0cd3af5e9f50ad11bbcd4407a46a21b8848ba574 docs: load the en locale
directly in Zod Mini</li>
<li>9d5e60f162997b764b40d45aa02481888db50dea docs: import locales from
zod/locales, not z.locales</li>
<li>34a626f307871ecbb0123947559328dc52ed5e3e docs: tighten the z.locales
tree-shaking note</li>
<li>74304ce5b5796b5edb9a88ceb8e170b6ea3e82df release: stage npm versions
instead of publishing them (<a
href="https://redirect.github.com/colinhacks/zod/issues/6622">#6622</a>)</li>
<li>b2ef983e0711ff6517d6020b021071e2e5653efa docs: add Code for Japan to
bronze sponsors</li>
<li>8fb2faf0584828a6a027d8279db36f6f52784462 docs: crop the Code for
Japan logo and list it first in bronze</li>
<li>bacad518c41610d654658172d325874bf0ee6290 docs: square the Code for
Japan logo to match the other bronze tiles</li>
<li>c42596bd1c87e941d7241d10e012c5c196adcc10 release: hold the run on
the release-approval environment until the staged versions are approved
(<a
href="https://redirect.github.com/colinhacks/zod/issues/6638">#6638</a>)</li>
<li>a2ba4a67986a3e6b2b131be30084a2f460d9ea67 fix(types): declare record
output and input as members, not base type arguments (<a
href="https://redirect.github.com/colinhacks/zod/issues/6645">#6645</a>)</li>
<li>a0ebf970f2d752e5f58527cd2942ff48be4f46bd fix(v4): check array, set
and map size bounds before parsing elements (<a
href="https://redirect.github.com/colinhacks/zod/issues/6652">#6652</a>)</li>
<li>529f78dd9431b07f49647fee3aa0819b3f8b66b7 4.6.6</li>
<li>9c219833c3a3764fa1f1ea9c5ecec8254a63c0b1 ci: stage at verbose so a
failed OIDC token exchange says why</li>
</ul>
<h2>v4.6.5</h2>
<h2>Commits:</h2>
<ul>
<li>d2b135cfb7a3582b9eb515756b9166bcb9521f4a docs: add the 4.6.x patch
highlights to the 4.6 post</li>
<li>f1448f7cee00df9fe1e9ad84a000aa1828cc8bc1 docs: fold the 4.6.x patch
highlights into the 4.6 post's own sections</li>
<li>de65a5cb39ed22a507fac935788f718fa88d104f docs: lead the properties
section with the check and add a Zod Mini tab (<a
href="https://redirect.github.com/colinhacks/zod/issues/6598">#6598</a>)</li>
<li>56222cd1532c07bcb91b67df529cab4c0a215330 feat(instanceof): key the
.properties() shape off the instance type (<a
href="https://redirect.github.com/colinhacks/zod/issues/6600">#6600</a>)</li>
<li>ca0229a404818290e6cdcfefcd7eb2d04bcbb543 Revert &quot;feat: add
z.currencyCode() over a vendored ISO 4217 list, refreshed weekly by CI
(<a
href="https://redirect.github.com/colinhacks/zod/issues/6595">#6595</a>)&quot;</li>
<li>cc4cd4ee9c52fcaa10964e48cc144541e41a5ed9 Revert &quot;Revert
&quot;feat: add z.currencyCode() over a vendored ISO 4217 list,
refreshed weekly by CI (<a
href="https://redirect.github.com/colinhacks/zod/issues/6595">#6595</a>)&quot;&quot;</li>
<li>0f3f5ee3ca56c7574bf849e54f79e9a6e02562ee 4.6.5</li>
<li>59bbc03e10c636b9eb3c393dfeb552819774ec21 chore: re-pin the
integration peers to the workspace zod after the 4.6.5 bump</li>
</ul>
<h2>v4.6.4</h2>
<p>A patch on top of <a
href="https://github.com/colinhacks/zod/releases/tag/v4.6.3">4.6.3</a>.</p>
<ul>
<li><a
href="https://github.com/colinhacks/zod/commit/d6bc1e30"><code>d6bc1e30</code></a>
feat: add <code>z.currencyCode()</code> over a vendored ISO 4217 list,
refreshed weekly by CI (<a
href="https://redirect.github.com/colinhacks/zod/pull/6595">#6595</a>)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/ad32d751"><code>ad32d751</code></a>
perf: <code>z.url()</code> rejects an invalid URL with
<code>URL.canParse()</code> instead of a throwing constructor, about 50x
faster; fewer allocations on the validation path (<a
href="https://redirect.github.com/colinhacks/zod/pull/6588">#6588</a>)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/2bb08717"><code>2bb08717</code></a>
chore: re-pin the integration peers to the workspace zod after the 4.6.4
bump</li>
<li><a
href="https://github.com/colinhacks/zod/commit/f6e1701a"><code>f6e1701a</code></a>
chore(deps): bump next to 15.5.25 and vite to 7.3.6 (<a
href="https://redirect.github.com/colinhacks/zod/pull/6153">#6153</a>)</li>
</ul>
<h2>v4.6.3</h2>
<p>A patch on top of <a
href="https://github.com/colinhacks/zod/releases/tag/v4.6.2">4.6.2</a>.</p>
<ul>
<li><a
href="https://github.com/colinhacks/zod/commit/413cce9a"><code>413cce9a</code></a>
fix(v4): make z.properties() a check again (<a
href="https://redirect.github.com/colinhacks/zod/pull/6594">#6594</a>) —
removes the standalone <code>z.properties()</code> schema from 4.6.0;
<code>z.instanceof().properties()</code> and
<code>.check(...z.properties())</code> are unchanged</li>
<li><a
href="https://github.com/colinhacks/zod/commit/75d63ee1"><code>75d63ee1</code></a>
docs: show only the <code>.properties()</code> method form in the 4.6
post</li>
<li><a
href="https://github.com/colinhacks/zod/commit/46da9572"><code>46da9572</code></a>
docs: match the error-message examples to what the parsers emit</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/colinhacks/zod/commit/b500a2ee95134f81d74da7911d7378dd2853d042"><code>b500a2e</code></a>
4.6.7</li>
<li><a
href="https://github.com/colinhacks/zod/commit/9c219833c3a3764fa1f1ea9c5ecec8254a63c0b1"><code>9c21983</code></a>
ci: stage at verbose so a failed OIDC token exchange says why</li>
<li><a
href="https://github.com/colinhacks/zod/commit/529f78dd9431b07f49647fee3aa0819b3f8b66b7"><code>529f78d</code></a>
4.6.6</li>
<li><a
href="https://github.com/colinhacks/zod/commit/a0ebf970f2d752e5f58527cd2942ff48be4f46bd"><code>a0ebf97</code></a>
fix(v4): check array, set and map size bounds before parsing elements
(<a
href="https://redirect.github.com/colinhacks/zod/issues/6652">#6652</a>)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/a2ba4a67986a3e6b2b131be30084a2f460d9ea67"><code>a2ba4a6</code></a>
fix(types): declare record output and input as members, not base type
argumen...</li>
<li><a
href="https://github.com/colinhacks/zod/commit/c42596bd1c87e941d7241d10e012c5c196adcc10"><code>c42596b</code></a>
release: hold the run on the release-approval environment until the
staged ve...</li>
<li><a
href="https://github.com/colinhacks/zod/commit/bacad518c41610d654658172d325874bf0ee6290"><code>bacad51</code></a>
docs: square the Code for Japan logo to match the other bronze
tiles</li>
<li><a
href="https://github.com/colinhacks/zod/commit/8fb2faf0584828a6a027d8279db36f6f52784462"><code>8fb2faf</code></a>
docs: crop the Code for Japan logo and list it first in bronze</li>
<li><a
href="https://github.com/colinhacks/zod/commit/b2ef983e0711ff6517d6020b021071e2e5653efa"><code>b2ef983</code></a>
docs: add Code for Japan to bronze sponsors</li>
<li><a
href="https://github.com/colinhacks/zod/commit/74304ce5b5796b5edb9a88ceb8e170b6ea3e82df"><code>74304ce</code></a>
release: stage npm versions instead of publishing them (<a
href="https://redirect.github.com/colinhacks/zod/issues/6622">#6622</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/colinhacks/zod/compare/v3.25.76...v4.6.7">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for zod since your current version.</p>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/linux-odyssey/linux-odyssey/network/alerts).

</details>
2026-11-03 20:43:29 +11:00
Justin Lin 7caadd6695 deps: update zod and vue-i18n 2026-11-03 20:42:28 +11:00
dependabot[bot] 7ab6a828ca chore(deps): bump the npm_and_yarn group across 2 directories with 2 updates
Bumps the npm_and_yarn group with 1 update in the /app directory: [vue-i18n](https://github.com/intlify/vue-i18n/tree/HEAD/packages/vue-i18n).
Bumps the npm_and_yarn group with 1 update in the /packages/constants directory: [zod](https://github.com/colinhacks/zod).


Updates `vue-i18n` from 11.3.0 to 11.4.14
- [Release notes](https://github.com/intlify/vue-i18n/releases)
- [Changelog](https://github.com/intlify/vue-i18n/blob/v11.4.14/CHANGELOG.md)
- [Commits](https://github.com/intlify/vue-i18n/commits/v11.4.14/packages/vue-i18n)

Updates `zod` from 3.25.76 to 4.6.7
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v3.25.76...v4.6.7)

---
updated-dependencies:
- dependency-name: vue-i18n
  dependency-version: 11.4.14
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: zod
  dependency-version: 4.6.7
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-11-03 09:39:04 +00:00
Justin Lin acbe310a4c chore(deps): bump the npm_and_yarn group across 2 directories with 1 update (#221)
Bumps the npm_and_yarn group with 1 update in the /server directory:
[zod](https://github.com/colinhacks/zod).
Bumps the npm_and_yarn group with 1 update in the /services/analytics
directory: [zod](https://github.com/colinhacks/zod).

Updates `zod` from 3.25.76 to 4.6.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/colinhacks/zod/releases">zod's
releases</a>.</em></p>
<blockquote>
<h2>v4.6.7</h2>
<h2>Commits:</h2>
<ul>
<li>b500a2ee95134f81d74da7911d7378dd2853d042 4.6.7</li>
</ul>
<h2>v4.6.6</h2>
<blockquote>
<p>Six malicious commits pushed to <code>main</code> on September 21
with a compromised git credential were reverted the same day in <a
href="https://redirect.github.com/colinhacks/zod/issues/6620">#6620</a>
and have since been removed from the history of <code>main</code>. None
were ever published to npm. The npm provenance for 4.6.6 names 284243fb,
the pre-rewrite copy of 9c219833 with identical contents.</p>
</blockquote>
<h2>Commits:</h2>
<ul>
<li>0cd3af5e9f50ad11bbcd4407a46a21b8848ba574 docs: load the en locale
directly in Zod Mini</li>
<li>9d5e60f162997b764b40d45aa02481888db50dea docs: import locales from
zod/locales, not z.locales</li>
<li>34a626f307871ecbb0123947559328dc52ed5e3e docs: tighten the z.locales
tree-shaking note</li>
<li>74304ce5b5796b5edb9a88ceb8e170b6ea3e82df release: stage npm versions
instead of publishing them (<a
href="https://redirect.github.com/colinhacks/zod/issues/6622">#6622</a>)</li>
<li>b2ef983e0711ff6517d6020b021071e2e5653efa docs: add Code for Japan to
bronze sponsors</li>
<li>8fb2faf0584828a6a027d8279db36f6f52784462 docs: crop the Code for
Japan logo and list it first in bronze</li>
<li>bacad518c41610d654658172d325874bf0ee6290 docs: square the Code for
Japan logo to match the other bronze tiles</li>
<li>c42596bd1c87e941d7241d10e012c5c196adcc10 release: hold the run on
the release-approval environment until the staged versions are approved
(<a
href="https://redirect.github.com/colinhacks/zod/issues/6638">#6638</a>)</li>
<li>a2ba4a67986a3e6b2b131be30084a2f460d9ea67 fix(types): declare record
output and input as members, not base type arguments (<a
href="https://redirect.github.com/colinhacks/zod/issues/6645">#6645</a>)</li>
<li>a0ebf970f2d752e5f58527cd2942ff48be4f46bd fix(v4): check array, set
and map size bounds before parsing elements (<a
href="https://redirect.github.com/colinhacks/zod/issues/6652">#6652</a>)</li>
<li>529f78dd9431b07f49647fee3aa0819b3f8b66b7 4.6.6</li>
<li>9c219833c3a3764fa1f1ea9c5ecec8254a63c0b1 ci: stage at verbose so a
failed OIDC token exchange says why</li>
</ul>
<h2>v4.6.5</h2>
<h2>Commits:</h2>
<ul>
<li>d2b135cfb7a3582b9eb515756b9166bcb9521f4a docs: add the 4.6.x patch
highlights to the 4.6 post</li>
<li>f1448f7cee00df9fe1e9ad84a000aa1828cc8bc1 docs: fold the 4.6.x patch
highlights into the 4.6 post's own sections</li>
<li>de65a5cb39ed22a507fac935788f718fa88d104f docs: lead the properties
section with the check and add a Zod Mini tab (<a
href="https://redirect.github.com/colinhacks/zod/issues/6598">#6598</a>)</li>
<li>56222cd1532c07bcb91b67df529cab4c0a215330 feat(instanceof): key the
.properties() shape off the instance type (<a
href="https://redirect.github.com/colinhacks/zod/issues/6600">#6600</a>)</li>
<li>ca0229a404818290e6cdcfefcd7eb2d04bcbb543 Revert &quot;feat: add
z.currencyCode() over a vendored ISO 4217 list, refreshed weekly by CI
(<a
href="https://redirect.github.com/colinhacks/zod/issues/6595">#6595</a>)&quot;</li>
<li>cc4cd4ee9c52fcaa10964e48cc144541e41a5ed9 Revert &quot;Revert
&quot;feat: add z.currencyCode() over a vendored ISO 4217 list,
refreshed weekly by CI (<a
href="https://redirect.github.com/colinhacks/zod/issues/6595">#6595</a>)&quot;&quot;</li>
<li>0f3f5ee3ca56c7574bf849e54f79e9a6e02562ee 4.6.5</li>
<li>59bbc03e10c636b9eb3c393dfeb552819774ec21 chore: re-pin the
integration peers to the workspace zod after the 4.6.5 bump</li>
</ul>
<h2>v4.6.4</h2>
<p>A patch on top of <a
href="https://github.com/colinhacks/zod/releases/tag/v4.6.3">4.6.3</a>.</p>
<ul>
<li><a
href="https://github.com/colinhacks/zod/commit/d6bc1e30"><code>d6bc1e30</code></a>
feat: add <code>z.currencyCode()</code> over a vendored ISO 4217 list,
refreshed weekly by CI (<a
href="https://redirect.github.com/colinhacks/zod/pull/6595">#6595</a>)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/ad32d751"><code>ad32d751</code></a>
perf: <code>z.url()</code> rejects an invalid URL with
<code>URL.canParse()</code> instead of a throwing constructor, about 50x
faster; fewer allocations on the validation path (<a
href="https://redirect.github.com/colinhacks/zod/pull/6588">#6588</a>)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/2bb08717"><code>2bb08717</code></a>
chore: re-pin the integration peers to the workspace zod after the 4.6.4
bump</li>
<li><a
href="https://github.com/colinhacks/zod/commit/f6e1701a"><code>f6e1701a</code></a>
chore(deps): bump next to 15.5.25 and vite to 7.3.6 (<a
href="https://redirect.github.com/colinhacks/zod/pull/6153">#6153</a>)</li>
</ul>
<h2>v4.6.3</h2>
<p>A patch on top of <a
href="https://github.com/colinhacks/zod/releases/tag/v4.6.2">4.6.2</a>.</p>
<ul>
<li><a
href="https://github.com/colinhacks/zod/commit/413cce9a"><code>413cce9a</code></a>
fix(v4): make z.properties() a check again (<a
href="https://redirect.github.com/colinhacks/zod/pull/6594">#6594</a>) —
removes the standalone <code>z.properties()</code> schema from 4.6.0;
<code>z.instanceof().properties()</code> and
<code>.check(...z.properties())</code> are unchanged</li>
<li><a
href="https://github.com/colinhacks/zod/commit/75d63ee1"><code>75d63ee1</code></a>
docs: show only the <code>.properties()</code> method form in the 4.6
post</li>
<li><a
href="https://github.com/colinhacks/zod/commit/46da9572"><code>46da9572</code></a>
docs: match the error-message examples to what the parsers emit</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/colinhacks/zod/commit/b500a2ee95134f81d74da7911d7378dd2853d042"><code>b500a2e</code></a>
4.6.7</li>
<li><a
href="https://github.com/colinhacks/zod/commit/9c219833c3a3764fa1f1ea9c5ecec8254a63c0b1"><code>9c21983</code></a>
ci: stage at verbose so a failed OIDC token exchange says why</li>
<li><a
href="https://github.com/colinhacks/zod/commit/529f78dd9431b07f49647fee3aa0819b3f8b66b7"><code>529f78d</code></a>
4.6.6</li>
<li><a
href="https://github.com/colinhacks/zod/commit/a0ebf970f2d752e5f58527cd2942ff48be4f46bd"><code>a0ebf97</code></a>
fix(v4): check array, set and map size bounds before parsing elements
(<a
href="https://redirect.github.com/colinhacks/zod/issues/6652">#6652</a>)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/a2ba4a67986a3e6b2b131be30084a2f460d9ea67"><code>a2ba4a6</code></a>
fix(types): declare record output and input as members, not base type
argumen...</li>
<li><a
href="https://github.com/colinhacks/zod/commit/c42596bd1c87e941d7241d10e012c5c196adcc10"><code>c42596b</code></a>
release: hold the run on the release-approval environment until the
staged ve...</li>
<li><a
href="https://github.com/colinhacks/zod/commit/bacad518c41610d654658172d325874bf0ee6290"><code>bacad51</code></a>
docs: square the Code for Japan logo to match the other bronze
tiles</li>
<li><a
href="https://github.com/colinhacks/zod/commit/8fb2faf0584828a6a027d8279db36f6f52784462"><code>8fb2faf</code></a>
docs: crop the Code for Japan logo and list it first in bronze</li>
<li><a
href="https://github.com/colinhacks/zod/commit/b2ef983e0711ff6517d6020b021071e2e5653efa"><code>b2ef983</code></a>
docs: add Code for Japan to bronze sponsors</li>
<li><a
href="https://github.com/colinhacks/zod/commit/74304ce5b5796b5edb9a88ceb8e170b6ea3e82df"><code>74304ce</code></a>
release: stage npm versions instead of publishing them (<a
href="https://redirect.github.com/colinhacks/zod/issues/6622">#6622</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/colinhacks/zod/compare/v3.25.76...v4.6.7">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for zod since your current version.</p>
</details>
<br />

Updates `zod` from 3.25.76 to 4.6.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/colinhacks/zod/releases">zod's
releases</a>.</em></p>
<blockquote>
<h2>v4.6.7</h2>
<h2>Commits:</h2>
<ul>
<li>b500a2ee95134f81d74da7911d7378dd2853d042 4.6.7</li>
</ul>
<h2>v4.6.6</h2>
<blockquote>
<p>Six malicious commits pushed to <code>main</code> on September 21
with a compromised git credential were reverted the same day in <a
href="https://redirect.github.com/colinhacks/zod/issues/6620">#6620</a>
and have since been removed from the history of <code>main</code>. None
were ever published to npm. The npm provenance for 4.6.6 names 284243fb,
the pre-rewrite copy of 9c219833 with identical contents.</p>
</blockquote>
<h2>Commits:</h2>
<ul>
<li>0cd3af5e9f50ad11bbcd4407a46a21b8848ba574 docs: load the en locale
directly in Zod Mini</li>
<li>9d5e60f162997b764b40d45aa02481888db50dea docs: import locales from
zod/locales, not z.locales</li>
<li>34a626f307871ecbb0123947559328dc52ed5e3e docs: tighten the z.locales
tree-shaking note</li>
<li>74304ce5b5796b5edb9a88ceb8e170b6ea3e82df release: stage npm versions
instead of publishing them (<a
href="https://redirect.github.com/colinhacks/zod/issues/6622">#6622</a>)</li>
<li>b2ef983e0711ff6517d6020b021071e2e5653efa docs: add Code for Japan to
bronze sponsors</li>
<li>8fb2faf0584828a6a027d8279db36f6f52784462 docs: crop the Code for
Japan logo and list it first in bronze</li>
<li>bacad518c41610d654658172d325874bf0ee6290 docs: square the Code for
Japan logo to match the other bronze tiles</li>
<li>c42596bd1c87e941d7241d10e012c5c196adcc10 release: hold the run on
the release-approval environment until the staged versions are approved
(<a
href="https://redirect.github.com/colinhacks/zod/issues/6638">#6638</a>)</li>
<li>a2ba4a67986a3e6b2b131be30084a2f460d9ea67 fix(types): declare record
output and input as members, not base type arguments (<a
href="https://redirect.github.com/colinhacks/zod/issues/6645">#6645</a>)</li>
<li>a0ebf970f2d752e5f58527cd2942ff48be4f46bd fix(v4): check array, set
and map size bounds before parsing elements (<a
href="https://redirect.github.com/colinhacks/zod/issues/6652">#6652</a>)</li>
<li>529f78dd9431b07f49647fee3aa0819b3f8b66b7 4.6.6</li>
<li>9c219833c3a3764fa1f1ea9c5ecec8254a63c0b1 ci: stage at verbose so a
failed OIDC token exchange says why</li>
</ul>
<h2>v4.6.5</h2>
<h2>Commits:</h2>
<ul>
<li>d2b135cfb7a3582b9eb515756b9166bcb9521f4a docs: add the 4.6.x patch
highlights to the 4.6 post</li>
<li>f1448f7cee00df9fe1e9ad84a000aa1828cc8bc1 docs: fold the 4.6.x patch
highlights into the 4.6 post's own sections</li>
<li>de65a5cb39ed22a507fac935788f718fa88d104f docs: lead the properties
section with the check and add a Zod Mini tab (<a
href="https://redirect.github.com/colinhacks/zod/issues/6598">#6598</a>)</li>
<li>56222cd1532c07bcb91b67df529cab4c0a215330 feat(instanceof): key the
.properties() shape off the instance type (<a
href="https://redirect.github.com/colinhacks/zod/issues/6600">#6600</a>)</li>
<li>ca0229a404818290e6cdcfefcd7eb2d04bcbb543 Revert &quot;feat: add
z.currencyCode() over a vendored ISO 4217 list, refreshed weekly by CI
(<a
href="https://redirect.github.com/colinhacks/zod/issues/6595">#6595</a>)&quot;</li>
<li>cc4cd4ee9c52fcaa10964e48cc144541e41a5ed9 Revert &quot;Revert
&quot;feat: add z.currencyCode() over a vendored ISO 4217 list,
refreshed weekly by CI (<a
href="https://redirect.github.com/colinhacks/zod/issues/6595">#6595</a>)&quot;&quot;</li>
<li>0f3f5ee3ca56c7574bf849e54f79e9a6e02562ee 4.6.5</li>
<li>59bbc03e10c636b9eb3c393dfeb552819774ec21 chore: re-pin the
integration peers to the workspace zod after the 4.6.5 bump</li>
</ul>
<h2>v4.6.4</h2>
<p>A patch on top of <a
href="https://github.com/colinhacks/zod/releases/tag/v4.6.3">4.6.3</a>.</p>
<ul>
<li><a
href="https://github.com/colinhacks/zod/commit/d6bc1e30"><code>d6bc1e30</code></a>
feat: add <code>z.currencyCode()</code> over a vendored ISO 4217 list,
refreshed weekly by CI (<a
href="https://redirect.github.com/colinhacks/zod/pull/6595">#6595</a>)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/ad32d751"><code>ad32d751</code></a>
perf: <code>z.url()</code> rejects an invalid URL with
<code>URL.canParse()</code> instead of a throwing constructor, about 50x
faster; fewer allocations on the validation path (<a
href="https://redirect.github.com/colinhacks/zod/pull/6588">#6588</a>)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/2bb08717"><code>2bb08717</code></a>
chore: re-pin the integration peers to the workspace zod after the 4.6.4
bump</li>
<li><a
href="https://github.com/colinhacks/zod/commit/f6e1701a"><code>f6e1701a</code></a>
chore(deps): bump next to 15.5.25 and vite to 7.3.6 (<a
href="https://redirect.github.com/colinhacks/zod/pull/6153">#6153</a>)</li>
</ul>
<h2>v4.6.3</h2>
<p>A patch on top of <a
href="https://github.com/colinhacks/zod/releases/tag/v4.6.2">4.6.2</a>.</p>
<ul>
<li><a
href="https://github.com/colinhacks/zod/commit/413cce9a"><code>413cce9a</code></a>
fix(v4): make z.properties() a check again (<a
href="https://redirect.github.com/colinhacks/zod/pull/6594">#6594</a>) —
removes the standalone <code>z.properties()</code> schema from 4.6.0;
<code>z.instanceof().properties()</code> and
<code>.check(...z.properties())</code> are unchanged</li>
<li><a
href="https://github.com/colinhacks/zod/commit/75d63ee1"><code>75d63ee1</code></a>
docs: show only the <code>.properties()</code> method form in the 4.6
post</li>
<li><a
href="https://github.com/colinhacks/zod/commit/46da9572"><code>46da9572</code></a>
docs: match the error-message examples to what the parsers emit</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/colinhacks/zod/commit/b500a2ee95134f81d74da7911d7378dd2853d042"><code>b500a2e</code></a>
4.6.7</li>
<li><a
href="https://github.com/colinhacks/zod/commit/9c219833c3a3764fa1f1ea9c5ecec8254a63c0b1"><code>9c21983</code></a>
ci: stage at verbose so a failed OIDC token exchange says why</li>
<li><a
href="https://github.com/colinhacks/zod/commit/529f78dd9431b07f49647fee3aa0819b3f8b66b7"><code>529f78d</code></a>
4.6.6</li>
<li><a
href="https://github.com/colinhacks/zod/commit/a0ebf970f2d752e5f58527cd2942ff48be4f46bd"><code>a0ebf97</code></a>
fix(v4): check array, set and map size bounds before parsing elements
(<a
href="https://redirect.github.com/colinhacks/zod/issues/6652">#6652</a>)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/a2ba4a67986a3e6b2b131be30084a2f460d9ea67"><code>a2ba4a6</code></a>
fix(types): declare record output and input as members, not base type
argumen...</li>
<li><a
href="https://github.com/colinhacks/zod/commit/c42596bd1c87e941d7241d10e012c5c196adcc10"><code>c42596b</code></a>
release: hold the run on the release-approval environment until the
staged ve...</li>
<li><a
href="https://github.com/colinhacks/zod/commit/bacad518c41610d654658172d325874bf0ee6290"><code>bacad51</code></a>
docs: square the Code for Japan logo to match the other bronze
tiles</li>
<li><a
href="https://github.com/colinhacks/zod/commit/8fb2faf0584828a6a027d8279db36f6f52784462"><code>8fb2faf</code></a>
docs: crop the Code for Japan logo and list it first in bronze</li>
<li><a
href="https://github.com/colinhacks/zod/commit/b2ef983e0711ff6517d6020b021071e2e5653efa"><code>b2ef983</code></a>
docs: add Code for Japan to bronze sponsors</li>
<li><a
href="https://github.com/colinhacks/zod/commit/74304ce5b5796b5edb9a88ceb8e170b6ea3e82df"><code>74304ce</code></a>
release: stage npm versions instead of publishing them (<a
href="https://redirect.github.com/colinhacks/zod/issues/6622">#6622</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/colinhacks/zod/compare/v3.25.76...v4.6.7">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for zod since your current version.</p>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/linux-odyssey/linux-odyssey/network/alerts).

</details>
2026-11-03 20:37:50 +11:00
Justin Lin 045941a05c deps: upgrade zod 2026-11-03 20:36:34 +11:00
Justin Lin 676c12de77 Fix: add rate limit to session and disable guest account (#222)
- Disable guest accounts in frontend and backend
- Apply in memory rate limit to new session creation (3 times per
minute)
- Add restart: always to traefik in docker compose production file
2026-11-03 20:33:22 +11:00
Justin Lin b510d18758 feat: add rate limit to session creation 2026-11-03 20:28:04 +11:00
Justin Lin 9ffcd9fa90 fix: disable guest login 2026-11-03 20:18:15 +11:00
Justin Lin 3106ae00d0 feat: set traefik always restart 2026-11-03 20:10:04 +11:00
dependabot[bot] 9ce161e4f3 chore(deps): bump the npm_and_yarn group across 2 directories with 1 update
Bumps the npm_and_yarn group with 1 update in the /server directory: [zod](https://github.com/colinhacks/zod).
Bumps the npm_and_yarn group with 1 update in the /services/analytics directory: [zod](https://github.com/colinhacks/zod).


Updates `zod` from 3.25.76 to 4.6.7
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v3.25.76...v4.6.7)

Updates `zod` from 3.25.76 to 4.6.7
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v3.25.76...v4.6.7)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 4.6.7
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: zod
  dependency-version: 4.6.7
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-31 22:06:42 +00:00
Justin Lin e449f9987b Bun migration (#218) 2026-10-11 17:57:47 +11:00
Justin Lin 419440a14f doc: remove NodeJS installation setup in Windows setup 2026-10-11 17:51:56 +11:00
Justin Lin 54225528b3 refactor: replace Jest with bun 2026-10-11 17:43:22 +11:00
Justin Lin 634dc8f987 refactor: use bun in Dockerfile and CI workflow 2026-10-11 17:24:12 +11:00
Justin Lin 77577d9b8d refactor: use bun to execute server and analytics 2026-10-11 17:04:46 +11:00
Justin Lin 2feedc329c refactor: use bun for package management
+ add package.json to each packages
+ update import path
2026-10-11 16:50:01 +11:00
Justin Lin fb7dc0eb73 Fix/execute permission (#217)
* fix: add execute permission to dog script in execute/en

* fix: add execute permission for lucky
2026-10-10 14:31:48 +11:00
Justin Lin f515228db6 deps: patch node-tar and form-data (#216) 2026-10-10 14:31:25 +11:00
Justin Lin 5e5cb38c70 deps: patch node-tar and form-data 2026-10-10 14:26:20 +11:00
Justin Lin 4de8bbfee0 fix: add missing translation (#215) 2026-10-10 09:52:28 +11:00
neilchen0812 5897e562d1 fix: add missing translation 2026-10-10 01:45:35 +10:30
Justin Lin 733e02ddd8 Issue#206 Fix missing translations and header on the ChooseUsername and CompleteModal page (#214) 2026-10-10 01:07:16 +11:00
neilchen0812 85dda9486e feat: add translation for ChooseUsernamePage 2026-10-10 00:30:02 +10:30
neilchen0812 54f73504ec fix: add header for ChooseUsernamePage 2026-10-10 00:29:25 +10:30
neilchen0812 b47e52406f feat: add translation for CompleteModal component 2026-10-10 00:28:26 +10:30
Justin Lin 1f8d4162f8 Fix saving session finished time, display session locale (#213)
- Show session locale
- Remove command counts on session list for performance
2026-10-10 00:19:10 +11:00
Justin Lin 4c3b7434c9 chore: clean up logs 2026-10-10 00:15:26 +11:00
Justin Lin 218c4cce44 feat: show locale and user link on session detail 2026-10-10 00:15:02 +11:00
Justin Lin 3d6eaf6b64 fix: disable join commands on session list for performance 2026-10-10 00:12:30 +11:00
Justin Lin accfbc620c feat: add link to user from session list 2026-10-09 23:54:32 +11:00
Justin Lin 994618f71c feat: display session locale 2026-10-09 23:51:09 +11:00
Justin Lin b5024631f7 fix: store session finish time 2026-10-09 23:49:12 +11:00
Justin Lin c5b91cf201 Fix Quest Map text overflow and refactor buttons in HTML (#212)
Rewrite the buttons as HTML buttons. Only use SVG for drawing lines.
2026-10-09 23:28:10 +11:00
Justin Lin 8665add560 chore(deps): bump the npm_and_yarn group across 1 directory with 4 updates (#210)
Bumps the npm_and_yarn group with 4 updates in the / directory:
[handlebars](https://github.com/handlebars-lang/handlebars.js),
[proxy-addr](https://github.com/jshttp/proxy-addr),
[shell-quote](https://github.com/ljharb/shell-quote) and
[source-map-js](https://github.com/7rulnik/source-map-js).

Updates `handlebars` from 4.7.9 to 4.7.10
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/handlebars-lang/handlebars.js/releases">handlebars's
releases</a>.</em></p>
<blockquote>
<h2>v4.7.10</h2>
<ul>
<li>security: Sanitize the source map URL when minifying - f37c599</li>
<li>security: Iterate lazily in #each and strip whitespace in linear
time - 812c226</li>
<li>security: Escape <code>&lt;!--</code> and <code>&lt;script</code> in
precompiled output - 609d1b1 GHSA-xw65-4hp5-5hc7</li>
<li>security: Don't trust special properties on context data - ceec388
GHSA-p8wg-vrv2-v86f</li>
<li>security: Only compile partials that are template strings -
c28ee7a</li>
<li>security: Only dispatch known node types in the Compiler and Visitor
- 7d501a5</li>
<li>security: Validate AST values in the compiler instead of the parser
- 703fdcc GHSA-8r5x-fm3f-whwj</li>
<li>Clarify that --root does not restrict filesystem access -
0fcf25c</li>
<li>Bump minimist to ^1.2.8 - ea8ed82</li>
<li>Fix Ruby component publishing documentation - d069c1c</li>
<li>Fix Composer component definition - 6714e07</li>
</ul>
<p>Compatibility notes:</p>
<ul>
<li><code>{{#each}}</code> iterates iterables such as <code>Map</code>,
<code>Set</code> and generators lazily, like <code>for...of</code>,
instead of
copying them into an array first. Values added to the iterable while the
block renders are now visited too.</li>
</ul>
<p><a
href="https://github.com/handlebars-lang/handlebars.js/compare/v4.7.9...v4.7.10">Commits</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/handlebars-lang/handlebars.js/blob/v4.7.10/release-notes.md">handlebars's
changelog</a>.</em></p>
<blockquote>
<h2>v4.7.10 - October 5th, 2026</h2>
<ul>
<li>security: Sanitize the source map URL when minifying - f37c599</li>
<li>security: Iterate lazily in #each and strip whitespace in linear
time - 812c226</li>
<li>security: Escape <code>&lt;!--</code> and <code>&lt;script</code> in
precompiled output - 609d1b1 GHSA-xw65-4hp5-5hc7</li>
<li>security: Don't trust special properties on context data - ceec388
GHSA-p8wg-vrv2-v86f</li>
<li>security: Only compile partials that are template strings -
c28ee7a</li>
<li>security: Only dispatch known node types in the Compiler and Visitor
- 7d501a5</li>
<li>security: Validate AST values in the compiler instead of the parser
- 703fdcc GHSA-8r5x-fm3f-whwj</li>
<li>Clarify that --root does not restrict filesystem access -
0fcf25c</li>
<li>Bump minimist to ^1.2.8 - ea8ed82</li>
<li>Fix Ruby component publishing documentation - d069c1c</li>
<li>Fix Composer component definition - 6714e07</li>
</ul>
<p>Compatibility notes:</p>
<ul>
<li><code>{{#each}}</code> iterates iterables such as <code>Map</code>,
<code>Set</code> and generators lazily, like <code>for...of</code>,
instead of
copying them into an array first. Values added to the iterable while the
block renders are now visited too.</li>
</ul>
<p><a
href="https://github.com/handlebars-lang/handlebars.js/compare/v4.7.9...v4.7.10">Commits</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/45ce15255e0f430ac6d19742b18e316b7539264e"><code>45ce152</code></a>
v4.7.10</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/e47b2365d5656ab5689ae226aef90a485a90c5d8"><code>e47b236</code></a>
Update release notes</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/f37c599de9187715eb1e9afedcb2d80c175487a0"><code>f37c599</code></a>
Sanitize the source map URL when minifying</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/812c2260cb8794ef4ab63a7f1d946431112560ca"><code>812c226</code></a>
Iterate lazily in #each and strip whitespace in linear time</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/609d1b11c833c9a3e00f56f2f34d22f425446725"><code>609d1b1</code></a>
Escape <code>&lt;!--</code> and <code>&lt;script</code> in precompiled
output</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/ceec388abe1d1aac8f6369860d5f390fa71ef4fa"><code>ceec388</code></a>
Don't trust special properties on context data</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/c28ee7adb312308e0fe26f4d435a481be5e1ff98"><code>c28ee7a</code></a>
Only compile partials that are template strings</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/7d501a5af2ac3aa9ac788a8889dbe419849e46f1"><code>7d501a5</code></a>
Only dispatch known node types in the Compiler and Visitor</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/703fdcc5fd6cc8d1cc0c33cc19de40c467c4b8d2"><code>703fdcc</code></a>
Validate AST values in the compiler instead of the parser</li>
<li><a
href="https://github.com/handlebars-lang/handlebars.js/commit/0fcf25c63038b43e78e17adbf029cf073e80554d"><code>0fcf25c</code></a>
Clarify that --root does not restrict filesystem access</li>
<li>Additional commits viewable in <a
href="https://github.com/handlebars-lang/handlebars.js/compare/v4.7.9...v4.7.10">compare
view</a></li>
</ul>
</details>
<br />

Updates `proxy-addr` from 2.0.7 to 2.0.8
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jshttp/proxy-addr/releases">proxy-addr's
releases</a>.</em></p>
<blockquote>
<h2>2.0.8</h2>
<h2>Important</h2>
<ul>
<li>Fix <a
href="https://www.cve.org/CVERecord?id=CVE-2026-90711">CVE-2026-90711</a>
(<a
href="https://github.com/jshttp/proxy-addr/security/advisories/GHSA-jqcg-44mw-7w3h">GHSA-jqcg-44mw-7w3h</a>)</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Add OSSF scorecard action by <a
href="https://github.com/carpasse"><code>@​carpasse</code></a> in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/27">jshttp/proxy-addr#27</a></li>
<li>Fix ci pipeline and add missing Node.JS versions by <a
href="https://github.com/carpasse"><code>@​carpasse</code></a> in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/26">jshttp/proxy-addr#26</a></li>
<li>[StepSecurity] Apply security best practices by <a
href="https://github.com/step-security-bot"><code>@​step-security-bot</code></a>
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/29">jshttp/proxy-addr#29</a></li>
<li>build(deps): bump coverallsapp/github-action from 1.2.5 to 2.3.6 by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/30">jshttp/proxy-addr#30</a></li>
<li>build(deps): bump github/codeql-action from 2.23.2 to 3.28.18 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/31">jshttp/proxy-addr#31</a></li>
<li>build(deps-dev): bump eslint-plugin-import from 2.23.4 to 2.31.0 by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/32">jshttp/proxy-addr#32</a></li>
<li>build(deps): bump ossf/scorecard-action from 2.0.6 to 2.4.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/33">jshttp/proxy-addr#33</a></li>
<li>build(deps): bump actions/upload-artifact from 3.1.3 to 4.6.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/35">jshttp/proxy-addr#35</a></li>
<li>build(deps-dev): bump deep-equal from 1.0.1 to 1.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/34">jshttp/proxy-addr#34</a></li>
<li>build(deps-dev): bump eslint-plugin-markdown from 2.2.0 to 2.2.1 by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/36">jshttp/proxy-addr#36</a></li>
<li>chore: add funding to package.json by <a
href="https://github.com/Phillip9587"><code>@​Phillip9587</code></a> in
<a
href="https://redirect.github.com/jshttp/proxy-addr/pull/40">jshttp/proxy-addr#40</a></li>
<li>build(deps): bump github/codeql-action from 3.28.18 to 3.29.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/41">jshttp/proxy-addr#41</a></li>
<li>build(deps): bump github/codeql-action from 3.29.7 to 3.29.11 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/43">jshttp/proxy-addr#43</a></li>
<li>build(deps): bump actions/checkout from 3.6.0 to 5.0.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/42">jshttp/proxy-addr#42</a></li>
<li>build(deps): bump actions/upload-artifact from 4.6.2 to 5.0.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/47">jshttp/proxy-addr#47</a></li>
<li>build(deps): bump github/codeql-action from 3.29.11 to 4.31.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/46">jshttp/proxy-addr#46</a></li>
<li>build(deps): bump coverallsapp/github-action from 2.3.6 to 2.3.7 by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/50">jshttp/proxy-addr#50</a></li>
<li>build(deps): bump github/codeql-action from 4.31.2 to 4.31.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/49">jshttp/proxy-addr#49</a></li>
<li>build(deps): bump actions/checkout from 5.0.0 to 6.0.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/48">jshttp/proxy-addr#48</a></li>
<li>build(deps): bump actions/checkout from 6.0.0 to 6.0.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/56">jshttp/proxy-addr#56</a></li>
<li>build(deps): bump github/codeql-action from 4.31.5 to 4.32.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/55">jshttp/proxy-addr#55</a></li>
<li>build(deps): bump github/codeql-action from 4.32.0 to 4.32.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/57">jshttp/proxy-addr#57</a></li>
<li>build(deps): bump actions/upload-artifact from 5.0.0 to 7.0.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/58">jshttp/proxy-addr#58</a></li>
<li>Fix &quot;arugment&quot; typo in README by <a
href="https://github.com/schiwekM"><code>@​schiwekM</code></a> in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/61">jshttp/proxy-addr#61</a></li>
<li>build(deps): bump github/codeql-action from 4.32.4 to 4.36.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/64">jshttp/proxy-addr#64</a></li>
<li>build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/63">jshttp/proxy-addr#63</a></li>
<li>build(deps): bump ossf/scorecard-action from 2.4.2 to 2.4.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/45">jshttp/proxy-addr#45</a></li>
<li>build(deps-dev): bump eslint-plugin-import from 2.31.0 to 2.32.0 by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/39">jshttp/proxy-addr#39</a></li>
<li>chore(ci): npm-publish via reusable workflows by <a
href="https://github.com/sheplu"><code>@​sheplu</code></a> in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/54">jshttp/proxy-addr#54</a></li>
<li>refresh CI by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/69">jshttp/proxy-addr#69</a></li>
<li>fix: typo by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/71">jshttp/proxy-addr#71</a></li>
<li>Release: 2.0.8 by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/70">jshttp/proxy-addr#70</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/carpasse"><code>@​carpasse</code></a>
made their first contribution in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/27">jshttp/proxy-addr#27</a></li>
<li><a
href="https://github.com/step-security-bot"><code>@​step-security-bot</code></a>
made their first contribution in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/29">jshttp/proxy-addr#29</a></li>
<li><a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
made their first contribution in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/30">jshttp/proxy-addr#30</a></li>
<li><a
href="https://github.com/Phillip9587"><code>@​Phillip9587</code></a>
made their first contribution in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/40">jshttp/proxy-addr#40</a></li>
<li><a href="https://github.com/schiwekM"><code>@​schiwekM</code></a>
made their first contribution in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/61">jshttp/proxy-addr#61</a></li>
<li><a href="https://github.com/sheplu"><code>@​sheplu</code></a> made
their first contribution in <a
href="https://redirect.github.com/jshttp/proxy-addr/pull/54">jshttp/proxy-addr#54</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jshttp/proxy-addr/compare/v2.0.7...v2.0.8">https://github.com/jshttp/proxy-addr/compare/v2.0.7...v2.0.8</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jshttp/proxy-addr/blob/master/HISTORY.md">proxy-addr's
changelog</a>.</em></p>
<blockquote>
<h1>2.0.8</h1>
<ul>
<li>Fix <a
href="https://www.cve.org/CVERecord?id=CVE-2026-90711">CVE-2026-90711</a>
(<a
href="https://github.com/jshttp/proxy-addr/security/advisories/GHSA-jqcg-44mw-7w3h">GHSA-jqcg-44mw-7w3h</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/jshttp/proxy-addr/commit/a11ad82545698af5c33e59f3ed0b52eab79bf610"><code>a11ad82</code></a>
2.0.8 (<a
href="https://redirect.github.com/jshttp/proxy-addr/issues/70">#70</a>)</li>
<li><a
href="https://github.com/jshttp/proxy-addr/commit/780911d84d18e2c5fa008ed0c0d387631ec11965"><code>780911d</code></a>
fix: reject IPv4 trust via mapped IPv6 subnets with a short prefix</li>
<li><a
href="https://github.com/jshttp/proxy-addr/commit/92e103e3f3ab0467c8846cacea71f27dfc81091d"><code>92e103e</code></a>
fix(ci): use publised as release trigger event (<a
href="https://redirect.github.com/jshttp/proxy-addr/issues/71">#71</a>)</li>
<li><a
href="https://github.com/jshttp/proxy-addr/commit/3e5ac75d275d82606d33d6ac47c0ff43c2eccee9"><code>3e5ac75</code></a>
ci: merge coverage via artifacts, disable fail-fast, add Node.js 23-26
(<a
href="https://redirect.github.com/jshttp/proxy-addr/issues/69">#69</a>)</li>
<li><a
href="https://github.com/jshttp/proxy-addr/commit/4b9db8190923840eb732b752a70f3e5ff713768c"><code>4b9db81</code></a>
chore(ci): npm-publish via workflows (<a
href="https://redirect.github.com/jshttp/proxy-addr/issues/54">#54</a>)</li>
<li><a
href="https://github.com/jshttp/proxy-addr/commit/655e8950435ac457c586e8287da4d5993b7d0db5"><code>655e895</code></a>
build(deps-dev): bump eslint-plugin-import from 2.31.0 to 2.32.0 (<a
href="https://redirect.github.com/jshttp/proxy-addr/issues/39">#39</a>)</li>
<li><a
href="https://github.com/jshttp/proxy-addr/commit/50ce4d09132a4c34f5485b52740ce879a9223b1f"><code>50ce4d0</code></a>
build(deps): bump ossf/scorecard-action from 2.4.2 to 2.4.3 (<a
href="https://redirect.github.com/jshttp/proxy-addr/issues/45">#45</a>)</li>
<li><a
href="https://github.com/jshttp/proxy-addr/commit/0fd347f5b342e7502da58a512dc998d4a59cea24"><code>0fd347f</code></a>
build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 (<a
href="https://redirect.github.com/jshttp/proxy-addr/issues/63">#63</a>)</li>
<li><a
href="https://github.com/jshttp/proxy-addr/commit/6a517fa25c741cc107a90019df458b34f580ce55"><code>6a517fa</code></a>
build(deps): bump github/codeql-action from 4.32.4 to 4.36.0 (<a
href="https://redirect.github.com/jshttp/proxy-addr/issues/64">#64</a>)</li>
<li><a
href="https://github.com/jshttp/proxy-addr/commit/0d45e2a88e82a2faf1148956b6457e3a6c99ebcd"><code>0d45e2a</code></a>
Fix &quot;arugment&quot; typo in README (<a
href="https://redirect.github.com/jshttp/proxy-addr/issues/61">#61</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/jshttp/proxy-addr/compare/v2.0.7...v2.0.8">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for proxy-addr since your current version.</p>
</details>
<br />

Updates `shell-quote` from 1.10.0 to 1.12.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md">shell-quote's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/ljharb/shell-quote/compare/v1.11.0...v1.12.0">v1.12.0</a>
- 2026-10-02</h2>
<h3>Fixed</h3>
<ul>
<li>[New] <code>parse</code>: support here-documents
(<code>&amp;lt;&amp;lt;</code>) <a
href="https://redirect.github.com/ljharb/shell-quote/issues/31"><code>[#31](https://github.com/ljharb/shell-quote/issues/31)</code></a></li>
</ul>
<h3>Commits</h3>
<ul>
<li>[New] <code>parse</code>: support tab-stripping here-documents
(<code>&amp;lt;&amp;lt;-</code>) <a
href="https://github.com/ljharb/shell-quote/commit/dbfac376d4065d37539d3abdb5e76847f93797d3"><code>dbfac37</code></a></li>
<li>[New] <code>parse</code>: support output process substitution
(<code>&amp;gt;(</code>) <a
href="https://github.com/ljharb/shell-quote/commit/20533154bb57809c80f55318b8493aef49505f4e"><code>2053315</code></a></li>
<li>[New] <code>parse</code>: support the <code>case</code> test-next
terminator (<code>;;&amp;</code>) <a
href="https://github.com/ljharb/shell-quote/commit/7d688b9bec1917a22cccd4d4c887128a9c66e8a0"><code>7d688b9</code></a></li>
<li>[New] <code>parse</code>: support the <code>case</code> fall-through
terminator (<code>;&amp;</code>) <a
href="https://github.com/ljharb/shell-quote/commit/f27010ed04bcd925795b350afb1c49e36bbd1ba3"><code>f27010e</code></a></li>
<li>[New] <code>parse</code>: support redirecting output despite
<code>noclobber</code> (<code>&amp;gt;|</code>) <a
href="https://github.com/ljharb/shell-quote/commit/b78d19c14da6356cc12c46b3478203247ab8a295"><code>b78d19c</code></a></li>
<li>[New] <code>parse</code>: support opening a file for reading and
writing (<code>&amp;lt;&amp;gt;</code>) <a
href="https://github.com/ljharb/shell-quote/commit/21cc333eb0ce5bf094f595b7fdc01b3447ffd4b0"><code>21cc333</code></a></li>
<li>[New] <code>parse</code>: support redirecting stdout and stderr
(<code>&amp;&amp;gt;</code>) <a
href="https://github.com/ljharb/shell-quote/commit/6ad6cd215f89adcc29dd601e085fa54083c2f911"><code>6ad6cd2</code></a></li>
<li>[New] <code>parse</code>: support appending stdout and stderr
(<code>&amp;&amp;gt;&amp;gt;</code>) <a
href="https://github.com/ljharb/shell-quote/commit/90cde9cfd8af30fcb65e9fd2cb2f9e181d3f103b"><code>90cde9c</code></a></li>
<li>[Dev Deps] update <code>@ljharb/eslint-config</code> <a
href="https://github.com/ljharb/shell-quote/commit/3a7b4ae3960c3ff4413932e276c5b0ecb3a2b456"><code>3a7b4ae</code></a></li>
</ul>
<h2><a
href="https://github.com/ljharb/shell-quote/compare/v1.10.0...v1.11.0">v1.11.0</a>
- 2026-09-29</h2>
<h3>Fixed</h3>
<ul>
<li>[Refactor] <code>quote</code>: drop a replace that can never match
in the single-quote branch <a
href="https://redirect.github.com/ljharb/shell-quote/issues/15"><code>[#15](https://github.com/ljharb/shell-quote/issues/15)</code></a></li>
<li>[New] <code>parse</code>: support bash ANSI-C quoting
(<code>$'...'</code>) <a
href="https://redirect.github.com/ljharb/shell-quote/issues/32"><code>[#32](https://github.com/ljharb/shell-quote/issues/32)</code></a></li>
</ul>
<h3>Commits</h3>
<ul>
<li>[Fix] <code>quote</code>: reject line terminators in tokens after a
<code>comment</code> <a
href="https://github.com/ljharb/shell-quote/commit/6002b2ed90c6b83095eb272b6b0adaf3a172b0bc"><code>6002b2e</code></a></li>
<li>[Fix] <code>parse</code>: preserve text after special shell
parameters <a
href="https://github.com/ljharb/shell-quote/commit/81b08a532e898a3627f9305fa13d643ffa82a9d3"><code>81b08a5</code></a></li>
<li>[Fix] <code>parse</code>: an escaped backslash does not escape the
character after it <a
href="https://github.com/ljharb/shell-quote/commit/d708019016ce26e1a8a05af4b296e35ef8095c9e"><code>d708019</code></a></li>
<li>[Fix] <code>quote</code>: preserve <code>!</code> in arguments that
also contain <code>'</code> <a
href="https://github.com/ljharb/shell-quote/commit/ad399279dbbbd086967d2040c1558b4888b074e6"><code>ad39927</code></a></li>
<li>[Fix] <code>parse</code>: treat <code>$_name</code> as a variable
name, not <code>$_</code> followed by text <a
href="https://github.com/ljharb/shell-quote/commit/28f88cd422ae4046aca9556c4b74ca90b0ea7f6b"><code>28f88cd</code></a></li>
<li>[Fix] <code>quote</code>: preserve empty glob patterns <a
href="https://github.com/ljharb/shell-quote/commit/35c9b97a744211091b772f145bef0b6a5562b68e"><code>35c9b97</code></a></li>
<li>[Fix] <code>quote</code>: escape <code>~</code> in glob patterns to
prevent shell tilde-expansion <a
href="https://github.com/ljharb/shell-quote/commit/239d49cae6d231436ea4e676850037018c790c49"><code>239d49c</code></a></li>
<li>[Dev Deps] update <code>@ljharb/eslint-config</code>,
<code>auto-changelog</code>, <code>eslint</code>, <code>evalmd</code> <a
href="https://github.com/ljharb/shell-quote/commit/b1e406ed4287a134cc649db47b9a59e21b304472"><code>b1e406e</code></a></li>
<li>[meta] npmignore some files <a
href="https://github.com/ljharb/shell-quote/commit/ebfc3080cf5f68db5edfddfba49dc8c4ccacd2d5"><code>ebfc308</code></a></li>
<li>[actions] add permissions <a
href="https://github.com/ljharb/shell-quote/commit/3429b0d349211786765e9e68478e029d96ad44e9"><code>3429b0d</code></a></li>
<li>[actions] set least-privilege <code>cache-mode</code> <a
href="https://github.com/ljharb/shell-quote/commit/36f23944db50dd3f0df4da9c7cba0bb63df05f64"><code>36f2394</code></a></li>
<li>[Dev Deps] update <code>eslint</code> <a
href="https://github.com/ljharb/shell-quote/commit/6de9a41ecfc4fe9f9546df08866c8ead039f8909"><code>6de9a41</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/ljharb/shell-quote/commit/6ecb8aa618ba6dc6c3b087fce6d7660320d2adeb"><code>6ecb8aa</code></a>
v1.12.0</li>
<li><a
href="https://github.com/ljharb/shell-quote/commit/3a7b4ae3960c3ff4413932e276c5b0ecb3a2b456"><code>3a7b4ae</code></a>
[Dev Deps] update <code>@ljharb/eslint-config</code></li>
<li><a
href="https://github.com/ljharb/shell-quote/commit/7d688b9bec1917a22cccd4d4c887128a9c66e8a0"><code>7d688b9</code></a>
[New] <code>parse</code>: support the <code>case</code> test-next
terminator (<code>;;&amp;</code>)</li>
<li><a
href="https://github.com/ljharb/shell-quote/commit/f27010ed04bcd925795b350afb1c49e36bbd1ba3"><code>f27010e</code></a>
[New] <code>parse</code>: support the <code>case</code> fall-through
terminator (<code>;&amp;</code>)</li>
<li><a
href="https://github.com/ljharb/shell-quote/commit/90cde9cfd8af30fcb65e9fd2cb2f9e181d3f103b"><code>90cde9c</code></a>
[New] <code>parse</code>: support appending stdout and stderr
(<code>&amp;&gt;&gt;</code>)</li>
<li><a
href="https://github.com/ljharb/shell-quote/commit/6ad6cd215f89adcc29dd601e085fa54083c2f911"><code>6ad6cd2</code></a>
[New] <code>parse</code>: support redirecting stdout and stderr
(<code>&amp;&gt;</code>)</li>
<li><a
href="https://github.com/ljharb/shell-quote/commit/20533154bb57809c80f55318b8493aef49505f4e"><code>2053315</code></a>
[New] <code>parse</code>: support output process substitution
(<code>&gt;(</code>)</li>
<li><a
href="https://github.com/ljharb/shell-quote/commit/b78d19c14da6356cc12c46b3478203247ab8a295"><code>b78d19c</code></a>
[New] <code>parse</code>: support redirecting output despite
<code>noclobber</code> (<code>&gt;|</code>)</li>
<li><a
href="https://github.com/ljharb/shell-quote/commit/21cc333eb0ce5bf094f595b7fdc01b3447ffd4b0"><code>21cc333</code></a>
[New] <code>parse</code>: support opening a file for reading and writing
(<code>\&lt;&gt;</code>)</li>
<li><a
href="https://github.com/ljharb/shell-quote/commit/dbfac376d4065d37539d3abdb5e76847f93797d3"><code>dbfac37</code></a>
[New] <code>parse</code>: support tab-stripping here-documents
(<code>&lt;&lt;-</code>)</li>
<li>Additional commits viewable in <a
href="https://github.com/ljharb/shell-quote/compare/v1.10.0...v1.12.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `source-map-js` from 1.2.1 to 1.2.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/7rulnik/source-map-js/releases">source-map-js's
releases</a>.</em></p>
<blockquote>
<h2>v1.2.2</h2>
<ul>
<li>
<p>Fix crash when executing in browser with CSP script-src that don't
permit unsafe-eval (<a
href="https://redirect.github.com/7rulnik/source-map-js/pull/29">#29</a>)
<a href="https://github.com/xfournet"><code>@​xfournet</code></a></p>
</li>
<li>
<p>Fix denial of service from malicious indexed source maps
(CVE-2026-93749) (<a
href="https://redirect.github.com/7rulnik/source-map-js/pull/79">#79</a>)</p>
<p>Reported by <a
href="https://github.com/waydeshi"><code>@​waydeshi</code></a> in <a
href="https://redirect.github.com/7rulnik/source-map-js/issues/76">#76</a>.
A fix was also proposed by <a
href="https://github.com/aniebiet"><code>@​aniebiet</code></a> in <a
href="https://redirect.github.com/7rulnik/source-map-js/pull/78">#78</a>.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/7rulnik/source-map-js/blob/main/CHANGELOG.md">source-map-js's
changelog</a>.</em></p>
<blockquote>
<h2>1.2.2</h2>
<ul>
<li>
<p>Fix crash when executing in browser with CSP script-src that don't
permit unsafe-eval (<a
href="https://redirect.github.com/7rulnik/source-map-js/pull/29">#29</a>)
<a href="https://github.com/xfournet"><code>@​xfournet</code></a></p>
</li>
<li>
<p>Fix denial of service from malicious indexed source maps
(CVE-2026-93749) (<a
href="https://redirect.github.com/7rulnik/source-map-js/pull/79">#79</a>)</p>
<p>Reported by <a
href="https://github.com/waydeshi"><code>@​waydeshi</code></a> in <a
href="https://redirect.github.com/7rulnik/source-map-js/issues/76">#76</a>.
A fix was also proposed by <a
href="https://github.com/aniebiet"><code>@​aniebiet</code></a> in <a
href="https://redirect.github.com/7rulnik/source-map-js/pull/78">#78</a>.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/7rulnik/source-map-js/commit/0a1d334fd1e55a47df97fcd60a7915d46df3b08a"><code>0a1d334</code></a>
1.2.2</li>
<li><a
href="https://github.com/7rulnik/source-map-js/commit/4c6fa26d77419bd8e48ec92844866cce7d9ae739"><code>4c6fa26</code></a>
Update changelog</li>
<li><a
href="https://github.com/7rulnik/source-map-js/commit/cf7658058ceeaa8619d5ae0ec90be6905209d016"><code>cf76580</code></a>
Fix denial of service from malicious indexed source maps
(CVE-2026-93749) (<a
href="https://redirect.github.com/7rulnik/source-map-js/issues/79">#79</a>)</li>
<li><a
href="https://github.com/7rulnik/source-map-js/commit/7899a86615c630f4fc220273ff9fe2e8e49a56df"><code>7899a86</code></a>
Fix crash when executing browser with CSP script-src that don't permit
unsafe...</li>
<li>See full diff in <a
href="https://github.com/7rulnik/source-map-js/compare/v1.2.1...v1.2.2">compare
view</a></li>
</ul>
</details>
<br />
2026-10-09 23:24:43 +11:00
Justin Lin 119f8c552a refactor: replace svg rect with html button
Only use svg to draw lines
2026-10-09 23:23:02 +11:00
Justin Lin 22c71d367c fix: quest map wrap text 2026-10-09 23:14:04 +11:00
dependabot[bot] c3893a9ca3 chore(deps): bump the npm_and_yarn group across 1 directory with 4 updates
Bumps the npm_and_yarn group with 4 updates in the / directory: [handlebars](https://github.com/handlebars-lang/handlebars.js), [proxy-addr](https://github.com/jshttp/proxy-addr), [shell-quote](https://github.com/ljharb/shell-quote) and [source-map-js](https://github.com/7rulnik/source-map-js).


Updates `handlebars` from 4.7.9 to 4.7.10
- [Release notes](https://github.com/handlebars-lang/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/v4.7.10/release-notes.md)
- [Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.9...v4.7.10)

Updates `proxy-addr` from 2.0.7 to 2.0.8
- [Release notes](https://github.com/jshttp/proxy-addr/releases)
- [Changelog](https://github.com/jshttp/proxy-addr/blob/master/HISTORY.md)
- [Commits](https://github.com/jshttp/proxy-addr/compare/v2.0.7...v2.0.8)

Updates `shell-quote` from 1.10.0 to 1.12.0
- [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/shell-quote/compare/v1.10.0...v1.12.0)

Updates `source-map-js` from 1.2.1 to 1.2.2
- [Release notes](https://github.com/7rulnik/source-map-js/releases)
- [Changelog](https://github.com/7rulnik/source-map-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/7rulnik/source-map-js/compare/v1.2.1...v1.2.2)

---
updated-dependencies:
- dependency-name: handlebars
  dependency-version: 4.7.10
  dependency-type: indirect
- dependency-name: proxy-addr
  dependency-version: 2.0.8
  dependency-type: indirect
- dependency-name: shell-quote
  dependency-version: 1.12.0
  dependency-type: indirect
- dependency-name: source-map-js
  dependency-version: 1.2.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-09 12:03:41 +00:00
Justin Lin 4260e742df Feature/multilingual quests (#209) 2026-10-09 22:58:05 +11:00
neilchen0812 a7039714aa refactor: read selected locale inside session store 2026-10-09 17:12:28 +10:30
Justin Lin 174bab7494 security: switch CodeQL to advanced set up (#211) 2026-10-09 17:34:20 +11:00
Justin Lin 9f0804a194 security: switch CodeQL to advanced set up 2026-10-09 17:32:37 +11:00
Justin Lin de0eb1b33b chore(deps): bump axios from 1.18.0 to 1.20.0 in the npm_and_yarn group across 1 directory (#208)
Bumps the npm_and_yarn group with 1 update in the / directory:
[axios](https://github.com/axios/axios).

Updates `axios` from 1.18.0 to 1.20.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/releases">axios's
releases</a>.</em></p>
<blockquote>
<h2>v1.20.0 — August 19, 2026</h2>
<p>This release hardens runtime option handling, adds RFC 9110
status-code aliases, fixes Node.js and XHR reliability issues, and
refreshes project tooling and documentation.</p>
<h2>⚠️ Breaking Changes &amp; Deprecations</h2>
<ul>
<li>HTTP Status Naming: Added ContentTooLarge (413) and
UnprocessableContent (422), while retaining PayloadTooLarge and
UnprocessableEntity as backward-compatible deprecated aliases. (<a
href="https://redirect.github.com/axios/axios/issues/11082">#11082</a>)</li>
</ul>
<h2>🔒 Security Fixes</h2>
<ul>
<li>Runtime Option Handling: Hardened behavioral configuration reads
against shared and foreign prototype pollution and normalized unsafe
interceptor replacement objects. This also clarifies Fetch redirect and
custom implementation behavior, HTTP/2 DNS and proxy handling,
CIDR-based NO_PROXY matching, and malformed data URI rejection; see the
PR for documented compatibility effects. (<a
href="https://redirect.github.com/axios/axios/issues/11141">#11141</a>)</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<ul>
<li>Interceptor Lifecycle: Prevented unbounded handler-array growth by
trimming trailing ejected interceptors without changing iteration
semantics, and kept interceptor operations safe when the public handlers
field is nullish. (<a
href="https://redirect.github.com/axios/axios/issues/11087">#11087</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11118">#11118</a>)</li>
<li>Request Error Preservation: Prevented custom Error.prepareStackTrace
implementations that return non-string values from replacing the
original request failure with an unrelated TypeError. (<a
href="https://redirect.github.com/axios/axios/issues/11109">#11109</a>)</li>
<li>XHR Reliability: Navigation-canceled requests now reject with
ECONNABORTED instead of resolving with status 0, while successful
downloads flush their final progress callback during the live loadend
dispatch. (<a
href="https://redirect.github.com/axios/axios/issues/11094">#11094</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11121">#11121</a>)</li>
<li>Node.js Socket Memory: Removed request-context retention from
per-socket error listeners, preventing completed response data from
being pinned for the lifetime of pooled keep-alive sockets. (<a
href="https://redirect.github.com/axios/axios/issues/11091">#11091</a>)</li>
<li>Core Methods and HTTP Errors: Prevented structural method-header
buckets from leaking into outgoing headers, standardized invalid DNS
lookup and httpVersion failures as AxiosError.ERR_BAD_OPTION_VALUE, and
corrected the timeoutErrorMessage merge strategy. (<a
href="https://redirect.github.com/axios/axios/issues/11096">#11096</a>)</li>
</ul>
<h2>🔧 Maintenance &amp; Chores</h2>
<ul>
<li>Dependencies: Updated fast-uri, postcss, js-yaml, mocha,
development-tooling groups, and GitHub Actions dependencies. (<a
href="https://redirect.github.com/axios/axios/issues/11092">#11092</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11098">#11098</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11099">#11099</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11106">#11106</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11107">#11107</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11122">#11122</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11123">#11123</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11126">#11126</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11127">#11127</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11133">#11133</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11140">#11140</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11143">#11143</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11144">#11144</a>)</li>
<li>Documentation: Applied the v1.19.0 documentation updates, added the
missing fs import to the README stream example, introduced localized
global search, and repaired the interceptor test link. (<a
href="https://redirect.github.com/axios/axios/issues/11101">#11101</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11113">#11113</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11097">#11097</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11119">#11119</a>)</li>
<li>Sponsorship: Updated sponsorship links and data and added
ScrapingBee as a sponsor. (<a
href="https://redirect.github.com/axios/axios/issues/11124">#11124</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11136">#11136</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11137">#11137</a>)</li>
<li>CI and Release: Switched ESM smoke tests to locked dependencies and
synchronized package and runtime version metadata for v1.20.0. (<a
href="https://redirect.github.com/axios/axios/issues/11128">#11128</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11152">#11152</a>)</li>
</ul>
<h2>🌟 New Contributors</h2>
<p>We are thrilled to welcome our new contributors. Thank you for
helping improve axios:</p>
<ul>
<li><a href="https://github.com/yens1"><code>@​yens1</code></a> (<a
href="https://redirect.github.com/axios/axios/issues/11109">#11109</a>)</li>
<li><a
href="https://github.com/Sasireddy001"><code>@​Sasireddy001</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11113">#11113</a>)</li>
<li><a
href="https://github.com/ari-token-security"><code>@​ari-token-security</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11094">#11094</a>)</li>
<li><a
href="https://github.com/timothyokooboh"><code>@​timothyokooboh</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11097">#11097</a>)</li>
<li><a
href="https://github.com/gi9439041-png"><code>@​gi9439041-png</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11119">#11119</a>)</li>
<li><a
href="https://github.com/Hashim1999164"><code>@​Hashim1999164</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11082">#11082</a>)</li>
<li><a href="https://github.com/v-dev-cl"><code>@​v-dev-cl</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11091">#11091</a>)</li>
<li><a href="https://github.com/r0h1tb"><code>@​r0h1tb</code></a> (<a
href="https://redirect.github.com/axios/axios/issues/11118">#11118</a>)</li>
<li><a href="https://github.com/ostapondo"><code>@​ostapondo</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11121">#11121</a>)</li>
</ul>
<p>Full Changelog (<a
href="https://github.com/axios/axios/compare/v1.19.0...v1.20.0">https://github.com/axios/axios/compare/v1.19.0...v1.20.0</a>)</p>
<h2>v1.19.0 - July 22, 2026</h2>
<p>This release raises the form-data security floor, adds configuration
and type-system capabilities, and fixes NO_PROXY matching, interceptor
errors, progress reporting, and serialization edge cases.</p>
<h2>🔒 Security Fixes</h2>
<ul>
<li>Multipart Form Data: Raised the form-data dependency floor to
^4.0.6, preventing fresh installations from resolving versions affected
by the CRLF injection vulnerability GHSA-hmw2-7cc7-3qxx (<a
href="https://github.com/advisories/GHSA-hmw2-7cc7-3qxx">https://github.com/advisories/GHSA-hmw2-7cc7-3qxx</a>).
(<a
href="https://redirect.github.com/axios/axios/issues/11028">#11028</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>v1.19.0 — July 22, 2026</h2>
<p>This release raises the form-data security floor, adds configuration
and type-system capabilities, and fixes NO_PROXY matching, interceptor
errors, progress reporting, and serialization edge cases.</p>
<h2>🔒 Security Fixes</h2>
<ul>
<li>Multipart Form Data: Raised the form-data dependency floor to
^4.0.6, preventing fresh installations from resolving versions affected
by the CRLF injection vulnerability GHSA-hmw2-7cc7-3qxx (<a
href="https://github.com/advisories/GHSA-hmw2-7cc7-3qxx">https://github.com/advisories/GHSA-hmw2-7cc7-3qxx</a>).
(<a
href="https://redirect.github.com/axios/axios/issues/11028">#11028</a>)</li>
</ul>
<h2>🚀 New Features</h2>
<ul>
<li>Configuration Extensibility: Preserved own-enumerable symbol-keyed
fields through mergeConfig and added a generic params type across public
TypeScript declarations, responses, errors,
adapters, and serializers. (<a
href="https://redirect.github.com/axios/axios/issues/11043">#11043</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11081">#11081</a>)</li>
<li>Header Parameter Parsing: Added the opt-in
AxiosHeaders.parseParameters() parser for quote-aware, RFC-style HTTP
parameter parsing while preserving legacy parsing behavior. (<a
href="https://redirect.github.com/axios/axios/issues/11051">#11051</a>)</li>
<li>HTTP Status Codes: Added the missing Cloudflare 520
WebServerReturnsAnUnknownError status and matching ESM/CJS declarations.
(<a
href="https://redirect.github.com/axios/axios/issues/11067">#11067</a>)</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<ul>
<li>
<p>Form Data Conversion: Limited formDataToJSON path splitting to dot
and bracket notation, preserving literal punctuation in keys, and
removed browser-facing Buffer.from usage from toFormData to avoid
unnecessary polyfills. (<a
href="https://redirect.github.com/axios/axios/issues/11006">#11006</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11018">#11018</a>)</p>
</li>
<li>
<p>Proxy Bypass: Canonicalized IPv4 shorthand, octal, and hexadecimal
forms during NO_PROXY matching and honored * entries within comma- or
space-separated bypass lists. (<a
href="https://redirect.github.com/axios/axios/issues/11029">#11029</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11053">#11053</a>)</p>
</li>
<li>
<p>Cancellation: Propagated already-aborted input signals immediately
when composing abort signals. (<a
href="https://redirect.github.com/axios/axios/issues/11035">#11035</a>)</p>
</li>
<li>
<p>Header Handling: Preserved empty first values for duplicate singleton
headers and made AxiosHeaders#getSetCookie() consistently return arrays
for present values. (<a
href="https://redirect.github.com/axios/axios/issues/11036">#11036</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11037">#11037</a>)</p>
</li>
<li>
<p>URL Handling: Included normalized, safely redacted offending URLs in
malformed-protocol errors and removed repeated trailing slashes when
combining base URLs. (<a
href="https://redirect.github.com/axios/axios/issues/11008">#11008</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11038">#11038</a>)</p>
</li>
<li>
<p>Progress Events: Clamped malformed negative progress values to zero
and ensured final Node.js download progress events are delivered before
streamed responses close. (<a
href="https://redirect.github.com/axios/axios/issues/11039">#11039</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11040">#11040</a>)</p>
</li>
<li>
<p>Error and JSON Serialization: Serialized Set values as arrays in
JSON-compatible snapshots and synthesized useful AxiosError messages
from otherwise-empty AggregateError instances. (<a
href="https://redirect.github.com/axios/axios/issues/11044">#11044</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11059">#11059</a>)</p>
</li>
<li>
<p>Content-Length Enforcement: Corrected base64 data: URL size
estimation so maxContentLength is enforced consistently by the HTTP and
Fetch adapters. (<a
href="https://redirect.github.com/axios/axios/issues/11061">#11061</a>)</p>
</li>
<li>
<p>Synchronous Interceptors: Prevented requests from being dispatched
after synchronous request interceptors fail unless their paired
rejection handler resolves successfully. (<a
href="https://redirect.github.com/axios/axios/issues/11071">#11071</a>)</p>
</li>
</ul>
<h2>🔧 Maintenance &amp; Chores</h2>
<ul>
<li>Dependencies: Updated development and test tooling, the docs
fixture's Axios version, and GitHub Actions integrations including
Checkout, Setup Node, Setup Deno, and Zizmor. (<a
href="https://redirect.github.com/axios/axios/issues/11031">#11031</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11055">#11055</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11056">#11056</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11058">#11058</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11079">#11079</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11080">#11080</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11088">#11088</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11089">#11089</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11090">#11090</a>)</li>
<li>Build Outputs: Limited sourcemap generation to published minified
bundles, removing broken map references from non-minified builds. (<a
href="https://redirect.github.com/axios/axios/issues/11054">#11054</a>)</li>
<li>Form Data Internals: Centralized FormData header handling and made
the Node.js adapter tolerate getHeaders() returning undefined under the
content-only policy. (<a
href="https://redirect.github.com/axios/axios/issues/11062">#11062</a>)</li>
<li>Developer Experience: Ignored common local AI-tooling directories
and fixed a constant-reassignment crash when the development sandbox
serves its root path. (<a
href="https://redirect.github.com/axios/axios/issues/11032">#11032</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11073">#11073</a>)</li>
<li>Documentation: Updated sponsor information, clarified that baseURL
is not a path-security boundary, scoped provenance claims to attested
releases, and corrected the configuration-defaults documentation. (<a
href="https://redirect.github.com/axios/axios/issues/11041">#11041</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11068">#11068</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11076">#11076</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11078">#11078</a>)</li>
<li>Publishing: Simplified v1 publishing to use the npm version bundled
with Node.js 26 and updated package metadata for the 1.19.0 release. (<a
href="https://redirect.github.com/axios/axios/issues/11083">#11083</a>,
<a
href="https://redirect.github.com/axios/axios/issues/11095">#11095</a>)</li>
</ul>
<h2>🌟 New Contributors</h2>
<p>We are thrilled to welcome our new contributors. Thank you for
helping improve Axios:</p>
<ul>
<li><a
href="https://github.com/afonsojramos"><code>@​afonsojramos</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11028">#11028</a>)</li>
<li><a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a> (<a
href="https://redirect.github.com/axios/axios/issues/11006">#11006</a>)</li>
<li><a
href="https://github.com/yassertawfik4"><code>@​yassertawfik4</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11024">#11024</a>)</li>
<li><a
href="https://github.com/AnandSundar"><code>@​AnandSundar</code></a> (<a
href="https://redirect.github.com/axios/axios/issues/11029">#11029</a>)</li>
<li><a
href="https://github.com/lin-hongkuan"><code>@​lin-hongkuan</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11035">#11035</a>)</li>
<li><a
href="https://github.com/Wali007-lab"><code>@​Wali007-lab</code></a> (<a
href="https://redirect.github.com/axios/axios/issues/11054">#11054</a>)</li>
<li><a href="https://github.com/magicdawn"><code>@​magicdawn</code></a>
(<a
href="https://redirect.github.com/axios/axios/issues/11043">#11043</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/axios/axios/commit/84a9f3b9a4f3244b8c8e818f557d64c7b964fb25"><code>84a9f3b</code></a>
chore(release): prepare release 1.20.0 (<a
href="https://redirect.github.com/axios/axios/issues/11152">#11152</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/e6824eec5fcf9da467a9792724396badc490c469"><code>e6824ee</code></a>
fix: core methodList, HTTP adapter errors, and add tests (<a
href="https://redirect.github.com/axios/axios/issues/11096">#11096</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/d8a919fd81403d59058c0e9dbefc540407dee83f"><code>d8a919f</code></a>
fix(xhr): flush final progress during the live loadend dispatch (<a
href="https://redirect.github.com/axios/axios/issues/11121">#11121</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/2d2a21af8a433089474a2149781799c93acbcf3c"><code>2d2a21a</code></a>
fix(interceptors): tolerate nullish handlers in syncHandlerEntries (<a
href="https://redirect.github.com/axios/axios/issues/11118">#11118</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/d19040bda7a8be2f82c3c6e1a5bc03917daee39a"><code>d19040b</code></a>
fix: harden runtime option handling (<a
href="https://redirect.github.com/axios/axios/issues/11141">#11141</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/e0a02dd16671deabe2b809334d4c2ebede29a233"><code>e0a02dd</code></a>
chore(deps): bump zizmorcore/zizmor-action from 0.6.1 to 0.6.2 in the
github-...</li>
<li><a
href="https://github.com/axios/axios/commit/d10cb3aa3cda1d78721ddf96be590478df26cd81"><code>d10cb3a</code></a>
chore(deps-dev): bump the development_dependencies group with 4 updates
(<a
href="https://redirect.github.com/axios/axios/issues/11143">#11143</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/2c94646eb7cb7ab9dcb2aefdb04ab1b040c28e16"><code>2c94646</code></a>
chore(deps): bump js-yaml and mocha in /tests/smoke/cjs (<a
href="https://redirect.github.com/axios/axios/issues/11133">#11133</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/76c12bce5a4fe9a45bef9a5bf2baaf599d7d382e"><code>76c12bc</code></a>
chore(deps-dev): bump js-yaml from 4.3.0 to 4.3.1 (<a
href="https://redirect.github.com/axios/axios/issues/11140">#11140</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/ba98559a7f5a18e531b5762387e5957bd281af3d"><code>ba98559</code></a>
docs: add ScrapingBee sponsor (<a
href="https://redirect.github.com/axios/axios/issues/11137">#11137</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/axios/axios/compare/v1.18.0...v1.20.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=axios&package-manager=npm_and_yarn&previous-version=1.18.0&new-version=1.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/linux-odyssey/linux-odyssey/network/alerts).

</details>
2026-10-09 16:50:22 +11:00
neilchen0812 5e8d3f275d fix: remove unnecessary operator and imports 2026-10-09 01:25:38 +10:30
Tai-Lin Chen 6a097c02ed Merge branch 'main' into feature/multilingual-quests 2026-10-08 10:11:13 +10:30
neilchen0812 9165a4ecf6 fix: add missing zod dependency to analytics 2026-10-08 10:05:25 +10:30
neilchen0812 4bb27a2cbd feat: add English translations for quests 2026-10-08 09:38:28 +10:30
neilchen0812 66b0b7ba68 feat: support changing quest language 2026-10-08 02:46:44 +10:30
dependabot[bot] 6e780811a2 chore(deps): bump axios
Bumps the npm_and_yarn group with 1 update in the / directory: [axios](https://github.com/axios/axios).


Updates `axios` from 1.18.0 to 1.20.0
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.18.0...v1.20.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.20.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-05 22:24:50 +00:00
Justin Lin 68d1beea69 Add CodeQL analysis workflow configuration (#207)
Add language Go and GitHub Actions
2026-10-06 09:24:20 +11:00
Justin Lin 08fc200e47 Add CodeQL analysis workflow configuration
Add language Go and GitHub Actions
2026-10-06 09:21:57 +11:00
Justin Lin eb9e68953b chore(deps): bump dompurify from 3.4.13 to 3.4.16 in the npm_and_yarn group across 1 directory (#205)
Bumps the npm_and_yarn group with 1 update in the / directory:
[dompurify](https://github.com/cure53/DOMPurify).

Updates `dompurify` from 3.4.13 to 3.4.16
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cure53/DOMPurify/releases">dompurify's
releases</a>.</em></p>
<blockquote>
<h2>DOMPurify 3.4.16</h2>
<ul>
<li>Fixed a problem with <code>IN_PLACE</code> node removal when working
with hooks, thanks <a
href="https://github.com/manus-pi"><code>@​manus-pi</code></a></li>
<li>Fixed a problem with <code>IN_PLACE</code> sanitization and raw-text
roots, thanks <a
href="https://github.com/h-t-m"><code>@​h-t-m</code></a></li>
<li>Fixed a problem with ESM default exports landing in CommonJS
declarations, thanks <a
href="https://github.com/ssi02014"><code>@​ssi02014</code></a></li>
<li>Migrated from <code>rollup</code> to <code>rolldown</code> because
performance, thanks <a
href="https://github.com/ssi02014"><code>@​ssi02014</code></a></li>
<li>Bumped several dependencies where possible</li>
</ul>
<h2>DOMPurify 3.4.15</h2>
<ul>
<li>Added better clobbering hardening when XML content is involved,
thanks <a
href="https://github.com/gnyselcuk"><code>@​gnyselcuk</code></a></li>
<li>Added several smaller hardening and edge-case improvements, thanks
<a
href="https://github.com/leechristensen"><code>@​leechristensen</code></a></li>
<li>Bumped several dependencies where possible</li>
</ul>
<h2>DOMPurify 3.4.14</h2>
<ul>
<li>Fixed an issue with possible bypasses when risky tags are
allow-listed, thanks <a
href="https://github.com/AlirezaRouhbakhsh"><code>@​AlirezaRouhbakhsh</code></a></li>
<li>Fixed a couple of edge cases with mixed document contexts, thanks <a
href="https://github.com/fishjojo1"><code>@​fishjojo1</code></a></li>
<li>Added the SVG <code>pointer-events</code> and
<code>vector-effect</code> presentation attributes to the allow-list,
thanks <a
href="https://github.com/Jaybhade"><code>@​Jaybhade</code></a></li>
<li>Conducted another refactoring run, removed dead branches and
duplicated logic, flattened attribute validation</li>
<li>Updated the documentation in several spots, README, wiki, etc.,
thanks <a
href="https://github.com/Akokonunes"><code>@​Akokonunes</code></a></li>
<li>Updated several development dependencies and CI workflow
actions</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/cure53/DOMPurify/commit/b9b9d80f7e401771c2ccaef5f45def7eec8f27d7"><code>b9b9d80</code></a>
release: 3.4.16 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1636">#1636</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/1d7460c4f8a27be825c11b1c9d346d79db32c1e5"><code>1d7460c</code></a>
release: 3.4.15 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1609">#1609</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/4e6fe24173f1a85eafacd95e3c82966e29d34d49"><code>4e6fe24</code></a>
release: 3.4.14 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1587">#1587</a>)</li>
<li>See full diff in <a
href="https://github.com/cure53/DOMPurify/compare/3.4.13...3.4.16">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dompurify&package-manager=npm_and_yarn&previous-version=3.4.13&new-version=3.4.16)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/linux-odyssey/linux-odyssey/network/alerts).

</details>
2026-10-06 09:20:21 +11:00
neilchen0812 9b8d7109cf refactor: move original quest content into each quest's zh-TW folder 2026-10-05 22:36:50 +10:30
dependabot[bot] fae9a012aa chore(deps): bump dompurify
Bumps the npm_and_yarn group with 1 update in the / directory: [dompurify](https://github.com/cure53/DOMPurify).


Updates `dompurify` from 3.4.13 to 3.4.16
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.13...3.4.16)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.16
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-05 05:32:02 +00:00
Justin Lin 2dc3546c98 chore(deps): bump the npm_and_yarn group across 1 directory with 7 updates (#204)
Bumps the npm_and_yarn group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [validator](https://github.com/validatorjs/validator.js) | `13.11.0` |
`13.15.22` |
| [@trpc/server](https://github.com/trpc/trpc/tree/HEAD/packages/server)
| `11.1.1` | `11.8.0` |
| [yaml](https://github.com/eemeli/yaml) | `2.3.4` | `2.8.3` |
| [bn.js](https://github.com/indutny/bn.js) | `4.12.0` | `4.12.5` |
| [flatted](https://github.com/WebReflection/flatted) | `3.3.1` |
`3.4.4` |
| [jws](https://github.com/brianloveswords/node-jws) | `3.2.2` | `3.2.3`
|
| [rollup](https://github.com/rollup/rollup) | `4.40.0` | `4.63.5` |


Updates `validator` from 13.11.0 to 13.15.22
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/validatorjs/validator.js/releases">validator's
releases</a>.</em></p>
<blockquote>
<h2>13.15.22</h2>
<h3>Fixes, New Locales and Enhancements</h3>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2622">#2622</a>
<code>isURL</code>: fix regression with hostnames with ports <a
href="https://github.com/mbtools"><code>@​mbtools</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2616">#2616</a>
<code>isLength</code>: improve handling Unicode variation selectors <a
href="https://github.com/koral"><code>@​koral</code></a>--</li>
<li><strong>Doc fixes and others:</strong>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2621">#2621</a>
<a href="https://github.com/mbtools"><code>@​mbtools</code></a></li>
</ul>
</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/mbtools"><code>@​mbtools</code></a> made
their first contribution in <a
href="https://redirect.github.com/validatorjs/validator.js/pull/2622">validatorjs/validator.js#2622</a></li>
<li><a href="https://github.com/koral"><code>@​koral</code></a>-- made
their first contribution in <a
href="https://redirect.github.com/validatorjs/validator.js/pull/2616">validatorjs/validator.js#2616</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/validatorjs/validator.js/compare/13.15.20...13.15.22">https://github.com/validatorjs/validator.js/compare/13.15.20...13.15.22</a></p>
<h2>13.15.20</h2>
<h3>Fixes, New Locales and Enhancements</h3>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2556">#2556</a>
<code>isMobilePhone</code>: add <code>ar-QA</code> locale <a
href="https://github.com/WardKhaddour"><code>@​WardKhaddour</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2576">#2576</a>
<code>isAlpha</code>/<code>isAlphanuneric</code>: add Indic locales
(<code>ta-IN</code>, <code>te-IN</code>, <code>kn-IN</code>,
<code>ml-IN</code>, <code>gu-IN</code>, <code>pa-IN</code>,
<code>or-IN</code>) <a
href="https://github.com/avadootharajesh"><code>@​avadootharajesh</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2574">#2574</a>
<code>isBase64</code>: improve padding regex <a
href="https://github.com/KrayzeeKev"><code>@​KrayzeeKev</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2584">#2584</a>
<code>isVAT</code>: improve <code>FR</code> locale <a
href="https://github.com/iamAmer"><code>@​iamAmer</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2608">#2608</a>
<code>isURL</code>: improve protocol detection. Resolves CVE-2025-56200
<a href="https://github.com/theofidry"><code>@​theofidry</code></a></li>
<li><strong>Doc fixes and others:</strong>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2563">#2563</a>
<a href="https://github.com/stoneLeaf"><code>@​stoneLeaf</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2581">#2581</a>
<a
href="https://github.com/camillobruni"><code>@​camillobruni</code></a></li>
</ul>
</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/stoneLeaf"><code>@​stoneLeaf</code></a>
made their first contribution in <a
href="https://redirect.github.com/validatorjs/validator.js/pull/2563">validatorjs/validator.js#2563</a></li>
<li><a
href="https://github.com/WardKhaddour"><code>@​WardKhaddour</code></a>
made their first contribution in <a
href="https://redirect.github.com/validatorjs/validator.js/pull/2556">validatorjs/validator.js#2556</a></li>
<li><a
href="https://github.com/avadootharajesh"><code>@​avadootharajesh</code></a>
made their first contribution in <a
href="https://redirect.github.com/validatorjs/validator.js/pull/2576">validatorjs/validator.js#2576</a></li>
<li><a
href="https://github.com/KrayzeeKev"><code>@​KrayzeeKev</code></a> made
their first contribution in <a
href="https://redirect.github.com/validatorjs/validator.js/pull/2574">validatorjs/validator.js#2574</a></li>
<li><a href="https://github.com/iamAmer"><code>@​iamAmer</code></a> made
their first contribution in <a
href="https://redirect.github.com/validatorjs/validator.js/pull/2584">validatorjs/validator.js#2584</a></li>
<li><a
href="https://github.com/camillobruni"><code>@​camillobruni</code></a>
made their first contribution in <a
href="https://redirect.github.com/validatorjs/validator.js/pull/2581">validatorjs/validator.js#2581</a></li>
<li><a href="https://github.com/theofidry"><code>@​theofidry</code></a>
made their first contribution in <a
href="https://redirect.github.com/validatorjs/validator.js/pull/2608">validatorjs/validator.js#2608</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/validatorjs/validator.js/compare/13.15.15...13.15.20">https://github.com/validatorjs/validator.js/compare/13.15.15...13.15.20</a></p>
<h2>13.15.15</h2>
<h3>Fixes, New Locales and Enhancements</h3>
<ul>
<li><code>isMobilePhone</code>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2514">#2514</a>
improve <code>el-CY</code> locale <a
href="https://github.com/rezk2ll"><code>@​rezk2ll</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2512">#2512</a>
improve <code>pt-AO</code> locale <a
href="https://github.com/renaldodev"><code>@​renaldodev</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2502">#2502</a>
improve <code>ar-OM</code> locale <a
href="https://github.com/tomcastro"><code>@​tomcastro</code></a></li>
</ul>
</li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2089">#2089</a>
<code>isIP</code>: allow usage of option object <a
href="https://github.com/pixelbucket-dev"><code>@​pixelbucket-dev</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2526">#2526</a>
<code>isPassportNumber</code>: improve <code>CA</code> locale <a
href="https://github.com/evanbechtol"><code>@​evanbechtol</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2491">#2491</a>
<code>isBase64</code>: improve validation based on RFC4648 <a
href="https://github.com/aseyfpour"><code>@​aseyfpour</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2479">#2479</a>
<code>isPostalCode</code>: improve <code>FR</code> locale <a
href="https://github.com/Rajput-Balram"><code>@​Rajput-Balram</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2088">#2088</a>
<code>isBefore</code>: allow usage of option object <a
href="https://github.com/pixelbucket-dev"><code>@​pixelbucket-dev</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2346">#2346</a>
<code>isRgbColor</code>: allow second digit in rgba alpha value <a
href="https://github.com/controlol"><code>@​controlol</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/validatorjs/validator.js/blob/master/CHANGELOG.md">validator's
changelog</a>.</em></p>
<blockquote>
<h1>13.15.22</h1>
<h3>Fixes, New Locales and Enhancements</h3>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2622">#2622</a>
<code>isURL</code>: fix regression with hostnames with ports <a
href="https://github.com/mbtools"><code>@​mbtools</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2616">#2616</a>
<code>isLength</code>: improve handling Unicode variation selectors <a
href="https://github.com/koral"><code>@​koral</code></a>--</li>
<li><strong>Doc fixes and others:</strong>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2621">#2621</a>
<a href="https://github.com/mbtools"><code>@​mbtools</code></a></li>
</ul>
</li>
</ul>
<h1>13.15.20</h1>
<h3>Fixes, New Locales and Enhancements</h3>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2556">#2556</a>
<code>isMobilePhone</code>: add <code>ar-QA</code> locale <a
href="https://github.com/WardKhaddour"><code>@​WardKhaddour</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2576">#2576</a>
<code>isAlpha</code>/<code>isAlphanuneric</code>: add Indic locales
(<code>ta-IN</code>, <code>te-IN</code>, <code>kn-IN</code>,
<code>ml-IN</code>, <code>gu-IN</code>, <code>pa-IN</code>,
<code>or-IN</code>) <a
href="https://github.com/avadootharajesh"><code>@​avadootharajesh</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2574">#2574</a>
<code>isBase64</code>: improve padding regex <a
href="https://github.com/KrayzeeKev"><code>@​KrayzeeKev</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2584">#2584</a>
<code>isVAT</code>: improve <code>FR</code> locale <a
href="https://github.com/iamAmer"><code>@​iamAmer</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2608">#2608</a>
<code>isURL</code>: improve protocol detection. Resolves CVE-2025-56200
<a href="https://github.com/theofidry"><code>@​theofidry</code></a></li>
<li><strong>Doc fixes and others:</strong>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2563">#2563</a>
<a href="https://github.com/stoneLeaf"><code>@​stoneLeaf</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2581">#2581</a>
<a
href="https://github.com/camillobruni"><code>@​camillobruni</code></a></li>
</ul>
</li>
</ul>
<h1>13.15.15</h1>
<h3>Fixes, New Locales and Enhancements</h3>
<ul>
<li><code>isMobilePhone</code>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2514">#2514</a>
improve <code>el-CY</code> locale <a
href="https://github.com/rezk2ll"><code>@​rezk2ll</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2512">#2512</a>
improve <code>pt-AO</code> locale <a
href="https://github.com/renaldodev"><code>@​renaldodev</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2502">#2502</a>
improve <code>ar-OM</code> locale <a
href="https://github.com/tomcastro"><code>@​tomcastro</code></a></li>
</ul>
</li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2089">#2089</a>
<code>isIP</code>: allow usage of option object <a
href="https://github.com/pixelbucket-dev"><code>@​pixelbucket-dev</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2526">#2526</a>
<code>isPassportNumber</code>: improve <code>CA</code> locale <a
href="https://github.com/evanbechtol"><code>@​evanbechtol</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2491">#2491</a>
<code>isBase64</code>: improve validation based on RFC4648 <a
href="https://github.com/aseyfpour"><code>@​aseyfpour</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2479">#2479</a>
<code>isPostalCode</code>: improve <code>FR</code> locale <a
href="https://github.com/Rajput-Balram"><code>@​Rajput-Balram</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2088">#2088</a>
<code>isBefore</code>: allow usage of option object <a
href="https://github.com/pixelbucket-dev"><code>@​pixelbucket-dev</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2346">#2346</a>
<code>isRgbColor</code>: allow second digit in rgba alpha value <a
href="https://github.com/controlol"><code>@​controlol</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2453">#2453</a>
<code>isIP</code>: improve IPv6 regex <a
href="https://github.com/ShreySinha02"><code>@​ShreySinha02</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2052">#2052</a>
<code>isPostalCode</code>: add <code>PK</code> locale <a
href="https://github.com/mateeni-dev"><code>@​mateeni-dev</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2529">#2529</a>
<code>isPostalCode</code>: improve <code>TW</code> locale <a
href="https://github.com/Crocsx"><code>@​Crocsx</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2550">#2550</a>
<code>isPassportNumber</code>: improve <code>US</code> locale <a
href="https://github.com/yitzchak-schechter"><code>@​yitzchak-schechter</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2553">#2553</a>
<code>isUUID</code>: add <code>loose</code> option <a
href="https://github.com/bc-m"><code>@​bc-m</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2551">#2551</a>
<code>isPostalCode</code>: add <code>BD</code> locale <a
href="https://github.com/tanvirrb"><code>@​tanvirrb</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2555">#2555</a>
<code>isLicensePlate</code>: improve <code>pt-PT</code> locale <a
href="https://github.com/castrosu"><code>@​castrosu</code></a></li>
<li><strong>Doc fixes and others:</strong>
<ul>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2372">#2372</a>
<a
href="https://github.com/EmersonRabelo"><code>@​EmersonRabelo</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2538">#2538</a>
<a href="https://github.com/WikiRik"><code>@​WikiRik</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2539">#2539</a>
<a href="https://github.com/WikiRik"><code>@​WikiRik</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2540">#2540</a>
<a href="https://github.com/WikiRik"><code>@​WikiRik</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2549">#2549</a>
<a href="https://github.com/WikiRik"><code>@​WikiRik</code></a></li>
<li><a
href="https://redirect.github.com/validatorjs/validator.js/pull/2537">#2537</a>
<a href="https://github.com/sgress454"><code>@​sgress454</code></a></li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/validatorjs/validator.js/commit/f2b5c17dbe03f2ca9ad9122c597f81e86ce1a9a1"><code>f2b5c17</code></a>
maintenance: 2511 release (<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2627">#2627</a>)</li>
<li><a
href="https://github.com/validatorjs/validator.js/commit/d457ecaf55b0f3d8bd379d82757425d0d13dd382"><code>d457eca</code></a>
fix(isLength): correctly handle Unicode variation selectors (<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2616">#2616</a>)</li>
<li><a
href="https://github.com/validatorjs/validator.js/commit/f2e3633f22fd3016656789d100bc451d857e7488"><code>f2e3633</code></a>
docs: add install instructions to contibution guide (<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2621">#2621</a>)</li>
<li><a
href="https://github.com/validatorjs/validator.js/commit/cf401458b8733d981a3724d634c795a9d612b516"><code>cf40145</code></a>
fix: URL validation for hostnames with ports (no protocol) (<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2622">#2622</a>)</li>
<li><a
href="https://github.com/validatorjs/validator.js/commit/4af61243ba0ae93f29e7689040e188b5849ff1b0"><code>4af6124</code></a>
maintenance: 2510 release (<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2585">#2585</a>)</li>
<li><a
href="https://github.com/validatorjs/validator.js/commit/30d4fe02c16d36ed471f12da658c4b5d843781e0"><code>30d4fe0</code></a>
13.15.20</li>
<li><a
href="https://github.com/validatorjs/validator.js/commit/cbef5088f02d36caf978f378bb845fe49bdc0809"><code>cbef508</code></a>
fix(isURL): improve protocol detection. Resolves CVE-2025-56200 (<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2608">#2608</a>)</li>
<li><a
href="https://github.com/validatorjs/validator.js/commit/6f436be36945e460ee624bf72a935a06daded859"><code>6f436be</code></a>
Fix typo in validators.test.js (<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2581">#2581</a>)</li>
<li><a
href="https://github.com/validatorjs/validator.js/commit/3c857088d58197453957a2b924dfedea328003b6"><code>3c85708</code></a>
Fix: correct French VAT (FR) validation regex and add tests (<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2584">#2584</a>)</li>
<li><a
href="https://github.com/validatorjs/validator.js/commit/eee525cd117d24ac905b9432f3f5a27e96aa9719"><code>eee525c</code></a>
<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2491">#2491</a>
<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2573">#2573</a>
Simplify isBase64 to prevent stack overflow (<a
href="https://redirect.github.com/validatorjs/validator.js/issues/2574">#2574</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/validatorjs/validator.js/compare/13.11.0...13.15.22">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~wikirik">wikirik</a>, a new releaser for
validator since your current version.</p>
</details>
<br />

Updates `@trpc/server` from 11.1.1 to 11.8.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/trpc/trpc/releases">@​trpc/server's
releases</a>.</em></p>
<blockquote>
<h2>v11.8.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(server): support streaming in API Gateway REST API by <a
href="https://github.com/anatolzak"><code>@​anatolzak</code></a> in <a
href="https://redirect.github.com/trpc/trpc/pull/7039">trpc/trpc#7039</a></li>
<li>fixes <a
href="https://github.com/advisories/GHSA-43p4-m455-4f4j">https://github.com/advisories/GHSA-43p4-m455-4f4j</a></li>
</ul>
<h2>v11.7.2</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(server): missing sse options when using mergeRouter by <a
href="https://github.com/timcole"><code>@​timcole</code></a> in <a
href="https://redirect.github.com/trpc/trpc/pull/7023">trpc/trpc#7023</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/KitsuneKode"><code>@​KitsuneKode</code></a>
made their first contribution in <a
href="https://redirect.github.com/trpc/trpc/pull/6975">trpc/trpc#6975</a></li>
<li><a href="https://github.com/timcole"><code>@​timcole</code></a> made
their first contribution in <a
href="https://redirect.github.com/trpc/trpc/pull/7023">trpc/trpc#7023</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/trpc/trpc/compare/v11.7.1...v11.7.2">https://github.com/trpc/trpc/compare/v11.7.1...v11.7.2</a></p>
<h2>v11.7.1</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(tanstack-react-query): keyPrefix of undefined by <a
href="https://github.com/Nick-Lucas"><code>@​Nick-Lucas</code></a> in <a
href="https://redirect.github.com/trpc/trpc/pull/6990">trpc/trpc#6990</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/theoludwig"><code>@​theoludwig</code></a> made
their first contribution in <a
href="https://redirect.github.com/trpc/trpc/pull/6906">trpc/trpc#6906</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/trpc/trpc/compare/v11.7.0...v11.7.1">https://github.com/trpc/trpc/compare/v11.7.0...v11.7.1</a></p>
<h2>v11.7.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(client): do not emit &quot;connecting&quot; when initializing
websocket subscription by <a
href="https://github.com/hmatthieu"><code>@​hmatthieu</code></a> in <a
href="https://redirect.github.com/trpc/trpc/pull/6970">trpc/trpc#6970</a></li>
<li>fix(server): Export octet types by <a
href="https://github.com/Nick-Lucas"><code>@​Nick-Lucas</code></a> in <a
href="https://redirect.github.com/trpc/trpc/pull/6981">trpc/trpc#6981</a></li>
<li>feat(tanstack-react-query): Add QueryKey and MutationKey Prefix
option by <a
href="https://github.com/Nick-Lucas"><code>@​Nick-Lucas</code></a> in <a
href="https://redirect.github.com/trpc/trpc/pull/6976">trpc/trpc#6976</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/trpc/trpc/compare/v11.6.0...v11.7.0">https://github.com/trpc/trpc/compare/v11.6.0...v11.7.0</a></p>
<h2>v11.6.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: add precondition required response code by <a
href="https://github.com/y-nk"><code>@​y-nk</code></a> in <a
href="https://redirect.github.com/trpc/trpc/pull/6954">trpc/trpc#6954</a></li>
<li>fix(client): <code>httpBatchStreamLink</code> in React Native
&quot;stream ends with TypeError&quot; by <a
href="https://github.com/KATT"><code>@​KATT</code></a> in <a
href="https://redirect.github.com/trpc/trpc/pull/6960">trpc/trpc#6960</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/elrion018"><code>@​elrion018</code></a>
made their first contribution in <a
href="https://redirect.github.com/trpc/trpc/pull/6932">trpc/trpc#6932</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/trpc/trpc/compare/v11.5.1...v11.6.0">https://github.com/trpc/trpc/compare/v11.5.1...v11.6.0</a></p>
<h2>v11.5.1</h2>
<h2>What's Changed</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/trpc/trpc/commit/a247ce28817ea682f3ffda9255678db18a8b3391"><code>a247ce2</code></a>
v11.8.0</li>
<li><a
href="https://github.com/trpc/trpc/commit/78629d524968ef8db5a7adf68d8b95a44369d77e"><code>78629d5</code></a>
Fix bug (<a
href="https://github.com/trpc/trpc/tree/HEAD/packages/server/issues/7043">#7043</a>)</li>
<li><a
href="https://github.com/trpc/trpc/commit/9a17cef999278555a0e1e6322f1a2579180eecb9"><code>9a17cef</code></a>
feat(server): support streaming in API Gateway REST API (<a
href="https://github.com/trpc/trpc/tree/HEAD/packages/server/issues/7039">#7039</a>)</li>
<li><a
href="https://github.com/trpc/trpc/commit/fa8d8061d033c8bd51410d126840c457215954cd"><code>fa8d806</code></a>
chore(deps): update dependency valibot to v1.2.0 [security] (<a
href="https://github.com/trpc/trpc/tree/HEAD/packages/server/issues/7026">#7026</a>)</li>
<li><a
href="https://github.com/trpc/trpc/commit/14e3d4a47edf007c2bdd90efcc07387d0a68549b"><code>14e3d4a</code></a>
v11.7.2</li>
<li><a
href="https://github.com/trpc/trpc/commit/ffa88b0f3e2e7215f967a223287541cf2425c65c"><code>ffa88b0</code></a>
fix: missing sse options when using mergeRouter (<a
href="https://github.com/trpc/trpc/tree/HEAD/packages/server/issues/7023">#7023</a>)</li>
<li><a
href="https://github.com/trpc/trpc/commit/16db2d0002bbde23388ac800f411168c48c546eb"><code>16db2d0</code></a>
chore(deps): update dependency <code>@​oxc-project/runtime</code> to
v0.97.0 (<a
href="https://github.com/trpc/trpc/tree/HEAD/packages/server/issues/7004">#7004</a>)</li>
<li><a
href="https://github.com/trpc/trpc/commit/d6bb04dafc4f0a887ff1ab3002758ff424a8df17"><code>d6bb04d</code></a>
v11.7.1</li>
<li><a
href="https://github.com/trpc/trpc/commit/5961a63c0161c24c0b21e47503a357d3b7c4410a"><code>5961a63</code></a>
v11.7.0</li>
<li><a
href="https://github.com/trpc/trpc/commit/4c9efbb587f6bc327c5d92dbe95c82690002aa72"><code>4c9efbb</code></a>
Export octet types (<a
href="https://github.com/trpc/trpc/tree/HEAD/packages/server/issues/6981">#6981</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/trpc/trpc/commits/v11.8.0/packages/server">compare
view</a></li>
</ul>
</details>
<br />

Updates `yaml` from 2.3.4 to 2.8.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/eemeli/yaml/releases">yaml's
releases</a>.</em></p>
<blockquote>
<h2>v2.8.3</h2>
<ul>
<li>Add <code>trailingComma</code> ToString option for multiline flow
formatting (<a
href="https://redirect.github.com/eemeli/yaml/issues/670">#670</a>)</li>
<li>Catch stack overflow during node composition (1e84ebb)</li>
</ul>
<h2>v2.8.2</h2>
<ul>
<li>Serialize -0 as -0 (<a
href="https://redirect.github.com/eemeli/yaml/issues/638">#638</a>)</li>
<li>Do not double newlines for empty map values (<a
href="https://redirect.github.com/eemeli/yaml/issues/642">#642</a>)</li>
</ul>
<h2>v2.8.1</h2>
<ul>
<li>Preserve empty block literals (<a
href="https://redirect.github.com/eemeli/yaml/issues/634">#634</a>)</li>
</ul>
<h2>v2.8.0</h2>
<ul>
<li>Add node cache for faster alias resolution (<a
href="https://redirect.github.com/eemeli/yaml/issues/612">#612</a>)</li>
<li>Re-introduce compatibility with Node.js 14.6 (<a
href="https://redirect.github.com/eemeli/yaml/issues/614">#614</a>)</li>
<li>Add <code>--merge</code> option to CLI tool (<a
href="https://redirect.github.com/eemeli/yaml/issues/611">#611</a>)</li>
<li>Improve error for tag resolution error on null value (<a
href="https://redirect.github.com/eemeli/yaml/issues/616">#616</a>)</li>
<li>Allow empty string as plain scalar representation, for failsafe
schema (<a
href="https://redirect.github.com/eemeli/yaml/issues/616">#616</a>)</li>
<li>docs: include cli example (<a
href="https://redirect.github.com/eemeli/yaml/issues/617">#617</a>)</li>
</ul>
<h2>v2.7.1</h2>
<ul>
<li>Do not allow seq with single-line collection value on same line with
map key (<a
href="https://redirect.github.com/eemeli/yaml/issues/603">#603</a>)</li>
<li>Improve warning &amp; avoid TypeError on bad YAML 1.1 nodes (<a
href="https://redirect.github.com/eemeli/yaml/issues/610">#610</a>)</li>
</ul>
<h2>v2.7.0</h2>
<p>The library is now available on JSR as <a
href="https://jsr.io/@eemeli/yaml">@​eemeli/yaml</a> and on deno.land/x
as <a href="https://deno.land/x/yaml">yaml</a>. In addition to Node.js
and browsers, it should work in Deno, Bun, and Cloudflare Workers.</p>
<ul>
<li>Use .ts extension in all relative imports (<a
href="https://redirect.github.com/eemeli/yaml/issues/591">#591</a>)</li>
<li>Ignore newline after block seq indicator as space before value (<a
href="https://redirect.github.com/eemeli/yaml/issues/590">#590</a>)</li>
<li>Require Node.js 14.18 or later (was 14.6) (<a
href="https://redirect.github.com/eemeli/yaml/issues/598">#598</a>)</li>
</ul>
<h2>v2.6.1</h2>
<ul>
<li>Do not strip <code>:00</code> seconds from <code>!!timestamp</code>
values (<a
href="https://redirect.github.com/eemeli/yaml/issues/578">#578</a>, with
thanks to <a
href="https://github.com/qraynaud"><code>@​qraynaud</code></a>)</li>
<li>Tighten regexp for JSON <code>!!bool</code> (<a
href="https://redirect.github.com/eemeli/yaml/issues/587">#587</a>, with
thanks to <a
href="https://github.com/vra5107"><code>@​vra5107</code></a>)</li>
<li>Default to literal block scalar if folded would overflow (<a
href="https://redirect.github.com/eemeli/yaml/issues/585">#585</a>)</li>
</ul>
<h2>v2.6.0</h2>
<ul>
<li>Use a proper tag for <code>!!merge &lt;&lt;</code> keys (<a
href="https://redirect.github.com/eemeli/yaml/issues/580">#580</a>)</li>
<li>Add <code>stringKeys</code> parse option (<a
href="https://redirect.github.com/eemeli/yaml/issues/581">#581</a>)</li>
<li>Stringify a Document as a Document (<a
href="https://redirect.github.com/eemeli/yaml/issues/576">#576</a>)</li>
<li>Add sponsorship by <a
href="https://manifest.build/">Manifest</a></li>
</ul>
<h2>v2.5.1</h2>
<ul>
<li>Include range in flow sequence pair maps (<a
href="https://redirect.github.com/eemeli/yaml/issues/573">#573</a>)</li>
</ul>
<h2>v2.5.0</h2>
<ul>
<li>Add <code>--indent</code> option to CLI tool (<a
href="https://redirect.github.com/eemeli/yaml/issues/559">#559</a>, with
thanks to <a
href="https://github.com/danielbayley"><code>@​danielbayley</code></a>)</li>
<li>Require newline in all cases for props on block sequence (<a
href="https://redirect.github.com/eemeli/yaml/issues/557">#557</a>)</li>
<li>Always reset indentation in lexer on <code>...</code> (<a
href="https://redirect.github.com/eemeli/yaml/issues/558">#558</a>)</li>
<li>Ignore <code>minContentWidth</code> if greater than
<code>lineWidth</code> (<a
href="https://redirect.github.com/eemeli/yaml/issues/562">#562</a>)</li>
<li>Drop unused <code>Collection.maxFlowStringSingleLineLength</code>
(<a href="https://redirect.github.com/eemeli/yaml/issues/522">#522</a>,
<a
href="https://redirect.github.com/eemeli/yaml/issues/421">#421</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/eemeli/yaml/commit/ce14587484822bffb0f7d31aefedcaf2dc0d0387"><code>ce14587</code></a>
2.8.3</li>
<li><a
href="https://github.com/eemeli/yaml/commit/1e84ebbea7ec35011a4c61bbb820a529ee4f359b"><code>1e84ebb</code></a>
fix: Catch stack overflow during node composition</li>
<li><a
href="https://github.com/eemeli/yaml/commit/6b24090280eaaab5040112bba41ccef57f39c2d5"><code>6b24090</code></a>
ci: Include Prettier check in lint action</li>
<li><a
href="https://github.com/eemeli/yaml/commit/9424dee38c85163fad53ac27533c7c4bdaf7495d"><code>9424dee</code></a>
chore: Refresh lockfile</li>
<li><a
href="https://github.com/eemeli/yaml/commit/d1aca82bc15a4c261bdc58561d32189a5d3a45ef"><code>d1aca82</code></a>
Add trailingComma ToString option for multiline flow formatting (<a
href="https://redirect.github.com/eemeli/yaml/issues/670">#670</a>)</li>
<li><a
href="https://github.com/eemeli/yaml/commit/43215099f7fcdac422d778c15e70d83c691b0e41"><code>4321509</code></a>
ci: Drop the branch filter from GitHub PR actions</li>
<li><a
href="https://github.com/eemeli/yaml/commit/47207d0fc7d4f863cd5fbdcff1378637bd93e847"><code>47207d0</code></a>
chore: Update docs-slate</li>
<li><a
href="https://github.com/eemeli/yaml/commit/5212faeed5936d1fa291d2f28672e4a96e2c2c5d"><code>5212fae</code></a>
chore: Update docs-slate</li>
<li><a
href="https://github.com/eemeli/yaml/commit/086fa6b5bae325da18734750cddee231ce578930"><code>086fa6b</code></a>
2.8.2</li>
<li><a
href="https://github.com/eemeli/yaml/commit/95f01e98032ddf199b42bb3ba0737303b35ef752"><code>95f01e9</code></a>
chore: Add funding to package.json</li>
<li>Additional commits viewable in <a
href="https://github.com/eemeli/yaml/compare/v2.3.4...v2.8.3">compare
view</a></li>
</ul>
</details>
<br />

Updates `bn.js` from 4.12.0 to 4.12.5
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/indutny/bn.js/commit/026da9f3a9540e0b48d9bc3c0a0bdcc2a8b19278"><code>026da9f</code></a>
4.12.5</li>
<li><a
href="https://github.com/indutny/bn.js/commit/13b78c2c9a8e18a5c96f7b51e4d42f5da21358a7"><code>13b78c2</code></a>
fix: correct divRound rounding for negative operands (<a
href="https://redirect.github.com/indutny/bn.js/issues/320">#320</a>)</li>
<li><a
href="https://github.com/indutny/bn.js/commit/9c6ef2f789473013500066b3cf9ac0c17396e701"><code>9c6ef2f</code></a>
fix: normalize sign when imuln multiplies by zero (<a
href="https://redirect.github.com/indutny/bn.js/issues/321">#321</a>)</li>
<li><a
href="https://github.com/indutny/bn.js/commit/12f9f8f2577c1befb864b25a612377f9ed17588c"><code>12f9f8f</code></a>
4.12.4</li>
<li><a
href="https://github.com/indutny/bn.js/commit/6b98684d6958e10605d9566b5704384b9fbb06b6"><code>6b98684</code></a>
fix: clear surplus words in inotn so notn(width) stays below 2 ** width
(<a
href="https://redirect.github.com/indutny/bn.js/issues/319">#319</a>)</li>
<li><a
href="https://github.com/indutny/bn.js/commit/39fe4389c773327ed15f29f77f8b7dbbff4beb4c"><code>39fe438</code></a>
4.12.3</li>
<li><a
href="https://github.com/indutny/bn.js/commit/67ecb35dabaf252001b649c12d69c4b57deac6f6"><code>67ecb35</code></a>
backport(4.x): fix imaskn state (<a
href="https://redirect.github.com/indutny/bn.js/issues/317">#317</a>)</li>
<li><a
href="https://github.com/indutny/bn.js/commit/c4098bac2470418f8e0f6bf11fe0cb676a2b9047"><code>c4098ba</code></a>
4.12.2</li>
<li><a
href="https://github.com/indutny/bn.js/commit/6277fd705e51edae1c404c65f03ba2e512706945"><code>6277fd7</code></a>
backport(4.x): Fix imuln/muln with zero (backport of <a
href="https://redirect.github.com/indutny/bn.js/issues/313">#313</a>)
(<a
href="https://redirect.github.com/indutny/bn.js/issues/314">#314</a>)</li>
<li><a
href="https://github.com/indutny/bn.js/commit/ac0d4afaae91701815b9edc19789e44e7690d688"><code>ac0d4af</code></a>
4.12.1</li>
<li>Additional commits viewable in <a
href="https://github.com/indutny/bn.js/compare/v4.12.0...v4.12.5">compare
view</a></li>
</ul>
</details>
<br />

Updates `flatted` from 3.3.1 to 3.4.4
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/WebReflection/flatted/commit/e6f5ca700c4ca8104a6a83472c8219e267bd5e84"><code>e6f5ca7</code></a>
3.4.4</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/47f14fac0b1a41989f216b0cda4c50596ca339f6"><code>47f14fa</code></a>
removed E_STRICT from PHP</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/40505688464c49fe6374e7bc4cdd9bd2e9e6f330"><code>4050568</code></a>
fixced go-lang issues in CI</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/4303f4db38ba0ba8d5e2ed6e9689cefc74c46b63"><code>4303f4d</code></a>
Merge pull request <a
href="https://redirect.github.com/WebReflection/flatted/issues/101">#101</a>
from mfinelli/gocriticfixes</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/106735b609c15df51539a0d7c0a270182efd904c"><code>106735b</code></a>
updated package-lock.json</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/670a1bdf9dcfba02111c3034294366f10696fb53"><code>670a1bd</code></a>
3.4.3</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/50a61a90ea5ca64c114f0aa040ad127e3a97feff"><code>50a61a9</code></a>
Fix <a
href="https://redirect.github.com/WebReflection/flatted/issues/104">#104</a>
- allow <code>null</code> as replacer value</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/8aa64f460cf0c4dac9cc214c831aade28f8f2c6e"><code>8aa64f4</code></a>
solved crytical errors over dependencies</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/b85577f39ff85959d02e8862cc0dde8114b43762"><code>b85577f</code></a>
Fix go-critic errors</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/bb8c63cea5befd4315519cb4458c6fc07bb9cf7b"><code>bb8c63c</code></a>
Merge pull request <a
href="https://redirect.github.com/WebReflection/flatted/issues/100">#100</a>
from WebReflection/WebReflection-patch-1</li>
<li>Additional commits viewable in <a
href="https://github.com/WebReflection/flatted/compare/v3.3.1...v3.4.4">compare
view</a></li>
</ul>
</details>
<br />

Updates `jws` from 3.2.2 to 3.2.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/brianloveswords/node-jws/releases">jws's
releases</a>.</em></p>
<blockquote>
<h2>v3.2.3</h2>
<h3>Changed</h3>
<ul>
<li>Fix advisory GHSA-869p-cjfg-cm3x: createSign and createVerify now
require
that a non empty secret is provided (via opts.secret, opts.privateKey or
opts.key)
when using HMAC algorithms.</li>
<li>Upgrading JWA version to 1.4.2, addressing a compatibility issue for
Node &gt;= 25.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/auth0/node-jws/blob/master/CHANGELOG.md">jws's
changelog</a>.</em></p>
<blockquote>
<h2>[3.2.3]</h2>
<h3>Changed</h3>
<ul>
<li>Fix advisory GHSA-869p-cjfg-cm3x: createSign and createVerify now
require
that a non empty secret is provided (via opts.secret, opts.privateKey or
opts.key)
when using HMAC algorithms.</li>
<li>Upgrading JWA version to 1.4.2, adressing a compatibility issue for
Node &gt;= 25.</li>
</ul>
<h2>[3.0.0]</h2>
<h3>Changed</h3>
<ul>
<li><strong>BREAKING</strong>: <code>jwt.verify</code> now requires an
<code>algorithm</code> parameter, and
<code>jws.createVerify</code> requires an <code>algorithm</code> option.
The <code>&quot;alg&quot;</code> field
signature headers is ignored. This mitigates a critical security flaw
in the library which would allow an attacker to generate signatures with
arbitrary contents that would be accepted by <code>jwt.verify</code>.
See
<a
href="https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/">https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/</a>
for details.</li>
</ul>
<h2><a
href="https://github.com/brianloveswords/node-jws/compare/v1.0.1...v2.0.0">2.0.0</a>
- 2015-01-30</h2>
<h3>Changed</h3>
<ul>
<li>
<p><strong>BREAKING</strong>: Default payload encoding changed from
<code>binary</code> to
<code>utf8</code>. <code>utf8</code> is a is a more sensible default
than <code>binary</code> because
many payloads, as far as I can tell, will contain user-facing
strings that could be in any language. (<!-- raw HTML omitted --><a
href="https://github.com/brianloveswords/node-jws/commit/6b6de48">6b6de48</a><!--
raw HTML omitted -->)</p>
</li>
<li>
<p>Code reorganization, thanks <a
href="https://github.com/fearphage"><code>@​fearphage</code></a>! (<!--
raw HTML omitted --><a
href="https://github.com/brianloveswords/node-jws/commit/7880050">7880050</a><!--
raw HTML omitted -->)</p>
</li>
</ul>
<h3>Added</h3>
<ul>
<li>Option in all relevant methods for <code>encoding</code>. For those
few users
that might be depending on a <code>binary</code> encoding of the
messages, this
is for them. (<!-- raw HTML omitted --><a
href="https://github.com/brianloveswords/node-jws/commit/6b6de48">6b6de48</a><!--
raw HTML omitted -->)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/auth0/node-jws/commit/4f6e73f24df42f07d632dec6431ade8eda8d11a6"><code>4f6e73f</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/auth0/node-jws/commit/bd0fea57f35a97b6749a632b19ae5100d6d35729"><code>bd0fea5</code></a>
version 3.2.3</li>
<li><a
href="https://github.com/auth0/node-jws/commit/7c3b4b411004c206af8901fa3f8e644127bbf8d9"><code>7c3b4b4</code></a>
Enhance tests for HMAC streaming sign and verify</li>
<li><a
href="https://github.com/auth0/node-jws/commit/a9b8ed999de8f8fff486ac9167514577a0fae323"><code>a9b8ed9</code></a>
Improve secretOrKey initialization in VerifyStream</li>
<li><a
href="https://github.com/auth0/node-jws/commit/6707fde62cbae465a7f11e52760fb994dbc0e0dc"><code>6707fde</code></a>
Improve secret handling in SignStream</li>
<li>See full diff in <a
href="https://github.com/brianloveswords/node-jws/compare/v3.2.2...v3.2.3">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~julien.wollscheid">julien.wollscheid</a>, a
new releaser for jws since your current version.</p>
</details>
<br />

Updates `rollup` from 4.40.0 to 4.63.5
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rollup/rollup/releases">rollup's
releases</a>.</em></p>
<blockquote>
<h2>v4.63.5</h2>
<h2>4.63.5</h2>
<p><em>2026-09-24</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Fix an issue where watch mode would hang instead of terminating when
closing via Ctrl+C (<a
href="https://redirect.github.com/rollup/rollup/issues/6521">#6521</a>)</li>
<li>Avoid starting overlapping watch mode runs when plugins invalidate
files at the wrong time (<a
href="https://redirect.github.com/rollup/rollup/issues/6526">#6526</a>)</li>
<li>Fix many edge cases where watch mode events were not properly
emitted to listeners, especially when errors occur (<a
href="https://redirect.github.com/rollup/rollup/issues/6526">#6526</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6520">#6520</a>:
Lock file maintenance (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot], <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6521">#6521</a>:
Terminate watch mode via natural process exit when possible (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6523">#6523</a>:
Protect cc pin against renovate lock file maintenance (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6525">#6525</a>:
docs: fix typos 'interations' and 'coresponding' (<a
href="https://github.com/haimingZZ"><code>@​haimingZZ</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6526">#6526</a>:
fix(watch): prevent overlapping runs and other run lifecycle bugs (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>v4.63.4</h2>
<h2>4.63.4</h2>
<p><em>2026-09-19</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Ensure meta information of the cached module is exposed in
<code>shouldTransformCachedModule</code> (<a
href="https://redirect.github.com/rollup/rollup/issues/6442">#6442</a>)</li>
<li>Do not create invalid code if import attribute values contain
special characters (<a
href="https://redirect.github.com/rollup/rollup/issues/6502">#6502</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6429">#6429</a>:
ci: collect Rust coverage from JS tests in dedicated job (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6442">#6442</a>:
fix: expose cached module meta during cache checks (<a
href="https://github.com/ychampion"><code>@​ychampion</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6496">#6496</a>:
docs: name the parameter runHook actually takes (<a
href="https://github.com/darkdi"><code>@​darkdi</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6502">#6502</a>:
Escape quotes and backslashes in import attribute values (<a
href="https://github.com/dylanpulver"><code>@​dylanpulver</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6517">#6517</a>:
Improve agent instructions (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6518">#6518</a>:
fix(deps): update minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6519">#6519</a>:
Request Copilot code review via workflow (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>v4.63.3</h2>
<h2>4.63.3</h2>
<p><em>2026-09-14</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Make sure that the internal shims for basename and extname in the
browser build fully match NodeJS (<a
href="https://redirect.github.com/rollup/rollup/issues/6473">#6473</a>)</li>
<li>Always report and recover from failures on invalidation in watch
mode (<a
href="https://redirect.github.com/rollup/rollup/issues/6506">#6506</a>)</li>
<li>Respect windows line terminators when tree-shaking in situations
where line-breaks need to be removed to prevent automatic semicolon
insertion (<a
href="https://redirect.github.com/rollup/rollup/issues/6514">#6514</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rollup/rollup/blob/master/CHANGELOG.md">rollup's
changelog</a>.</em></p>
<blockquote>
<h2>4.63.5</h2>
<p><em>2026-09-24</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Fix an issue where watch mode would hang instead of terminating when
closing via Ctrl+C (<a
href="https://redirect.github.com/rollup/rollup/issues/6521">#6521</a>)</li>
<li>Avoid starting overlapping watch mode runs when plugins invalidate
files at the wrong time (<a
href="https://redirect.github.com/rollup/rollup/issues/6526">#6526</a>)</li>
<li>Fix many edge cases where watch mode events were not properly
emitted to listeners, especially when errors occur (<a
href="https://redirect.github.com/rollup/rollup/issues/6526">#6526</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6520">#6520</a>:
Lock file maintenance (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot], <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6521">#6521</a>:
Terminate watch mode via natural process exit when possible (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6523">#6523</a>:
Protect cc pin against renovate lock file maintenance (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6525">#6525</a>:
docs: fix typos 'interations' and 'coresponding' (<a
href="https://github.com/haimingZZ"><code>@​haimingZZ</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6526">#6526</a>:
fix(watch): prevent overlapping runs and other run lifecycle bugs (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>4.63.4</h2>
<p><em>2026-09-19</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Ensure meta information of the cached module is exposed in
<code>shouldTransformCachedModule</code> (<a
href="https://redirect.github.com/rollup/rollup/issues/6442">#6442</a>)</li>
<li>Do not create invalid code if import attribute values contain
special characters (<a
href="https://redirect.github.com/rollup/rollup/issues/6502">#6502</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6429">#6429</a>:
ci: collect Rust coverage from JS tests in dedicated job (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6442">#6442</a>:
fix: expose cached module meta during cache checks (<a
href="https://github.com/ychampion"><code>@​ychampion</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6496">#6496</a>:
docs: name the parameter runHook actually takes (<a
href="https://github.com/darkdi"><code>@​darkdi</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6502">#6502</a>:
Escape quotes and backslashes in import attribute values (<a
href="https://github.com/dylanpulver"><code>@​dylanpulver</code></a>, <a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6517">#6517</a>:
Improve agent instructions (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6518">#6518</a>:
fix(deps): update minor/patch updates (<a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot])</li>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6519">#6519</a>:
Request Copilot code review via workflow (<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<h2>4.63.3</h2>
<p><em>2026-09-14</em></p>
<h3>Bug Fixes</h3>
<ul>
<li>Make sure that the internal shims for basename and extname in the
browser build fully match NodeJS (<a
href="https://redirect.github.com/rollup/rollup/issues/6473">#6473</a>)</li>
<li>Always report and recover from failures on invalidation in watch
mode (<a
href="https://redirect.github.com/rollup/rollup/issues/6506">#6506</a>)</li>
<li>Respect windows line terminators when tree-shaking in situations
where line-breaks need to be removed to prevent automatic semicolon
insertion (<a
href="https://redirect.github.com/rollup/rollup/issues/6514">#6514</a>)</li>
</ul>
<h3>Pull Requests</h3>
<ul>
<li><a
href="https://redirect.github.com/rollup/rollup/pull/6473">#6473</a>:
fix(browser): match node's basename and extname (<a
href="https://github.com/luantaraschi"><code>@​luantaraschi</code></a>,
<a
href="https://github.com/lukastaegert"><code>@​lukastaegert</code></a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/rollup/rollup/commit/3722484c33c58b3ab0cbbfcca09b8f267d420329"><code>3722484</code></a>
4.63.5</li>
<li><a
href="https://github.com/rollup/rollup/commit/9156d5b509b6b27676d34430ca9be6eb82a34f86"><code>9156d5b</code></a>
fix(watch): prevent overlapping runs and other run lifecycle bugs (<a
href="https://redirect.github.com/rollup/rollup/issues/6526">#6526</a>)</li>
<li><a
href="https://github.com/rollup/rollup/commit/87fbbf6b3f8c55c81f1f07673957ebd70bc57c07"><code>87fbbf6</code></a>
Protect cc pin against renovate lock file maintenance (<a
href="https://redirect.github.com/rollup/rollup/issues/6523">#6523</a>)</li>
<li><a
href="https://github.com/rollup/rollup/commit/30f0442482c0ab2b37e7e7af3bdd04e6bb292c48"><code>30f0442</code></a>
docs: fix typos 'interations' and 'coresponding' (<a
href="https://redirect.github.com/rollup/rollup/issues/6525">#6525</a>)</li>
<li><a
href="https://github.com/rollup/rollup/commit/b54c4c2af5762e846109f1b1f09d5a944486498a"><code>b54c4c2</code></a>
Lock file maintenance (<a
href="https://redirect.github.com/rollup/rollup/issues/6520">#6520</a>)</li>
<li><a
href="https://github.com/rollup/rollup/commit/c28de6fa616ff6525802996a6b480b57d1e7b0e1"><code>c28de6f</code></a>
Terminate watch mode via natural process exit when possible (<a
href="https://redirect.github.com/rollup/rollup/issues/6521">#6521</a>)</li>
<li><a
href="https://github.com/rollup/rollup/commit/ba78d5752a1e1ff4ff4af3a8bffab7691d822f7d"><code>ba78d57</code></a>
4.63.4</li>
<li><a
href="https://github.com/rollup/rollup/commit/67c3379f61a105839e26afdf519f2f65a0a2e248"><code>67c3379</code></a>
Escape quotes and backslashes in import attribute values (<a
href="https://redirect.github.com/rollup/rollup/issues/6502">#6502</a>)</li>
<li><a
href="https://github.com/rollup/rollup/commit/35f6053b8b655befc57f8db79006e8cd47312699"><code>35f6053</code></a>
fix: expose cached module meta during cache checks (<a
href="https://redirect.github.com/rollup/rollup/issues/6442">#6442</a>)</li>
<li><a
href="https://github.com/rollup/rollup/commit/b7ae5e20fa60caa4e4d73d32200991104c5e9616"><code>b7ae5e2</code></a>
Request Copilot code review via workflow (<a
href="https://redirect.github.com/rollup/rollup/issues/6519">#6519</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/rollup/rollup/compare/v4.40.0...v4.63.5">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for rollup since your current version.</p>
</details>
<details>
<summary>Install script changes</summary>
<p>This version modifies <code>prepare</code> script that runs during
installation. Review the package contents before updating.</p>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/linux-odyssey/linux-odyssey/network/alerts).

</details>
2026-09-26 11:24:13 +10:00
dependabot[bot] a74a9d71f2 chore(deps): bump the npm_and_yarn group across 1 directory with 7 updates
Bumps the npm_and_yarn group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [validator](https://github.com/validatorjs/validator.js) | `13.11.0` | `13.15.22` |
| [@trpc/server](https://github.com/trpc/trpc/tree/HEAD/packages/server) | `11.1.1` | `11.8.0` |
| [yaml](https://github.com/eemeli/yaml) | `2.3.4` | `2.8.3` |
| [bn.js](https://github.com/indutny/bn.js) | `4.12.0` | `4.12.5` |
| [flatted](https://github.com/WebReflection/flatted) | `3.3.1` | `3.4.4` |
| [jws](https://github.com/brianloveswords/node-jws) | `3.2.2` | `3.2.3` |
| [rollup](https://github.com/rollup/rollup) | `4.40.0` | `4.63.5` |



Updates `validator` from 13.11.0 to 13.15.22
- [Release notes](https://github.com/validatorjs/validator.js/releases)
- [Changelog](https://github.com/validatorjs/validator.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/validatorjs/validator.js/compare/13.11.0...13.15.22)

Updates `@trpc/server` from 11.1.1 to 11.8.0
- [Release notes](https://github.com/trpc/trpc/releases)
- [Commits](https://github.com/trpc/trpc/commits/v11.8.0/packages/server)

Updates `yaml` from 2.3.4 to 2.8.3
- [Release notes](https://github.com/eemeli/yaml/releases)
- [Commits](https://github.com/eemeli/yaml/compare/v2.3.4...v2.8.3)

Updates `bn.js` from 4.12.0 to 4.12.5
- [Release notes](https://github.com/indutny/bn.js/releases)
- [Changelog](https://github.com/indutny/bn.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/indutny/bn.js/compare/v4.12.0...v4.12.5)

Updates `flatted` from 3.3.1 to 3.4.4
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.1...v3.4.4)

Updates `jws` from 3.2.2 to 3.2.3
- [Release notes](https://github.com/brianloveswords/node-jws/releases)
- [Changelog](https://github.com/auth0/node-jws/blob/master/CHANGELOG.md)
- [Commits](https://github.com/brianloveswords/node-jws/compare/v3.2.2...v3.2.3)

Updates `rollup` from 4.40.0 to 4.63.5
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.40.0...v4.63.5)

---
updated-dependencies:
- dependency-name: validator
  dependency-version: 13.15.22
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: "@trpc/server"
  dependency-version: 11.8.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: yaml
  dependency-version: 2.8.3
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: bn.js
  dependency-version: 4.12.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: flatted
  dependency-version: 3.4.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: jws
  dependency-version: 3.2.3
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: rollup
  dependency-version: 4.63.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-26 01:19:42 +00:00
Justin Lin 34ce90323a chore(deps): bump the npm_and_yarn group across 1 directory with 12 updates (#203)
Bumps the npm_and_yarn group with 12 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
|
[@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core)
| `7.24.0` | `7.29.6` |
| [axios](https://github.com/axios/axios) | `1.8.2` | `1.18.0` |
| [dompurify](https://github.com/cure53/DOMPurify) | `3.2.4` | `3.4.13`
|
| [postcss](https://github.com/postcss/postcss) | `8.5.3` | `8.5.23` |
| [mongoose](https://github.com/Automattic/mongoose) | `8.9.5` |
`8.24.1` |
|
[@babel/plugin-transform-modules-systemjs](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs)
| `7.23.9` | `7.29.8` |
| [browserslist](https://github.com/browserslist/browserslist) |
`4.23.0` | `4.29.1` |
| [engine.io](https://github.com/socketio/socket.io) | `6.5.4` | `6.5.5`
|
| [nanoid](https://github.com/ai/nanoid) | `3.3.11` | `3.3.19` |
| [shell-quote](https://github.com/ljharb/shell-quote) | `1.8.1` |
`1.10.0` |
| [socket.io-parser](https://github.com/socketio/socket.io) | `4.2.4` |
`4.2.7` |
| [tmp](https://github.com/raszi/node-tmp) | `0.2.1` | `0.2.7` |


Updates `@babel/core` from 7.24.0 to 7.29.6
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/babel/babel/releases">@​babel/core's
releases</a>.</em></p>
<blockquote>
<h2>v7.29.6 (2026-05-25)</h2>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/18014">#18014</a>
Catchup source map position in preserveFormat (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/18001">#18001</a>
[7.x packport]Improve input source map handling (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>, <code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17998">#17998</a>
Preserve original identifier names from input sourcemaps (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17992">#17992</a>)
(<a href="https://github.com/Andarist"><code>@​Andarist</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 3</h4>
<ul>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
<li>Mateusz Burzyński (<a
href="https://github.com/Andarist"><code>@​Andarist</code></a>)</li>
<li>Nicolò Ribaudo (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
<h2>v7.29.5 (2026-05-05)</h2>
<h4>🏠  Internal</h4>
<ul>
<li><code>babel-preset-env</code>
<ul>
<li>Update <code>@babel/*</code> dependencies</li>
</ul>
</li>
</ul>
<h2>v7.29.4 (2026-05-05)</h2>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-plugin-transform-modules-systemjs</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17974">#17974</a>
[7.x backport]fix(systemjs): improve module string name support (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 1</h4>
<ul>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
<h2>v7.29.3 (2026-04-30)</h2>
<h4>👓 Spec Compliance</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17923">#17923</a>
Support flow extends bound (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-helper-create-class-features-plugin</code>,
<code>babel-plugin-proposal-decorators</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17931">#17931</a>
fix(decorators): replace super within all removed static elements (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-register</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17915">#17915</a> Fix
thread synchronization issues in <code>@babel/register</code> (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-compat-data</code>,
<code>babel-plugin-bugfix-safari-rest-destructuring-rhs-array</code>,
<code>babel-preset-env</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17788">#17788</a> Add
bugfix plugin for Safari array rest destructuring bug (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>💅 Polish</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17782">#17782</a>
Improve trailing comma comment handling (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>📝 Documentation</h4>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17847">#17847</a>
Replace npmjs.com links with npmx.dev (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/babel/babel/commit/04ea6b27fdac8f40c3481aec2080ac9678779509"><code>04ea6b2</code></a>
v7.29.6</li>
<li><a
href="https://github.com/babel/babel/commit/99f498a9b9fa0b900d603fbe8f6601bb3b9e42bb"><code>99f498a</code></a>
[7.x packport]Improve input source map handling (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/18001">#18001</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/feba0a3654c596bd369d1ef1231f5d56666d56dc"><code>feba0a3</code></a>
Preserve original identifier names from input sourcemaps (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17992">#17992</a>)
(<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17998">#17998</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/aa8394e454337d118ac3d40bfa3ee1a3cb3f3ed2"><code>aa8394e</code></a>
v7.29.0</li>
<li><a
href="https://github.com/babel/babel/commit/ad0d03f0c92404a60ec6b1c12f15febd38e2397a"><code>ad0d03f</code></a>
[7.x backport] feat: Allow specifying startLine in code frame (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17739">#17739</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/d7f400889567ae18ef9ac41b024b5120f6060e17"><code>d7f4008</code></a>
v7.28.6</li>
<li><a
href="https://github.com/babel/babel/commit/e130225028e93e106135586f344cfa44c4aac847"><code>e130225</code></a>
Polish(standalone): improve message on invalid preset/plugin (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17606">#17606</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/99dcba5e71de3bd81ce14077cfa5b6df58e9b177"><code>99dcba5</code></a>
chore: enable some ts-eslint rules (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17592">#17592</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/c92c4919771105140015167f25f7bacac77c90d9"><code>c92c491</code></a>
Improve Unicode handling in code-frame tokenizer (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17589">#17589</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/d725e399fd6a4da463cff4918cf71aa03b8beb14"><code>d725e39</code></a>
Add <code>BABEL_7_TO_8_DANGEROUSLY_DISABLE_VERSION_CHECK</code> (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17569">#17569</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/babel/babel/commits/v7.29.6/packages/babel-core">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for <code>@​babel/core</code> since your current version.</p>
</details>
<br />

Updates `axios` from 1.8.2 to 1.18.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/releases">axios's
releases</a>.</em></p>
<blockquote>
<h2>v1.18.0 — June 13, 2026</h2>
<p>This release hardens redirect and URL handling, improves the
validateStatus configuration semantics, and includes updates to
documentation, dependencies, and release metadata.</p>
<h2>🔒 Security Fixes</h2>
<ul>
<li>
<p><strong>Redirect Header Safety:</strong> Added Node HTTP adapter
support for stripping caller-specified sensitive headers on cross-origin
redirects, helping prevent custom auth headers such as API keys from
leaking to another origin. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10892">#10892</a></strong>)</p>
</li>
<li>
<p><strong>URL And Request Hardening:</strong> Rejects malformed
<code>http:</code> and <code>https:</code> URLs that omit
<code>//</code> with <code>ERR_INVALID_URL</code>, while tightening
prototype-pollution-safe config reads, stream size limits, FormData
depth handling, data URL sizing, and local <code>NO_PROXY</code>
matching. (<strong><a
href="https://redirect.github.com/axios/axios/issues/11000">#11000</a></strong>)</p>
</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<ul>
<li><strong>Status Validation:</strong> Added
<code>transitional.validateStatusUndefinedResolves</code> so
applications can opt in to treating <code>validateStatus:
undefined</code> like the option was omitted, while
<code>validateStatus: null</code> remains the explicit way to accept
every status. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li>
</ul>
<h2>🔧 Maintenance &amp; Chores</h2>
<ul>
<li>
<p><strong>Documentation:</strong> Published the v1.17.0 release notes,
fixed a changelog typo, clarified the package update PR policy, and
marked the <code>proxy</code> request config as Node.js-only in the
advanced docs. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10988">#10988</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10992">#10992</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</p>
</li>
<li>
<p><strong>Dependencies:</strong> Bumped <code>@babel/core</code>,
<code>@babel/preset-env</code>, <code>@commitlint/cli</code>,
<code>@commitlint/config-conventional</code>,
<code>@rollup/plugin-babel</code>, <code>@rollup/plugin-commonjs</code>,
<code>@vitest/browser</code>, <code>@vitest/browser-playwright</code>,
<code>eslint</code>, <code>lint-staged</code>, <code>rollup</code>,
<code>vitest</code>, and <code>actions/checkout</code>. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10989">#10989</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10996">#10996</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10997">#10997</a></strong>)</p>
</li>
<li>
<p><strong>Release Metadata:</strong> Prepared the 1.18.0 release by
updating package metadata and the runtime <code>VERSION</code> value.
(<strong><a
href="https://redirect.github.com/axios/axios/issues/11003">#11003</a></strong>)</p>
</li>
</ul>
<h2>🌟 New Contributors</h2>
<p>We are thrilled to welcome our new contributors. Thank you for
helping improve axios:</p>
<ul>
<li><strong><a
href="https://github.com/drori12"><code>@​drori12</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>)</li>
<li><strong><a
href="https://github.com/eyupcanakman"><code>@​eyupcanakman</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li>
<li><strong><a
href="https://github.com/Adi-Beker"><code>@​Adi-Beker</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</li>
</ul>
<p><a
href="https://github.com/axios/axios/compare/v1.17.0...v1.18.0">Full
Changelog</a></p>
<h2>v1.17.0 — June 1, 2026</h2>
<p>This release adds Node HTTP zstd decompression, hardens config and
release workflows, and fixes authentication, header, proxy, and
type-handling regressions.</p>
<h2>🔒 Security Fixes</h2>
<ul>
<li><strong>Config Hardening:</strong> Guarded <code>socketPath</code>,
<code>params</code>, and <code>paramsSerializer</code> reads with
own-property checks to prevent inherited prototype values from affecting
request behavior, including SSRF-sensitive paths. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10901">#10901</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10922">#10922</a></strong>)</li>
<li><strong>Release Publishing:</strong> Switched the publish workflow
to npm staged publishing for safer, auditable package releases with
provenance. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10926">#10926</a></strong>)</li>
</ul>
<h2>🚀 New Features</h2>
<ul>
<li><strong>HTTP Compression:</strong> Added Node HTTP adapter support
for zstd response decompression, with
<code>transitional.advertiseZstdAcceptEncoding</code> controlling
whether <code>zstd</code> is advertised in <code>Accept-Encoding</code>.
(<strong><a
href="https://redirect.github.com/axios/axios/issues/6792">#6792</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10920">#10920</a></strong>)</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<ul>
<li><strong>Authentication Handling:</strong> Restored Basic auth on
same-origin Node redirects while continuing to strip credentials
cross-origin, and aligned the fetch adapter with HTTP adapter behavior
for URL-embedded Basic auth. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10929">#10929</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10896">#10896</a></strong>)</li>
<li><strong>Proxy TLS:</strong> Preserved user <code>httpsAgent</code>
TLS options when tunneling HTTPS requests through HTTP CONNECT proxies.
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10957">#10957</a></strong>)</li>
<li><strong>React Native FormData:</strong> Cleared default
<code>Content-Type</code> for React Native <code>FormData</code> so
multipart boundaries can be generated correctly. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10898">#10898</a></strong>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's
changelog</a>.</em></p>
<blockquote>
<h2>v1.18.0 — June 13, 2026</h2>
<p>This release hardens redirect and URL handling, improves the
validateStatus configuration semantics, and includes updates to
documentation, dependencies, and release metadata.</p>
<h2>🔒 Security Fixes</h2>
<ul>
<li>
<p><strong>Redirect Header Safety:</strong> Added Node HTTP adapter
support for stripping caller-specified sensitive headers on cross-origin
redirects, helping prevent custom auth headers such as API keys from
leaking to another origin. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10892">#10892</a></strong>)</p>
</li>
<li>
<p><strong>URL And Request Hardening:</strong> Rejects malformed
<code>http:</code> and <code>https:</code> URLs that omit
<code>//</code> with <code>ERR_INVALID_URL</code>, while tightening
prototype-pollution-safe config reads, stream size limits, FormData
depth handling, data URL sizing, and local <code>NO_PROXY</code>
matching. (<strong><a
href="https://redirect.github.com/axios/axios/issues/11000">#11000</a></strong>)</p>
</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<ul>
<li><strong>Status Validation:</strong> Added
<code>transitional.validateStatusUndefinedResolves</code> so
applications can opt in to treating <code>validateStatus:
undefined</code> like the option was omitted, while
<code>validateStatus: null</code> remains the explicit way to accept
every status. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li>
</ul>
<h2>🔧 Maintenance &amp; Chores</h2>
<ul>
<li>
<p><strong>Documentation:</strong> Published the v1.17.0 release notes,
fixed a changelog typo, clarified the package update PR policy, and
marked the <code>proxy</code> request config as Node.js-only in the
advanced docs. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10988">#10988</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10992">#10992</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</p>
</li>
<li>
<p><strong>Dependencies:</strong> Bumped <code>@babel/core</code>,
<code>@babel/preset-env</code>, <code>@commitlint/cli</code>,
<code>@commitlint/config-conventional</code>,
<code>@rollup/plugin-babel</code>, <code>@rollup/plugin-commonjs</code>,
<code>@vitest/browser</code>, <code>@vitest/browser-playwright</code>,
<code>eslint</code>, <code>lint-staged</code>, <code>rollup</code>,
<code>vitest</code>, and <code>actions/checkout</code>. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10989">#10989</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10996">#10996</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10997">#10997</a></strong>)</p>
</li>
<li>
<p><strong>Release Metadata:</strong> Prepared the 1.18.0 release by
updating package metadata and the runtime <code>VERSION</code> value.
(<strong><a
href="https://redirect.github.com/axios/axios/issues/11003">#11003</a></strong>)</p>
</li>
</ul>
<h2>🌟 New Contributors</h2>
<p>We are thrilled to welcome our new contributors. Thank you for
helping improve axios:</p>
<ul>
<li><strong><a
href="https://github.com/drori12"><code>@​drori12</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>)</li>
<li><strong><a
href="https://github.com/eyupcanakman"><code>@​eyupcanakman</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li>
<li><strong><a
href="https://github.com/Adi-Beker"><code>@​Adi-Beker</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</li>
</ul>
<p><a
href="https://github.com/axios/axios/compare/v1.17.0...v1.18.0">Full
Changelog</a></p>
<h2>v1.17.0 — June 1, 2026</h2>
<p>This release adds Node HTTP zstd decompression, hardens config and
release workflows, and fixes authentication, header, proxy, and
type-handling regressions.</p>
<h2>🔒 Security Fixes</h2>
<ul>
<li><strong>Config Hardening:</strong> Guarded <code>socketPath</code>,
<code>params</code>, and <code>paramsSerializer</code> reads with
own-property checks to prevent inherited prototype values from affecting
request behavior, including SSRF-sensitive paths. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10901">#10901</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10922">#10922</a></strong>)</li>
<li><strong>Release Publishing:</strong> Switched the publish workflow
to npm staged publishing for safer, auditable package releases with
provenance. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10926">#10926</a></strong>)</li>
</ul>
<h2>🚀 New Features</h2>
<ul>
<li><strong>HTTP Compression:</strong> Added Node HTTP adapter support
for zstd response decompression, with
<code>transitional.advertiseZstdAcceptEncoding</code> controlling
whether <code>zstd</code> is advertised in <code>Accept-Encoding</code>.
(<strong><a
href="https://redirect.github.com/axios/axios/issues/6792">#6792</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10920">#10920</a></strong>)</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<ul>
<li><strong>Authentication Handling:</strong> Restored Basic auth on
same-origin Node redirects while continuing to strip credentials
cross-origin, and aligned the fetch adapter with HTTP adapter behavior
for URL-embedded Basic auth. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10929">#10929</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10896">#10896</a></strong>)</li>
<li><strong>Proxy TLS:</strong> Preserved user <code>httpsAgent</code>
TLS options when tunneling HTTPS requests through HTTP CONNECT proxies.
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10957">#10957</a></strong>)</li>
<li><strong>React Native FormData:</strong> Cleared default
<code>Content-Type</code> for React Native <code>FormData</code> so
multipart boundaries can be generated correctly. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10898">#10898</a></strong>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/axios/axios/commit/2d06f96e8602c2db13b65a26340ee4a1bbc0b61f"><code>2d06f96</code></a>
chore(release): prepare release 1.18.0 (<a
href="https://redirect.github.com/axios/axios/issues/11003">#11003</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/32fc489632377d214db55bfa4e2c48486a7d7ce2"><code>32fc489</code></a>
fix: malformed http urls (<a
href="https://redirect.github.com/axios/axios/issues/11000">#11000</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/b40ce498abfa10d90b873b4fd08f520afa5d2545"><code>b40ce49</code></a>
chore(deps-dev): bump the development_dependencies group with 10 updates
(<a
href="https://redirect.github.com/axios/axios/issues/10">#10</a>...</li>
<li><a
href="https://github.com/axios/axios/commit/fe964f960ecb52c3e1155b0daf7be77541956b01"><code>fe964f9</code></a>
docs: mark proxy config as Node.js only (<a
href="https://redirect.github.com/axios/axios/issues/10995">#10995</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/5f229d2d1f018d1db3dab6bbe034dbf3f9041b99"><code>5f229d2</code></a>
chore(deps): bump actions/checkout from 6.0.2 to 6.0.3 in the
github-actions ...</li>
<li><a
href="https://github.com/axios/axios/commit/fae9d4e7db6a858c407c75e607a071c533c5c4f6"><code>fae9d4e</code></a>
docs: clarify package update PR policy (<a
href="https://redirect.github.com/axios/axios/issues/10992">#10992</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/28ab2ced820e55192806c53472ab3eb0cbb68dc2"><code>28ab2ce</code></a>
chore(deps-dev): bump the development_dependencies group with 2 updates
(<a
href="https://redirect.github.com/axios/axios/issues/10989">#10989</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/a8e4f13aeecc45a3b8fab3ecfd9ddb5d70fb772b"><code>a8e4f13</code></a>
fix(core): keep default validateStatus when request passes undefined (<a
href="https://redirect.github.com/axios/axios/issues/10899">#10899</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/614f4552a17de757d4171ad7c3bd38c9c1025fd8"><code>614f455</code></a>
docs: publish v1.17.0 release notes (<a
href="https://redirect.github.com/axios/axios/issues/10988">#10988</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/6bb12c191f5380fad321322fb90216ae0dc36985"><code>6bb12c1</code></a>
fix: custom auth headers not stripped on cross-origin redirects (<a
href="https://redirect.github.com/axios/axios/issues/10892">#10892</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/axios/axios/compare/v1.8.2...v1.18.0">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for axios since your current version.</p>
</details>
<details>
<summary>Install script changes</summary>
<p>This version modifies <code>prepare</code> script that runs during
installation. Review the package contents before updating.</p>
</details>
<br />

Updates `dompurify` from 3.2.4 to 3.4.13
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cure53/DOMPurify/releases">dompurify's
releases</a>.</em></p>
<blockquote>
<h2>DOMPurify 3.4.13</h2>
<ul>
<li>Fixed an issue with hook removal during <code>IN_PLACE</code>
sanitization, thanks <a
href="https://github.com/koyokr"><code>@​koyokr</code></a></li>
<li>Fixed an issue with hooks potentially bypassing the clone guard,
thanks <a
href="https://github.com/AkshayjainG"><code>@​AkshayjainG</code></a></li>
<li>Fixed an issue with DOM clobbering via <code>ownerDocument</code>
during <code>IN_PLACE</code>, thanks <a
href="https://github.com/AkshayjainG"><code>@​AkshayjainG</code></a></li>
<li>Bumped several dependencies where possible</li>
</ul>
<h2>DOMPurify 3.4.12</h2>
<ul>
<li>Fixed an issue where a hook would not get called for custom
elements, thanks <a
href="https://github.com/Rikuxx0"><code>@​Rikuxx0</code></a></li>
<li>Hardened the handling of hooks removing elements, <a
href="https://github.com/mkrause-bee360"><code>@​mkrause-bee360</code></a></li>
<li>Added support for a few new SVG attributes, thanks <a
href="https://github.com/cbn-falias"><code>@​cbn-falias</code></a> &amp;
<a
href="https://github.com/Develop-KIM"><code>@​Develop-KIM</code></a></li>
<li>Hardened the handling of declarative partial updates</li>
<li>Updated the documentation is several spots, README, wiki, etc.</li>
<li>Bumped several dependencies where possible</li>
</ul>
<h2>DOMPurify 3.4.11</h2>
<ul>
<li>Fixed an issue with a leaky config for hooks via
<code>setConfig</code>, thanks <a
href="https://github.com/trace37labs"><code>@​trace37labs</code></a></li>
<li>Bumped vulnerable development dependencies to arrive at plain 0 with
<code>npm audit</code></li>
<li>Updated the <code>osv-scanner</code> suppression list as no
vulnerable dependencies are left for now</li>
<li>Updated up the linting tool-chain and removed now-redundant lint
directives</li>
<li>Updated the documentation is several spots, README, wiki, etc.</li>
<li>Bumped several dependencies where possible</li>
</ul>
<h2>DOMPurify 3.4.10</h2>
<ul>
<li>Refactored codebase for clarity: extracted the public type
declarations into <code>types.ts</code></li>
<li>Decomposed the three largest sanitizer functions into focused
helpers</li>
<li>Removed duplicated defaults and dead branches, consolidated
<code>SAFE_FOR_TEMPLATES</code> scrubbing into single shared path</li>
<li>Improved per-node performance by hoisting the mXSS probe regexes and
testing <code>textContent</code> before <code>innerHTML</code></li>
<li>Added a deterministic micro-benchmark harness (<code>npm run
bench</code>) with a <code>--compare</code> mode</li>
<li>Reduced CI cost by running the full three-engine browser suite once
per PR</li>
<li>Refreshed the <code>demos/</code> folder so every demo runs again,
and added a SVG-via-<code>&lt;img&gt;</code> demo</li>
<li>Documented the bench and <code>test:happydom</code> scripts in the
README</li>
<li>Completed the Attack Classes &amp; Bypass History wiki page</li>
<li>Bumped several dependencies where possible</li>
</ul>
<h2>DOMPurify 3.4.9</h2>
<ul>
<li>Further improved the handling of Trusted Types config options,
thanks <a
href="https://github.com/offset"><code>@​offset</code></a></li>
<li>Further improved the handling of <code>IN_PLACE</code> sanitization,
thanks <a
href="https://github.com/mozfreddyb"><code>@​mozfreddyb</code></a></li>
<li>Added more test coverage for <code>IN_PLACE</code> and Trusted Types
related usage</li>
<li>Bumped several dependencies where possible</li>
<li>Updated README and wiki with more accurate documentation &amp;
attack samples</li>
</ul>
<h2>DOMPurify 3.4.8</h2>
<ul>
<li>Cleaned up the repository root, renamed some and removed unneeded
files</li>
<li>Fixed an issue with handling of Trusted Types policies, thanks <a
href="https://github.com/fulstadev"><code>@​fulstadev</code></a></li>
<li>Fixed the node iterator for better template scrubbing, thanks <a
href="https://github.com/IamLeandrooooo"><code>@​IamLeandrooooo</code></a></li>
<li>Included formerly missing LICENSE-MPL in published npm package,
thanks <a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a></li>
<li>Bumped several dependencies where possible</li>
</ul>
<h2>DOMPurify 3.4.7</h2>
<ul>
<li>Hardened the handling of Shadow Roots when using
<code>IN_PLACE</code>, thanks <a
href="https://github.com/GameZoneHacker"><code>@​GameZoneHacker</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/cure53/DOMPurify/commit/3067f774676975de12306effd6db6ad7a9a8c17f"><code>3067f77</code></a>
release: 3.4.13 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1562">#1562</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/a9ca1e537422319a557a9a2aa61f003b23b4a197"><code>a9ca1e5</code></a>
release: 3.4.12 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1537">#1537</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/0cae5187403132f96a6d357649e4b15633fc210a"><code>0cae518</code></a>
release: 3.4.11 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1494">#1494</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/6ee5716f8336989753611beeca364957c0eb0c3e"><code>6ee5716</code></a>
release: 3.4.10 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1478">#1478</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/52102472d46035857c52df19e44285f8a1e102fc"><code>5210247</code></a>
release: 3.4.9 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1459">#1459</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/bcdd8285412dc9c4c149652aed2d712e790d6ccf"><code>bcdd828</code></a>
release: 3.4.8 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1439">#1439</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/ca30f070c360df162a3e3848e80e6fd3c9e74bff"><code>ca30f07</code></a>
release: 3.4.7 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1414">#1414</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/bb7739e5bccec7e1ab3dae3f3e42d02db3acaaae"><code>bb7739e</code></a>
release: 3.4.6 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1394">#1394</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/011b0c78f2a0f57ee54f5fcccb697a46ca6e63ea"><code>011b0c7</code></a>
release: 3.4.5 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1382">#1382</a>)</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/5817ad969c15e67dfcd6cb37248d6e9c1553e7c3"><code>5817ad9</code></a>
release: 3.4.4 (<a
href="https://redirect.github.com/cure53/DOMPurify/issues/1374">#1374</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/cure53/DOMPurify/compare/3.2.4...3.4.13">compare
view</a></li>
</ul>
</details>
<details>
<summary>Install script changes</summary>
<p>This version adds <code>prepare</code> script that runs during
installation. Review the package contents before updating.</p>
</details>
<br />

Updates `postcss` from 8.5.3 to 8.5.23
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/releases">postcss's
releases</a>.</em></p>
<blockquote>
<h2>8.5.23</h2>
<ul>
<li>Do not load source map without <code>opts.from</code> for security
reasons.</li>
</ul>
<h2>8.5.22</h2>
<ul>
<li>Fixed custom property losing semicolon before a comment (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
</ul>
<h2>8.5.21</h2>
<ul>
<li>Fixed childless at-rule losing semicolon before comment (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed docs (by <a
href="https://github.com/isker"><code>@​isker</code></a>).</li>
</ul>
<h2>8.5.20</h2>
<ul>
<li>Fixed missing space if <code>AtRule#params</code> is set after (by
<a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed mixing AST error on warnings (by <a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
</ul>
<h2>8.5.19</h2>
<ul>
<li>Fixed cleaning <code>before</code> for new nodes inserted to
<code>Root</code> (by <a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
</ul>
<h2>8.5.18</h2>
<ul>
<li>Restricted loading previous source maps file to the
<code>opts.from</code> folder for security reasons (use <code>unsafeMap:
true</code> to disable the check).</li>
</ul>
<h2>8.5.17</h2>
<ul>
<li>Fixed <code>Maximum call stack size exceeded</code> error.</li>
<li>Fixed Prototype hijacking for <code>postcss.fromJSON()</code>.</li>
<li>Fixed <code>Input#origin()</code> for unmapped end position (by <a
href="https://github.com/chatman-media"><code>@​chatman-media</code></a>).</li>
</ul>
<h2>8.5.16</h2>
<ul>
<li>Fixed <code>Input#origin()</code> position (by <a
href="https://github.com/mizdra"><code>@​mizdra</code></a>).</li>
<li>Fixed <code>raws</code> after rehydrating a JSON AST (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed putting parent-less node in <code>nodes</code> of new node (by
<a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
<li>Fixed computing <code>offset</code> in <code>positionBy()</code> (by
<a
href="https://github.com/greymoth-jp"><code>@​greymoth-jp</code></a>).</li>
<li>Fixed <code>rangeBy()</code> on <code>index: 0</code> (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
</ul>
<h2>8.5.15</h2>
<ul>
<li>Fixed declaration parsing performance (by <a
href="https://github.com/homanp"><code>@​homanp</code></a>).</li>
</ul>
<h2>8.5.14</h2>
<ul>
<li>Fixed custom syntax regression (by <a
href="https://github.com/43081j"><code>@​43081j</code></a>).</li>
</ul>
<h2>8.5.13</h2>
<ul>
<li>Fixed <code>postcss-scss</code> commend regression.</li>
</ul>
<h2>8.5.12</h2>
<ul>
<li>Fixed reading any file via user-generated CSS.</li>
<li>Added <code>opts.unsafeMap</code> to disable checks.</li>
</ul>
<h2>8.5.11</h2>
<ul>
<li>Fixed nested brackets parsing performance (by <a
href="https://github.com/offset"><code>@​offset</code></a>).</li>
</ul>
<h2>8.5.10</h2>
<ul>
<li>Fixed XSS via unescaped <code>&lt;/style&gt;</code> in non-bundler
cases (by <a
href="https://github.com/TharVid"><code>@​TharVid</code></a>).</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/blob/main/CHANGELOG.md">postcss's
changelog</a>.</em></p>
<blockquote>
<h2>8.5.23</h2>
<ul>
<li>Do not load source map without <code>opts.from</code> for security
reasons.</li>
</ul>
<h2>8.5.22</h2>
<ul>
<li>Fixed custom property losing semicolon before a comment (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
</ul>
<h2>8.5.21</h2>
<ul>
<li>Fixed childless at-rule losing semicolon before comment (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed docs (by <a
href="https://github.com/isker"><code>@​isker</code></a>).</li>
</ul>
<h2>8.5.20</h2>
<ul>
<li>Fixed missing space if <code>AtRule#params</code> is set after (by
<a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed mixing AST error on warnings (by <a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
</ul>
<h2>8.5.19</h2>
<ul>
<li>Fixed cleaning <code>before</code> for new nodes inserted to
<code>Root</code> (by <a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
</ul>
<h2>8.5.18</h2>
<ul>
<li>Restricted loading previous source maps file to the
<code>opts.from</code> folder for security reasons (use <code>unsafeMap:
true</code> to disable the check).</li>
</ul>
<h2>8.5.17</h2>
<ul>
<li>Fixed <code>Maximum call stack size exceeded</code> error.</li>
<li>Fixed Prototype hijacking for <code>postcss.fromJSON()</code>.</li>
<li>Fixed <code>Input#origin()</code> for unmapped end position (by <a
href="https://github.com/chatman-media"><code>@​chatman-media</code></a>).</li>
</ul>
<h2>8.5.16</h2>
<ul>
<li>Fixed <code>Input#origin()</code> position (by <a
href="https://github.com/mizdra"><code>@​mizdra</code></a>).</li>
<li>Fixed <code>raws</code> after rehydrating a JSON AST (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed putting parent-less node in <code>nodes</code> of new node (by
<a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
<li>Fixed computing <code>offset</code> in <code>positionBy()</code> (by
<a
href="https://github.com/greymoth-jp"><code>@​greymoth-jp</code></a>).</li>
<li>Fixed <code>rangeBy()</code> on <code>index: 0</code> (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
</ul>
<h2>8.5.15</h2>
<ul>
<li>Fixed declaration parsing performance (by <a
href="https://github.com/homanp"><code>@​homanp</code></a>).</li>
</ul>
<h2>8.5.14</h2>
<ul>
<li>Fixed custom syntax regression (by <a
href="https://github.com/43081j"><code>@​43081j</code></a>).</li>
</ul>
<h2>8.5.13</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/postcss/postcss/commit/eb9e1fe793740bb3280bdf5bf98147f857f011bd"><code>eb9e1fe</code></a>
Release 8.5.23 version</li>
<li><a
href="https://github.com/postcss/postcss/commit/9d19c78ac91108b3f7d7130e55c6fa806c0efb84"><code>9d19c78</code></a>
Update dependencies</li>
<li><a
href="https://github.com/postcss/postcss/commit/7beca139e70f9075c6b19700fcb00dd8033e5da8"><code>7beca13</code></a>
Does no load source map file without opts.from</li>
<li><a
href="https://github.com/postcss/postcss/commit/decea51421682341401575b3740709fda0e12930"><code>decea51</code></a>
Typo</li>
<li><a
href="https://github.com/postcss/postcss/commit/c18e30d126395d42a0726aa00e03a8f1088985ae"><code>c18e30d</code></a>
Update EM banner</li>
<li><a
href="https://github.com/postcss/postcss/commit/98a39ad73d163a90be924d5126c771262110f1fc"><code>98a39ad</code></a>
Update EM banner</li>
<li><a
href="https://github.com/postcss/postcss/commit/a3e48c492ddec0e4879d513b8b995fee887af352"><code>a3e48c4</code></a>
Release 8.5.22 version</li>
<li><a
href="https://github.com/postcss/postcss/commit/f49d6911795f53b2cfe023bb686bf1144ec30618"><code>f49d691</code></a>
Fix custom property losing its semicolon before a comment (<a
href="https://redirect.github.com/postcss/postcss/issues/2117">#2117</a>)</li>
<li><a
href="https://github.com/postcss/postcss/commit/28e0daf8f2fe5ba9e19ea3f8c27c8fe176f9419e"><code>28e0daf</code></a>
Release 8.5.21 version</li>
<li><a
href="https://github.com/postcss/postcss/commit/3d2b4e43e38274f233b5609d09687cadad8215d9"><code>3d2b4e4</code></a>
Update dependencies</li>
<li>Additional commits viewable in <a
href="https://github.com/postcss/postcss/compare/8.5.3...8.5.23">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for postcss since your current version.</p>
</details>
<br />

Updates `mongoose` from 8.9.5 to 8.24.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Automattic/mongoose/releases">mongoose's
releases</a>.</em></p>
<blockquote>
<h2>8.24.1</h2>
<ul>
<li>fix(documentarray): reindex subdocs after array reordering and
removal so subsequent nested changes save using the correct path <a
href="https://redirect.github.com/Automattic/mongoose/issues/16282">#16282</a>
<a href="https://github.com/AbdelrahmanHafez">AbdelrahmanHafez</a></li>
<li>fix(document): avoid accessing special properties in
<code>Document.prototype.get()</code></li>
<li>fix(schema): avoid returning inherited properties from schema path
lookups, including paths underneath maps of subdocuments</li>
<li>fix(clone): isolate cloned arrays from source documents <a
href="https://redirect.github.com/Automattic/mongoose/issues/16281">#16281</a>
<a href="https://github.com/AbdelrahmanHafez">AbdelrahmanHafez</a></li>
<li>types: enable exactOptionalPropertyTypes in TypeScript tests <a
href="https://redirect.github.com/Automattic/mongoose/issues/16287">#16287</a></li>
</ul>
<h1>8.24.0 / 2026-05-14</h1>
<ul>
<li>feat(aggregate): add pipelineForUnionWith() helper to allow reusing
pipelines with $unionWith in TypeScript <a
href="https://redirect.github.com/Automattic/mongoose/issues/16247">#16247</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16041">#16041</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16033">#16033</a></li>
<li>fix(connection): handle calling watch() on disconnected connection
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16246">#16246</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16034">#16034</a></li>
<li>types: handle compiling with exactOptionalPropertyTypes <a
href="https://redirect.github.com/Automattic/mongoose/issues/16286">#16286</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16273">#16273</a></li>
</ul>
<h1>8.23.1 / 2026-04-23</h1>
<ul>
<li>fix(model): support sort option in Model.bulkWrite() updateOne and
replaceOne operations <a
href="https://redirect.github.com/Automattic/mongoose/issues/16091">#16091</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16079">#16079</a></li>
<li>fix(setDefaultsOnInsert): check child filter paths before applying
defaults (backport <a
href="https://redirect.github.com/Automattic/mongoose/issues/16031">#16031</a>
to 8.x) <a
href="https://redirect.github.com/Automattic/mongoose/issues/16219">#16219</a>
<a href="https://github.com/marklai1998">marklai1998</a></li>
<li>fix(schema): always pass raw string value to error validators, only
trim to 30 chars for maxlength validator <a
href="https://redirect.github.com/Automattic/mongoose/issues/16238">#16238</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16236">#16236</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15550">#15550</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15571">#15571</a></li>
</ul>
<h1>8.23.0 / 2026-02-09</h1>
<ul>
<li>feat(document): add flattenUUIDs option to toObject() and toJSON()
(backport <a
href="https://redirect.github.com/Automattic/mongoose/issues/15021">#15021</a>
to 8.x)</li>
</ul>
<h1>8.22.1 / 2025-02-04</h1>
<ul>
<li>fix: handle other top-level query operators in sanitizeFilter</li>
<li>fix(document): when cloning a doc with subdocs, make sure the
subdocs parent is the cloned doc <a
href="https://redirect.github.com/Automattic/mongoose/issues/15904">#15904</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15901">#15901</a></li>
<li>types(models): support Mongoose query casting in
AnyBulkWriteOperation filter property <a
href="https://redirect.github.com/Automattic/mongoose/issues/15910">#15910</a></li>
<li>types: add toBSON() to documents <a
href="https://redirect.github.com/Automattic/mongoose/issues/15927">#15927</a></li>
</ul>
<h1>8.22.0 / 2026-01-27</h1>
<ul>
<li>feat(model): allow passing strict option to hydrate() <a
href="https://redirect.github.com/Automattic/mongoose/issues/15944">#15944</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15940">#15940</a></li>
</ul>
<h2>8.21.1</h2>
<ul>
<li>fix(clone): fix parent doc for map subdocuments and array
subdocuments <a
href="https://redirect.github.com/Automattic/mongoose/issues/15958">#15958</a>
<a href="https://github.com/AbdelrahmanHafez">AbdelrahmanHafez</a></li>
<li>fix(document): when cloning a doc with subdocs, make sure the
subdocs parent is the cloned doc <a
href="https://redirect.github.com/Automattic/mongoose/issues/15904">#15904</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15901">#15901</a></li>
<li>fix: respect currentTime schema option in bulkWrite updates <a
href="https://redirect.github.com/Automattic/mongoose/issues/15976">#15976</a>
<a href="https://github.com/sderrow">sderrow</a></li>
<li>types(models): support Mongoose query casting in
AnyBulkWriteOperation filter property <a
href="https://redirect.github.com/Automattic/mongoose/issues/15910">#15910</a></li>
<li>types: add toBSON() to documents <a
href="https://redirect.github.com/Automattic/mongoose/issues/15927">#15927</a></li>
</ul>
<h1>8.21.0 / 2025-12-29</h1>
<ul>
<li>feat(document): add support for getAtomics() to allow custom
container types to utilize atomics <a
href="https://redirect.github.com/Automattic/mongoose/issues/15817">#15817</a></li>
<li>feat(document+model): pass options to pre('deleteOne') and
update+options to pre('updateOne') hooks <a
href="https://redirect.github.com/Automattic/mongoose/issues/15908">#15908</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15870">#15870</a></li>
<li>fix: add support for typescript style enums <a
href="https://redirect.github.com/Automattic/mongoose/issues/15914">#15914</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15913">#15913</a>
<a href="https://github.com/mjfwebb">mjfwebb</a></li>
</ul>
<h1>8.20.4 / 2025-12-18</h1>
<ul>
<li>fix(model): ensure $isDeleted is set after calling doc.deleteOne()
successfully <a
href="https://redirect.github.com/Automattic/mongoose/issues/15898">#15898</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md">mongoose's
changelog</a>.</em></p>
<blockquote>
<h1>8.24.1 / 2026-06-22</h1>
<ul>
<li>fix(documentarray): reindex subdocs after array reordering and
removal so subsequent nested changes save using the correct path <a
href="https://redirect.github.com/Automattic/mongoose/issues/16282">#16282</a>
<a href="https://github.com/AbdelrahmanHafez">AbdelrahmanHafez</a></li>
<li>fix(document): avoid accessing special properties in
<code>Document.prototype.get()</code></li>
<li>fix(schema): avoid returning inherited properties from schema path
lookups, including paths underneath maps of subdocuments</li>
<li>fix(clone): isolate cloned arrays from source documents <a
href="https://redirect.github.com/Automattic/mongoose/issues/16281">#16281</a>
<a href="https://github.com/AbdelrahmanHafez">AbdelrahmanHafez</a></li>
<li>types: enable exactOptionalPropertyTypes in TypeScript tests <a
href="https://redirect.github.com/Automattic/mongoose/issues/16287">#16287</a></li>
</ul>
<h1>9.7.2 / 2026-06-22</h1>
<ul>
<li>fix(documentarray): reindex subdocs after array reordering and
removal so subsequent nested changes save using the correct path <a
href="https://redirect.github.com/Automattic/mongoose/issues/16282">#16282</a>
<a href="https://github.com/AbdelrahmanHafez">AbdelrahmanHafez</a></li>
<li>fix(document): avoid accessing special properties in
<code>Document.prototype.get()</code></li>
<li>fix(schema): only return own properties in schematype lookups and
disallow setting schema paths under special properties</li>
<li>docs: update homepage sponsor layout</li>
</ul>
<h1>9.7.1 / 2026-06-17</h1>
<ul>
<li>perf(document+model): improve save performance by avoiding
unnecessary promise allocations and reducing path/default/dirty-state
overhead <a
href="https://redirect.github.com/Automattic/mongoose/issues/16331">#16331</a></li>
<li>fix(schema): include ObjectId regex pattern in
<code>toJSONSchema()</code> output <a
href="https://redirect.github.com/Automattic/mongoose/issues/16335">#16335</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16334">#16334</a>
<a href="https://github.com/AbdelrahmanHafez">AbdelrahmanHafez</a></li>
<li>fix(populate): split populate into separate queries per document if
the resulting <code>$in</code> filter has more than 50k elements to
reduce risk of BSON size errors <a
href="https://redirect.github.com/Automattic/mongoose/issues/16333">#16333</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/5890">#5890</a></li>
<li>docs: add assistant sidebar with MongoDB Knowledge integration <a
href="https://redirect.github.com/Automattic/mongoose/issues/16311">#16311</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16283">#16283</a></li>
<li>docs: update docs copy buttons, edit links, homepage alignment, and
<code>llms.txt</code> generation <a
href="https://redirect.github.com/Automattic/mongoose/issues/16326">#16326</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16327">#16327</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16329">#16329</a></li>
</ul>
<h1>9.7.0 / 2026-06-09</h1>
<ul>
<li>feat: add Node.js TracingChannel support for APM instrumentation <a
href="https://redirect.github.com/Automattic/mongoose/issues/16275">#16275</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16105">#16105</a>
<a href="https://github.com/logaretm">logaretm</a></li>
<li>feat(model): add standard schema adapter for models <a
href="https://redirect.github.com/Automattic/mongoose/issues/16308">#16308</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16280">#16280</a></li>
<li>fix(cursor): avoid waiting on buffering to run aggregation
middleware <a
href="https://redirect.github.com/Automattic/mongoose/issues/16289">#16289</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16284">#16284</a></li>
<li>fix(document): throw error if overwriting array selected with
<code>$slice</code> <a
href="https://redirect.github.com/Automattic/mongoose/issues/16313">#16313</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/2432">#2432</a></li>
<li>fix(schema): remove <code>validateSync()</code> union fallback <a
href="https://redirect.github.com/Automattic/mongoose/issues/16310">#16310</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16291">#16291</a>
<a href="https://github.com/AbdelrahmanHafez">AbdelrahmanHafez</a></li>
<li>types: cast primitive types within unions when applying create
casting <a
href="https://redirect.github.com/Automattic/mongoose/issues/16320">#16320</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16316">#16316</a></li>
<li>docs: add <code>llms.txt</code> <a
href="https://redirect.github.com/Automattic/mongoose/issues/16312">#16312</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15687">#15687</a></li>
<li>docs: rewrite documents docs <a
href="https://redirect.github.com/Automattic/mongoose/issues/16298">#16298</a></li>
<li>docs(model): clarify some details on <code>model.validate()</code>
casting <a
href="https://redirect.github.com/Automattic/mongoose/issues/16308">#16308</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16280">#16280</a></li>
<li>docs(findOneAndUpdate): clarify update handling of undefined <a
href="https://redirect.github.com/Automattic/mongoose/issues/16299">#16299</a></li>
<li>docs(model): fix link to be absolute <a
href="https://redirect.github.com/Automattic/mongoose/issues/16321">#16321</a>
<a href="https://github.com/hasezoey">hasezoey</a></li>
</ul>
<h1>9.6.3 / 2026-05-27</h1>
<ul>
<li>fix(clone): isolate cloned arrays from source documents <a
href="https://redirect.github.com/Automattic/mongoose/issues/16281">#16281</a>
<a href="https://github.com/AbdelrahmanHafez">AbdelrahmanHafez</a></li>
<li>fix(update): preserve user-provided
<code>$setOnInsert.createdAt</code> with <code>overwriteImmutable:
true</code> <a
href="https://redirect.github.com/Automattic/mongoose/issues/16278">#16278</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15781">#15781</a>
<a href="https://github.com/AbdelrahmanHafez">AbdelrahmanHafez</a></li>
<li>fix(schema): always pass raw string value to error validators, only
trim to 30 chars for maxlength validator <a
href="https://redirect.github.com/Automattic/mongoose/issues/16238">#16238</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16236">#16236</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15550">#15550</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15571">#15571</a></li>
<li>types: add <code>$percentile</code> to TypeScript aggregation
expression types <a
href="https://redirect.github.com/Automattic/mongoose/issues/16290">#16290</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16288">#16288</a></li>
<li>docs: update default pool sizes on createConnection() <a
href="https://redirect.github.com/Automattic/mongoose/issues/16295">#16295</a>
<a href="https://github.com/torbiak-samdesk">torbiak-samdesk</a></li>
<li>docs: improve code block copy button behavior and sidebar scrolling
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16294">#16294</a>
<a href="https://github.com/DraXx-Van">DraXx-Van</a></li>
<li>docs: remove broken link to deleted schema example <a
href="https://redirect.github.com/Automattic/mongoose/issues/16297">#16297</a>
<a href="https://github.com/kaseken">kaseken</a></li>
</ul>
<h1>8.24.0 / 2026-05-14</h1>
<ul>
<li>feat(aggregate): add pipelineForUnionWith() helper to allow reusing
pipelines with $unionWith in TypeScript <a
href="https://redirect.github.com/Automattic/mongoose/issues/16247">#16247</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16041">#16041</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/16033">#16033</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/Automattic/mongoose/commit/d5dd19e1dae8dd70f39eae357357f63dcb54055e"><code>d5dd19e</code></a>
chore: release 8.24.1</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/0c346a4047faccb2015f2fd6490e4bab5d249149"><code>0c346a4</code></a>
fix(documentarray): reindex subdocs after reordering (<a
href="https://redirect.github.com/Automattic/mongoose/issues/16282">#16282</a>)</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/550b8037a276accb242495b31e6d9446720bdd49"><code>550b803</code></a>
fix(document): additional defensive checks in
Document.prototype.get()</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/953d085bee5a16b5d6c5af33a156e6314d6d9a45"><code>953d085</code></a>
fix(schema): only return own properties in schematype lookups</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/1e1679f3193cf952edf40e3c07b91a7191ef9612"><code>1e1679f</code></a>
types: use exactOptionalPropertyTypes in tests (<a
href="https://redirect.github.com/Automattic/mongoose/issues/16287">#16287</a>)</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/051b095f8d4daff4bcc266668e4f293d53bffea7"><code>051b095</code></a>
fix(clone): isolate cloned arrays from source documents (<a
href="https://redirect.github.com/Automattic/mongoose/issues/16281">#16281</a>)</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/89ca7f2d432422fdacfceb9125a6a879cef8a7d8"><code>89ca7f2</code></a>
chore: release 8.24.0</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/6922aa4520a5b4082be0f243109b0a0b4978476d"><code>6922aa4</code></a>
Merge pull request <a
href="https://redirect.github.com/Automattic/mongoose/issues/16286">#16286</a>
from Automattic/vkarpov15/gh-16273-8x</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/4295effda92d560cd5f5cdb0472c17697ddde927"><code>4295eff</code></a>
types: handle compiling with exactOptionalPropertyTypes</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/f712fdbbb400e76c305b9352ade4080094103f35"><code>f712fdb</code></a>
Merge pull request <a
href="https://redirect.github.com/Automattic/mongoose/issues/16246">#16246</a>
from Automattic/vkarpov15/<a
href="https://redirect.github.com/Automattic/mongoose/issues/16034">gh-16034</a></li>
<li>Additional commits viewable in <a
href="https://github.com/Automattic/mongoose/compare/8.9.5...8.24.1">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for mongoose since your current version.</p>
</details>
<br />

Updates `@babel/plugin-transform-modules-systemjs` from 7.23.9 to 7.29.8
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/babel/babel/releases">@​babel/plugin-transform-modules-systemjs's
releases</a>.</em></p>
<blockquote>
<h2>v7.29.8 (2026-07-31)</h2>
<h4>👓 Spec Compliance</h4>
<ul>
<li><code>babel-generator</code>, <code>babel-parser</code>,
<code>babel-plugin-transform-spread</code>, <code>babel-traverse</code>,
<code>babel-types</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17871">#17871</a>
Disallow super call after new (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/18046">#18046</a>
fix(generator): improve new callee parens check (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-node</code>,
<code>babel-plugin-transform-modules-systemjs</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/18044">#18044</a>
fix(systemjs): support <code>__proto__</code> as an export name (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 2</h4>
<ul>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
<li>Nicolò Ribaudo (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
<h2>v7.29.7 (2026-05-25)</h2>
<p>Re-release all packages with npm provenance attestations</p>
<h2>v7.29.6 (2026-05-25)</h2>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/18014">#18014</a>
Catchup source map position in preserveFormat (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/18001">#18001</a>
[7.x packport]Improve input source map handling (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>, <code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17998">#17998</a>
Preserve original identifier names from input sourcemaps (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs/issues/17992">#17992</a>)
(<a href="https://github.com/Andarist"><code>@​Andarist</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 3</h4>
<ul>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
<li>Mateusz Burzyński (<a
href="https://github.com/Andarist"><code>@​Andarist</code></a>)</li>
<li>Nicolò Ribaudo (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
<h2>v7.29.5 (2026-05-05)</h2>
<h4>🏠  Internal</h4>
<ul>
<li><code>babel-preset-env</code>
<ul>
<li>Update <code>@babel/*</code> dependencies</li>
</ul>
</li>
</ul>
<h2>v7.29.4 (2026-05-05)</h2>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-plugin-transform-modules-systemjs</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17974">#17974</a>
[7.x backport]fix(systemjs): improve module string name support (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 1</h4>
<ul>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/babel/babel/commit/5de11ca9234379b78ef95df72aebbec93f28bf45"><code>5de11ca</code></a>
v7.29.8</li>
<li><a
href="https://github.com/babel/babel/commit/f08d4342e1f189a56e7cee46e60a1817af96219e"><code>f08d434</code></a>
fix(systemjs): support <strong>proto</strong> as an export name (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs/issues/18044">#18044</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/4fba7541180bf5f58256d8e358b544e3831ad090"><code>4fba754</code></a>
v7.29.7</li>
<li><a
href="https://github.com/babel/babel/commit/a458f66074b97d54773db8159af673d23b26079b"><code>a458f66</code></a>
v7.29.4</li>
<li><a
href="https://github.com/babel/babel/commit/32ebd5aaf2526ddd176fd6a3d1e3dc594abdc8d9"><code>32ebd5a</code></a>
[7.x backport]fix(systemjs): improve module string name support (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs/issues/17974">#17974</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/aa8394e454337d118ac3d40bfa3ee1a3cb3f3ed2"><code>aa8394e</code></a>
v7.29.0</li>
<li><a
href="https://github.com/babel/babel/commit/0053db620c05acf0036f593b5aaf4e372daa79d0"><code>0053db6</code></a>
Update polyfill packages (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs/issues/17727">#17727</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/61647ae2397c82c3c71f077b5ab109106a5cac0f"><code>61647ae</code></a>
v7.28.5</li>
<li><a
href="https://github.com/babel/babel/commit/a177d551adba99773f4ff00ea9bf46550def6132"><code>a177d55</code></a>
[Babel 8] Use <code>t.traverseFast</code> to replace some
<code>path.traverse</code> (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs/issues/17518">#17518</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/eebd3a06021c13d335b5b0bd79734df3abbea678"><code>eebd3a0</code></a>
v7.27.1</li>
<li>Additional commits viewable in <a
href="https://github.com/babel/babel/commits/v7.29.8/packages/babel-plugin-transform-modules-systemjs">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for <code>@​babel/plugin-transform-modules-systemjs</code>
since your current version.</p>
</details>
<br />

Updates `browserslist` from 4.23.0 to 4.29.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/browserslist/browserslist/releases">browserslist's
releases</a>.</em></p>
<blockquote>
<h2>4.29.1</h2>
<ul>
<li>Fixed config name loading protection on Windows (by <a
href="https://github.com/oss-security-shop"><code>@​oss-security-shop</code></a>).</li>
<li>Fixed case-insensitive negation queries (by <a
href="https://github.com/jakezwang"><code>@​jakezwang</code></a>).</li>
<li>Fixed percentage and supports queries case-insensitive (by <a
href="https://github.com/wahidrizka"><code>@​wahidrizka</code></a>).</li>
<li>Fixed old Node.js tests (by <a
href="https://github.com/aaron-belenky"><code>@​aaron-belenky</code></a>).</li>
<li>Reduced code (by <a
href="https://github.com/charmander"><code>@​charmander</code></a>).</li>
</ul>
<h2>4.29.0</h2>
<ul>
<li>Added query continuations across lines and array entries (by <a
href="https://github.com/fzlzjerry"><code>@​fzlzjerry</code></a>).</li>
</ul>
<h2>4.28.9</h2>
<ul>
<li>Improve <code>or</code> parsing performance (by <a
href="https://github.com/NotAFlightRisk"><code>@​NotAFlightRisk</code></a>).</li>
</ul>
<h2>4.28.8</h2>
<ul>
<li>Fixed <code>including kaios</code> in baseline queries (by <a
href="https://github.com/Jaybhade"><code>@​Jaybhade</code></a>).</li>
</ul>
<h2>4.28.7</h2>
<ul>
<li>Improved parsing performance.</li>
<li>Fixed unbounded memory growth (by <a
href="https://github.com/alanturing881"><code>@​alanturing881</code></a>).</li>
<li>Fixed prototype write issue (by <a
href="https://github.com/alanturing881"><code>@​alanturing881</code></a>).</li>
</ul>
<h2>4.28.6</h2>
<ul>
<li>Fixed Electron version queries (by <a
href="https://github.com/spokodev"><code>@​spokodev</code></a>).</li>
</ul>
<h2>4.28.5</h2>
<ul>
<li>Fixed <code>&gt;</code> and <code>&gt;=</code> queries (by <a
href="https://github.com/spokodev"><code>@​spokodev</code></a>).</li>
</ul>
<h2>4.28.4</h2>
<ul>
<li>Fixed <code>SyntaxError</code> regression of 4.28.3.</li>
</ul>
<h2>4.28.3</h2>
<ul>
<li>Fixed baseline query case-insensitivity (by <a
href="https://github.com/swwind"><code>@​swwind</code></a>).</li>
</ul>
<h2>4.28.2</h2>
<ul>
<li>Fix prototype pollution (by <a
href="https://github.com/chluo1997"><code>@​chluo1997</code></a>).</li>
</ul>
<h2>4.28.1</h2>
<ul>
<li>Removed Baseline warning since we have it own warning.</li>
</ul>
<h2>4.27.0</h2>
<ul>
<li>Added <code>BROWSERSLIST_TRACE_WARNING</code> environment
variable.</li>
</ul>
<h2>4.26.3</h2>
<ul>
<li>Fixed <code>throwOnMissing</code> with <code>extends</code> quer...

_Description has been truncated_
2026-09-26 11:12:36 +10:00
dependabot[bot] 604f1ef4b6 chore(deps): bump the npm_and_yarn group across 1 directory with 12 updates
Bumps the npm_and_yarn group with 12 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) | `7.24.0` | `7.29.6` |
| [axios](https://github.com/axios/axios) | `1.8.2` | `1.18.0` |
| [dompurify](https://github.com/cure53/DOMPurify) | `3.2.4` | `3.4.13` |
| [postcss](https://github.com/postcss/postcss) | `8.5.3` | `8.5.23` |
| [mongoose](https://github.com/Automattic/mongoose) | `8.9.5` | `8.24.1` |
| [@babel/plugin-transform-modules-systemjs](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs) | `7.23.9` | `7.29.8` |
| [browserslist](https://github.com/browserslist/browserslist) | `4.23.0` | `4.29.1` |
| [engine.io](https://github.com/socketio/socket.io) | `6.5.4` | `6.5.5` |
| [nanoid](https://github.com/ai/nanoid) | `3.3.11` | `3.3.19` |
| [shell-quote](https://github.com/ljharb/shell-quote) | `1.8.1` | `1.10.0` |
| [socket.io-parser](https://github.com/socketio/socket.io) | `4.2.4` | `4.2.7` |
| [tmp](https://github.com/raszi/node-tmp) | `0.2.1` | `0.2.7` |



Updates `@babel/core` from 7.24.0 to 7.29.6
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.29.6/packages/babel-core)

Updates `axios` from 1.8.2 to 1.18.0
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.8.2...v1.18.0)

Updates `dompurify` from 3.2.4 to 3.4.13
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.2.4...3.4.13)

Updates `postcss` from 8.5.3 to 8.5.23
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.3...8.5.23)

Updates `mongoose` from 8.9.5 to 8.24.1
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.9.5...8.24.1)

Updates `@babel/plugin-transform-modules-systemjs` from 7.23.9 to 7.29.8
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.29.8/packages/babel-plugin-transform-modules-systemjs)

Updates `browserslist` from 4.23.0 to 4.29.1
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/browserslist/browserslist/compare/4.23.0...4.29.1)

Updates `engine.io` from 6.5.4 to 6.5.5
- [Release notes](https://github.com/socketio/socket.io/releases)
- [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io/commits)

Updates `nanoid` from 3.3.11 to 3.3.19
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.11...3.3.19)

Updates `shell-quote` from 1.8.1 to 1.10.0
- [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/shell-quote/compare/v1.8.1...v1.10.0)

Updates `socket.io-parser` from 4.2.4 to 4.2.7
- [Release notes](https://github.com/socketio/socket.io/releases)
- [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io/compare/socket.io-parser@4.2.4...socket.io-parser@4.2.7)

Updates `tmp` from 0.2.1 to 0.2.7
- [Changelog](https://github.com/raszi/node-tmp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/raszi/node-tmp/compare/v0.2.1...v0.2.7)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-version: 7.29.6
  dependency-type: direct:development
  dependency-group: npm_and_yarn
- dependency-name: axios
  dependency-version: 1.18.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: dompurify
  dependency-version: 3.4.13
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: postcss
  dependency-version: 8.5.23
  dependency-type: direct:development
  dependency-group: npm_and_yarn
- dependency-name: mongoose
  dependency-version: 8.24.1
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: "@babel/plugin-transform-modules-systemjs"
  dependency-version: 7.29.8
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: browserslist
  dependency-version: 4.29.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: engine.io
  dependency-version: 6.5.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: nanoid
  dependency-version: 3.3.19
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: shell-quote
  dependency-version: 1.10.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: socket.io-parser
  dependency-version: 4.2.7
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: tmp
  dependency-version: 0.2.7
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-26 01:08:54 +00:00
Justin Lin 43a76c4952 chore(deps-dev): bump vite from 6.3.3 to 6.4.3 in the npm_and_yarn group across 1 directory (#197)
Bumps the npm_and_yarn group with 1 update in the / directory:
[vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).

Updates `vite` from 6.3.3 to 6.4.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>v6.4.3</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v6.4.3/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v6.4.2</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v6.4.2/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/v6.4.3/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><!-- raw HTML omitted -->6.4.3 (2026-06-01)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22572">#22572</a>,
reject windows alternate paths (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22576">#22576</a>)
(<a
href="https://github.com/vitejs/vite/commit/96b0c10162e9c55485d922db2cfc6b8227cbc176">96b0c10</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/22572">#22572</a>
<a
href="https://redirect.github.com/vitejs/vite/issues/22576">#22576</a></li>
<li>fix(deps): backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22571">#22571</a>,
reject UNC paths for launch-editor-middleware (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22575">#22575</a>)
(<a
href="https://github.com/vitejs/vite/commit/8fed5cf540c0d475266787f52072f258478cd42f">8fed5cf</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/22571">#22571</a>
<a
href="https://redirect.github.com/vitejs/vite/issues/22575">#22575</a></li>
</ul>
<h2><!-- raw HTML omitted -->6.4.2 (2026-04-06)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix: apply server.fs check to env transport (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22159">#22159</a>)
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22163">#22163</a>)
(<a
href="https://github.com/vitejs/vite/commit/fe28e47e9463e4c9619f94bfa06d2f8f1411b44b">fe28e47</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/22159">#22159</a>
<a
href="https://redirect.github.com/vitejs/vite/issues/22163">#22163</a></li>
<li>fix: avoid path traversal with optimize deps sourcemap handler (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22161">#22161</a>)
(<a
href="https://github.com/vitejs/vite/commit/ca4da5d1fb45c9cfdce606aa30825095791b164b">ca4da5d</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/22161">#22161</a></li>
</ul>
<h2><!-- raw HTML omitted -->6.4.1 (2025-10-20)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix(dev): trim trailing slash before <code>server.fs.deny</code>
check (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20968">#20968</a>)
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20969">#20969</a>)
(<a
href="https://github.com/vitejs/vite/commit/1114b5d7ea03e26572708715343bec69db4536e8">1114b5d</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/20968">#20968</a>
<a
href="https://redirect.github.com/vitejs/vite/issues/20969">#20969</a></li>
</ul>
<h2>6.4.0 (2025-10-15)</h2>
<ul>
<li>feat: allow passing down resolved config to vite's createServer (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20932">#20932</a>)
(<a
href="https://github.com/vitejs/vite/commit/ca6455ee9eb6111a9caa9810506a1b9ac96a520a">ca6455e</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/20932">#20932</a></li>
</ul>
<h2><!-- raw HTML omitted -->6.3.7 (2025-10-14)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix(esbuild): inject esbuild helpers correctly for esbuild 0.25.9+
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20940">#20940</a>)
(<a
href="https://github.com/vitejs/vite/commit/c59a222aa584c087cfe710173de1b9ecb597a3ff">c59a222</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/20940">#20940</a></li>
</ul>
<h2><!-- raw HTML omitted -->6.3.6 (2025-09-08)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix: apply <code>fs.strict</code> check to HTML files (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20736">#20736</a>)
(<a
href="https://github.com/vitejs/vite/commit/0ab19ea9fcb66f544328f442cf6e70f7c0528d5f">0ab19ea</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/20736">#20736</a></li>
<li>fix: upgrade sirv to 3.0.2 (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20735">#20735</a>)
(<a
href="https://github.com/vitejs/vite/commit/e11d24008b97d4ca731ecc1a3b95260a6d12e7e0">e11d240</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/20735">#20735</a></li>
<li>test: detect ts support via <code>process.features</code> (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20544">#20544</a>)
(<a
href="https://github.com/vitejs/vite/commit/7d9922972b62329d37a71d4da5a4a382d0bf8a79">7d99229</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/20544">#20544</a></li>
</ul>
<h2><!-- raw HTML omitted -->6.3.5 (2025-05-05)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix(ssr): handle uninitialized export access as undefined (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19959">#19959</a>)
(<a
href="https://github.com/vitejs/vite/commit/fd38d076fe2455aac1e00a7b15cd51159bf12bb5">fd38d07</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/19959">#19959</a></li>
</ul>
<h2><!-- raw HTML omitted -->6.3.4 (2025-04-30)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix: check static serve file inside sirv (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19965">#19965</a>)
(<a
href="https://github.com/vitejs/vite/commit/c22c43de612eebb6c182dd67850c24e4fab8cacb">c22c43d</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/19965">#19965</a></li>
<li>fix(optimizer): return plain object when using <code>require</code>
to import externals in optimized dependenci (<a
href="https://github.com/vitejs/vite/commit/efc5eab253419fde0a6a48b8d2f233063d6a9643">efc5eab</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/19940">#19940</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite/commit/6c2c881f15495738ff03bc1d67cc052c07e0cac4"><code>6c2c881</code></a>
release: v6.4.3</li>
<li><a
href="https://github.com/vitejs/vite/commit/96b0c10162e9c55485d922db2cfc6b8227cbc176"><code>96b0c10</code></a>
fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22572">#22572</a>,
reject windows alternate paths (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22576">#22576</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/8fed5cf540c0d475266787f52072f258478cd42f"><code>8fed5cf</code></a>
fix(deps): backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22571">#22571</a>,
reject UNC paths for launch-editor-middleware (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/2">#2</a>...</li>
<li><a
href="https://github.com/vitejs/vite/commit/6b3fad02abd550bd7b79934ff92c58dbd7f33045"><code>6b3fad0</code></a>
release: v6.4.2</li>
<li><a
href="https://github.com/vitejs/vite/commit/ca4da5d1fb45c9cfdce606aa30825095791b164b"><code>ca4da5d</code></a>
fix: avoid path traversal with optimize deps sourcemap handler (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22161">#22161</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/fe28e47e9463e4c9619f94bfa06d2f8f1411b44b"><code>fe28e47</code></a>
fix: apply server.fs check to env transport (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22159">#22159</a>)
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22163">#22163</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/5487f4f641f70c47ea05fd101a4319897df048b3"><code>5487f4f</code></a>
release: v6.4.1</li>
<li><a
href="https://github.com/vitejs/vite/commit/1114b5d7ea03e26572708715343bec69db4536e8"><code>1114b5d</code></a>
fix(dev): trim trailing slash before <code>server.fs.deny</code> check
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20968">#20968</a>)
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20969">#20969</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/f12697c0f64b9a37196b9ab218a0911829d5b103"><code>f12697c</code></a>
release: v6.4.0</li>
<li><a
href="https://github.com/vitejs/vite/commit/ca6455ee9eb6111a9caa9810506a1b9ac96a520a"><code>ca6455e</code></a>
feat: allow passing down resolved config to vite's createServer (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20932">#20932</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite/commits/v6.4.3/packages/vite">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for vite since your current version.</p>
</details>
<br />
2026-09-26 11:03:42 +10:00
dependabot[bot] 492f27cf29 chore(deps-dev): bump vite in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 6.3.3 to 6.4.3
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.4.3/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.4.3/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.3.4
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-26 00:59:48 +00:00
Justin Lin cf5e8a1f24 feat: implement multilingual feature for UI (#202) 2026-09-26 10:57:20 +10:00
Justin Lin 7b16722e55 fix: move translation button to rightmost 2026-09-26 10:51:54 +10:00
Justin Lin a037c7d512 docs: refine Windows setup instructions (#201) 2026-09-26 10:35:48 +10:00
neilchen0812 c9b04682c9 fix(i18n): correct key name for landing navbar 2026-09-26 00:09:43 +09:30
neilchen0812 03fbae616d feat(i18n): add localized content for game page 2026-09-22 02:33:53 +09:30
neilchen0812 87df12ac85 feat(i18n): add localized content for leaderboard 2026-09-22 01:31:48 +09:30
neilchen0812 10c8dd5f0e feat(i18n): add localized content for quest map 2026-09-22 01:22:25 +09:30
neilchen0812 4a43df9dd9 feat(i18n): add localized content for game navbar 2026-09-22 00:57:39 +09:30
neilchen0812 013a5acaa7 feat(i18n): add localized content for authentication error 2026-09-21 22:49:27 +09:30
neilchen0812 bd1d5af699 feat(i18n): add localized content for authentication form 2026-09-21 22:09:25 +09:30
neilchen0812 e4da258a8d feat(i18n): add localized content for landing page 2026-09-21 03:17:30 +09:30
neilchen0812 4aeba17a1d feat(i18n): add landing page navbar translations for en and zh-tw 2026-09-21 01:55:43 +09:30
neilchen0812 0fddc05443 feat(i18n): implement language selector 2026-09-21 01:49:48 +09:30
neilchen0812 a3c69764c8 feat(i18n): add frontend internationalization setup 2026-09-20 20:42:26 +09:30
neilchen0812 f0a279fa83 docs: refine Windows setup instructions 2026-09-20 16:57:32 +09:30
Justin Lin f1038e40f4 fix: analytics start path 2026-02-27 20:59:21 +11:00
Justin Lin c5fb65db51 feat: add IMAGE_TAG variables in production compose 2026-02-27 20:59:21 +11:00
Justin Lin d4c67a7d81 fix: forward headers to backend to setup cookies properly 2026-02-27 20:43:53 +11:00
Justin Lin 0a1973f220 Feat terminal service (#196) 2026-02-27 16:06:58 +11:00
Justin Lin 776ef1162a chore: change console log to logger 2026-02-27 16:04:27 +11:00
Justin Lin 5b7bf0794c chore: Move open terminal in new tab to terminal component 2026-02-27 16:02:28 +11:00
Justin Lin ab4d06498a chore: update traefik version 2026-02-27 16:01:43 +11:00
Justin Lin d9fc465731 feat: remove container on finish 2025-05-09 16:46:13 +08:00
Justin Lin dca6861940 fix: remove writng error user terminal on disconnecting 2025-05-09 16:36:53 +08:00
Justin Lin 8161849504 feat: use traefik to proxy in production 2025-05-09 16:36:21 +08:00
Justin Lin 3c2dfcf322 refactor: update Dockerfile paths for analytics service 2025-05-05 19:55:41 +08:00
Justin Lin 0341efdd50 docs: update README with TLDR section and improve development instructions 2025-05-05 19:55:41 +08:00
Justin Lin aba492ff43 fix: reset terminal on connection and improve error handling 2025-05-05 19:55:41 +08:00
Justin Lin c2566cf3dd fix: change dev port of traefik to 8000 2025-05-05 19:55:41 +08:00
Justin Lin 307af61726 refactor: remove generating keypair 2025-05-05 19:55:41 +08:00
Justin Lin 740cbcecb4 refactor: move analytics into services directory 2025-05-05 19:55:40 +08:00
Justin Lin e43cbe26ce refactor: remove deprecated container package 2025-05-05 19:55:40 +08:00
Justin Lin 95c4fb71ae feat: handle command hooks
feat: handle copy

feat: handle remove

feat: handle move and home ~ path

refactor: improve error handling in cmd-hook

feat: handlePwd
2025-05-05 19:55:40 +08:00
Justin Lin d755822908 chore: update go.mod to remove unnecessary indirect dependencies 2025-05-05 19:55:40 +08:00
Justin Lin 372378021d feat: add timout settings for reconnectin websocket 2025-05-05 19:55:40 +08:00
Justin Lin 63e36c1c98 fix: reduce size of quest image by removing unnecessary apt cache 2025-05-05 19:55:40 +08:00
Justin Lin 2f7845e63e fix: write echo start on starting 2025-05-05 19:55:40 +08:00
Justin Lin 156abc044a refactor: clean up unused code 2025-05-05 19:55:40 +08:00
Justin Lin 21ff710f83 fix: cannot backspace in terminal 2025-05-05 19:55:40 +08:00
Justin Lin fb863ba030 fix: make quest image building process cleaner 2025-05-05 19:55:40 +08:00
Justin Lin c7e6d31b9c feat: connect frontend terminal to terminal service
fix: use ReconnectWebSocket to make the connection more stable

fix: typescript error on importing css in vue
2025-05-05 19:55:35 +08:00
Justin Lin 9c9456693d feat: handle dev server proxy by traefik 2025-05-05 19:54:35 +08:00
Justin Lin 5e81db2759 feat: connect terminal service to backend
feat: put terminal service into container

refactor: separate main into terminal and websocket

feat: create zsh using commander in home

feat: pass backendUrl to container

feat: pass token to ws server to cmd-hook

feat: gen terminal access token for frontend

feat: success to connect through traefik

fix: handle invalid jwt

feat: connect to session container via traefik
2025-05-05 19:53:33 +08:00
Justin Lin 0b08a9a5d9 feat: init cmd-hook and move terminal-service to services directory
feat: put cmd-hook in container

feat: cmd-hook request type, auto restart setup

feat: handle ls
2025-05-05 19:51:06 +08:00
Justin Lin 58b6448c3d feat: init terminal-service
feat: make interactive ws terminal
2025-05-05 19:50:34 +08:00
306 changed files with 7339 additions and 11642 deletions

No files matched your search

+3 -1
View File
@@ -1,4 +1,6 @@
**/node_modules
.git
**/dist
**/tsconfig.tsbuildinfo
**/tsconfig.tsbuildinfo
data
postgres-data
+1 -1
View File
@@ -1,6 +1,6 @@
HOST=localhost
PORT=3000
BASE_URL=http://localhost:5173
BASE_URL=http://localhost:8000
MONGO_URL=mongodb://localhost:27017/odyssey-test
SECRET_KEY=sample-secret
DOCKER_NETWORK=linux-odyssey-players-dev
+2 -1
View File
@@ -2,4 +2,5 @@ vite.config.js
.gitignore
data
mongo-init.js
dist
dist
postgres-data
+3 -1
View File
@@ -2,7 +2,9 @@ module.exports = {
root: true,
env: {
node: true,
jest: true,
},
globals: {
Bun: 'readonly',
},
plugins: ['@typescript-eslint', 'cypress', 'vue'],
extends: [
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
uses: ./.github/workflows/build-docker-image.yml
with:
imageName: 'linuxodyssey/analytics'
dockerfilePath: './packages/analytics/Dockerfile'
dockerfilePath: './services/analytics/Dockerfile'
target: prod
secrets: inherit
+9 -6
View File
@@ -11,18 +11,21 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: oven-sh/setup-bun@v2
with:
node-version: 20
bun-version: 1.3.14
- name: Install dependencies
run: yarn install
run: bun install --frozen-lockfile
- name: Type check
run: bun run type-check
- name: Build
run: yarn build
run: bun run build
- name: Lint
run: yarn lint
run: bun run lint
- name: Test
run: yarn test
run: bun run test
+103
View File
@@ -0,0 +1,103 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
on:
push:
branches: [ "main", "dev" ]
pull_request:
branches: [ "main", "dev" ]
schedule:
- cron: '25 14 * * 4'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: go
build-mode: autobuild
- language: javascript-typescript
build-mode: none
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v7
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- name: Run manual build steps
if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
run: docker-compose -f docker-compose.testing.yml build base backend app-test cypress
- name: Build Test Quests
run: docker-compose -f docker-compose.testing.yml run --rm backend yarn build:quests
run: docker-compose -f docker-compose.testing.yml run --rm backend bun run build:quests
- name: Run Cypress Tests
env:
+5 -1
View File
@@ -1,5 +1,8 @@
config
.quest
tmp
services/terminal-service/terminal-service
bin
# Logs
logs
@@ -141,4 +144,5 @@ dist
.pnp.*
#screenshots
tests/cypress/screenshots
tests/cypress/screenshots
services/cmd-hook/cmd-hook
+4 -4
View File
@@ -4,10 +4,10 @@
{
"type": "node",
"request": "launch",
"name": "File Graph Yarn Jest",
"runtimeExecutable": "yarn",
"args": ["test", "--runInBand"],
"cwd": "${workspaceFolder}/packages/file-graph",
"name": "File Graph Tests",
"runtimeExecutable": "bun",
"args": ["test", "packages/file-graph"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
+3
View File
@@ -4,5 +4,8 @@
"editor.formatOnSave": true,
"yaml.schemas": {
"packages/game/quest.json": "quests/**/game.yml"
},
"[go]": {
"editor.defaultFormatter": "golang.go"
}
}
+27 -19
View File
@@ -3,11 +3,17 @@
[![Production](https://github.com/linux-odyssey/linux-odyssey/actions/workflows/production.yml/badge.svg)](https://github.com/linux-odyssey/linux-odyssey/actions/workflows/production.yml)
[![Staging](https://github.com/linux-odyssey/linux-odyssey/actions/workflows/staging.yml/badge.svg)](https://github.com/linux-odyssey/linux-odyssey/actions/workflows/staging.yml)
## TLDR
bun install
cp .env.sample .env
docker compose up -d
bun run dev
## Requirements
- NodeJS v20+
- Bun: v1.3+
- Docker
- Yarn: v1.22
## Known Issues
@@ -19,7 +25,7 @@ Windows user please refer to [docs/windows-setup.md](docs/windows-setup.md) for
git clone https://github.com/lancatlin/linux-odyssey.git
cd linux-odyssey
yarn install
bun install
## Project Structures
@@ -41,10 +47,6 @@ The configuration is stored in the `.env` file. You can copy from the sample fil
cp .env.sample .env
The backend will use a SSH key pair to login to the player's container. The private key is on the host, and the public key is copied to the player's container.
The key pair is stored in `./config/ssh_key` and `./config/ssh_key.pub`. If it doesn't exist, the backend will generate a new pair and store them.
## Docker Setup
### Docker compose files explaination
@@ -70,7 +72,6 @@ This will start the db. it will automatically restarts by Docker.
Building quest images:
docker compose build base
yarn build:quests
### Build Quest Images in Details
@@ -102,34 +103,41 @@ Customized `entrypoint.sh` for each quest is not yet supported.
To build all quests:
yarn build:quests
bun run build:quests
The base image is built with docker-compose, so you can use `docker compose build base` to rebuild it. Once you rebuild the base image, you have to rebuild all quests.
### Optional: Mounting Host Directory
To improve the development experience, we can mount the host directory to the container in the pattern:
To update the home content of a quest, simply re-create a new session will do. The home content is mounted and copied on container creation.
To further improve the development experience, we can mount the host directory to the container in the pattern:
/path/to/linux-odyssey/quests/${quest_id}/home:/home/commander
/path/to/linux-odyssey/packages/container:/usr/local/lib/container
You can edit the files on your host, and the changes will be reflected in the container. This is disabled by default. To enable it, you can set the following environment variables:
MOUNT_QUEST=true
### Optional: Mounting terminal service & cmd-hook
To make the development of terminal services & cmd-hook smoother, we can enable `MOUNT_CLI` to mount the local binaries into container.
MOUNT_CLI
And you can run `air` inside of `services/terminal-service` or `services/cmd-hook` to get auto recompiling.
## Development
Copy `.env.sample` to `.env` and customize it for your needs.
Run dev server (frontend, backend):
yarn dev
**IMPORTANT NOTE**: only the app and server have hot-reloading, other packages require manually running `yarn dev` in each package.
bun run dev
To develop analytics dashboard:
yarn analytics
bun run analytics
The default username and password is `alex` and `Alex1234`.
@@ -137,12 +145,12 @@ The default username and password is `alex` and `Alex1234`.
Unit tests:
yarn test:unit
bun run test
Run Cypress locally, using the current development containers:
docker compose up -d
yarn test:e2e
bun run test:e2e
Run Cypress in container, create brand-new containers along with it:
@@ -174,7 +182,7 @@ Start the service
# Server side
docker compose -f docker-compose.prod.yml pull
yarn build:quests
bun run build:quests
docker compose -f docker-compose.prod.yml up -d
### Necessary Configuration
@@ -188,4 +196,4 @@ You can copy from `.env.sample`
You can generate a random key by running
yarn setup
bun run setup
+12 -5
View File
@@ -1,20 +1,27 @@
# Base stage
FROM node:20-alpine as build
FROM oven/bun:1.3.14-alpine AS build
WORKDIR /app
COPY package.json yarn.lock ./
COPY package.json bun.lock ./
COPY app/package.json ./app/package.json
COPY server/package.json ./server/package.json
RUN yarn install --frozen-lockfile
COPY services/analytics/package.json ./services/analytics/package.json
COPY tests/package.json ./tests/package.json
COPY packages/constants/package.json ./packages/constants/package.json
COPY packages/file-graph/package.json ./packages/file-graph/package.json
COPY packages/game/package.json ./packages/game/package.json
COPY packages/models/package.json ./packages/models/package.json
COPY packages/utils/package.json ./packages/utils/package.json
RUN bun install --frozen-lockfile --filter app
COPY tsconfig.json ./tsconfig.json
COPY server ./server
COPY packages ./packages
COPY app ./app
RUN yarn workspace app build
RUN bun run --filter app build
# Production stage
FROM nginx:stable-alpine as prod
FROM nginx:stable-alpine AS prod
COPY --from=build /app/app/dist /usr/share/nginx/html
COPY deployment/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
+14 -8
View File
@@ -16,15 +16,21 @@
"@fortawesome/free-regular-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/vue-fontawesome": "^3.0.3",
"@odyssey/constants": "workspace:*",
"@odyssey/file-graph": "workspace:*",
"@odyssey/game": "workspace:*",
"@odyssey/utils": "workspace:*",
"@trpc/client": "^11.1.0",
"@types/dompurify": "^3.0.5",
"axios": "^1.8.2",
"dompurify": "^3.2.4",
"axios": "^1.20.0",
"dompurify": "^3.4.16",
"marked": "^10.0.0",
"pinia": "^2.1.7",
"reconnecting-websocket": "^4.4.0",
"socket.io-client": "^4.7.1",
"validator": "^13.11.0",
"validator": "^13.15.22",
"vue": "^3.3.4",
"vue-i18n": "11.4.14",
"vue-router": "^4.2.4",
"vue-toastification": "^2.0.0-rc.5",
"vue3-lottie": "^3.2.0",
@@ -34,14 +40,14 @@
},
"devDependencies": {
"@types/validator": "^13.11.9",
"@vue/compiler-sfc": "^3.3.13",
"autoprefixer": "^10.4.14",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.3",
"@vitejs/plugin-vue": "^5.2.2",
"@vue/compiler-sfc": "^3.3.13",
"@vue/tsconfig": "^0.7.0",
"autoprefixer": "^10.4.14",
"postcss": "^8.5.23",
"tailwindcss": "^3.3.3",
"typescript": "~5.7.2",
"vite": "^6.3.1",
"vite": "^6.4.3",
"vue-tsc": "^2.2.8"
}
}
+44 -31
View File
@@ -1,10 +1,13 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { computed, onMounted, ref } from 'vue'
import { RouterLink, useRouter } from 'vue-router'
import { useToast } from 'vue-toastification'
import api from '../utils/api'
const { t } = useI18n()
const emit = defineEmits(['onSubmit', 'onChange'])
defineProps({
type: {
type: String,
@@ -84,15 +87,16 @@ const handleChange = () => {
}
}
const registerGuest = async () => {
try {
await api.post('/auth/register-guest')
router.push({ name: 'map' })
} catch (err) {
console.error(err)
toast.error('Something went wrong.')
}
}
// Guest account currently disabled
// const registerGuest = async () => {
// try {
// await api.post('/auth/register-guest')
// router.push({ name: 'map' })
// } catch (err) {
// console.error(err)
// toast.error('Something went wrong.')
// }
// }
</script>
<template>
<!-- login page -->
@@ -110,7 +114,7 @@ const registerGuest = async () => {
:icon="['fas', 'circle-exclamation']"
class="px-1 text-sm"
/>
<span>建議使用電腦全螢幕執行</span>
<span>{{ t('authform.recommand_pc_fullscreen') }}</span>
</div>
<form @submit.prevent="handleSubmit()" class="w-full">
<div v-if="socialLogin && hasSocialLogins">
@@ -124,7 +128,7 @@ const registerGuest = async () => {
:icon="['fab', 'google']"
class="text-text-secondary px-3 text-lg"
/>
<span class="font-medium"> 以 Google 繼續 </span>
<span class="font-medium"> {{ t('authform.google_login') }} </span>
</a>
<a
id="GitHubLogin"
@@ -136,14 +140,14 @@ const registerGuest = async () => {
:icon="['fab', 'github']"
class="text-text-secondary px-3 text-lg"
/>
<span class="font-medium"> 以 GitHub 繼續 </span>
<span class="font-medium"> {{ t('authform.github_login') }} </span>
</a>
<p
id="or"
class="text-text-secondary flex justify-center mt-3"
v-if="type === 'login' || type === 'register'"
>
或
{{ t('authform.or') }}
</p>
</div>
<div class="mb-6">
@@ -152,20 +156,22 @@ const registerGuest = async () => {
id="username"
ref="usernameInput"
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
:placeholder="type === 'login' ? '電子郵件 / 帳號名稱' : '帳號名稱'"
:placeholder="
t('authform.username') +
(type === 'login' ? ' / ' + t('authform.email') : '')
"
v-model="username"
required
@input="handleChange()"
autocomplete="username"
/>
<label
class="text-sm font-normal text-text-secondary"
<p
class="mx-1 text-xs font-normal text-text-secondary"
id="NameRules"
v-if="type === 'username' || type === 'register'"
v-if="type === 'register'"
>
<p>可用小寫字母、數字、"_"和"-"</p>
<p>小寫字母開頭,至多32字元</p>
</label>
{{ t('authform.username_rules') }}
</p>
</div>
<div class="mb-6" v-if="type === 'register'">
<input
@@ -173,7 +179,7 @@ const registerGuest = async () => {
id="email"
ref="emailInput"
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
placeholder="電子郵件"
:placeholder="t('authform.email')"
v-model="email"
required
@input="handleChange()"
@@ -185,11 +191,18 @@ const registerGuest = async () => {
type="password"
id="password"
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
placeholder="密碼"
:placeholder="t('authform.password')"
v-model="password"
required
@input="handleChange()"
/>
<p
class="mx-1 text-xs font-normal text-text-secondary"
id="PasswordRules"
v-if="type === 'register'"
>
{{ t('authform.password_rules') }}
</p>
</div>
<p
id="ErrorDisplay"
@@ -203,39 +216,39 @@ const registerGuest = async () => {
class="inline-flex justify-center rounded-lg font-black py-2 bg-text-primary text-bg w-full"
type="submit"
>
<span v-if="type === 'login'"> 登入 </span>
<span v-else> 註冊 </span>
<span v-if="type === 'login'"> {{ t('authform.login') }} </span>
<span v-else> {{ t('authform.register') }} </span>
</button>
<p id="SwitchLoginRegister" class="text-text flex justify-center mt-3">
<span id="CheckRegistered" v-if="type === 'register'">
已經有帳號了嗎?
{{ t('authform.already_registered') }}
<RouterLink
id="SwitchtoLogin"
class="text-text-primary font-bold"
to="/login"
>
<u> 登入 </u>
<u> {{ t('authform.login') }} </u>
</RouterLink></span
>
<span id="CheckRegistered" v-else-if="type === 'login'">
還沒有帳號嗎?
{{ t('authform.not_registered') }}
<RouterLink
id="SwitchtoRegister"
class="text-text-primary font-bold"
to="/register"
>
<u> 註冊 </u>
<u> {{ t('authform.register') }} </u>
</RouterLink></span
>
</p>
<button
<!-- <button
id="register-guest"
class="rounded-lg py-2 mt-3 bg-bg-primary text-text-secondary w-full border-text-secondary border-2"
@click="registerGuest()"
>
以訪客身分繼續
</button>
{{ t('authform.continue_as_guest') }}
</button> -->
</form>
</div>
</template>
+16 -6
View File
@@ -1,10 +1,13 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useToast } from 'vue-toastification'
import { ref, defineProps, onMounted } from 'vue'
import MarkdownText from './MarkdownText.vue'
import { trpc } from '../utils/trpc'
const { t, locale } = useI18n()
const props = defineProps({
questTitle: {
type: String,
@@ -36,7 +39,7 @@ const handleQuests = (id: string) => {
if (questUnlocked) {
router.push({ name: 'game', params: { questId: id } })
} else {
toast.warning('你還沒完成前一個關卡!')
toast.warning(t('quest.locked'))
}
}
const handleColour = () => {
@@ -49,8 +52,15 @@ const handleColour = () => {
}
}
onMounted(async () => {
const quest = await trpc.quests.getQuestDetail.query(questId)
questInstruction.value = quest.instruction
try {
const quest = await trpc.quests.getQuestDetail.query({
questId,
locale: locale.value,
})
questInstruction.value = quest.instruction
} catch (error) {
toast.error(t('quest.load_quest_instruction_failed'), error)
}
handleColour()
})
</script>
@@ -61,7 +71,6 @@ onMounted(async () => {
<span class="close text-text content-between" @click="closeModal"
>&times;</span
>
<h2
id="QuestTitle"
class="text-2xl text-text mb-5 w-full inline-flex justify-center"
@@ -81,9 +90,10 @@ onMounted(async () => {
target="_blank"
@click="handleQuests(questId)"
:style="{ backgroundColor: questColor, color: questTextColor }"
class="inline-flex justify-center rounded-lg text-base font-black py-3 mt-5 w-full text-lg"
>開始冒險</a
class="inline-flex justify-center rounded-lg text-base font-black py-3 mt-5 w-full"
>
{{ t('quest.start') }}
</a>
</div>
</div>
</template>
+91 -91
View File
@@ -1,22 +1,22 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { ref, onMounted, watch, computed } from 'vue'
import { useToast } from 'vue-toastification'
import { DAG } from '../../../packages/utils'
import { DAG } from '@odyssey/utils'
import { trpc } from '../utils/trpc'
import useUserProfile from '../store/userProfile'
import QuestIntro from './QuestIntro.vue'
const { t, locale } = useI18n()
const store = useUserProfile()
const toast = useToast()
const svgWidth = ref(window.innerWidth)
const svgHeight = ref(window.innerHeight)
const marginX = 120
const marginY = 120
const nodeWidth = 160
const nodeHeight = 50
const opened = ref<Node | null>(null)
type Node = {
id: string
@@ -44,14 +44,18 @@ const dragStartY = ref(0)
const offsetX = ref(0)
const offsetY = ref(0)
function startDrag(event: MouseEvent) {
function startDrag(event: PointerEvent) {
isDragging.value = true
dragStartX.value = event.clientX - offsetX.value
dragStartY.value = event.clientY - offsetY.value
}
function drag(event: MouseEvent) {
function drag(event: PointerEvent) {
if (!isDragging.value) return
// Capture only once dragging starts so plain clicks still reach the node buttons
const el = event.currentTarget as HTMLElement
if (!el.hasPointerCapture(event.pointerId))
el.setPointerCapture(event.pointerId)
offsetX.value = event.clientX - dragStartX.value
offsetY.value = event.clientY - dragStartY.value
}
@@ -64,7 +68,8 @@ async function computeGraphData() {
if (!store.progress) return
try {
const quests = await trpc.quests.getQuests.query()
const quests = await trpc.quests.getQuests.query({ locale: locale.value })
const dag = new DAG(quests)
const nodesValues = dag.getNodes()
@@ -72,10 +77,8 @@ async function computeGraphData() {
id: node.id,
title: node.title,
x: marginX * node.layer * 2,
y:
marginY * node.index -
(marginX * dag.getLayer(node.id)) / 2 +
svgHeight.value / 2,
// Centered on 0; the world container is anchored at the viewport's vertical center
y: (node.index - (dag.getLayer(node.id) + 1) / 2) * marginY,
completed: store.progress[node.id]?.completed || false,
unlocked: node.requirements.every(
(req: string) => store.progress[req]?.completed
@@ -96,8 +99,8 @@ async function computeGraphData() {
graphData.value = { nodes, edges }
} catch (error) {
console.error('Error computing graph data:', error)
toast.error('Failed to load quest data')
console.error(t('quest_map.compute_graph_failed'), error)
toast.error(t('quest_map.load_quest_data_failed'))
}
}
function handleNodeClick(node: Node) {
@@ -115,15 +118,15 @@ onMounted(async () => {
})
watch(() => store.progress, computeGraphData, { deep: true })
watch(locale, () => {
opened.value = null
computeGraphData()
})
const curvedPath = computed(() => {
const edgePath = computed(() => {
return (source: Node, target: Node) => {
// const dx = target.x - source.x
// const dy = target.y - source.y
// const dr = Math.sqrt(dx * dx + dy * dy)
const dr = 0
const sweep = target.index > source.index ? 0 : 1 // Determines if the arc should curve up or down based on node index
return `M${source.x},${source.y}A${dr},${dr} 0 0,${sweep} ${target.x},${target.y}`
const mx = (source.x + target.x) / 2
return `M${source.x},${source.y}C${mx},${source.y} ${mx},${target.y} ${target.x},${target.y}`
}
})
@@ -151,54 +154,46 @@ const edgeStyle = computed(() => {
class="p-10 absolute w-fit z-2 font-mono flex flax-wrap text-xl"
style="width: 30%; height: 6%; font-size: 3vh; color: #00ff00"
>
踏上你的Linux冒險之旅吧!
{{ t('quest_map.intro') }}
</h1>
<svg
:width="svgWidth"
:height="svgHeight"
class="absolute"
@mousedown="startDrag"
@mousemove="drag"
@mouseup="endDrag"
@mouseleave="endDrag"
<div
class="absolute inset-0 overflow-hidden select-none"
:class="isDragging ? 'cursor-grabbing' : 'cursor-grab'"
style="touch-action: none"
@pointerdown="startDrag"
@pointermove="drag"
@pointerup="endDrag"
@pointercancel="endDrag"
>
<g :transform="`translate(${offsetX}, ${offsetY})`">
<g
v-for="edge in graphData.edges"
:key="`${edge.source.id}-${edge.target.id}`"
>
<div
class="absolute top-1/2 left-0"
:style="{ transform: `translate(${offsetX}px, ${offsetY}px)` }"
>
<svg class="absolute overflow-visible pointer-events-none">
<path
:d="curvedPath(edge.source, edge.target)"
v-for="edge in graphData.edges"
:key="`${edge.source.id}-${edge.target.id}`"
:d="edgePath(edge.source, edge.target)"
:class="['edge', edgeStyle(edge)]"
/>
</g>
<g
</svg>
<button
v-for="node in graphData.nodes"
:key="node.id"
type="button"
:class="['node', nodeStyle(node)]"
:style="{
left: `${node.x - nodeWidth / 2}px`,
top: `${node.y - nodeHeight / 2}px`,
width: `${nodeWidth}px`,
height: `${nodeHeight}px`,
}"
@click="handleNodeClick(node)"
>
<rect
:x="node.x - nodeWidth / 2"
:y="node.y - nodeHeight / 2"
:width="nodeWidth"
:height="nodeHeight"
rx="10"
ry="10"
:class="['node', nodeStyle(node)]"
/>
<text
:x="node.x"
:y="node.y"
text-anchor="middle"
alignment-baseline="middle"
:class="['node-text', nodeStyle(node)]"
font-size="18"
>
{{ node.title }}
</text>
</g>
</g>
</svg>
<span class="line-clamp-2">{{ node.title }}</span>
</button>
</div>
</div>
<QuestIntro
:questTitle="opened.title"
:questId="opened.id"
@@ -211,44 +206,49 @@ const edgeStyle = computed(() => {
</template>
<style scoped>
svg {
overflow: visible;
}
.node {
&.completed {
fill: #6cf76c;
}
&.unlocked {
fill: #8c8c92;
}
&.locked {
fill: #505050;
}
position: absolute;
display: flex;
align-items: center;
justify-content: center;
padding: 0 0.5rem;
text-align: center;
border-radius: 10px;
cursor: pointer;
transition:
filter 0.15s,
box-shadow 0.15s;
}
.node-text {
&.completed {
fill: #1d1d1d;
}
&.unlocked {
fill: #ffffff;
}
&.locked {
fill: #a0a0a0;
}
.node:hover {
filter: brightness(1.15);
}
.node:focus-visible {
outline: none;
box-shadow: 0 0 0 3px #00ff00;
}
.node.completed {
background-color: #6cf76c;
color: #1d1d1d;
}
.node.unlocked {
background-color: #8c8c92;
color: #ffffff;
}
.node.locked {
background-color: #505050;
color: #a0a0a0;
}
.edge {
stroke-width: 3;
fill: none;
&.unlocked {
stroke: #adadb5;
stroke-dasharray: none;
}
&.locked {
stroke: #454552;
stroke-dasharray: 5, 5;
}
}
.edge.unlocked {
stroke: #adadb5;
stroke-dasharray: none;
}
.edge.locked {
stroke: #454552;
stroke-dasharray: 5, 5;
}
</style>
+10 -2
View File
@@ -1,7 +1,15 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
<template>
<font-awesome-icon :icon="['fas', 'list']" class="text-text-primary p-1" />
<h1 id="CommandBook" class="inline text-text-primary font-xl">指令之書</h1>
<h1 id="CommandBook" class="inline text-text-primary font-xl">
{{ t('game.command_book') }}
</h1>
<div id="cheatsheets">
<p class="text-text-secondary">-- --指令列表-- --</p>
<p class="text-text-secondary">-- --{{ t('game.cheatsheets') }}-- --</p>
</div>
</template>
+10 -5
View File
@@ -1,4 +1,5 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useToast } from 'vue-toastification'
import { ref } from 'vue'
@@ -6,6 +7,8 @@ import { Vue3Lottie } from 'vue3-lottie'
// import { surveyUrl } from '../config'
import CompleteAnimation from '../../img/complete-animation.json'
const { t } = useI18n()
const showModal = ref(true) // Controls whether the modal is visible or not
const router = useRouter()
const toast = useToast()
@@ -29,7 +32,7 @@ const backtoMap = async () => {
try {
router.push({ name: 'map' })
} catch (err) {
toast.error('無法讀取地圖')
toast.error(t('quest_map.load_quest_map_failed'))
console.error(err)
}
}
@@ -49,7 +52,7 @@ setTimeout(() => {
id="QuestCompleted"
class="text-2xl text-text mb-5 w-full inline-flex justify-center"
>
關卡完成!
{{ t('game.quest_completed') }}
</h2>
<div class="z-10 right-1/2 top-1/2" @animationend="defineComponent">
<Vue3Lottie
@@ -58,16 +61,18 @@ setTimeout(() => {
:width="200"
/>
</div>
<p class="text-base text-text text-center">恭喜你完成這一關!</p>
<p class="text-base text-text text-center">
接下來回到地圖,迎接新的挑戰吧!
{{ t('game.quest_completed_desc_1') }}
</p>
<p class="text-base text-text text-center">
{{ t('game.quest_completed_desc_2') }}
</p>
<a
id="BacktoMap"
target="_blank"
@click="backtoMap"
class="inline-flex justify-center rounded-lg text-base font-black py-2 mt-3 bg-text-primary w-full"
>回到地圖</a
>{{ t('game.back_to_map') }}</a
>
</div>
<div style="position: relative; height: 100vh; overflow: auto">
+56 -10
View File
@@ -1,29 +1,62 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useToast } from 'vue-toastification'
import useSession from '../../store/session'
import type { QuestLocale } from '@odyssey/constants'
import { useSession } from '../../store/session'
import { openBugReport, openQuestSurvey } from '../../utils/formbricks'
import { trpc } from '../../utils/trpc'
const { t, locale } = useI18n()
const toast = useToast()
const router = useRouter()
const sessionStore = useSession()
const reset = async () => {
console.log('resetting...')
await sessionStore.createSession()
const selectedLocale = locale.value as QuestLocale
const questId = sessionStore.session?.quest
if (!questId) return
try {
const quests = await trpc.quests.getQuests.query({
locale: selectedLocale,
})
console.log({
selectedLocale,
questId,
availableQuestIds: quests.map((quest) => quest.id),
})
if (!quests.some((quest) => quest.id === questId)) {
toast.warning(t('game.language_unavailable'))
return
}
await sessionStore.createSession()
} catch (error) {
console.error('Failed to reset quest:', error)
toast.error(t('game.reset_failed'))
}
}
const continuePlay = async () => {
try {
router.push({ name: 'map' })
} catch (err) {
useToast().error('無法讀取地圖')
useToast().error(t('quest_map.load_quest_map_failed'))
console.error(err)
}
}
</script>
<template>
<section class="mt-2 flex flex-row gap-3 justify-center">
<section class="mt-2 flex flex-row gap-2 justify-center">
<button
id="survey"
:title="t('game_nav.survey')"
class="bg-bg-secondary rounded-lg p-2"
@click="openQuestSurvey"
>
@@ -31,15 +64,18 @@ const continuePlay = async () => {
:icon="['fas', 'file-invoice']"
class="text-text-primary px-1"
/>
<p class="text-text-primary inline md:flex">問卷</p>
<p class="text-text-primary text-xs">{{ t('game_nav.survey') }}</p>
</button>
<button
title="Bug Report"
id="bug-report"
:title="t('game_nav.bug_report')"
@click="openBugReport"
class="bg-bg-secondary rounded-lg p-2"
>
<font-awesome-icon :icon="['fas', 'bug']" class="text-text-primary" />
<p class="text-text-primary inline ml-1 md:flex">回報</p>
<p class="text-text-primary text-xs">
{{ t('game_nav.bug_report') }}
</p>
</button>
<!-- <button disabled id="solution" class="bg-bg-disabled rounded-lg p-2">
<font-awesome-icon
@@ -48,15 +84,23 @@ const continuePlay = async () => {
/>
<p class="text-text-disabled inline ml-1 md:flex">解答</p>
</button> -->
<button id="reset" class="bg-bg-secondary rounded-lg p-2" @click="reset">
<button
id="reset"
:title="t('game.reset')"
class="bg-bg-secondary rounded-lg p-2"
@click="reset"
>
<font-awesome-icon
:icon="['fas', 'arrow-rotate-left']"
class="text-text-primary px-1"
/>
<p class="text-text-primary inline ml-1 md:flex">重來</p>
<p class="text-text-primary text-xs">
{{ t('game.reset') }}
</p>
</button>
<button
id="continue"
:title="t('game.continue')"
class="bg-bg-secondary rounded-lg p-2"
@click="continuePlay"
>
@@ -64,7 +108,9 @@ const continuePlay = async () => {
:icon="['far', 'circle-right']"
class="text-text-primary px-1"
/>
<p class="text-text-primary inline ml-1 md:flex">繼續</p>
<p class="text-text-primary text-xs">
{{ t('game.continue') }}
</p>
</button>
</section>
</template>
+8 -3
View File
@@ -1,8 +1,11 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { computed, ref, watch } from 'vue'
import useSession from '../../store/session'
import { useSession } from '../../store/session'
import MarkdownText from '../MarkdownText.vue'
const { t } = useI18n()
const sessionStore = useSession()
const current = ref(-1)
const hintDetails = ref<HTMLDetailsElement | null>(null)
@@ -52,7 +55,9 @@ watch(response, () => {
:icon="['far', 'lightbulb']"
class="text-yellow-200 p-2 content-center"
/>
<h1 class="inline text-text w-1/2 font-xl p-2 m-1">說明</h1>
<h1 class="inline text-text w-1/2 font-xl p-2 m-1">
{{ t('game.description') }}
</h1>
<div v-if="current !== -1" class="flex w-full justify-end items-end">
<button
class="p-2 m-1 w-1/8"
@@ -98,7 +103,7 @@ watch(response, () => {
class="text-text-primary font-xl whitespace-pre-wrap"
>
<details ref="hintDetails">
<summary class="cursor-pointer">提示</summary>
<summary class="cursor-pointer">{{ t('game.hint') }}</summary>
<MarkdownText :content="response.hint" />
</details>
</li>
+6 -3
View File
@@ -1,7 +1,10 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { computed } from 'vue'
import MarkdownText from '../MarkdownText.vue'
import useSession from '../../store/session'
import { useSession } from '../../store/session'
const { t } = useI18n()
const sessionStore = useSession()
const tasks = computed(() => {
@@ -31,14 +34,14 @@ const tasks = computed(() => {
:content="sessionStore.quest.instruction"
/>
<br />
<p id="tasks" class="text-text">任務:</p>
<p id="tasks" class="text-text font-bold">{{ t('game.task') }}</p>
<ul v-if="sessionStore.session">
<li v-for="task in tasks" :key="task.id">
<MarkdownText :class="task.class" :content="task.content" />
</li>
</ul>
</div>
<p class="text-text" v-else>Loading...</p>
<p class="text-text" v-else>{{ t('game.loading') }}</p>
</div>
</div>
</template>
+5 -2
View File
@@ -1,7 +1,10 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { useToast } from 'vue-toastification'
import { computed } from 'vue'
import useSession from '../../store/session'
import { useSession } from '../../store/session'
const { t } = useI18n()
const toast = useToast()
const sessionStore = useSession()
@@ -31,7 +34,7 @@ const startSession = async () => {
:icon="['fas', 'play']"
class="text-text-primary h-full px-3"
/>
<p class="text-text-primary inline ml-1 md:flex">開始</p>
<p class="text-text-primary inline ml-1 md:flex">{{ t('game.start') }}</p>
</button>
</div>
</template>
+15 -2
View File
@@ -1,6 +1,11 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { onMounted, onUnmounted, ref } from 'vue'
import { useTerminal } from '../../store/session'
import { useSession, useTerminal } from '../../store/session'
const { t } = useI18n()
const sessionStore = useSession()
const terminal = ref<HTMLElement | null>(null)
const term = useTerminal()
@@ -22,7 +27,15 @@ onMounted(() => {
<div class="flex flex-col h-full">
<div class="flex items-center gap-2 p-1">
<font-awesome-icon :icon="['fas', 'terminal']" class="text-text" />
<button id="Terminal" class="text-text">終端機</button>
<p id="Terminal" class="text-text">{{ t('game.terminal') }}</p>
<a
class="text-xs font-normal text-gray-200 ml-10 bg-bg-primary rounded-lg px-2 py-1 hover:bg-bg-primary-hover transition-colors duration-300"
:href="`/terminal/${sessionStore.session?.containerName}?token=${sessionStore.session?.token}`"
target="_blank"
>
{{ t('game.open_terminal_in_new_tab') }}
</a>
</div>
<div
id="terminal"
+1 -1
View File
@@ -1,6 +1,6 @@
<script setup lang="ts">
import FileNode from '../FileNode.vue'
import useSession from '../../store/session'
import { useSession } from '../../store/session'
const sessionStore = useSession()
</script>
@@ -1,13 +1,15 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useToast } from 'vue-toastification'
import { logout } from '../../utils/auth'
import { trpc } from '../../utils/trpc'
import { openBugReport } from '../../utils/formbricks'
import useSession from '../../store/session'
import { useSession } from '../../store/session'
import useUserProfile from '../../store/userProfile'
const { t } = useI18n()
const userStore = useUserProfile()
const sessionStore = useSession()
const router = useRouter()
@@ -21,7 +23,7 @@ const handleLogout = async () => {
sessionStore.reset()
router.push({ name: 'login' })
} catch (err) {
toast.error('登出失敗')
toast.error(t('game_nav.sign_out_failed'))
console.error(err)
}
}
@@ -35,7 +37,7 @@ onMounted(async () => {
try {
await userStore.loadUserProfile()
} catch (err) {
toast.error('無法讀取使用者資料')
toast.error(t('game_nav.load_user_profile_failed'))
console.error(err)
}
})
@@ -67,7 +69,7 @@ onMounted(async () => {
{{ userStore.username }}
</p>
<button
title="Survey"
:title="t('game_nav.survey')"
target="_blank"
class="md:h-5 md:w-5 px-1.5 w-auto"
@click="openSurvey"
@@ -76,37 +78,36 @@ onMounted(async () => {
:icon="['fas', 'file-invoice']"
class="text-text-primary inline"
/>
<span class="text-text sm:hidden px-2">Survey</span>
</button>
<RouterLink
title="LeaderBoard"
:title="t('game_nav.leaderboard')"
to="/leaderboard"
class="md:h-5 md:w-5 px-1.5 w-auto"
>
<font-awesome-icon :icon="['fas', 'trophy']" class="text-text-primary" />
<span class="text-text sm:hidden px-2">Leader Board</span>
</RouterLink>
<RouterLink title="Map" to="/map" class="md:h-5 md:w-5 px-1.5 w-auto">
<RouterLink
:title="t('game_nav.map')"
to="/map"
class="md:h-5 md:w-5 px-1.5 w-auto"
>
<font-awesome-icon :icon="['fas', 'map']" class="text-text-primary" />
<span class="text-text sm:hidden px-2">Map</span>
</RouterLink>
<button
title="Bug Report"
:title="t('game_nav.bug_report')"
@click="openBugReport"
class="md:h-5 md:w-5 px-1.5 w-auto"
>
<font-awesome-icon :icon="['fas', 'bug']" class="text-text-primary" />
<span class="text-text sm:hidden px-2">Bug Report</span>
</button>
<button
title="Sign Out"
:title="t('game_nav.sign_out')"
@click="handleLogout"
class="md:h-5 md:w-5 px-1.5 w-auto"
class="md:h-5 md:w-5 px-1.5 mr-2 w-auto"
>
<font-awesome-icon
:icon="['fas', 'arrow-right-from-bracket']"
class="text-text-primary"
/>
<span class="text-text sm:hidden px-2">Sign Out</span>
</button>
</template>
+8 -2
View File
@@ -1,5 +1,10 @@
<script setup lang="ts">
import { defineProps, ref } from 'vue'
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import LanguageSelector from './LanguageSelector.vue'
const { t } = useI18n()
defineProps({
title: {
@@ -19,7 +24,7 @@ const toggleMenu = () => {
</script>
<template>
<div
class="w-full top-0 px-5 fixed flex flex-row flex-wrap bg-bg-secondary justify-between items-center sm:justify-between"
class="w-full top-0 px-2 fixed flex flex-row flex-wrap bg-bg-secondary justify-between items-center sm:justify-between"
>
<div class="flex flex-row items-center gap-3" :class="{ hidden: menuOpen }">
<img src="../../img/icon_totem.svg" class="h-8 justify-self-start" />
@@ -44,6 +49,7 @@ const toggleMenu = () => {
:class="{ hidden: !menuOpen }"
>
<component :is="headerComponent" />
<LanguageSelector />
</div>
<div
v-if="windowWidth"
@@ -1,6 +1,9 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { bugReportUrl } from '../../config'
const { t } = useI18n()
const scrollToSection = (sectionId: string) => {
const section = document.getElementById(sectionId)
if (section) {
@@ -21,22 +24,25 @@ const scrollToSection = (sectionId: string) => {
@click="scrollToSection('intro')"
style="font-size: 2vh"
>
前言
{{ t('landing_nav.intro') }}
</button>
<button
id="Feature"
class="text-text inline-block font-bold whitespace-nowrap pt-1 px-2 hover:text-text-primary"
@click="scrollToSection('feature')"
style="font-size: 2vh"
>
特色</button
><button
{{ t('landing_nav.features') }}
</button>
<button
id="Info"
class="text-text inline-block font-bold whitespace-nowrap pt-1 px-2 hover:text-text-primary"
@click="scrollToSection('about')"
style="font-size: 2vh"
>
關於
{{ t('landing_nav.about') }}
</button>
<button
@@ -45,18 +51,27 @@ const scrollToSection = (sectionId: string) => {
@click="scrollToSection('contact')"
style="font-size: 2vh"
>
聯絡我們
{{ t('landing_nav.contact') }}
</button>
<RouterLink
title="Sign In"
id="SignIn"
to="/register"
class="text-text inline-block font-bold whitespace-nowrap pt-1 px-2 hover:text-text-primary"
style="font-size: 2vh"
>
登入
{{ t('landing_nav.login') }}
</RouterLink>
<a title="Bug Report" :href="bugReportUrl" target="_blank" class="h-5 w-5">
<font-awesome-icon :icon="['fas', 'bug']" class="text-text-primary" />
<a
:title="t('landing_nav.report_bug')"
:href="bugReportUrl"
target="_blank"
class="h-5 w-5"
>
<font-awesome-icon
:icon="['fas', 'bug']"
class="text-text inline-block font-bold whitespace-nowrap pt-1 px-2 hover:text-text-primary"
/>
</a>
</template>
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import type { QuestLocale } from '@odyssey/constants'
import { SUPPORTED_LOCALES, LOCALE_NAME_MAP } from '@odyssey/constants'
import { setLocale } from '../../i18n'
const { t, locale } = useI18n({ useScope: 'global' })
function changeLanguage(event: Event) {
const selectedLocale = (event.target as HTMLSelectElement)
.value as QuestLocale
setLocale(selectedLocale)
}
</script>
<template>
<select
:value="locale"
:title="t('language.change')"
class="bg-bg-secondary px-3 py-2 text-sm text-text shadow-md outline-none"
aria-label="Language"
@change="changeLanguage"
style="font-size: 2vh"
>
<option v-for="locale in SUPPORTED_LOCALES" :key="locale" :value="locale">
{{ LOCALE_NAME_MAP[locale] }}
</option>
</select>
</template>
+39
View File
@@ -0,0 +1,39 @@
import { createI18n } from 'vue-i18n'
import type { QuestLocale } from '@odyssey/constants'
import { SUPPORTED_LOCALES } from '@odyssey/constants'
import en from './locales/en.json'
import zhTW from './locales/zh-TW.json'
function isSupportedLocale(locale: string): locale is QuestLocale {
return SUPPORTED_LOCALES.includes(locale as QuestLocale)
}
function getInitialLocale(): QuestLocale {
const savedLocale = localStorage.getItem('locale')
if (savedLocale && isSupportedLocale(savedLocale)) {
return savedLocale
}
return navigator.language.startsWith('zh') ? 'zh-TW' : 'en'
}
const initialLocale = getInitialLocale()
document.documentElement.lang = initialLocale
export const i18n = createI18n({
legacy: false,
locale: initialLocale,
fallbackLocale: 'zh-TW',
messages: {
'zh-TW': zhTW,
en,
},
})
export function setLocale(locale: QuestLocale) {
i18n.global.locale.value = locale
localStorage.setItem('locale', locale)
document.documentElement.lang = locale
}
+116
View File
@@ -0,0 +1,116 @@
{
"language": {
"change": "Change language"
},
"landing_nav": {
"intro": "Introduction",
"features": "Features",
"about": "About",
"contact": "Contact",
"login": "Sign in",
"report_bug": "Report a bug"
},
"landing": {
"intro": "Programming is about more than writing code - it also means knowing how to interact effectively with your computer. Yet programming education often overlooks the importance of the development environment, leaving many learners frustrated. A development environment includes all the tools needed to write and run software, many of which are used through terminal commands. While most learners use Windows or macOS, much of the software world runs on Linux. Linux Odyssey is an interactive online learning platform designed to bridge that gap.",
"feature1": "Easy for Beginners",
"feature1_desc": "Setting up and using development tools can be a major hurdle for beginners. With Linux Odyssey, there is nothing to install - learners can access a real Linux environment directly from their browser.",
"feature2": "Learn Through Play",
"feature2_desc": "Linux Odyssey combines the fun of gaming with practical learning. Through carefully designed levels, learners take on challenges, solve puzzles, and master Linux commands along the way.",
"feature3": "Hands-on Linux Experience",
"feature3_desc": "Linux Odyssey goes beyond theory by providing real hands-on experience. Every command runs in a real Linux environment, giving learners an authentic introduction to the world of software development.",
"start_journey": "Grab your keyboard and begin your Linux adventure!",
"team_intro": "Meet the Team",
"team_desc": "NTUT Intelligent Automation Engineering, 2nd Cohort",
"team_member1": "Wancat",
"team_member2": "Neil",
"team_member3": "A.H.",
"team_member4": "Ray Gur",
"awards": "Awards",
"award_desc": "2023 InnoServe Awards - 2nd Place, Titansoft Agile Development Award",
"player_feedback": "What Players Say",
"feedback1": "\"It's really fun - just like a puzzle game.\"",
"feedback2": "\"I never knew free software existed. Thank you!\"",
"feedback3": "\"It's pretty fun. It makes programming enjoyable.\"",
"feedback4": "\"I used to dislike computer class, but now I like it a little more.\"",
"feedback5": "\"The program is really beginner-friendly, and I learned a lot.\"",
"feedback6": "\"It's very well made, clear, and easy to understand. A lot of thought went into the level design.\"",
"feedback7": "\"I found the experience really interesting. I got to try programming in a way I never had before, and the student mentors were very helpful. Thank you for explaining everything so carefully. I hope I can join an activity like this again.\"",
"feedback8": "\"I used to think programming was difficult, but now I find it interesting.\"",
"feedback9": "\"I used to think programming was difficult and had nothing to do with my life. After this class, it feels much more approachable.\"",
"contact_us": "Contact Us"
},
"authform": {
"google_login": "Continue with Google",
"github_login": "Continue with GitHub",
"or": "or",
"username": "Username",
"username_rules": "At most 32 characters, lowercase first, use lowercase letters, numbers, _, and -",
"email": "Email",
"password": "Password",
"login": "Login",
"register": "Register",
"already_registered": "Already have an account?",
"not_registered": "Don't have an account?",
"continue_as_guest": "Continue as Guest",
"password_rules": "At least 8 characters, including uppercase and lowercase letters and numbers",
"recommand_pc_fullscreen": "Recommended to use desktop version in full-screen mode"
},
"authform_error": {
"too_many_requests": "Too many requests, please try again in 2 minutes",
"unauthorized": "Invalid username or password",
"auth_failed": "Something went wrong",
"invalid_username": "Invalid username",
"invalid_email": "Invalid email",
"invalid_password": "Invalid password",
"username_taken": "Username is already taken",
"email_taken": "Email is already taken"
},
"game_nav": {
"survey": "Survey",
"leaderboard": "Leaderboard",
"map": "Map",
"bug_report": "Bug Report",
"sign_out": "Sign Out",
"sign_out_failed": "Sign Out Failed",
"load_user_profile_failed": "Failed to Load User Profile"
},
"quest_map": {
"title": "Quest Map",
"intro": "Embark on your Linux adventure!",
"load_quest_map_failed": "Failed to Load Quest Map",
"compute_graph_failed": "Error computing graph data: ",
"load_quest_data_failed": "Failed to Load Quest Data"
},
"quest": {
"start": "Start Adventure",
"locked": "Quest not unlocked",
"load_quest_instruction_failed": "Failed to Load Quest Instruction: "
},
"leaderboard": {
"title": "Leaderboard",
"username": "Username",
"score": "Score",
"completed_quests": "Completed Quests",
"load_leaderboard_failed": "Failed to Load Leaderboard"
},
"game": {
"start": "Start",
"task": "Task:",
"loading": "Loading...",
"description": "Description",
"hint": "Hint",
"terminal": "Terminal",
"open_terminal_in_new_tab": "Open Terminal in New Tab",
"reset": "Reset",
"continue": "Continue",
"command_book": "Command Book",
"cheatsheets": "Cheat Sheets",
"reset_to_apply_language": "Reset quest to apply language changes",
"reset_failed": "Reset failed",
"language_unavailable": "This quest does not support the selected language, please choose another language",
"quest_completed": "Quest Completed",
"quest_completed_desc_1": "Congratulations! You have completed this quest!",
"quest_completed_desc_2": "Return to the map to face new challenges!",
"back_to_map": "Back to Map"
}
}
+116
View File
@@ -0,0 +1,116 @@
{
"language": {
"change": "切換語言"
},
"landing_nav": {
"intro": "前言",
"features": "特色",
"about": "關於",
"contact": "聯絡我們",
"login": "登入",
"report_bug": "回報錯誤"
},
"landing": {
"intro": "程式設計不僅僅是寫程式碼,還涉及到如何有效地與你的電腦互動。程式教育卻往往忽略背後「開發環境」的重要性,使得許多學生在過程中充滿挫折。「開發環境」是寫程式、執行程式過程所需要的一切工具。而這些工具需要在終端機輸入指令來使用。大部分的程式要用來運行的環境,並非 Windows 或 Mac OS,而是 Linux 作業系統。 Linux Odyssey 即是為此設計的線上 Linux 互動教學網站。",
"feature1": "初學者也能立即上手",
"feature1_desc": "我們明白對於初學者來說,設定和使用開發工具可能是一大障礙。學習者無需安裝任何軟體,僅需通過瀏覽器即可連上一個真實的 Linux 環境。",
"feature2": "遊戲般的學習體驗",
"feature2_desc": "Linux Odyssey 融合了遊戲的樂趣與學習的實用性。透過精心設計的遊戲關卡,學習者可以一邊接受挑戰、破解謎題,一邊掌握 Linux 指令的運用。",
"feature3": "真實的 Linux 操作之旅",
"feature3_desc": "Linux Odyssey 提供的不僅是理論知識,更是真實的操作體驗。每一個指令都是在真實的 Linux 環境中執行,讓學習者能夠真正深入軟體開發的世界。",
"start_journey": "準備好鍵盤,跟我們一起開啟你的 Linux 冒險吧!",
"team_intro": "團隊介紹",
"team_desc": "國立臺北科技大學 智慧自動化工程科 第二屆",
"team_member1": "Wancat",
"team_member2": "Neil",
"team_member3": "A.H.",
"team_member4": "Ray Gur",
"awards": "獲獎紀錄",
"award_desc": "2023大專校院資訊應用服務創新競賽 鈦坦敏捷開發特別獎 第二名",
"player_feedback": "玩家感想",
"feedback1": "\"很好玩很像益智遊戲\"",
"feedback2": "\"我從來不知道自由軟體的存在,謝謝你們。\"",
"feedback3": "\"還蠻好玩的,讓程式變好玩\"",
"feedback4": "\"以前不喜歡電腦課現在覺得喜歡一點點\"",
"feedback5": "\"程式真的對新手很友善,讓我學到了很多東西\"",
"feedback6": "\"感覺做得很好很簡明易懂關卡設計很用心\"",
"feedback7": "\"這個體驗我覺得非常有趣,可以體驗到沒辦法體驗的程式,學長也都熱心指導,非常感謝學長的用心的講解,希望以後還可以再體驗這種活動\"",
"feedback8": "\"以前我覺得寫程式很難不過現在覺得很有趣\"",
"feedback9": "\"以前覺得寫程式是我生活中碰不到而且很難的項目。但通過這堂課之後,覺得寫程式不再那麼難以親近\"",
"contact_us": "聯絡我們"
},
"authform": {
"google_login": "以 Google 繼續",
"github_login": "以 GitHub 繼續",
"or": "或",
"username": "帳號名稱",
"username_rules": "至多 32 字元,小寫字母開頭,可用小寫字母、數字、_ 和 -",
"email": "電子郵件",
"password": "密碼",
"login": "登入",
"register": "註冊",
"already_registered": "已經有帳號了嗎?",
"not_registered": "還沒有帳號嗎?",
"continue_as_guest": "以訪客身分繼續",
"password_rules": "至少 8 個字元,包含數字及大小寫字母",
"recommand_pc_fullscreen": "建議使用電腦版全螢幕操作"
},
"authform_error": {
"too_many_requests": "太多請求,兩分鐘後再試一次",
"unauthorized": "無效的帳號名稱或密碼",
"auth_failed": "出了點問題",
"invalid_username": "無效的帳號名稱",
"invalid_email": "無效的電子郵件",
"invalid_password": "無效的密碼",
"username_taken": "帳號名稱已被使用",
"email_taken": "電子郵件已被使用"
},
"game_nav": {
"survey": "問卷",
"leaderboard": "排行榜",
"map": "地圖",
"bug_report": "回報錯誤",
"sign_out": "登出",
"sign_out_failed": "登出失敗",
"load_user_profile_failed": "無法讀取使用者資料"
},
"quest_map": {
"title": "關卡地圖",
"intro": "踏上你的Linux冒險之旅吧!",
"load_quest_map_failed": "無法讀取關卡地圖",
"compute_graph_failed": "計算關卡地圖時出錯:",
"load_quest_data_failed": "無法讀取關卡"
},
"quest": {
"start": "開始冒險",
"locked": "關卡尚未解鎖",
"load_quest_instruction_failed": "無法讀取關卡說明:"
},
"leaderboard": {
"title": "排行榜",
"username": "使用者名稱",
"score": "分數",
"completed_quests": "完成關卡",
"load_leaderboard_failed": "無法讀取排行榜"
},
"game": {
"start": "開始",
"task": "任務:",
"loading": "載入中...",
"description": "說明",
"hint": "提示",
"terminal": "終端機",
"open_terminal_in_new_tab": "在新分頁開啟終端機",
"reset": "重置",
"continue": "繼續",
"command_book": "指令之書",
"cheatsheets": "指令列表",
"reset_to_apply_language": "重置關卡以套用語言變更",
"reset_failed": "重置失敗",
"language_unavailable": "此關卡不支援所選語言,請選擇其他語言",
"quest_completed": "關卡完成",
"quest_completed_desc_1": "恭喜你完成了這個關卡!",
"quest_completed_desc_2": "回到地圖,迎接新的挑戰吧!",
"back_to_map": "回到地圖"
}
}
+7 -9
View File
@@ -1,18 +1,15 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import './style.css'
/* import font awesome icon component */
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import './library'
/* import Vue Toastification */
import Toast, { POSITION } from 'vue-toastification'
/* import Vue Lottie */
import Vue3Lottie from 'vue3-lottie'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' // import font awesome icon component
import { i18n } from './i18n'
import Toast, { POSITION } from 'vue-toastification' // import Vue Toastification
import Vue3Lottie from 'vue3-lottie' // import Vue Lottie
import 'vue-toastification/dist/index.css'
import App from './App.vue'
import router from './router'
import formbricks from './utils/formbricks'
import './style.css'
import './library'
const app = createApp(App)
const pinia = createPinia()
@@ -21,6 +18,7 @@ app.component('font-awesome-icon', FontAwesomeIcon)
app.use(pinia)
app.use(router)
app.use(i18n)
router.afterEach(() => {
if (typeof formbricks !== 'undefined') {
+28 -22
View File
@@ -1,14 +1,13 @@
import { defineStore } from 'pinia'
import {
FileGraph,
type FileGraphUpdateEvent,
} from '../../../packages/file-graph'
import type { IResponse, ITask } from '../../../packages/game'
import type { QuestLocale } from '@odyssey/constants'
import { FileGraph, type FileGraphUpdateEvent } from '@odyssey/file-graph'
import type { IResponse, ITask } from '@odyssey/game'
import type { SessionDetail } from '../../../server/src/routers/sessionRouter'
import Socket from '../utils/socket'
import SocketTerminal from '../utils/terminal'
import type { Session } from '../types'
import { trpc } from '../utils/trpc'
import { i18n } from '../i18n'
const socket = new Socket()
const term = new SocketTerminal()
@@ -34,40 +33,49 @@ interface Store {
quest: QuestDetailResponse | null
}
const useSession = defineStore('session', {
export const useSession = defineStore('session', {
state: (): Store => ({
session: null,
questId: '',
quest: null,
}),
actions: {
async setQuest(questId: string) {
this.quest = await trpc.quests.getQuestDetail.query(questId)
async setQuest(questId: string, locale: QuestLocale) {
this.quest = await trpc.quests.getQuestDetail.query({
questId,
locale,
})
this.questId = questId
},
async setSession(session: SessionDetail) {
await this.setQuest(session.quest, session.locale)
this.session = {
...session,
graph: new FileGraph(session.graph),
pwd: '/home/commander',
containerName: session.containerName || '',
}
term.reset()
await socket.connect(this.session)
await term.connect(
`/terminal/${session.containerName}/ws?token=${session.token}`
)
term.focus()
},
async createSession() {
const locale = i18n.global.locale.value
const session = await trpc.session.createSession.mutate({
questId: this.questId,
locale,
})
await this.setSession(session)
socket.emit('terminal', 'echo start\n')
term.send('echo start\n')
},
async getActiveSession() {
const session = await trpc.session.getActiveSession.query({
questId: this.questId,
})
async getActiveSession(questId: string) {
const session = await trpc.session.getActiveSession.query({ questId })
if (session) {
this.setSession(session)
await this.setSession(session)
}
},
newUpdate(update: SessionUpdate) {
@@ -94,12 +102,12 @@ const useSession = defineStore('session', {
},
setup() {
if (hasSetup) return
socket.on('terminal', (data: string) => {
term.write(data)
})
term.onData((data: string) => {
socket.emit('terminal', data)
})
// socket.on('terminal', (data: string) => {
// term.write(data)
// })
// term.onData((data: string) => {
// socket.emit('terminal', data)
// })
socket.on('graph', (event: FileGraphUpdateEvent) => {
if (!this.session) return
this.session.graph.handleEvent(event)
@@ -122,5 +130,3 @@ const useSession = defineStore('session', {
export function useTerminal() {
return term
}
export default useSession
+4 -2
View File
@@ -1,5 +1,5 @@
import type { FileGraph } from '../../packages/file-graph'
import type { IResponse, ITask } from '../../packages/game'
import type { FileGraph } from '@odyssey/file-graph'
import type { IResponse, ITask } from '@odyssey/game'
export interface Task {
id: number
@@ -21,4 +21,6 @@ export interface Session {
pwd: string
tasks: ITask[]
responses: IResponse[]
token: string
containerName: string
}
+4
View File
@@ -0,0 +1,4 @@
declare module '*.css' {
const content: string
export default content
}
+8 -3
View File
@@ -1,4 +1,5 @@
import api from './api'
import { i18n } from '../i18n'
import {
TooManyRequestsError,
@@ -32,11 +33,15 @@ function handleRequestError(err: {
const { path, msg } = errors[0]
switch (path) {
case 'username':
throw new ValidationError('Username is already taken')
throw new ValidationError(
i18n.global.t('authform_error.username_taken')
)
case 'email':
throw new ValidationError('Email is already taken')
throw new ValidationError(i18n.global.t('authform_error.email_taken'))
case 'password':
throw new ValidationError('Password is too weak')
throw new ValidationError(
i18n.global.t('authform_error.invalid_password')
)
default:
throw new ValidationError(msg)
}
+1 -1
View File
@@ -1,5 +1,5 @@
import formbricks from '@formbricks/js/website'
import useSession from '../store/session'
import { useSession } from '../store/session'
import useUserProfile from '../store/userProfile'
if (typeof window !== 'undefined') {
+1 -3
View File
@@ -23,11 +23,9 @@ class SocketWrapper {
this.socket.on('connect', () => {
console.log('Socket connected to session', session._id)
})
this.socket.once('terminal', () => {
resolve()
})
this.socket.on('connect_error', reject)
this.bindListeners()
})
+45 -6
View File
@@ -1,10 +1,12 @@
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import ReconnectingWebSocket from 'reconnecting-websocket'
import 'xterm/css/xterm.css'
class SocketTerminal {
private term: Terminal
private fitAddon: FitAddon
private socket: ReconnectingWebSocket | null = null
constructor() {
this.term = new Terminal({
@@ -19,6 +21,44 @@ class SocketTerminal {
})
this.fitAddon = new FitAddon()
this.term.loadAddon(this.fitAddon)
this.term.onData((data) => {
if (this.socket) {
this.socket.send(data)
}
})
}
connect(url: string): Promise<void> {
return new Promise((resolve, reject) => {
console.log('Connecting to terminal', url)
this.term.write('\r\n\x1B[1;32mConnecting to terminal\x1B[0m\r\n')
this.socket = new ReconnectingWebSocket(url, [], {
connectionTimeout: 5000,
maxRetries: 10,
})
this.socket.onopen = () => {
console.log('Connected to terminal')
this.term.reset()
this.term.write('\r\n\x1B[1;32mConnected to terminal\x1B[0m\r\n')
resolve()
}
this.socket.onclose = () => {
console.log('Disconnected from terminal')
}
this.socket.onerror = (error) => {
console.error('WebSocket error:', error)
}
this.socket.onmessage = (event) => {
console.log('Received message from terminal')
const data =
typeof event.data === 'string'
? event.data
: new TextDecoder().decode(event.data)
this.term.write(data)
}
})
}
resizeScreen(): void {
@@ -34,12 +74,10 @@ class SocketTerminal {
this.resizeScreen()
}
write(message: string): void {
this.term.write(message)
}
onData(callback: (data: string) => void): void {
this.term.onData(callback)
send(message: string): void {
if (this.socket) {
this.socket.send(message)
}
}
focus(): void {
@@ -48,6 +86,7 @@ class SocketTerminal {
reset(): void {
this.term.reset()
this.socket?.close()
}
}
+12 -7
View File
@@ -1,10 +1,14 @@
<script setup lang="ts">
import { isValidUsername } from '../../../packages/utils'
import { useI18n } from 'vue-i18n'
import { isValidUsername } from '@odyssey/utils'
import AuthForm from '../components/AuthForm.vue'
import Background from '../components/DynamicBackground.vue'
import DynamicBackground from '../components/DynamicBackground.vue'
import HeaderPart from '../components/header/HeaderPart.vue'
import { TooManyRequestsError, ValidationError } from '../utils/errors'
import { checkUsername, chooseUsername } from '../utils/auth'
const { t } = useI18n()
async function check({
username,
error,
@@ -15,21 +19,21 @@ async function check({
}) {
if (username) {
if (!isValidUsername(username)) {
error('無效的帳號名稱')
error(t('authform_error.invalid_username'))
return
}
try {
await checkUsername(username)
} catch (err) {
if (err instanceof TooManyRequestsError) {
error('太多請求,兩分鐘後再試一次。')
error(t('authform_error.too_many_requests'))
return
}
if (err instanceof ValidationError) {
error(err.message)
return
}
error('出了點問題,請再試一次。')
error(t('authform_error.auth_failed'))
}
}
}
@@ -49,7 +53,7 @@ async function handleSubmit({
success()
} catch (err: any) {
if (err instanceof TooManyRequestsError) {
error('太多請求,兩分鐘後再試一次。')
error(t('authform_error.too_many_requests'))
return
}
if (err instanceof ValidationError) {
@@ -63,10 +67,11 @@ async function handleSubmit({
<template>
<div class="w-screen h-screen">
<Background class="w-full h-full" />
<DynamicBackground class="w-full h-full" />
<div
class="h-screen w-screen absolute top-0 left-0 flex flex-wrap justify-center content-center"
>
<HeaderPart />
<div class="w-fit">
<AuthForm
@onSubmit="handleSubmit"
+18 -3
View File
@@ -1,6 +1,8 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { useToast } from 'vue-toastification'
import { computed, onMounted, watch } from 'vue'
import useSession from '../store/session'
import { useSession } from '../store/session'
import useUserProfile from '../store/userProfile'
import HeaderPart from '../components/header/HeaderPart.vue'
import GameHeaderComponents from '../components/header/GameHeaderComponents.vue'
@@ -13,6 +15,8 @@ import CompleteModal from '../components/game/CompleteModal.vue'
import StartButton from '../components/game/StartButton.vue'
import { openQuestSurvey } from '../utils/formbricks'
const { t, locale } = useI18n()
const toast = useToast()
const sessionStore = useSession()
const userStore = useUserProfile()
@@ -27,6 +31,13 @@ watch(completed, (newValue, oldValue) => {
}
})
watch(locale, (newLocale) => {
const { session } = sessionStore
if (session && newLocale !== session.locale) {
toast.info(t('game.reset_to_apply_language'))
}
})
const props = defineProps({
questId: {
type: String,
@@ -37,8 +48,12 @@ const props = defineProps({
onMounted(async () => {
sessionStore.reset()
sessionStore.setup()
await sessionStore.setQuest(props.questId)
await sessionStore.getActiveSession()
await sessionStore.getActiveSession(props.questId)
if (!sessionStore.session) {
await sessionStore.setQuest(props.questId, locale.value)
}
})
</script>
+43 -53
View File
@@ -1,10 +1,13 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import ContactButton from '../components/ContactButton.vue'
import DynamicBackground from '../components/DynamicBackground.vue'
import LandingHeaderComponents from '../components/header/LandingHeaderComponents.vue'
import HeaderPart from '../components/header/HeaderPart.vue'
import { facebookUrl, githubUrl } from '../config'
const { t } = useI18n()
</script>
<template>
<div class="w-screen h-screen bg-scroll bg-bg">
@@ -18,13 +21,9 @@ import { facebookUrl, githubUrl } from '../config'
<div
class="flex flex-col md:flex-row mt-10 justify-around gap-5 items-center my-10"
>
<h1 class="text-text-primary text-7xl font-extrabold font-mono">
Linux
</h1>
<h1 class="text-text-primary text-7xl font-extrabold">Linux</h1>
<img src="../img/icon_totem.svg" class="h-[30vh]" />
<h1 class="text-text-primary text-7xl font-extrabold font-mono">
Odyssey
</h1>
<h1 class="text-text-primary text-7xl font-extrabold">Odyssey</h1>
</div>
<!-- intro -->
<div class="w-full md:w-2/3 px-5">
@@ -36,13 +35,7 @@ import { facebookUrl, githubUrl } from '../config'
class="text-text inline-block bg-bg-primary p-5 rounded-xl opacity-90"
style="font-size: 2.5vh"
>
程式設計不僅僅是寫程式碼,還涉及到如何有效地與你的電腦互動。
程式教育卻往往忽略背後「開發環境」的重要性,
使得許多學生在過程中充滿挫折。
「開發環境」是寫程式、執行程式過程所需要的一切工具。
而這些工具需要在終端機輸入指令來使用。
大部分的程式要用來運行的環境,並非 Windows 或 Mac OS,而是 Linux
作業系統。 Linux Odyssey 即是為此設計的線上 Linux 互動教學網站。
{{ t('landing.intro') }}
</h1>
</section>
<section
@@ -57,31 +50,27 @@ import { facebookUrl, githubUrl } from '../config'
class="h-[18vh] row-span-2"
/>
<h1
class="text-text-primary p-5 font-extrabold font-mono col-span-2"
class="text-text-primary p-5 font-extrabold col-span-2"
style="font-size: 3.5vh"
>
初學者也能立即上手
{{ t('landing.feature1') }}
</h1>
<h1 class="text-text p-2 col-span-2" style="font-size: 2.5vh">
我們明白對於初學者來說,設定和使用開發工具可能是一大障礙。
學習者無需安裝任何軟體,僅需通過瀏覽器即可連上一個真實的 Linux
環境。
{{ t('landing.feature1_desc') }}
</h1>
</div>
<div
class="bg-bg-primary p-5 rounded-xl opacity-90 grid grid-cols-3 grid-rows-2 justify-items-center items-center"
>
<h1
class="text-text-primary p-5 font-extrabold font-mono col-span-2"
class="text-text-primary p-5 font-extrabold col-span-2"
style="font-size: 3.5vh"
>
遊戲般的學習體驗
{{ t('landing.feature2') }}
</h1>
<img src="../img/icon_sword.svg" class="h-[18vh] row-span-2" />
<h1 class="text-text p-2 col-span-2" style="font-size: 2.5vh">
Linux Odyssey 融合了遊戲的樂趣與學習的實用性。
透過精心設計的遊戲關卡,學習者可以一邊接受挑戰、破解謎題,
一邊掌握 Linux 指令的運用。
{{ t('landing.feature2_desc') }}
</h1>
</div>
<div
@@ -92,15 +81,13 @@ import { facebookUrl, githubUrl } from '../config'
class="h-[18vh] row-span-2"
/>
<h1
class="text-text-primary p-5 font-extrabold font-mono col-span-2 pt-8"
class="text-text-primary p-5 font-extrabold col-span-2 pt-8"
style="font-size: 3.5vh"
>
真實的 Linux 操作之旅
{{ t('landing.feature3') }}
</h1>
<h1 class="text-text p-2 col-span-2" style="font-size: 2.5vh">
Linux Odyssey 提供的不僅是理論知識,更是真實的操作體驗。
每一個指令都是在真實的 Linux 環境中執行,
讓學習者能夠真正深入軟體開發的世界。
{{ t('landing.feature3_desc') }}
</h1>
</div>
</section>
@@ -120,7 +107,7 @@ import { facebookUrl, githubUrl } from '../config'
>
<RouterLink title="StartGame" id="StartGame" to="/register">
<div class="text-text text-xl p-2 w-full text-center">
準備好鍵盤,跟我們一起開啟你的 Linux 冒險吧!
{{ t('landing.start_journey') }}
</div>
</RouterLink>
</section>
@@ -129,24 +116,25 @@ import { facebookUrl, githubUrl } from '../config'
class="text-text flex flex-col items-center mt-10 gap-10"
>
<div class="w-full flex flex-col items-center gap-2">
<h1 class="text-text-primary text-3xl font-extrabold font-mono">
團隊介紹
<h1 class="text-text-primary text-3xl font-extrabold">
{{ t('landing.team_intro') }}
</h1>
<p class="text-lg">國立臺北科技大學 智慧自動化工程科 第二屆</p>
<p class="text-lg">
{{ t('landing.team_desc') }}
</p>
<div class="flex flex-row gap-5 justify-center">
<h1 class="font-bold">Wancat</h1>
<h1 class="font-bold">Neil</h1>
<h1 class="font-bold">A.H.</h1>
<h1 class="font-bold">Ray Gur</h1>
<h1 class="font-bold">{{ t('landing.team_member1') }}</h1>
<h1 class="font-bold">{{ t('landing.team_member2') }}</h1>
<h1 class="font-bold">{{ t('landing.team_member3') }}</h1>
<h1 class="font-bold">{{ t('landing.team_member4') }}</h1>
</div>
</div>
<div class="w-full flex flex-col items-center gap-2">
<h1 class="text-text-primary text-3xl font-extrabold font-mono">
得獎肯定
<h1 class="text-text-primary text-3xl font-extrabold">
{{ t('landing.awards') }}
</h1>
<h1 class="text-xl text-center">
大專校院資訊應用服務創新競賽<br />
鈦坦敏捷開發特別獎 第二名
{{ t('landing.award_desc') }}
</h1>
</div>
<div class="container mx-auto">
@@ -154,35 +142,37 @@ import { facebookUrl, githubUrl } from '../config'
class="justify-items-center grid grid-cols-1 sm:grid-cols-3 gap-5"
>
<h1
class="text-text-primary text-3xl font-extrabold font-mono sm:col-span-3 gap-6"
class="text-text-primary text-3xl font-extrabold sm:col-span-3 gap-6"
>
玩家感想
{{ t('landing.player_feedback') }}
<!--可以做成翻頁卡牌一次一個-->
</h1>
<h1 class="text-xl text-center">"很好玩很像益智遊戲"</h1>
<h1 class="text-xl text-center">
"我從來不知道自由軟體的存在,謝謝你們。"
{{ t('landing.feedback1') }}
</h1>
<h1 class="text-xl text-center">
"還蠻好玩的,讓程式變好玩"
{{ t('landing.feedback2') }}
</h1>
<h1 class="text-xl text-center">
"以前不喜歡電腦課現在覺得喜歡一點點"
{{ t('landing.feedback3') }}
</h1>
<h1 class="text-xl text-center">
"程式真的對新手很友善,讓我學到了很多東西"
{{ t('landing.feedback4') }}
</h1>
<h1 class="text-xl text-center">
"感覺做得很好很簡明易懂關卡設計很用心"
{{ t('landing.feedback5') }}
</h1>
<h1 class="text-xl text-center">
"這個體驗我覺得非常有趣,可以體驗到沒辦法體驗的程式,學長也都熱心指導,非常感謝學長的用心的講解,希望以後還可以再體驗這種活動"
{{ t('landing.feedback6') }}
</h1>
<h1 class="text-xl text-center">
"以前我覺得寫程式很難不過現在覺得很有趣"
{{ t('landing.feedback7') }}
</h1>
<h1 class="text-xl text-center">
"以前覺得寫程式是我生活中碰不到而且很難的項目。但通過這堂課之後,覺得寫程式不再那麼難以親近"
{{ t('landing.feedback8') }}
</h1>
<h1 class="text-xl text-center">
{{ t('landing.feedback9') }}
</h1>
</div>
</div>
@@ -192,8 +182,8 @@ import { facebookUrl, githubUrl } from '../config'
id="contact"
class="text-text mt-10 flex flex-col items-center"
>
<h1 class="text-text-primary font-extrabold font-mono text-3xl">
聯絡我們
<h1 class="text-text-primary font-extrabold text-3xl">
{{ t('landing.contact_us') }}
</h1>
<div
class="flex flex-row items-center justify-around mt-5 gap-5 mb-5"
+20 -6
View File
@@ -1,4 +1,5 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { ref, onMounted } from 'vue'
import { useToast } from 'vue-toastification'
import DynamicBackground from '../components/DynamicBackground.vue'
@@ -6,6 +7,8 @@ import HeaderPart from '../components/header/HeaderPart.vue'
import GameHeaderComponents from '../components/header/GameHeaderComponents.vue'
import api from '../utils/api'
const { t } = useI18n()
const leaderboard = ref<
{
username: string
@@ -21,7 +24,7 @@ async function getLeaderboard() {
leaderboard.value = res.data
} catch (err: any) {
console.error(err)
toast.error('讀取排行榜失敗')
toast.error(t('leaderboard.load_leaderboard_failed'))
}
}
@@ -37,22 +40,33 @@ onMounted(async () => {
class="w-screen h-screen absolute top-0 left-0 flex flex-wrap justify-center content-center"
>
<div class="w-full">
<HeaderPart title="排行榜" :headerComponent="GameHeaderComponents" />
<HeaderPart
:title="t('leaderboard.title')"
:headerComponent="GameHeaderComponents"
/>
</div>
<div class="w-fit h-[94vh] m-3">
<div
class="h-full bg-bg border-8 border-bg-primary flex flex-col items-center rounded-3xl p-10"
>
<h1 class="text-text-primary text-3xl mb-5">排行榜</h1>
<h1 class="text-text-primary text-3xl mb-5">
{{ t('leaderboard.title') }}
</h1>
<div class="max-h-300 overflow-auto">
<table class="w-full text-sm text-left text-text">
<thead
class="text-xs text-text-secondary uppercase bg-bg-secondary"
>
<tr>
<th scope="col" class="px-6 py-3">使用者名稱</th>
<th scope="col" class="px-6 py-3">分數</th>
<th scope="col" class="px-6 py-3">完成關卡</th>
<th scope="col" class="px-6 py-3">
{{ t('leaderboard.username') }}
</th>
<th scope="col" class="px-6 py-3">
{{ t('leaderboard.score') }}
</th>
<th scope="col" class="px-6 py-3">
{{ t('leaderboard.completed_quests') }}
</th>
</tr>
</thead>
<tbody>
+7 -4
View File
@@ -1,4 +1,5 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import AuthForm from '../components/AuthForm.vue'
import DynamicBackground from '../components/DynamicBackground.vue'
import HeaderPart from '../components/header/HeaderPart.vue'
@@ -10,6 +11,8 @@ import {
} from '../utils/errors'
import { login } from '../utils/auth'
const { t } = useI18n()
const handleLogin = async ({
username,
password,
@@ -27,19 +30,19 @@ const handleLogin = async ({
if (isSuccess) success()
} catch (err) {
if (err instanceof TooManyRequestsError) {
error('太多請求,兩分鐘後再試一次。')
error(t('authform_error.too_many_requests'))
return
}
if (err instanceof UnauthorizedError) {
error('錯誤的帳號名稱或密碼。')
error(t('authform_error.unauthorized'))
return
}
if (err instanceof ValidationError) {
error('無效的帳號名稱或密碼。')
error(err.message)
return
}
console.error(err)
error('出了點問題。')
error(t('authform_error.auth_failed'))
}
}
</script>
+4 -1
View File
@@ -1,13 +1,16 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import QuestMap from '../components/QuestMap.vue'
import HeaderPart from '../components/header/HeaderPart.vue'
import GameHeaderComponents from '../components/header/GameHeaderComponents.vue'
const { t } = useI18n()
</script>
<template>
<div class="w-fit">
<HeaderPart
title="關卡地圖"
:title="t('quest_map.title')"
:headerComponent="GameHeaderComponents"
class="z-50"
/>
+13 -10
View File
@@ -1,7 +1,8 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import validator from 'validator'
import { isValidUsername } from '../../../packages/utils'
import { passwordPolicy } from '../../../packages/constants'
import { isValidUsername } from '@odyssey/utils'
import { passwordPolicy } from '@odyssey/constants'
import AuthForm from '../components/AuthForm.vue'
import DynamicBackground from '../components/DynamicBackground.vue'
import HeaderPart from '../components/header/HeaderPart.vue'
@@ -12,6 +13,8 @@ import {
ValidationError,
} from '../utils/errors'
const { t } = useI18n()
function handleRegister({
username,
email,
@@ -30,11 +33,11 @@ function handleRegister({
.then(success)
.catch((err) => {
if (err instanceof TooManyRequestsError) {
error('太多請求,兩分鐘後再試一次。')
error(t('authform_error.too_many_requests'))
return
}
if (err instanceof UnauthorizedError) {
error('無效的帳號名稱或密碼。')
error(t('authform_error.unauthorized'))
return
}
if (err instanceof ValidationError) {
@@ -42,7 +45,7 @@ function handleRegister({
return
}
console.error(err)
error('出了點問題。')
error(t('authform_error.auth_failed'))
})
}
@@ -59,15 +62,15 @@ async function check({
error: (msg: string) => void
}) {
if (username && !isValidUsername(username)) {
error('無效的帳號名稱')
error(t('authform_error.invalid_username'))
return
}
if (email && !validator.isEmail(email)) {
error('無效的電子郵件')
error(t('authform_error.invalid_email'))
return
}
if (password && !validator.isStrongPassword(password, passwordPolicy)) {
error('密碼必須超過8個字元,至少包含一個數字、一個大寫及一個小寫。')
error(t('authform_error.invalid_password'))
return
}
try {
@@ -78,11 +81,11 @@ async function check({
return
}
if (err instanceof TooManyRequestsError) {
error('太多請求,兩分鐘後再試一次。')
error(t('authform_error.too_many_requests'))
return
}
console.error(err)
error('出了點問題。')
error(t('authform_error.auth_failed'))
}
}
</script>
+1 -10
View File
@@ -1,20 +1,11 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@game': path.resolve(__dirname, '../packages/game'),
'@models': path.resolve(__dirname, '../packages/models'),
'@utils': path.resolve(__dirname, '../packages/utils'),
'@constants': path.resolve(__dirname, '../packages/constants'),
'@file-graph': path.resolve(__dirname, '../packages/file-graph'),
},
},
server: {
host: '0.0.0.0',
proxy: {
'/trpc': {
target: process.env.API_TARGET || 'http://localhost:3000',
-6
View File
@@ -1,6 +0,0 @@
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
],
}
+2172
View File
File diff suppressed because it is too large. Load diff
+3
View File
@@ -0,0 +1,3 @@
[test]
coverage = true
coverageDir = "coverage"
-41
View File
@@ -7,45 +7,4 @@ server {
index index.html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:3000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering off;
}
location /trpc/ {
proxy_pass http://backend:3000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering off;
}
location /api-docs/ {
proxy_pass http://backend:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /socket.io/ {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering off;
}
}
+44 -7
View File
@@ -1,6 +1,24 @@
services:
traefik:
image: traefik:v3.6.9
restart: always
ports:
- 8000:8000
- 8080:8080
networks:
- players
- internal
command:
- '--api.insecure=true'
- '--providers.docker=true'
- '--providers.docker.exposedbydefault=false'
- '--entrypoints.web.address=:8000'
- '--entrypoints.web.forwardedHeaders.insecure=true' # trust all X-Forwarded headers
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
app:
image: linuxodyssey/frontend
image: linuxodyssey/frontend:${IMAGE_TAG:-latest}
depends_on:
- backend
restart: always
@@ -10,11 +28,15 @@ services:
target: prod
networks:
- internal
ports:
- 8080:80
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.app.entrypoints=web'
- 'traefik.http.routers.app.rule=PathPrefix(`/`)'
- 'traefik.http.routers.app.service=app'
- 'traefik.http.services.app.loadbalancer.server.port=80'
backend:
image: linuxodyssey/backend
image: linuxodyssey/backend:${IMAGE_TAG:-latest}
depends_on:
- db
restart: always
@@ -36,12 +58,27 @@ services:
- DOCKER_NETWORK=linux-odyssey-players
- BACKEND_URL=http://backend:3000
- HOST_PROJECT_ROOT=${PWD}
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.backend-api.entrypoints=web'
- 'traefik.http.routers.backend-api.rule=PathPrefix(`/api`)'
- 'traefik.http.routers.backend-api.service=backend'
- 'traefik.http.routers.backend-socket.entrypoints=web'
- 'traefik.http.routers.backend-socket.rule=PathPrefix(`/socket.io`)'
- 'traefik.http.routers.backend-socket.service=backend'
- 'traefik.http.routers.backend-trpc.entrypoints=web'
- 'traefik.http.routers.backend-trpc.rule=PathPrefix(`/trpc`)'
- 'traefik.http.routers.backend-trpc.service=backend'
- 'traefik.http.routers.backend-api-docs.entrypoints=web'
- 'traefik.http.routers.backend-api-docs.rule=PathPrefix(`/api-docs`)'
- 'traefik.http.routers.backend-api-docs.service=backend'
- 'traefik.http.services.backend.loadbalancer.server.port=3000'
analytics:
image: linuxodyssey/analytics
image: linuxodyssey/analytics:${IMAGE_TAG:-latest}
build:
context: .
dockerfile: packages/analytics/Dockerfile
dockerfile: services/analytics/Dockerfile
target: prod
restart: always
depends_on:
@@ -67,7 +104,7 @@ services:
- .env.prod
base:
image: linuxodyssey/quest-base
image: linuxodyssey/quest-base:${IMAGE_TAG:-latest}
build:
context: .
dockerfile: ./quests/Dockerfile
+27 -2
View File
@@ -1,8 +1,26 @@
version: '3'
services:
traefik:
image: traefik:v3.6.9
networks:
- players-dev
command:
- '--api.insecure=true'
- '--providers.docker=true'
- '--providers.docker.exposedbydefault=false'
- '--providers.file.directory=/etc/traefik/conf'
- '--providers.file.watch=true'
- '--entrypoints.web.address=:8000'
ports:
- '8000:8000'
- '8080:8080'
extra_hosts:
- 'host.docker.internal:host-gateway'
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik/conf:/etc/traefik/conf
db:
image: mongo:6
restart: always
networks:
- internal
ports:
@@ -19,6 +37,13 @@ services:
dockerfile: ./quests/Dockerfile
extra_hosts:
- 'host.docker.internal:host-gateway'
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.base.rule=PathPrefix(`/terminal/base`)'
- 'traefik.http.middlewares.base-stripprefix.stripprefix.prefixes=/terminal/base'
- 'traefik.http.routers.base.middlewares=base-stripprefix'
- 'traefik.http.routers.base.entrypoints=web'
- 'traefik.http.services.base.loadbalancer.server.port=9090'
networks:
internal:
+143 -92
View File
@@ -1,141 +1,192 @@
# Windows Environment Setup
## Install WSL and Ubuntu
## 1. Install WSL and Ubuntu
Please refer to the Official [Setup WSL](https://learn.microsoft.com/en-us/windows/wsl/setup/environment) on Microsoft's website.
Refer to Microsoft’s official [WSL installation guide](https://learn.microsoft.com/en-us/windows/wsl/install).
Run the following command in PowerShell as Administrator:
Open PowerShell as Administrator and run:
wsl --install
```powershell
wsl --install
```
Then restart the computer. After restarting, you can open Ubuntu terminal by searching "Ubuntu" in Start menu. You will be prompted to create a new user account. Once you have done that, you can continue with the following steps.
Restart your computer after the installation finishes.
## Setup Environment (In Ubuntu terminal)
Open Ubuntu from the Start menu. The first time Ubuntu starts, it will ask you to create a Linux username and password.
1. Update and upgrade
Verify that Ubuntu is using WSL 2 by running this command in PowerShell:
```
sudo apt-get update
sudo apt-get upgrade
```
```powershell
wsl --update
wsl --list --verbose
```
1. Install Git
Ubuntu should show `2` in the `VERSION` column.
```
sudo apt-get install git
```
If it is using WSL 1, run:
1. Install Node.js (Version 20.x)
```powershell
wsl --set-version Ubuntu 2
```
```
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install nodejs
sudo apt install build-essential
sudo npm install -g yarn
```
## 2. Install Docker Desktop
## Install Docker
Install [Docker Desktop for Windows](https://docs.docker.com/desktop/setup/install/windows-install/).
(Refer to [get.docker.com](https://get.docker.com/))
Start Docker Desktop after installation.
To install the latest stable versions of Docker CLI, Docker Engine, and their
dependencies:
Docker Desktop normally uses the WSL 2 engine automatically. If the `Use the WSL 2 based engine` option appears under `Settings > General`, ensure it is enabled.
1. Download the script
Go to:
```
curl -fsSL https://get.docker.com -o install-docker.sh
```
```text
Settings > Resources > WSL Integration
```
1. verify the script's content
Enable integration with your Ubuntu distribution, then select **Apply & restart**.
```
cat install-docker.sh
```
If the WSL Integration section is unavailable, ensure Docker Desktop is using Linux containers.
1. run the script with --dry-run to verify the steps it executes
> [!IMPORTANT]
> Do not separately install Docker Engine inside Ubuntu when using Docker Desktop. Having both installations may cause conflicts.
```
sh install-docker.sh --dry-run
```
Open the Ubuntu terminal and verify that Docker is available:
**NOTE: the script will recommend you to use Docker Desktop instead, but we need to use Docker inside WSL for the backend to work.** Just ignore it and wait for the installation to finish.
```bash
docker --version
docker compose version
docker run --rm hello-world
```
1. run the script either as root, or using sudo to perform the installation.
## 3. Set Up the Ubuntu Environment
```
sudo sh install-docker.sh
```
Run the following commands in the Ubuntu terminal.
1. Verify the installation
### Update the Package List
```
docker --version
```
```bash
sudo apt update
```
1. Add your user to the docker group
### Install the Required Tools
```
sudo usermod -aG docker $USER
```
```bash
sudo apt install -y git curl ca-certificates build-essential
```
**NOTE: You need to create a new WSL terminal to apply the changes.**
### Install Bun
1. Verify the installation
```bash
curl -fsSL https://bun.sh/install | bash
```
```
docker ps
```
This should return something like:
Restart your terminal (or run `source ~/.bashrc`) so `bun` is on your `PATH`.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Verify the installations:
## Run the Project (In Ubuntu terminal)
```bash
git --version
node --version
bun --version
```
1. Clone the repository
The Node.js version should be `20.x` or later, and the Bun version should be `1.3` or later.
```
git clone https://github.com/lancatlin/linux-odyssey.git
cd linux-odyssey
```
## 4. Clone the Project
Optional: To open the project in VSCode, run the following command inside the project folder:
> [!WARNING]
> Clone the repository into the WSL Linux filesystem, such as `~/projects`. Do not place it on a Windows-mounted drive such as `/mnt/c/...` or `/mnt/d/...`. The project uses a bind mount for MongoDB data, and Windows-mounted directories may cause permission and filesystem compatibility problems.
```
code .
```
Create and enter a project directory:
1. Install dependencies
```bash
mkdir -p <path-to-projects-directory>
cd <path-to-projects-directory>
```
```
yarn install
```
It is ok if there are some warnings and `gyp: ERR` errors, just verify there is `done` at the end.
Clone the repository:
1. Copy the environment variables
```bash
git clone https://github.com/linux-odyssey/linux-odyssey.git
cd linux-odyssey
```
```
cp .env.sample .env
```
### Optional: Open the Project in VS Code
1. Docker setup
Install [Visual Studio Code](https://code.visualstudio.com/) and the **WSL** extension first. Then run:
```
docker compose pull
docker compose build
docker compose up -d db
```
```bash
code .
```
<!-- Check folder ./config exist and is empty -->
<!-- Check .env file exist -->
## 5. Install Project Dependencies
1. Run the project
From the project root, run:
```
yarn build
yarn dev
```
```bash
bun install
```
<!-- Check ./config/ssh_key.pub is a file not a folder -->
Warnings during installation may be harmless. The installation succeeded if Bun finishes with an `installed` message and does not display an `error:` message.
Enjoy!
If a `gyp` error appears, confirm that it belongs to an optional dependency before ignoring it.
## 6. Create the Environment File
Copy the sample environment file:
```bash
cp .env.sample .env
```
Confirm that the file exists:
```bash
ls -la .env
```
The default values are suitable for local development. Do not use the sample secret key in a production environment.
## 7. Start the Docker Services
Ensure Docker Desktop is running, then execute:
```bash
docker compose pull
docker compose build
docker compose up -d
```
Check that the containers are running:
```bash
docker compose ps
```
To stop the Docker services later:
```bash
docker compose down
```
## 8. Run the Project
Start the frontend and backend development servers:
```bash
bun run dev
```
Keep the terminal running and open the following address in your browser:
[http://localhost:8000](http://localhost:8000)
To stop the development servers, press `Ctrl+C`.
### Optional: Verify the Production Build
You can verify that the project builds successfully by running:
```bash
bun run build
```
-201
View File
@@ -1,201 +0,0 @@
/**
* For a detailed explanation regarding each configuration property, visit:
* https://jestjs.io/docs/configuration
*/
import type { Config } from 'jest'
const config: Config = {
// All imported modules in your tests should be mocked automatically
// automock: false,
// Stop running tests after `n` failures
// bail: 0,
// The directory where Jest should store its cached dependency information
// cacheDirectory: "/tmp/jest_rs",
// Automatically clear mock calls, instances, contexts and results before every test
// clearMocks: false,
// Indicates whether the coverage information should be collected while executing the test
collectCoverage: true,
// An array of glob patterns indicating a set of files for which coverage information should be collected
// collectCoverageFrom: undefined,
// The directory where Jest should output its coverage files
coverageDirectory: 'coverage',
// An array of regexp pattern strings used to skip coverage collection
// coveragePathIgnorePatterns: [
// "/node_modules/"
// ],
// Indicates which provider should be used to instrument code for coverage
coverageProvider: 'v8',
// A list of reporter names that Jest uses when writing coverage reports
// coverageReporters: [
// "json",
// "text",
// "lcov",
// "clover"
// ],
// An object that configures minimum threshold enforcement for coverage results
// coverageThreshold: undefined,
// A path to a custom dependency extractor
// dependencyExtractor: undefined,
// Make calling deprecated APIs throw helpful error messages
// errorOnDeprecated: false,
// The default configuration for fake timers
// fakeTimers: {
// "enableGlobally": false
// },
// Force coverage collection from ignored files using an array of glob patterns
// forceCoverageMatch: [],
// A path to a module which exports an async function that is triggered once before all test suites
// globalSetup: undefined,
// A path to a module which exports an async function that is triggered once after all test suites
// globalTeardown: undefined,
// A set of global variables that need to be available in all test environments
// globals: {},
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
// maxWorkers: "50%",
// An array of directory names to be searched recursively up from the requiring module's location
// moduleDirectories: [
// "node_modules"
// ],
// An array of file extensions your modules use
// moduleFileExtensions: [
// "js",
// "mjs",
// "cjs",
// "jsx",
// "ts",
// "tsx",
// "json",
// "node"
// ],
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1', // Redirect .js imports to .ts files
},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
// modulePathIgnorePatterns: [],
// Activates notifications for test results
// notify: false,
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",
// A preset that is used as a base for Jest's configuration
// preset: undefined,
// Run tests from one or more projects
// projects: undefined,
// Use this configuration option to add custom reporters to Jest
// reporters: undefined,
// Automatically reset mock state before every test
// resetMocks: false,
// Reset the module registry before running each individual test
// resetModules: false,
// A path to a custom resolver
// resolver: undefined,
// Automatically restore mock state and implementation before every test
// restoreMocks: false,
// The root directory that Jest should scan for tests and modules within
// rootDir: undefined,
// A list of paths to directories that Jest should use to search for files in
// roots: [
// "<rootDir>"
// ],
// Allows you to use a custom runner instead of Jest's default test runner
// runner: "jest-runner",
// The paths to modules that run some code to configure or set up the testing environment before each test
// setupFiles: [],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
// The number of seconds after which a test is considered as slow and reported as such in the results.
// slowTestThreshold: 5,
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
// snapshotSerializers: [],
// The test environment that will be used for testing
// testEnvironment: "jest-environment-node",
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
// Adds a location field to test results
// testLocationInResults: false,
// The glob patterns Jest uses to detect test files
// testMatch: [
// "**/__tests__/**/*.[jt]s?(x)",
// "**/?(*.)+(spec|test).[tj]s?(x)"
// ],
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
// testPathIgnorePatterns: [
// "/node_modules/"
// ],
// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
// This option allows the use of a custom results processor
// testResultsProcessor: undefined,
// This option allows use of a custom test runner
// testRunner: "jest-circus/runner",
// A map from regular expressions to paths to transformers
// transform: undefined,
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
// transformIgnorePatterns: [
// "/node_modules/",
// "\\.pnp\\.[^\\/]+$"
// ],
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
// Indicates whether each individual test should be reported during the run
// verbose: undefined,
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
// watchPathIgnorePatterns: [],
// Whether to use watchman for file crawling
// watchman: true,
}
export default config
+20 -25
View File
@@ -9,34 +9,31 @@
"app",
"server",
"packages/*",
"services/*",
"tests"
],
"scripts": {
"app": "yarn workspace app dev",
"build": "yarn workspace server build && yarn workspace app build && yarn workspace analytics build",
"dev": "concurrently -n \"App,Server\" -c \"bgBlue.bold,bgGreen.bold\" \"yarn workspace app dev\" \"yarn workspace server dev\"",
"server": "yarn workspace server dev",
"app": "bun run --filter app dev",
"build": "bun run --filter app build",
"dev": "concurrently -n \"App,Server\" -c \"bgBlue.bold,bgGreen.bold\" \"bun run --filter app dev\" \"bun run --filter server dev\"",
"server": "bun run --filter server dev",
"lint": "eslint .",
"format": "prettier --ignore-path .prettierignore --write app server",
"test": "yarn node --experimental-vm-modules --no-warnings $(yarn bin jest)",
"test:e2e": "yarn workspace tests test",
"test:open": "yarn workspace tests test:open",
"analytics": "yarn workspace analytics dev",
"setup": "yarn workspace server setup",
"clean": "yarn workspace server clean",
"build:quests": "yarn workspace server build:quests"
"test": "bun test",
"test:e2e": "bun run --filter tests test",
"test:open": "bun run --filter tests test:open",
"analytics": "bun run --filter analytics dev",
"setup": "bun run --filter server setup",
"clean": "bun run --filter server clean",
"build:quests": "bun run --filter server build:quests",
"type-check": "bun run --filter server --filter analytics --filter app type-check"
},
"devDependencies": {
"@babel/core": "^7.24.0",
"@babel/preset-env": "^7.24.0",
"@babel/preset-typescript": "^7.23.3",
"@jest/globals": "^29.7.0",
"@types/jest": "^29.5.12",
"@types/bun": "^1.4.2",
"@types/node": "^20.10.4",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vue/eslint-config-prettier": "^7.1.0",
"babel-jest": "^29.7.0",
"concurrently": "^8.2.2",
"eslint": "^8.56.0",
"eslint-config-airbnb-base": "^15.0.0",
@@ -47,15 +44,13 @@
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-vue": "^9.15.1",
"globals": "^16.0.0",
"jest": "^29.7.0",
"prettier": "^3.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.3.3",
"vue-eslint-parser": "^9.4.2",
"zod-to-json-schema": "^3.24.5"
"vue-eslint-parser": "^9.4.2"
},
"dependencies": {
"latest": "^0.2.0"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
"packageManager": "bun@1.3.14",
"overrides": {
"@mapbox/node-pre-gyp/tar": "^7.5.19",
"@cypress/request/form-data": "^2.5.4"
}
}
-26
View File
@@ -1,26 +0,0 @@
FROM node:20-alpine as build
WORKDIR /app
COPY ./package.json yarn.lock ./
COPY packages/analytics/package.json ./packages/analytics/package.json
RUN yarn install --frozen-lockfile
COPY tsconfig.json ./tsconfig.json
COPY packages ./packages
RUN yarn workspace analytics build
# Production stage
FROM node:20-alpine as prod
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/packages/analytics ./packages/analytics
ENV NODE_ENV=production
ENV HOST=0.0.0.0
ENV PORT=3001
EXPOSE 3001
WORKDIR /app/packages/analytics
CMD [ "yarn", "start" ]
-10
View File
@@ -1,10 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": ["src", "../models"],
"ts-node": {
"swc": true
}
}
+7
View File
@@ -16,3 +16,10 @@ export const getSessionsRequestSchema = z.object({
})
export type GetSessionsRequest = z.infer<typeof getSessionsRequestSchema>
export const SUPPORTED_LOCALES = ['zh-TW', 'en'] as const
export const LOCALE_NAME_MAP: Record<string, string> = {
'zh-TW': '繁體中文',
en: 'English',
}
export type QuestLocale = (typeof SUPPORTED_LOCALES)[number]
+13
View File
@@ -0,0 +1,13 @@
{
"name": "@odyssey/constants",
"version": "0.0.0",
"private": true,
"main": "index.ts",
"types": "index.ts",
"exports": {
".": "./index.ts"
},
"dependencies": {
"zod": "^4.6.7"
}
}
-69
View File
@@ -1,69 +0,0 @@
const fs = require('fs').promises
const { exit } = require('process')
const handleCommand = require('./handleCommand.js')
const {
API_ENDPOINT,
TOKEN,
PWD,
CMD_NAME,
CMD_OUTPUT_FILE,
CMD_ERROR_FILE,
CMD_EXIT_CODE,
} = process.env
async function readOrNone(file) {
try {
return await fs.readFile(file, 'utf8')
} catch (_) {
return ''
}
}
async function main() {
if (!CMD_NAME) exit(0)
const params = await handleCommand(CMD_NAME)
const output = await readOrNone(CMD_OUTPUT_FILE)
const error = await readOrNone(CMD_ERROR_FILE)
const payload = {
command: CMD_NAME,
output,
error,
exit_code: CMD_EXIT_CODE,
pwd: PWD,
params,
}
try {
const response = await fetch(`${API_ENDPOINT}/api/v1/commands`, {
method: 'POST',
headers: {
Authorization: `Bearer ${TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
})
if (!response.ok) {
console.error(`Failed to send command: ${response.statusText}`)
const responseBody = await response.text()
console.error(`Response Body: ${responseBody}`)
}
} catch (e) {
console.error('Error occurred while sending command:', e)
}
}
main()
.then(exit)
.catch((err) => {
console.log(
'發生預期外的錯誤,請嘗試重新啟動 Quest,如果問題持續發生,請幫我們填寫右上角的錯誤回報表單。'
)
if (err.response && err.response.data) {
console.log(err.response.data)
} else {
console.log(err)
}
exit(1)
})
-69
View File
@@ -1,69 +0,0 @@
const fs = require('fs').promises
const path = require('path')
const { resolvePath } = require('./utils')
async function collectFilesInfo(inputPath, level = 0, hiddenFiles = false) {
let stats
try {
stats = await fs.stat(inputPath)
} catch (e) {
if (e.code === 'ENOENT') {
return []
}
throw e
}
const name = path.basename(inputPath)
const discovered = level <= 1 && (hiddenFiles || !name.startsWith('.'))
const self = {
path: inputPath,
name,
type: stats.isDirectory() ? 'directory' : 'file',
discovered,
}
const files = [self]
if (stats.isDirectory() && level < 2) {
try {
let entries = await fs.readdir(inputPath)
if (entries.length === 0) {
self.empty = true
return files
}
if (level > 0) {
entries = entries.slice(0, 5)
}
const result = await Promise.all(
entries.map((entry) =>
collectFilesInfo(path.join(inputPath, entry), level + 1, hiddenFiles)
)
)
files.push(...result.flat())
} catch (_) {
// ignore
}
}
return files
}
async function discoverFiles(argv) {
const targetPath = argv._.length < 2 ? ['.'] : argv._.slice(1)
try {
const result = (
await Promise.all(
targetPath
.map((p) => resolvePath(p))
.map((p) => collectFilesInfo(p, 0, argv.a || argv.all))
)
).flat()
if (result.length === 0) {
return {}
}
return { discover: result }
} catch (_) {
return {}
}
}
module.exports = {
discoverFiles,
collectFilesInfo,
}
-174
View File
@@ -1,174 +0,0 @@
const fs = require('fs').promises
const path = require('path')
const minimist = require('minimist')
const { discoverFiles, collectFilesInfo } = require('./discover')
const { resolvePath } = require('./utils')
const commandListeners = {
ls: {
opts: {
boolean: ['a', 'l', 'h'],
},
handler: discoverFiles,
},
cd: {
handler: changeDirectory,
},
touch: {
handler: createFiles,
},
mkdir: {
opts: {
boolean: ['p'],
},
handler: createFiles,
},
cp: {
opts: {
boolean: ['r'],
},
handler: copyFiles,
},
rm: {
opts: {
boolean: ['r', 'f', 'v'],
},
handler: removeFiles,
},
rmdir: {
opts: {
boolean: ['p', 'v'],
},
handler: removeFiles,
},
mv: {
handler: moveFiles,
},
pwd: {
handler: showCurrentPath,
},
}
async function handleCommand(command) {
const name = command.split(' ')[0]
const listener = commandListeners[name]
if (!listener) return {}
const argv = minimist(command.split(' '), listener.opts)
return listener.handler(argv)
}
function changeDirectory() {
return {
pwd: process.cwd(),
}
}
async function createFiles(argv) {
const { _ } = argv
const files = _.slice(1)
const results = []
for (const file of files) {
const filePath = resolvePath(file)
try {
const exists = await fs.stat(filePath)
if (exists) {
results.push({
path: filePath,
type: exists.isFile() ? 'file' : 'directory',
discovered: true,
})
}
} catch (err) {
if (err.code !== 'ENOENT') {
throw err
}
}
}
return {
add: results,
}
}
async function copyFiles(argv) {
const { _ } = argv
const files = _.slice(1)
if (files.length === 0) {
return undefined
}
const dest = files.pop()
const destPath = resolvePath(dest)
return {
discover: await collectFilesInfo(destPath, 0, true),
}
}
async function removeFiles(argv) {
const files = argv._.slice(1)
const results = []
for (const file of files) {
const filePath = resolvePath(file)
try {
await fs.access(filePath, fs.constants.F_OK)
} catch {
results.push({
path: filePath,
type: 'file',
discovered: false,
})
}
}
return {
remove: results,
}
}
async function moveFiles(argv) {
const { _ } = argv
const sources = _.slice(1)
if (sources.length === 0) {
return undefined
}
const dest = sources.pop()
const results = {
add: [],
remove: [],
}
// check source
for (const source of sources) {
const sourcePath = resolvePath(source)
try {
await fs.access(sourcePath, fs.constants.F_OK)
} catch {
results.remove.push({
path: sourcePath,
type: 'file',
discovered: false,
})
}
}
// check dest
const destPath = resolvePath(dest)
results.add = await collectFilesInfo(destPath, 0, true)
return results
}
function showCurrentPath() {
const pwd = process.cwd()
const dirs = pwd.split('/')
let currentPath = '/'
const result = []
for (const dir of dirs) {
currentPath = path.join(currentPath, dir)
result.push({
path: currentPath,
type: 'directory',
discovered: true,
})
}
return {
add: result,
}
}
module.exports = handleCommand
-13
View File
@@ -1,13 +0,0 @@
{
"name": "container",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "",
"watch": ""
},
"dependencies": {
"minimist": "^1.2.8"
}
}
-10
View File
@@ -1,10 +0,0 @@
const os = require('os')
const path = require('path')
function resolvePath(p) {
return path.resolve(process.cwd(), p.replace('~', os.homedir()))
}
module.exports = {
resolvePath,
}
+10
View File
@@ -0,0 +1,10 @@
{
"name": "@odyssey/file-graph",
"version": "0.0.0",
"private": true,
"main": "index.ts",
"types": "index.ts",
"exports": {
".": "./index.ts"
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, test, expect } from '@jest/globals'
import { describe, test, expect, beforeEach } from 'bun:test'
import File from '../file.js'
describe('File', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, test, expect } from '@jest/globals'
import { describe, test, expect, beforeEach } from 'bun:test'
import FileGraph from '../fileGraph.js'
import FileNode from '../fileNode.js'
import { FileObject } from '../file.js'
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, test, expect } from '@jest/globals'
import { describe, test, expect, beforeEach } from 'bun:test'
import { ParentNotExistsError } from '../errors.js'
import FileNode, { IFileNode } from '../fileNode.js'
import { FileObject } from '../file.js'
+1 -1
View File
@@ -1,4 +1,4 @@
import { FileGraph, IFileNode } from '../file-graph'
import { FileGraph, IFileNode } from '@odyssey/file-graph'
import { Quest } from './Quest'
import {
IQuest,
+15
View File
@@ -0,0 +1,15 @@
{
"name": "@odyssey/game",
"version": "0.0.0",
"private": true,
"main": "index.ts",
"types": "index.ts",
"exports": {
".": "./index.ts"
},
"dependencies": {
"@odyssey/file-graph": "workspace:*",
"zod": "^4.6.7",
"zod-to-json-schema": "^3.24.5"
}
}
+1 -1
View File
@@ -21,7 +21,7 @@ export const commandSchema = z.object({
output: z.string().optional(),
error: z.string().optional(),
pwd: z.string().optional(),
params: commandParamsSchema.optional(),
params: commandParamsSchema.optional().nullable(),
})
export type ICommand = z.infer<typeof commandSchema>
+1 -1
View File
@@ -1,4 +1,4 @@
import { IFileNode } from '../../file-graph'
import { IFileNode } from '@odyssey/file-graph'
export * from './condition.js'
export * from './stage.js'
+2 -23
View File
@@ -1,28 +1,7 @@
import { test, expect } from '@jest/globals'
import { IFileExistenceChecker, IFileInput } from '../schema'
import { test, expect } from 'bun:test'
import { checkFiles } from '../condition/FileMatcher.js'
import { Condition } from '../condition/Condition.js'
export class MockFileChecker implements IFileExistenceChecker {
private files: IFileInput[] = [
{
path: '/home/user/hello.txt',
type: 'file',
},
{
path: '/home/user/world.txt',
type: 'file',
},
{
path: '/home/user/Downloads',
type: 'directory',
},
]
async exists(file: IFileInput): Promise<boolean> {
return this.files.some((f) => f.path === file.path && f.type === file.type)
}
}
import { MockFileChecker } from './mockFileChecker'
test('file matcher', async () => {
const checker = new MockFileChecker()
+2 -2
View File
@@ -1,11 +1,11 @@
import { test, expect } from '@jest/globals'
import { it, test, expect } from 'bun:test'
import { Condition } from '../condition/Condition'
import { OutputMatcher } from '../condition/OutputMatcher'
import { PwdMatcher } from '../condition/PwdMatcher'
import { CommandMatcher } from '../condition/CommandMatcher'
import { ErrorMatcher } from '../condition/ErrorMatcher'
import { conditionSchema } from '../schema'
import { MockFileChecker } from './asyncCondition.test'
import { MockFileChecker } from './mockFileChecker'
test('command match', () => {
const matcher = new CommandMatcher('^echo start$')
+2 -2
View File
@@ -1,7 +1,7 @@
import { expect, it, describe } from '@jest/globals'
import { describe, it, expect } from 'bun:test'
import { IQuest } from '../schema'
import { GameSession } from '../Session'
import { MockFileChecker } from './asyncCondition.test'
import { MockFileChecker } from './mockFileChecker'
const quest: IQuest = {
id: 'quest1',
+22
View File
@@ -0,0 +1,22 @@
import type { IFileExistenceChecker, IFileInput } from '../schema'
export class MockFileChecker implements IFileExistenceChecker {
private files: IFileInput[] = [
{
path: '/home/user/hello.txt',
type: 'file',
},
{
path: '/home/user/world.txt',
type: 'file',
},
{
path: '/home/user/Downloads',
type: 'directory',
},
]
async exists(file: IFileInput): Promise<boolean> {
return this.files.some((f) => f.path === file.path && f.type === file.type)
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
import { expect, describe, it } from '@jest/globals'
import { describe, it, expect } from 'bun:test'
import { IQuest } from '../schema'
import { GameSession } from '../Session'
import { MockFileChecker } from './asyncCondition.test'
import { MockFileChecker } from './mockFileChecker'
const quest: IQuest = {
id: 'quest1',
+2 -2
View File
@@ -1,6 +1,6 @@
import { test, expect } from '@jest/globals'
import { test, expect } from 'bun:test'
import { Stage } from '../Stage'
import { MockFileChecker } from './asyncCondition.test'
import { MockFileChecker } from './mockFileChecker'
const checker = new MockFileChecker()
+9 -5
View File
@@ -1,10 +1,14 @@
import mongoose from 'mongoose'
export { User, IUser } from './user.js'
export { Session, ISession } from './session.js'
export { Command, ICommand } from './command.js'
export { UserProfile, IUserProfile, IProgress } from './userProfile.js'
export { ILoginAttempt, LoginAttempt } from './loginAttempt.js'
export { User, type IUser } from './user.js'
export { Session, type ISession } from './session.js'
export { Command, type ICommand } from './command.js'
export {
UserProfile,
type IUserProfile,
type IProgress,
} from './userProfile.js'
export { type ILoginAttempt, LoginAttempt } from './loginAttempt.js'
export async function connectDB(uri: string) {
const db = await mongoose.connect(uri)
+14
View File
@@ -0,0 +1,14 @@
{
"name": "@odyssey/models",
"version": "0.0.0",
"private": true,
"main": "index.ts",
"types": "index.ts",
"exports": {
".": "./index.ts"
},
"dependencies": {
"@odyssey/constants": "workspace:*",
"mongoose": "^8.24.1"
}
}
+10
View File
@@ -1,4 +1,6 @@
import { model, Schema, Types } from 'mongoose'
import type { QuestLocale } from '@odyssey/constants'
import { SUPPORTED_LOCALES } from '@odyssey/constants'
export interface INode {
path: string
@@ -27,7 +29,9 @@ export interface ISession {
_id: Types.ObjectId
user: Types.ObjectId
quest: string
locale: QuestLocale
containerId: string | null
containerName: string | null
status: 'active' | 'finished' | 'inactive'
createdAt: Date
updatedAt: Date
@@ -51,7 +55,13 @@ export const Session = model<ISession>(
ref: 'Quest',
required: true,
},
locale: {
type: String,
enum: SUPPORTED_LOCALES,
required: true,
},
containerId: String,
containerName: String,
status: {
type: String,
enum: ['active', 'finished', 'inactive'],
+10
View File
@@ -0,0 +1,10 @@
{
"name": "@odyssey/utils",
"version": "0.0.0",
"private": true,
"main": "index.ts",
"types": "index.ts",
"exports": {
".": "./index.ts"
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { test, expect } from '@jest/globals'
import { test, expect } from 'bun:test'
import { isValidEmail, isValidUsername } from '../auth'
test('check valid username', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect } from '@jest/globals'
import { describe, it, expect } from 'bun:test'
import { buildFileCheckCmd, File } from '../commands'
describe('buildFileCheckCmd function', () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, it, expect } from '@jest/globals'
import { describe, it, expect } from 'bun:test'
import DAG from '../dag'
describe('dag layers', () => {
+1 -1
View File
@@ -29,7 +29,7 @@ precmd() {
export CMD_ERROR_FILE=/tmp/cmd.error
# Now run your Node.js script with the result as an argument
node /usr/local/lib/container/cli.js; rm /tmp/cmd.out /tmp/cmd.error 2>/dev/null
/usr/local/lib/cmd-hook/cmd-hook; rm /tmp/cmd.out /tmp/cmd.error 2>/dev/null
# Reset variables
unset CMD_START_TIME
+22 -19
View File
@@ -1,32 +1,35 @@
FROM debian:bookworm-slim
FROM golang:1.24-alpine AS cmd-hook-builder
WORKDIR /app
COPY ./services/cmd-hook/go.mod ./
RUN go mod download
COPY ./services/cmd-hook/*.go ./
RUN go build -o cmd-hook
FROM golang:1.24-alpine AS terminal-builder
WORKDIR /app
COPY ./services/terminal-service/go.mod ./
COPY ./services/terminal-service/go.sum ./
RUN go mod download
COPY ./services/terminal-service/*.go ./services/terminal-service/index.html ./
RUN go build -o terminal-service
FROM debian:bookworm-slim AS main
LABEL maintainer="wancat@wancat.cc"
RUN apt-get update && apt-get install -y \
vim \
zsh \
curl \
openssh-server
sudo \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /var/cache/apt/*
RUN curl -fsSL https://deb.nodesource.com/setup_20.x -o nodesource_setup.sh
RUN bash nodesource_setup.sh
RUN apt-get install -y nodejs
RUN npm install -g yarn
RUN node -v && yarn -v
WORKDIR /usr/local/lib/container
COPY ./packages/container/package.json ./yarn.lock ./
RUN yarn install --modules-folder /usr/src/node_modules
ENV NODE_PATH=/usr/src/node_modules
COPY ./packages/container /usr/local/lib/container
COPY ./quests/.includes/zshrc /etc/zsh/zshrc
RUN rm -f /etc/motd /etc/issue /etc/issue.net /etc/update-motd.d/*
RUN rm -rf /etc/skel && mkdir -p /etc/skel
RUN mkdir -p /etc/ssh/authorized_keys && chmod 755 /etc/ssh/authorized_keys
COPY ./quests/.includes/sshd_config /etc/ssh/sshd_config
COPY ./quests/entrypoint.sh /entrypoint.sh
COPY --from=cmd-hook-builder /app/cmd-hook /usr/local/lib/cmd-hook/cmd-hook
COPY --from=terminal-builder /app/terminal-service /usr/local/lib/terminal-service/terminal-service
EXPOSE 22
EXPOSE 9090
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
File renamed without changes.
+92
View File
@@ -0,0 +1,92 @@
id: checkpoint-01
title: Checkpoint 1
image: base
instruction: |
This quest tests your understanding of:
1. `echo`: print text
2. `ls`: list the contents of a folder
3. `cd`: move between folders
4. `pwd`: show your current path
requirements:
- path
stages:
- id: start
name: Click `Start` to begin
condition:
command: echo start
response:
content: |
This quest checks what you have learned in the previous lessons.
You will need to choose the commands yourself.
Think about which commands can help you complete each task.
To continue, make the terminal print `next`.
- id: next
name: Make the terminal print `next`
requirements:
- start
condition:
output: next
response:
content: |
Now list the contents of your current folder.
- id: ls-home
name: List the contents of the current folder
requirements:
- next
condition:
pwd: /home/commander
command: ls
response:
content: |
Enter the `folder03` folder.
- id: cd-folder03
name: Enter `folder03`
requirements:
- ls-home
condition:
pwd: /home/commander/folder03
response:
content: |
Show your current path in the terminal.
- id: pwd-folder03
name: Show your current path
requirements:
- cd-folder03
condition:
command: pwd
output: /home/commander/folder03
response:
content: |
Now enter the `folder02` folder
and list its contents.
- id: ls-folder02
name: Enter `folder02` and list its contents
requirements:
- pwd-folder03
condition:
pwd: /home/commander/folder02
command: ls
response:
content: |
Finally, stay in `folder02`
and list the contents of `folder01`.
- id: finish
name: Stay in `folder02` and list the contents of `folder01`
requirements:
- ls-folder02
condition:
pwd: /home/commander/folder02
output: file1.txt
response:
content: |
Congratulations! You passed this checkpoint!
You are ready to move on to the next lessons.
+7
View File
@@ -0,0 +1,7 @@
echo start
echo next
ls
cd folder03
pwd
cd ../folder02
ls ../folder01
File renamed without changes.
File renamed without changes.
Loaded 100 of 306 files, more files were not shown because too many files have changed in this diff. Show more