Compare commits

..
229 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
Justin Lin 3b77d91796 Quest: remove unnecessary ls-stages (#195)
* quest: remove ls-stages in create

* feat: prevent throwing errors when failed to copy files

* feat: log new command in dev mode

* quest: copy

* quest: mv

* quest: rm

* quest: execute. Add many exceptions

* feat: pwd discovers parent folders
2025-04-30 15:01:25 +08:00
Justin Lin f0a09ac4d9 Feat filegraph (#194)
* feat: update filegraph on touch command

* feat: update filegraph on mkdir

* feat: add different parsing opts for each command

* refactor: replace axios with fetch. put handleCommand to a new file

* feat: add config for mounting cli in dev stage

* refactor: clean up unused validators

* feat: add command handler for copy files. reuse resolvePath function

* feat: add rm handler, support specific files deletion. Glob not supported yet

* feat: handle discover cases that the folder is actually empty

* feat: handle discover empty folder better and support rmdir

* feat: handle mv command

* refactor: remove unused console logs
2025-04-29 20:40:02 +08:00
Justin Lin a732c1d119 chore(deps): bump the npm_and_yarn group across 1 directory with 2 updates (#193)
Bumps the npm_and_yarn group with 2 updates in the / directory:
[braces](https://github.com/micromatch/braces) and
[nanoid](https://github.com/ai/nanoid).

Updates `braces` from 3.0.2 to 3.0.3
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/micromatch/braces/commit/74b2db2938fad48a2ea54a9c8bf27a37a62c350d"><code>74b2db2</code></a>
3.0.3</li>
<li><a
href="https://github.com/micromatch/braces/commit/88f1429a0f47e1dd3813de35211fc97ffda27f9e"><code>88f1429</code></a>
update eslint. lint, fix unit tests.</li>
<li><a
href="https://github.com/micromatch/braces/commit/415d660c3002d1ab7e63dbf490c9851da80596ff"><code>415d660</code></a>
Snyk js braces 6838727 (<a
href="https://redirect.github.com/micromatch/braces/issues/40">#40</a>)</li>
<li><a
href="https://github.com/micromatch/braces/commit/190510f79db1adf21d92798b0bb6fccc1f72c9d6"><code>190510f</code></a>
fix tests, skip 1 test in test/braces.expand</li>
<li><a
href="https://github.com/micromatch/braces/commit/716eb9f12d820b145a831ad678618731927e8856"><code>716eb9f</code></a>
readme bump</li>
<li><a
href="https://github.com/micromatch/braces/commit/a5851e57f45c3431a94d83fc565754bc10f5bbc3"><code>a5851e5</code></a>
Merge pull request <a
href="https://redirect.github.com/micromatch/braces/issues/37">#37</a>
from coderaiser/fix/vulnerability</li>
<li><a
href="https://github.com/micromatch/braces/commit/2092bd1fb108d2c59bd62e243b70ad98db961538"><code>2092bd1</code></a>
feature: braces: add maxSymbols (<a
href="https://github.com/micromatch/braces/issues/">https://github.com/micromatch/braces/issues/</a>...</li>
<li><a
href="https://github.com/micromatch/braces/commit/9f5b4cf47329351bcb64287223ffb6ecc9a5e6d3"><code>9f5b4cf</code></a>
fix: vulnerability (<a
href="https://security.snyk.io/vuln/SNYK-JS-BRACES-6838727">https://security.snyk.io/vuln/SNYK-JS-BRACES-6838727</a>)</li>
<li><a
href="https://github.com/micromatch/braces/commit/98414f9f1fabe021736e26836d8306d5de747e0d"><code>98414f9</code></a>
remove funding file</li>
<li><a
href="https://github.com/micromatch/braces/commit/665ab5d561c017a38ba7aafd92cc6655b91d8c14"><code>665ab5d</code></a>
update keepEscaping doc (<a
href="https://redirect.github.com/micromatch/braces/issues/27">#27</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/micromatch/braces/compare/3.0.2...3.0.3">compare
view</a></li>
</ul>
</details>
<br />

Updates `nanoid` from 3.3.7 to 3.3.11
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/ai/nanoid/releases">nanoid's
releases</a>.</em></p>
<blockquote>
<h2>3.3.11</h2>
<ul>
<li>Fixed React Native support.</li>
</ul>
<h2>3.3.10</h2>
<ul>
<li>Fixed React Native support (by <a
href="https://github.com/steida"><code>@​steida</code></a>).</li>
</ul>
<h2>3.3.9</h2>
<ul>
<li>Reduced npm package size.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ai/nanoid/blob/main/CHANGELOG.md">nanoid's
changelog</a>.</em></p>
<blockquote>
<h2>3.3.11</h2>
<ul>
<li>Fixed React Native support.</li>
</ul>
<h2>3.3.10</h2>
<ul>
<li>Fixed React Native support (by <a
href="https://github.com/steida"><code>@​steida</code></a>).</li>
</ul>
<h2>3.3.9</h2>
<ul>
<li>Reduced npm package size.</li>
</ul>
<h2>3.3.8</h2>
<ul>
<li>Fixed a way to break Nano ID by passing non-integer size (by <a
href="https://github.com/myndzi"><code>@​myndzi</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/ai/nanoid/commit/37289ceee51a3194a1f121a1e5d2bbb864076b74"><code>37289ce</code></a>
Release 3.3.11 version</li>
<li><a
href="https://github.com/ai/nanoid/commit/23690b77719ec8043c2509d28c1d74b0e2295b75"><code>23690b7</code></a>
Fix CI</li>
<li><a
href="https://github.com/ai/nanoid/commit/c147962de7f5da3311a0e731030a28f49c5266a3"><code>c147962</code></a>
Fix RN support</li>
<li><a
href="https://github.com/ai/nanoid/commit/a83734e28fa071f51fe3614a5fb891f08a4b91b2"><code>a83734e</code></a>
Move to manually ESM/CJS dual package</li>
<li><a
href="https://github.com/ai/nanoid/commit/bb12e8a6f9c37ebe0b5ff2c697b8f9dcf34c8948"><code>bb12e8a</code></a>
Release 3.3.10 version</li>
<li><a
href="https://github.com/ai/nanoid/commit/8f44264cd724080447f40620974163f1daca4612"><code>8f44264</code></a>
Fix Expo support</li>
<li><a
href="https://github.com/ai/nanoid/commit/adf9b0c05eeeebbbf391c16bbd93da2fc275e235"><code>adf9b0c</code></a>
Release 3.3.9 version</li>
<li><a
href="https://github.com/ai/nanoid/commit/1c6f08825b4f17c4462bd1c19dbc3f1c5626b76f"><code>1c6f088</code></a>
Remove dev file from npm package</li>
<li><a
href="https://github.com/ai/nanoid/commit/3044cd5e73f4cf31795f61f6e6b961c8c0a5c744"><code>3044cd5</code></a>
Release 3.3.8 version</li>
<li><a
href="https://github.com/ai/nanoid/commit/4fe34959c34e5b3573889ed4f24fe91d1d3e7231"><code>4fe3495</code></a>
Update size limit</li>
<li>Additional commits viewable in <a
href="https://github.com/ai/nanoid/compare/3.3.7...3.3.11">compare
view</a></li>
</ul>
</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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
2025-04-28 00:14:54 +08:00
dependabot[bot] da473ceb8f chore(deps): bump the npm_and_yarn group across 1 directory with 2 updates
Bumps the npm_and_yarn group with 2 updates in the / directory: [braces](https://github.com/micromatch/braces) and [nanoid](https://github.com/ai/nanoid).


Updates `braces` from 3.0.2 to 3.0.3
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

Updates `nanoid` from 3.3.7 to 3.3.11
- [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.7...3.3.11)

---
updated-dependencies:
- dependency-name: braces
  dependency-version: 3.0.3
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: nanoid
  dependency-version: 3.3.11
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-27 09:04:42 +00:00
Justin Lin 01d60e259c chore(deps): bump mongoose from 8.1.3 to 8.9.5 (#185)
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.1.3 to
8.9.5.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Automattic/mongoose/releases">mongoose's
releases</a>.</em></p>
<blockquote>
<h1>8.9.5 / 2025-01-13</h1>
<ul>
<li>fix: disallow nested $where in populate match</li>
<li>fix(schema): handle bitwise operators on Int32 <a
href="https://redirect.github.com/Automattic/mongoose/issues/15176">#15176</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15170">#15170</a></li>
</ul>
<h1>8.9.4 / 2025-01-09</h1>
<ul>
<li>fix(document): fix document not applying manual populate when using
a function in schema.options.ref <a
href="https://redirect.github.com/Automattic/mongoose/issues/15138">#15138</a>
<a href="https://github.com/IchirokuXVI">IchirokuXVI</a></li>
<li>fix(model): make Model.validate() static correctly cast document
arrays <a
href="https://redirect.github.com/Automattic/mongoose/issues/15169">#15169</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15164">#15164</a></li>
<li>fix(model): allow passing validateBeforeSave option to bulkSave() to
skip validation <a
href="https://redirect.github.com/Automattic/mongoose/issues/15161">#15161</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15156">#15156</a></li>
<li>fix(schema): allow multiple self-referencing discriminator schemas
using Schema.prototype.discriminator <a
href="https://redirect.github.com/Automattic/mongoose/issues/15142">#15142</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15120">#15120</a></li>
<li>types: avoid BufferToBinary&lt;&gt; wiping lean types when passed to
generic functions <a
href="https://redirect.github.com/Automattic/mongoose/issues/15160">#15160</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15158">#15158</a></li>
<li>docs: fix &lt;code&gt; in header ids <a
href="https://redirect.github.com/Automattic/mongoose/issues/15159">#15159</a></li>
<li>docs: fix header in field-level-encryption.md <a
href="https://redirect.github.com/Automattic/mongoose/issues/15137">#15137</a>
<a href="https://github.com/damieng">damieng</a></li>
</ul>
<h1>8.9.3 / 2024-12-30</h1>
<ul>
<li>fix(schema): make duplicate index error a warning for now to prevent
blocking upgrading <a
href="https://redirect.github.com/Automattic/mongoose/issues/15135">#15135</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15112">#15112</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15109">#15109</a></li>
<li>fix(model): handle document array paths set to non-array values in
Model.castObject() <a
href="https://redirect.github.com/Automattic/mongoose/issues/15124">#15124</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15075">#15075</a></li>
<li>fix(document): avoid using childSchemas.path for compatibility with
pre-Mongoose-8.8 schemas <a
href="https://redirect.github.com/Automattic/mongoose/issues/15131">#15131</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15071">#15071</a></li>
<li>fix(model): avoid throwing unnecessary error if updateOne() returns
null in save() <a
href="https://redirect.github.com/Automattic/mongoose/issues/15126">#15126</a></li>
<li>perf(cursor): clear the stack every time if using populate with
batchSize to avoid stack overflows with large docs <a
href="https://redirect.github.com/Automattic/mongoose/issues/15136">#15136</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/10449">#10449</a></li>
<li>types: make BufferToBinary avoid Document instances <a
href="https://redirect.github.com/Automattic/mongoose/issues/15123">#15123</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15122">#15122</a></li>
<li>types(model+query): avoid stripping out virtuals when calling
populate with paths generic <a
href="https://redirect.github.com/Automattic/mongoose/issues/15132">#15132</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15111">#15111</a></li>
<li>types(schema): add missing removeIndex <a
href="https://redirect.github.com/Automattic/mongoose/issues/15134">#15134</a></li>
<li>types: add cleanIndexes() to IndexManager interface <a
href="https://redirect.github.com/Automattic/mongoose/issues/15127">#15127</a></li>
<li>docs: move search endpoint to netlify <a
href="https://redirect.github.com/Automattic/mongoose/issues/15119">#15119</a></li>
</ul>
<h1>8.9.2 / 2024-12-19</h1>
<ul>
<li>fix(schema): avoid throwing duplicate index error if index spec keys
have different order or index has a custom name <a
href="https://redirect.github.com/Automattic/mongoose/issues/15112">#15112</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15109">#15109</a></li>
<li>fix(map): clean modified subpaths when overwriting values in map of
subdocs <a
href="https://redirect.github.com/Automattic/mongoose/issues/15114">#15114</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15108">#15108</a></li>
<li>fix(aggregate): pull session from transaction local storage for
aggregation cursors <a
href="https://redirect.github.com/Automattic/mongoose/issues/15094">#15094</a>
<a href="https://github.com/IchirokuXVI">IchirokuXVI</a></li>
<li>types: correctly handle union types in BufferToBinary and related
helpers <a
href="https://redirect.github.com/Automattic/mongoose/issues/15103">#15103</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15102">#15102</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15057">#15057</a></li>
<li>types: add UUID to RefType <a
href="https://redirect.github.com/Automattic/mongoose/issues/15115">#15115</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15101">#15101</a></li>
<li>docs: remove link to Mongoose 5.x docs from dropdown <a
href="https://redirect.github.com/Automattic/mongoose/issues/15116">#15116</a></li>
<li>docs(connection+document+model): remove remaining references to
remove(), clarify that deleteOne() does not execute until then() or
exec() <a
href="https://redirect.github.com/Automattic/mongoose/issues/15113">#15113</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15107">#15107</a></li>
</ul>
<h1>8.9.1 / 2024-12-16</h1>
<ul>
<li>fix(connection): remove heartbeat check in load balanced mode <a
href="https://redirect.github.com/Automattic/mongoose/issues/15089">#15089</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15042">#15042</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/14812">#14812</a></li>
<li>fix(discriminator): gather childSchemas when creating discriminator
to ensure $getAllSubdocs() can properly get all subdocs <a
href="https://redirect.github.com/Automattic/mongoose/issues/15099">#15099</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15088">#15088</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15092">#15092</a></li>
<li>fix(model): handle discriminators in castObject() <a
href="https://redirect.github.com/Automattic/mongoose/issues/15096">#15096</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15075">#15075</a></li>
<li>fix(schema): throw error if duplicate index definition using unique
in schema path and subsequent .index() call <a
href="https://redirect.github.com/Automattic/mongoose/issues/15093">#15093</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15056">#15056</a></li>
<li>fix: mark documents that are populated using hydratedPopulatedDocs
option as populated in top-level doc <a
href="https://redirect.github.com/Automattic/mongoose/issues/15080">#15080</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15048">#15048</a></li>
<li>fix(document+schema): improve error message for get() on invalid
path <a
href="https://redirect.github.com/Automattic/mongoose/issues/15098">#15098</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15071">#15071</a></li>
<li>docs: remove more callback doc references &amp; some small other
changes <a
href="https://redirect.github.com/Automattic/mongoose/issues/15095">#15095</a></li>
</ul>
<h1>8.9.0 / 2024-12-13</h1>
<!-- 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.9.5 / 2025-01-13</h1>
<ul>
<li>fix: disallow nested $where in populate match CVE-2025-23061</li>
<li>fix(schema): handle bitwise operators on Int32 <a
href="https://redirect.github.com/Automattic/mongoose/issues/15176">#15176</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15170">#15170</a></li>
</ul>
<h1>7.8.4 / 2025-01-13</h1>
<ul>
<li>fix: disallow nested $where in populate match CVE-2025-23061</li>
</ul>
<h1>6.13.6 / 2025-01-13</h1>
<ul>
<li>fix: disallow nested $where in populate match CVE-2025-23061</li>
</ul>
<h1>8.9.4 / 2025-01-09</h1>
<ul>
<li>fix(document): fix document not applying manual populate when using
a function in schema.options.ref <a
href="https://redirect.github.com/Automattic/mongoose/issues/15138">#15138</a>
<a href="https://github.com/IchirokuXVI">IchirokuXVI</a></li>
<li>fix(model): make Model.validate() static correctly cast document
arrays <a
href="https://redirect.github.com/Automattic/mongoose/issues/15169">#15169</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15164">#15164</a></li>
<li>fix(model): allow passing validateBeforeSave option to bulkSave() to
skip validation <a
href="https://redirect.github.com/Automattic/mongoose/issues/15161">#15161</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15156">#15156</a></li>
<li>fix(schema): allow multiple self-referencing discriminator schemas
using Schema.prototype.discriminator <a
href="https://redirect.github.com/Automattic/mongoose/issues/15142">#15142</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15120">#15120</a></li>
<li>types: avoid BufferToBinary&lt;&gt; wiping lean types when passed to
generic functions <a
href="https://redirect.github.com/Automattic/mongoose/issues/15160">#15160</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15158">#15158</a></li>
<li>docs: fix <code>&lt;code&gt;</code> in header ids <a
href="https://redirect.github.com/Automattic/mongoose/issues/15159">#15159</a></li>
<li>docs: fix header in field-level-encryption.md <a
href="https://redirect.github.com/Automattic/mongoose/issues/15137">#15137</a>
<a href="https://github.com/damieng">damieng</a></li>
</ul>
<h1>8.9.3 / 2024-12-30</h1>
<ul>
<li>fix(schema): make duplicate index error a warning for now to prevent
blocking upgrading <a
href="https://redirect.github.com/Automattic/mongoose/issues/15135">#15135</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15112">#15112</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15109">#15109</a></li>
<li>fix(model): handle document array paths set to non-array values in
Model.castObject() <a
href="https://redirect.github.com/Automattic/mongoose/issues/15124">#15124</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15075">#15075</a></li>
<li>fix(document): avoid using childSchemas.path for compatibility with
pre-Mongoose-8.8 schemas <a
href="https://redirect.github.com/Automattic/mongoose/issues/15131">#15131</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15071">#15071</a></li>
<li>fix(model): avoid throwing unnecessary error if updateOne() returns
null in save() <a
href="https://redirect.github.com/Automattic/mongoose/issues/15126">#15126</a></li>
<li>perf(cursor): clear the stack every time if using populate with
batchSize to avoid stack overflows with large docs <a
href="https://redirect.github.com/Automattic/mongoose/issues/15136">#15136</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/10449">#10449</a></li>
<li>types: make BufferToBinary avoid Document instances <a
href="https://redirect.github.com/Automattic/mongoose/issues/15123">#15123</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15122">#15122</a></li>
<li>types(model+query): avoid stripping out virtuals when calling
populate with paths generic <a
href="https://redirect.github.com/Automattic/mongoose/issues/15132">#15132</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15111">#15111</a></li>
<li>types(schema): add missing removeIndex <a
href="https://redirect.github.com/Automattic/mongoose/issues/15134">#15134</a></li>
<li>types: add cleanIndexes() to IndexManager interface <a
href="https://redirect.github.com/Automattic/mongoose/issues/15127">#15127</a></li>
<li>docs: move search endpoint to netlify <a
href="https://redirect.github.com/Automattic/mongoose/issues/15119">#15119</a></li>
</ul>
<h1>8.9.2 / 2024-12-19</h1>
<ul>
<li>fix(schema): avoid throwing duplicate index error if index spec keys
have different order or index has a custom name <a
href="https://redirect.github.com/Automattic/mongoose/issues/15112">#15112</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15109">#15109</a></li>
<li>fix(map): clean modified subpaths when overwriting values in map of
subdocs <a
href="https://redirect.github.com/Automattic/mongoose/issues/15114">#15114</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15108">#15108</a></li>
<li>fix(aggregate): pull session from transaction local storage for
aggregation cursors <a
href="https://redirect.github.com/Automattic/mongoose/issues/15094">#15094</a>
<a href="https://github.com/IchirokuXVI">IchirokuXVI</a></li>
<li>types: correctly handle union types in BufferToBinary and related
helpers <a
href="https://redirect.github.com/Automattic/mongoose/issues/15103">#15103</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15102">#15102</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15057">#15057</a></li>
<li>types: add UUID to RefType <a
href="https://redirect.github.com/Automattic/mongoose/issues/15115">#15115</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15101">#15101</a></li>
<li>docs: remove link to Mongoose 5.x docs from dropdown <a
href="https://redirect.github.com/Automattic/mongoose/issues/15116">#15116</a></li>
<li>docs(connection+document+model): remove remaining references to
remove(), clarify that deleteOne() does not execute until then() or
exec() <a
href="https://redirect.github.com/Automattic/mongoose/issues/15113">#15113</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15107">#15107</a></li>
</ul>
<h1>8.9.1 / 2024-12-16</h1>
<ul>
<li>fix(connection): remove heartbeat check in load balanced mode <a
href="https://redirect.github.com/Automattic/mongoose/issues/15089">#15089</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15042">#15042</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/14812">#14812</a></li>
<li>fix(discriminator): gather childSchemas when creating discriminator
to ensure $getAllSubdocs() can properly get all subdocs <a
href="https://redirect.github.com/Automattic/mongoose/issues/15099">#15099</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15088">#15088</a>
<a
href="https://redirect.github.com/Automattic/mongoose/issues/15092">#15092</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/5af0a109fcf206eb765c02e0fffe54a78ab95174"><code>5af0a10</code></a>
chore: release 8.9.5</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/a42d8f5e3b8a6c2abd7d32c15b0cc5edac928d4e"><code>a42d8f5</code></a>
Merge branch '7.x'</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/73e81abe3ec012f8255d3ca9978594075378faf4"><code>73e81ab</code></a>
chore: release 7.8.4</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/4fe9a904e3c2184ce6d01d9c3c8f3b239616f155"><code>4fe9a90</code></a>
Merge branch '6.x' into 7.x</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/e59e342e5d01bfeee31c5d5c796745315ecf0fa9"><code>e59e342</code></a>
chore: release 6.13.6</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/64a9f9706f2428c49e0cfb8e223065acc645f7bc"><code>64a9f97</code></a>
fix: disallow nested $where in populate match</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/fa33717db8c6ee2331c68241abff7a81b84a70fb"><code>fa33717</code></a>
Merge pull request <a
href="https://redirect.github.com/Automattic/mongoose/issues/15176">#15176</a>
from Automattic/vkarpov15/<a
href="https://redirect.github.com/Automattic/mongoose/issues/15170">gh-15170</a></li>
<li><a
href="https://github.com/Automattic/mongoose/commit/072860237a2b8d968e06d4090a24127de8cdff24"><code>0728602</code></a>
test: make test cast non-boolean value</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/0cad0d71a8667295c6abd4636ea7d7b5cdc164e8"><code>0cad0d7</code></a>
fix(schema): handle bitwise operators on Int32</li>
<li><a
href="https://github.com/Automattic/mongoose/commit/39886fbb57aaf345d01c0294cf2c3d2781898c29"><code>39886fb</code></a>
docs: quick changelog formatting fix</li>
<li>Additional commits viewable in <a
href="https://github.com/Automattic/mongoose/compare/8.1.3...8.9.5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mongoose&package-manager=npm_and_yarn&previous-version=8.1.3&new-version=8.9.5)](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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
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>
2025-04-27 17:00:44 +08:00
dependabot[bot] 0aeb9fe47e chore(deps): bump mongoose from 8.1.3 to 8.9.5
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.1.3 to 8.9.5.
- [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.1.3...8.9.5)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-version: 8.9.5
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-27 08:59:09 +00:00
Justin Lin fd4f3bf8f5 chore(deps): bump dompurify from 3.0.9 to 3.2.4 (#187)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.0.9 to
3.2.4.
<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.2.4</h2>
<ul>
<li>Fixed a conditional and config dependent mXSS-style <a
href="https://nsysean.github.io/posts/dompurify-323-bypass/">bypass</a>
reported by <a
href="https://github.com/nsysean"><code>@​nsysean</code></a></li>
<li>Added a new feature to allow specific hook removal, thanks <a
href="https://github.com/davecardwell"><code>@​davecardwell</code></a></li>
<li>Added <em>purify.js</em> and <em>purify.min.js</em> to exports,
thanks <a
href="https://github.com/Aetherinox"><code>@​Aetherinox</code></a></li>
<li>Added better logic in case no window object is president, thanks <a
href="https://github.com/yehuya"><code>@​yehuya</code></a></li>
<li>Updated some dependencies called out by dependabot</li>
<li>Updated license files etc to show the correct year</li>
</ul>
<h2>DOMPurify 3.2.3</h2>
<ul>
<li>Fixed two conditional sanitizer bypasses discovered by <a
href="https://github.com/parrot409"><code>@​parrot409</code></a> and <a
href="https://x.com/slonser_"><code>@​Slonser</code></a></li>
<li>Updated the attribute clobbering checks to prevent future bypasses,
thanks <a
href="https://github.com/parrot409"><code>@​parrot409</code></a></li>
</ul>
<h2>DOMPurify 3.2.2</h2>
<ul>
<li>Fixed a possible bypass in case a rather specific config for custom
elements is set, thanks <a
href="https://github.com/yaniv-git"><code>@​yaniv-git</code></a></li>
<li>Fixed several minor issues with the type definitions, thanks again
<a href="https://github.com/reduckted"><code>@​reduckted</code></a></li>
<li>Fixed a minor issue with the types reference for trusted types,
thanks <a
href="https://github.com/reduckted"><code>@​reduckted</code></a></li>
<li>Fixed a minor problem with the template detection regex on some
systems, thanks <a
href="https://github.com/svdb99"><code>@​svdb99</code></a></li>
</ul>
<h2>DOMPurify 3.2.1</h2>
<ul>
<li>Fixed several minor issues with the type definitions, thanks <a
href="https://github.com/reduckted"><code>@​reduckted</code></a> <a
href="https://github.com/ghiscoding"><code>@​ghiscoding</code></a> <a
href="https://github.com/asamuzaK"><code>@​asamuzaK</code></a> <a
href="https://github.com/MiniDigger"><code>@​MiniDigger</code></a></li>
<li>Fixed an issue with non-minified dist files and order of imports,
thanks <a
href="https://github.com/reduckted"><code>@​reduckted</code></a></li>
</ul>
<h2>DOMPurify 3.2.0</h2>
<ul>
<li>Added type declarations, thanks <a
href="https://github.com/reduckted"><code>@​reduckted</code></a> , <a
href="https://github.com/philmayfield"><code>@​philmayfield</code></a>,
<a href="https://github.com/aloisklink"><code>@​aloisklink</code></a>,
<a href="https://github.com/ssi02014"><code>@​ssi02014</code></a> and
others</li>
<li>Fixed a minor issue with the handling of hooks, thanks <a
href="https://github.com/kevin-mizu"><code>@​kevin-mizu</code></a></li>
</ul>
<h2>DOMPurify 3.1.7</h2>
<ul>
<li>Fixed an issue with comment detection and possible bypasses with
specific config settings, thanks <a
href="https://github.com/masatokinugawa"><code>@​masatokinugawa</code></a></li>
<li>Fixed several smaller typos in documentation and test &amp; build
files, thanks <a
href="https://github.com/christianhg"><code>@​christianhg</code></a></li>
<li>Added better support for Angular compiler, thanks <a
href="https://github.com/jeroen1602"><code>@​jeroen1602</code></a></li>
<li>Added several new attributes to HTML and SVG allow-list, thanks <a
href="https://github.com/Gigabyte5671"><code>@​Gigabyte5671</code></a>
and <a href="https://github.com/Rotzbua"><code>@​Rotzbua</code></a></li>
<li>Removed the <code>foreignObject</code> element from the list of HTML
entry-points, thanks <a
href="https://github.com/masatokinugawa"><code>@​masatokinugawa</code></a></li>
<li>Bumped several dependencies to be more up to date</li>
</ul>
<h2>DOMPurify 3.1.6</h2>
<ul>
<li>Fixed an issue with the execution logic of attribute hooks to
prevent bypasses, thanks <a
href="https://github.com/kevin-mizu"><code>@​kevin-mizu</code></a></li>
<li>Fixed an issue with element removal leading to uncaught errors
through DOM Clobbering, thanks <a
href="https://github.com/realansgar"><code>@​realansgar</code></a></li>
<li>Fixed a minor problem with the bower file pointing to the wrong dist
path</li>
<li>Fixed several minor typos in docs, comments and comment blocks,
thanks <a
href="https://github.com/Rotzbua"><code>@​Rotzbua</code></a></li>
<li>Updated several development dependencies</li>
</ul>
<h2>DOMPurify 3.1.5</h2>
<ul>
<li>Fixed a minor issue with the dist paths in <code>bower.js</code>,
thanks <a
href="https://github.com/HakumenNC"><code>@​HakumenNC</code></a></li>
<li>Fixed a minor issue with sanitizing HTML coming from copy&amp;paste
Word content, thanks <a
href="https://github.com/kakao-bishop-cho"><code>@​kakao-bishop-cho</code></a></li>
</ul>
<h2>DOMPurify 3.1.4</h2>
<ul>
<li>Fixed an issue with the recently implemented <code>isNaN</code>
checks, thanks <a
href="https://github.com/tulach"><code>@​tulach</code></a></li>
<li>Added several new popover attributes to allow-list, thanks <a
href="https://github.com/Gigabyte5671"><code>@​Gigabyte5671</code></a></li>
<li>Fixed the tests and adjusted the test runner to cover all
branches</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/cure53/DOMPurify/commit/ec29e65f3675077c1a78e6edcab97f797f004a2e"><code>ec29e65</code></a>
Merge pull request <a
href="https://redirect.github.com/cure53/DOMPurify/issues/1062">#1062</a>
from cure53/main</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/1c1b1838625851939d4b86436feeb3e3ccb7dbb6"><code>1c1b183</code></a>
chore: Preparing 3.2.4 release</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/d18ffcb554e0001748865da03ac75dd7829f0f02"><code>d18ffcb</code></a>
fix: Changed the template literal regex to avoid a config-dependent
bypass</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/0d64d2b12f9ecaa28899c60aba0b9ed5072c4d93"><code>0d64d2b</code></a>
Merge pull request <a
href="https://redirect.github.com/cure53/DOMPurify/issues/1060">#1060</a>
from yehuya/initializeTestImprovements</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/9ad79331566e0671788b120cc1f682f4e7f33f44"><code>9ad7933</code></a>
tests: DOMPurify custom window tests improvements</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/72760ca8ee425c3129420390d4c10afe698ff2fb"><code>72760ca</code></a>
Merge pull request <a
href="https://redirect.github.com/cure53/DOMPurify/issues/1059">#1059</a>
from yehuya/fixMissingWindowElement</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/bc72d44b2e3cec00d8ef2427869d03cb668969fa"><code>bc72d44</code></a>
Fix tests</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/363a89dd3a051b72334cd4d0c867616fdc4ee40d"><code>363a89d</code></a>
fix: handle undefined Element in DOMPurify initialization</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/f41b45df18a9666a50c1ad2662cee259230cfef4"><code>f41b45d</code></a>
Update LICENSE</li>
<li><a
href="https://github.com/cure53/DOMPurify/commit/b25bf26d674ff4db9074cef01fc51490cb1369a0"><code>b25bf26</code></a>
Update README.md</li>
<li>Additional commits viewable in <a
href="https://github.com/cure53/DOMPurify/compare/3.0.9...3.2.4">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.0.9&new-version=3.2.4)](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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
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>
2025-04-27 16:57:01 +08:00
dependabot[bot] 39c81e6b6e chore(deps): bump dompurify from 3.0.9 to 3.2.4
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.0.9 to 3.2.4.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.0.9...3.2.4)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.2.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-27 08:54:25 +00:00
Justin Lin ef24270e7e fix: remove the usage of secret in workflows (#192) 2025-04-27 16:51:22 +08:00
Justin Lin 13b90f83c4 chore(deps): bump axios from 1.6.7 to 1.8.2 (#186)
Bumps [axios](https://github.com/axios/axios) from 1.6.7 to 1.8.2.
<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>Release v1.8.2</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>http-adapter:</strong> add allowAbsoluteUrls to path
building (<a
href="https://redirect.github.com/axios/axios/issues/6810">#6810</a>)
(<a
href="https://github.com/axios/axios/commit/fb8eec214ce7744b5ca787f2c3b8339b2f54b00f">fb8eec2</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/lexcorp16"
title="+1/-1 ([#6810](https://github.com/axios/axios/issues/6810)
)">Fasoro-Joseph Alexander</a></li>
</ul>
<h2>Release v1.8.1</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>utils:</strong> move <code>generateString</code> to platform
utils to avoid importing crypto module into client builds; (<a
href="https://redirect.github.com/axios/axios/issues/6789">#6789</a>)
(<a
href="https://github.com/axios/axios/commit/36a5a620bec0b181451927f13ac85b9888b86cec">36a5a62</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+51/-47
([#6789](https://github.com/axios/axios/issues/6789) )">Dmitriy
Mozgovoy</a></li>
</ul>
<h2>Release v1.8.0</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>examples:</strong> application crashed when navigating
examples in browser (<a
href="https://redirect.github.com/axios/axios/issues/5938">#5938</a>)
(<a
href="https://github.com/axios/axios/commit/1260ded634ec101dd5ed05d3b70f8e8f899dba6c">1260ded</a>)</li>
<li>missing word in SUPPORT_QUESTION.yml (<a
href="https://redirect.github.com/axios/axios/issues/6757">#6757</a>)
(<a
href="https://github.com/axios/axios/commit/1f890b13f2c25a016f3c84ae78efb769f244133e">1f890b1</a>)</li>
<li><strong>utils:</strong> replace getRandomValues with crypto module
(<a
href="https://redirect.github.com/axios/axios/issues/6788">#6788</a>)
(<a
href="https://github.com/axios/axios/commit/23a25af0688d1db2c396deb09229d2271cc24f6c">23a25af</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>Add config for ignoring absolute URLs (<a
href="https://redirect.github.com/axios/axios/issues/5902">#5902</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6192">#6192</a>)
(<a
href="https://github.com/axios/axios/commit/32c7bcc0f233285ba27dec73a4b1e81fb7a219b3">32c7bcc</a>)</li>
</ul>
<h3>Reverts</h3>
<ul>
<li>Revert &quot;chore: expose fromDataToStream to be consumable (<a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a>)&quot;
(<a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a>)
(<a
href="https://github.com/axios/axios/commit/1317261125e9c419fe9f126867f64d28f9c1efda">1317261</a>),
closes <a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a> <a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a></li>
</ul>
<h3>BREAKING CHANGES</h3>
<ul>
<li>
<p>code relying on the above will now combine the URLs instead of prefer
request URL</p>
</li>
<li>
<p>feat: add config option for allowing absolute URLs</p>
</li>
<li>
<p>fix: add default value for allowAbsoluteUrls in buildFullPath</p>
</li>
<li>
<p>fix: typo in flow control when setting allowAbsoluteUrls</p>
</li>
</ul>
<h3>Contributors to this release</h3>
<!-- 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><a
href="https://github.com/axios/axios/compare/v1.8.1...v1.8.2">1.8.2</a>
(2025-03-07)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>http-adapter:</strong> add allowAbsoluteUrls to path
building (<a
href="https://redirect.github.com/axios/axios/issues/6810">#6810</a>)
(<a
href="https://github.com/axios/axios/commit/fb8eec214ce7744b5ca787f2c3b8339b2f54b00f">fb8eec2</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/lexcorp16"
title="+1/-1 ([#6810](https://github.com/axios/axios/issues/6810)
)">Fasoro-Joseph Alexander</a></li>
</ul>
<h2><a
href="https://github.com/axios/axios/compare/v1.8.0...v1.8.1">1.8.1</a>
(2025-02-26)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>utils:</strong> move <code>generateString</code> to platform
utils to avoid importing crypto module into client builds; (<a
href="https://redirect.github.com/axios/axios/issues/6789">#6789</a>)
(<a
href="https://github.com/axios/axios/commit/36a5a620bec0b181451927f13ac85b9888b86cec">36a5a62</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+51/-47
([#6789](https://github.com/axios/axios/issues/6789) )">Dmitriy
Mozgovoy</a></li>
</ul>
<h1><a
href="https://github.com/axios/axios/compare/v1.7.9...v1.8.0">1.8.0</a>
(2025-02-25)</h1>
<h3>Bug Fixes</h3>
<ul>
<li><strong>examples:</strong> application crashed when navigating
examples in browser (<a
href="https://redirect.github.com/axios/axios/issues/5938">#5938</a>)
(<a
href="https://github.com/axios/axios/commit/1260ded634ec101dd5ed05d3b70f8e8f899dba6c">1260ded</a>)</li>
<li>missing word in SUPPORT_QUESTION.yml (<a
href="https://redirect.github.com/axios/axios/issues/6757">#6757</a>)
(<a
href="https://github.com/axios/axios/commit/1f890b13f2c25a016f3c84ae78efb769f244133e">1f890b1</a>)</li>
<li><strong>utils:</strong> replace getRandomValues with crypto module
(<a
href="https://redirect.github.com/axios/axios/issues/6788">#6788</a>)
(<a
href="https://github.com/axios/axios/commit/23a25af0688d1db2c396deb09229d2271cc24f6c">23a25af</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>Add config for ignoring absolute URLs (<a
href="https://redirect.github.com/axios/axios/issues/5902">#5902</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6192">#6192</a>)
(<a
href="https://github.com/axios/axios/commit/32c7bcc0f233285ba27dec73a4b1e81fb7a219b3">32c7bcc</a>)</li>
</ul>
<h3>Reverts</h3>
<ul>
<li>Revert &quot;chore: expose fromDataToStream to be consumable (<a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a>)&quot;
(<a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a>)
(<a
href="https://github.com/axios/axios/commit/1317261125e9c419fe9f126867f64d28f9c1efda">1317261</a>),
closes <a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a> <a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a></li>
</ul>
<h3>BREAKING CHANGES</h3>
<ul>
<li>
<p>code relying on the above will now combine the URLs instead of prefer
request URL</p>
</li>
<li>
<p>feat: add config option for allowing absolute URLs</p>
</li>
<li>
<p>fix: add default value for allowAbsoluteUrls in buildFullPath</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/axios/axios/commit/a9f7689b0c4b6d68c7f587c3aa376860da509d94"><code>a9f7689</code></a>
chore(release): v1.8.2 (<a
href="https://redirect.github.com/axios/axios/issues/6812">#6812</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/fb8eec214ce7744b5ca787f2c3b8339b2f54b00f"><code>fb8eec2</code></a>
fix(http-adapter): add allowAbsoluteUrls to path building (<a
href="https://redirect.github.com/axios/axios/issues/6810">#6810</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/98120457559e573024862e2925d56295a965ad7e"><code>9812045</code></a>
chore(sponsor): update sponsor block (<a
href="https://redirect.github.com/axios/axios/issues/6804">#6804</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/72acf759373ef4e211d5299818d19e50e08c02f8"><code>72acf75</code></a>
chore(sponsor): update sponsor block (<a
href="https://redirect.github.com/axios/axios/issues/6794">#6794</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/2e64afdff5c41e38284a6fb8312f2745072513a1"><code>2e64afd</code></a>
chore(release): v1.8.1 (<a
href="https://redirect.github.com/axios/axios/issues/6800">#6800</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/36a5a620bec0b181451927f13ac85b9888b86cec"><code>36a5a62</code></a>
fix(utils): move <code>generateString</code> to platform utils to avoid
importing crypto...</li>
<li><a
href="https://github.com/axios/axios/commit/cceb7b1e154fbf294135c93d3f91921643bbe49f"><code>cceb7b1</code></a>
chore(release): v1.8.0 (<a
href="https://redirect.github.com/axios/axios/issues/6795">#6795</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/23a25af0688d1db2c396deb09229d2271cc24f6c"><code>23a25af</code></a>
fix(utils): replace getRandomValues with crypto module (<a
href="https://redirect.github.com/axios/axios/issues/6788">#6788</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/32c7bcc0f233285ba27dec73a4b1e81fb7a219b3"><code>32c7bcc</code></a>
feat: Add config for ignoring absolute URLs (<a
href="https://redirect.github.com/axios/axios/issues/5902">#5902</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6192">#6192</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/4a3e26cf65bb040b7eb4577d5fd62199b0f3d017"><code>4a3e26c</code></a>
chore(config): adjust rollup config to preserve license header to
minified Ja...</li>
<li>Additional commits viewable in <a
href="https://github.com/axios/axios/compare/v1.6.7...v1.8.2">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.6.7&new-version=1.8.2)](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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
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>
2025-04-27 16:46:31 +08:00
Justin Lin cb77a3e266 chore(deps): bump @trpc/server from 11.1.0 to 11.1.1 (#188)
Bumps
[@trpc/server](https://github.com/trpc/trpc/tree/HEAD/packages/server)
from 11.1.0 to 11.1.1.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/trpc/trpc/commit/9c1c753a778ac7a2709b1e81be392231c4657319"><code>9c1c753</code></a>
v11.1.1</li>
<li><a
href="https://github.com/trpc/trpc/commit/9beb26c636d44852e0f407f3d7a82ad54df65b4d"><code>9beb26c</code></a>
Merge commit from fork</li>
<li>See full diff in <a
href="https://github.com/trpc/trpc/commits/v11.1.1/packages/server">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@trpc/server&package-manager=npm_and_yarn&previous-version=11.1.0&new-version=11.1.1)](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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
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>
2025-04-27 16:45:48 +08:00
Justin Lin 61cb36f357 Fix/login limit (By Vincent) (#191)
This PR is originally by @Vincent23412 from #190 . Edited by @lancatlin
2025-04-27 16:43:56 +08:00
Justin Lin 58f3bf7817 fix: use config value instead of hard coded values 2025-04-27 16:41:19 +08:00
Justin Lin ccbc4ff4b0 feat(rate-limiting): implement rate limiting for login attempts and enhance configuration
- Added environment variables for `RATE_LIMIT_MAX_FAILED_ATTEMPTS` and `RATE_LIMIT_LOCKOUT_TIME`
- Integrated rate limiting into the login process with a maximum of 5 failed attempts
- Refactored login attempt recording into the `authRouter`
- Removed deprecated `recordLogin` middleware and adjusted related logic
2025-04-27 16:29:03 +08:00
Justin Lin aef760478c fix: remove the usage of 2025-04-27 16:07:00 +08:00
Vincent23412 bda68ad293 fix path bugs 2025-04-27 16:02:21 +08:00
Vincent23412 af2f1ef707 feat(auth): add LoginAttempt schema and record login attempts with failure rate limit
- Added `LoginAttempt` Mongoose schema to store login history
- Integrated login attempt recording into login flow (success/failure)
- Created `rateLimitByAccount` middleware to block login if 10 failed attempts in 10 minutes
2025-04-27 15:57:34 +08:00
dependabot[bot] 3b4891412e chore(deps): bump @trpc/server from 11.1.0 to 11.1.1
Bumps [@trpc/server](https://github.com/trpc/trpc/tree/HEAD/packages/server) from 11.1.0 to 11.1.1.
- [Release notes](https://github.com/trpc/trpc/releases)
- [Commits](https://github.com/trpc/trpc/commits/v11.1.1/packages/server)

---
updated-dependencies:
- dependency-name: "@trpc/server"
  dependency-version: 11.1.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-27 07:47:14 +00:00
dependabot[bot] ef588414db chore(deps): bump axios from 1.6.7 to 1.8.2
Bumps [axios](https://github.com/axios/axios) from 1.6.7 to 1.8.2.
- [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.6.7...v1.8.2)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.8.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-27 07:47:09 +00:00
Justin Lin bc43184adc chore(deps): bump express from 4.19.2 to 4.20.0 (#163)
Bumps [express](https://github.com/expressjs/express) from 4.19.2 to
4.20.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/expressjs/express/releases">express's
releases</a>.</em></p>
<blockquote>
<h2>4.20.0</h2>
<h2>What's Changed</h2>
<h3>Important</h3>
<ul>
<li>IMPORTANT: The default <code>depth</code> level for parsing
URL-encoded data is now <code>32</code> (previously was
<code>Infinity</code>)</li>
<li>Remove link renderization in html while using
<code>res.redirect</code></li>
</ul>
<h3>Other Changes</h3>
<ul>
<li>4.19.2 Staging by <a
href="https://github.com/wesleytodd"><code>@​wesleytodd</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5561">expressjs/express#5561</a></li>
<li>remove duplicate location test for data uri by <a
href="https://github.com/wesleytodd"><code>@​wesleytodd</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5562">expressjs/express#5562</a></li>
<li>feat: document beta releases expectations by <a
href="https://github.com/marco-ippolito"><code>@​marco-ippolito</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5565">expressjs/express#5565</a></li>
<li>Cut down on duplicated CI runs by <a
href="https://github.com/jonchurch"><code>@​jonchurch</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5564">expressjs/express#5564</a></li>
<li>Add a Threat Model by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5526">expressjs/express#5526</a></li>
<li>Assign captain of encodeurl by <a
href="https://github.com/blakeembrey"><code>@​blakeembrey</code></a> in
<a
href="https://redirect.github.com/expressjs/express/pull/5579">expressjs/express#5579</a></li>
<li>Nominate jonchurch as repo captain for <code>http-errors</code>,
<code>expressjs.com</code>, <code>morgan</code>, <code>cors</code>,
<code>body-parser</code> by <a
href="https://github.com/jonchurch"><code>@​jonchurch</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5587">expressjs/express#5587</a></li>
<li>docs: update Security.md by <a
href="https://github.com/inigomarquinez"><code>@​inigomarquinez</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5590">expressjs/express#5590</a></li>
<li>docs: update triage nomination policy by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5600">expressjs/express#5600</a></li>
<li>Add CodeQL (SAST) by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5433">expressjs/express#5433</a></li>
<li>docs: add UlisesGascon as triage initiative captain by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5605">expressjs/express#5605</a></li>
<li>deps: encodeurl@~2.0.0 by <a
href="https://github.com/blakeembrey"><code>@​blakeembrey</code></a> in
<a
href="https://redirect.github.com/expressjs/express/pull/5569">expressjs/express#5569</a></li>
<li>skip QUERY method test by <a
href="https://github.com/jonchurch"><code>@​jonchurch</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5628">expressjs/express#5628</a></li>
<li>ignore ETAG query test on 21 and 22, reuse skip util by <a
href="https://github.com/jonchurch"><code>@​jonchurch</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5639">expressjs/express#5639</a></li>
<li>add support Node.js@22 in the CI by <a
href="https://github.com/mertcanaltin"><code>@​mertcanaltin</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5627">expressjs/express#5627</a></li>
<li>doc: add table of contents, tc/triager lists to readme by <a
href="https://github.com/mertcanaltin"><code>@​mertcanaltin</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5619">expressjs/express#5619</a></li>
<li>List and sort all projects, add captains by <a
href="https://github.com/blakeembrey"><code>@​blakeembrey</code></a> in
<a
href="https://redirect.github.com/expressjs/express/pull/5653">expressjs/express#5653</a></li>
<li>docs: add <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
as captain for cookie-parser by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5666">expressjs/express#5666</a></li>
<li>✨ bring back query tests for node 21 by <a
href="https://github.com/ctcpip"><code>@​ctcpip</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5690">expressjs/express#5690</a></li>
<li>[v4] Deprecate <code>res.clearCookie</code> accepting
<code>options.maxAge</code> and <code>options.expires</code> by <a
href="https://github.com/jonchurch"><code>@​jonchurch</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5672">expressjs/express#5672</a></li>
<li>skip QUERY tests for Node 21 only, still not supported by <a
href="https://github.com/jonchurch"><code>@​jonchurch</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5695">expressjs/express#5695</a></li>
<li>📝 update people, add ctcpip to TC by <a
href="https://github.com/ctcpip"><code>@​ctcpip</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5683">expressjs/express#5683</a></li>
<li>remove minor version pinning from ci by <a
href="https://github.com/jonchurch"><code>@​jonchurch</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5722">expressjs/express#5722</a></li>
<li>Fix link variable use in attribution section of CODE OF CONDUCT by
<a href="https://github.com/IamLizu"><code>@​IamLizu</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5762">expressjs/express#5762</a></li>
<li>Replace Appveyor windows testing with GHA by <a
href="https://github.com/jonchurch"><code>@​jonchurch</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5599">expressjs/express#5599</a></li>
<li>Add OSSF Scorecard badge by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5436">expressjs/express#5436</a></li>
<li>update scorecard link by <a
href="https://github.com/bjohansebas"><code>@​bjohansebas</code></a> in
<a
href="https://redirect.github.com/expressjs/express/pull/5814">expressjs/express#5814</a></li>
<li>Nominate <a
href="https://github.com/IamLizu"><code>@​IamLizu</code></a> to the
triage team by <a
href="https://github.com/UlisesGascon"><code>@​UlisesGascon</code></a>
in <a
href="https://redirect.github.com/expressjs/express/pull/5836">expressjs/express#5836</a></li>
<li>deps: path-to-regexp@0.1.8 by <a
href="https://github.com/blakeembrey"><code>@​blakeembrey</code></a> in
<a
href="https://redirect.github.com/expressjs/express/pull/5603">expressjs/express#5603</a></li>
<li>docs: specify new instructions for <code>question</code> and
<code>discuss</code> by <a
href="https://github.com/IamLizu"><code>@​IamLizu</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5835">expressjs/express#5835</a></li>
<li>4.x: Upgrade <code>merge-descriptors</code> dependency by <a
href="https://github.com/RobinTail"><code>@​RobinTail</code></a> in <a
href="https://redirect.github.com/expressjs/express/pull/5781">expressjs/express#5781</a></li>
<li>path-to-regexp@0.1.10 by <a
href="https://github.com/blakeembrey"><code>@​blakeembrey</code></a> in
<a
href="https://redirect.github.com/expressjs/express/pull/5902">expressjs/express#5902</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/marco-ippolito"><code>@​marco-ippolito</code></a>
made their first contribution in <a
href="https://redirect.github.com/expressjs/express/pull/5565">expressjs/express#5565</a></li>
<li><a
href="https://github.com/inigomarquinez"><code>@​inigomarquinez</code></a>
made their first contribution in <a
href="https://redirect.github.com/expressjs/express/pull/5590">expressjs/express#5590</a></li>
<li><a
href="https://github.com/mertcanaltin"><code>@​mertcanaltin</code></a>
made their first contribution in <a
href="https://redirect.github.com/expressjs/express/pull/5627">expressjs/express#5627</a></li>
<li><a href="https://github.com/ctcpip"><code>@​ctcpip</code></a> made
their first contribution in <a
href="https://redirect.github.com/expressjs/express/pull/5690">expressjs/express#5690</a></li>
<li><a
href="https://github.com/bjohansebas"><code>@​bjohansebas</code></a>
made their first contribution in <a
href="https://redirect.github.com/expressjs/express/pull/5814">expressjs/express#5814</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/expressjs/express/compare/4.19.1...4.20.0">https://github.com/expressjs/express/compare/4.19.1...4.20.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/expressjs/express/blob/master/History.md">express's
changelog</a>.</em></p>
<blockquote>
<h1>4.20.0 / 2024-09-10</h1>
<ul>
<li>deps: serve-static@0.16.0
<ul>
<li>Remove link renderization in html while redirecting</li>
</ul>
</li>
<li>deps: send@0.19.0
<ul>
<li>Remove link renderization in html while redirecting</li>
</ul>
</li>
<li>deps: body-parser@0.6.0
<ul>
<li>add <code>depth</code> option to customize the depth level in the
parser</li>
<li>IMPORTANT: The default <code>depth</code> level for parsing
URL-encoded data is now <code>32</code> (previously was
<code>Infinity</code>)</li>
</ul>
</li>
<li>Remove link renderization in html while using
<code>res.redirect</code></li>
<li>deps: path-to-regexp@0.1.10
<ul>
<li>Adds support for named matching groups in the routes using a
regex</li>
<li>Adds backtracking protection to parameters without regexes
defined</li>
</ul>
</li>
<li>deps: encodeurl@~2.0.0
<ul>
<li>Removes encoding of <code>\</code>, <code>|</code>, and
<code>^</code> to align better with URL spec</li>
</ul>
</li>
<li>Deprecate passing <code>options.maxAge</code> and
<code>options.expires</code> to <code>res.clearCookie</code>
<ul>
<li>Will be ignored in v5, clearCookie will set a cookie with an expires
in the past to instruct clients to delete the cookie</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/expressjs/express/commit/21df421ebc7a5249bb31101da666bbf22adc3f18"><code>21df421</code></a>
4.20.0</li>
<li><a
href="https://github.com/expressjs/express/commit/4c9ddc1c47bf579e55c2fe837d76a952e9fd8959"><code>4c9ddc1</code></a>
feat: upgrade to serve-static@0.16.0</li>
<li><a
href="https://github.com/expressjs/express/commit/9ebe5d500d22cbb2b8aaa73446866b084c747971"><code>9ebe5d5</code></a>
feat: upgrade to send@0.19.0 (<a
href="https://redirect.github.com/expressjs/express/issues/5928">#5928</a>)</li>
<li><a
href="https://github.com/expressjs/express/commit/ec4a01b6b8814d7b007f36a3023f4dbafdbc3d09"><code>ec4a01b</code></a>
feat: upgrade to body-parser@1.20.3 (<a
href="https://redirect.github.com/expressjs/express/issues/5926">#5926</a>)</li>
<li><a
href="https://github.com/expressjs/express/commit/54271f69b511fea198471e6ff3400ab805d6b553"><code>54271f6</code></a>
fix: don't render redirect values in anchor href</li>
<li><a
href="https://github.com/expressjs/express/commit/125bb742a38cd97938a3932b47cc301e41c31f5d"><code>125bb74</code></a>
path-to-regexp@0.1.10 (<a
href="https://redirect.github.com/expressjs/express/issues/5902">#5902</a>)</li>
<li><a
href="https://github.com/expressjs/express/commit/2a980ad16052e53b398c9953fea50e3daa0b495c"><code>2a980ad</code></a>
merge-descriptors@1.0.3 (<a
href="https://redirect.github.com/expressjs/express/issues/5781">#5781</a>)</li>
<li><a
href="https://github.com/expressjs/express/commit/a3e7e05e0a435b7b4be25bd38d8d0ca19a773ca9"><code>a3e7e05</code></a>
docs: specify new instructions for <code>question</code> and
<code>discuss</code></li>
<li><a
href="https://github.com/expressjs/express/commit/c5addb9a17c5b4c9fccdd2c04153a30595e03385"><code>c5addb9</code></a>
deps: path-to-regexp@0.1.8 (<a
href="https://redirect.github.com/expressjs/express/issues/5603">#5603</a>)</li>
<li><a
href="https://github.com/expressjs/express/commit/e35380a39d94937e3d0f7119e0efbc7cd69d003f"><code>e35380a</code></a>
docs: add <a
href="https://github.com/IamLizu"><code>@​IamLizu</code></a> to the
triage team (<a
href="https://redirect.github.com/expressjs/express/issues/5836">#5836</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/expressjs/express/compare/4.19.2...4.20.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=express&package-manager=npm_and_yarn&previous-version=4.19.2&new-version=4.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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
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>
2025-04-27 15:46:10 +08:00
Justin Lin 13fb8737a3 Fix deploy (#183) 2025-04-27 12:38:16 +08:00
Justin Lin eaced63c68 feat: add console logger in production 2025-04-27 12:34:27 +08:00
Justin Lin b64cc6028c feat: add proxy settings to nginx.conf 2025-04-27 12:34:05 +08:00
Justin Lin dbf26bb490 fix: add docker cli into backend image 2025-04-27 12:33:36 +08:00
Justin Lin 698dc368e6 fix: use wrong parsed command body (#182) 2025-04-26 18:48:04 +08:00
Justin LinandCopilot 0a8ef9a37e Update packages/container/cli.js
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-26 18:45:35 +08:00
Justin Lin aeed963a75 fix: use wrong parsed command body 2025-04-26 18:43:43 +08:00
Justin Lin 128aae33ec fix: update project root detection and quest directory path (#181) 2025-04-26 18:13:27 +08:00
Justin Lin b86697b6db fix: validate command input in newCommand controller 2025-04-26 18:10:33 +08:00
Justin Lin cb1e395579 refactor: update project root detection and quest directory path 2025-04-26 18:02:49 +08:00
Justin Lin fbe1319183 fix: analytics dockerfile (#180) 2025-04-26 17:30:08 +08:00
Justin Lin 94389d4e1c fix: analytics dockerfile 2025-04-26 17:27:49 +08:00
Justin Lin a66b4f5adb Refactor game/packages/trpc (#179)
- Refactor game core logic in `packages/game`
- Use Zod to parse quests and store in memory directly
- Get quest responses dynamically. Not stored in Session anymore.
- Use tRPC to re-implement some of APIs
- Remove all package.json in `packages`, import them as regular files
- Add JSON schema for quest.yml for better editing experience
- Refine quest files
2025-04-26 17:10:58 +08:00
Justin Lin 9498bb77ef fix: linting 2025-04-26 17:02:47 +08:00
Justin Lin 6fe49c4f38 fix: dockerfile, production env settings 2025-04-26 16:38:32 +08:00
Justin Lin 3985d5d089 fix: server and app build 2025-04-26 13:22:32 +08:00
Justin Lin 253564376d fix: analytics type errors 2025-04-26 13:10:48 +08:00
Justin Lin f7e2b00358 fix: test in game and file-graph 2025-04-26 12:52:12 +08:00
Justin Lin d450613816 clean: remove unused code 2025-04-26 12:48:29 +08:00
Justin Lin 129d2ff49b quest: checkpoint-03 2025-04-26 12:35:20 +08:00
Justin Lin ad0cb3e4b2 quest: checkpoint-02 2025-04-26 12:30:57 +08:00
Justin Lin 66365b106e quest: checkpoint-1 2025-04-26 12:27:17 +08:00
Justin Lin f6ee9f91d4 quest: execute 2025-04-26 12:23:46 +08:00
Justin Lin 67e84d8cf9 quest: rm, fix copy (stages removed by AI) 2025-04-26 12:10:53 +08:00
Justin Lin fda0357a73 feat: add file moving quest with instructions and example files 2025-04-26 11:49:40 +08:00
Justin Lin e9e924165d feat: improve Description page switcher style 2025-04-26 11:48:07 +08:00
Justin Lin 937c5de6b8 fix: terminal overflow 2025-04-26 11:46:36 +08:00
Justin Lin 53c5391f61 quest: copy 2025-04-26 11:27:55 +08:00
Justin Lin 876cae6947 feat: close hint for new responses 2025-04-26 11:27:44 +08:00
Justin Lin beb58e233e quests: tab & create 2025-04-26 11:09:23 +08:00
Justin Lin f7860c6197 fix: update CLIFileExistenceChecker to accept containerId in constructor 2025-04-26 11:09:10 +08:00
Justin Lin 5077f9c677 feat: read quest 2025-04-25 19:57:49 +08:00
Justin Lin 9be288d2de feat: add new path quest with file navigation and update quest structure 2025-04-25 19:55:11 +08:00
Justin Lin cd6f062556 refactor: enhance get-started quest 2025-04-25 12:36:39 +08:00
Justin Lin c61f844e42 feat: add exploration quest with file navigation instructions and example files 2025-04-25 12:01:25 +08:00
Justin Lin 26e79690f8 feat: add pwd handling to session and update related components 2025-04-25 11:33:16 +08:00
Justin Lin fba92dad46 feat: integrate filegraph 2025-04-24 23:30:12 +08:00
Justin Lin b3ed0e646e fix: app import inteface 2025-04-24 23:23:58 +08:00
Justin Lin 87b8ca5d04 wip: replace packages with pure files 2025-04-24 23:20:40 +08:00
Justin Lin 2d95ca382f wip: integrate filegraph into session 2025-04-24 22:05:10 +08:00
Justin Lin cdd22634e0 refactor: replace "folder" with "directory" across file handling components and tests 2025-04-24 21:24:55 +08:00
Justin Lin 7e50c8e06c refactor: remove condition tests and update file node interfaces in game session
TODO: replace "folder" with "directory"
2025-04-24 18:10:47 +08:00
Justin Lin 0685d71299 refactor: remove print.js and simplify response handling in cli.js 2025-04-24 18:08:09 +08:00
Justin Lin 56049a0a29 fix: DAG setLayer logic 2025-04-23 17:58:24 +08:00
Justin Lin 9b5da4e818 feat: enhance game description with collapsible hint section and update hint text format 2025-04-23 17:44:23 +08:00
Justin Lin ab63595fba feat: add JSON schema for quest 2025-04-23 17:40:55 +08:00
Justin Lin 52e9a13645 feat: add isFinished method to GameSession and update commandController to handle session completion 2025-04-23 17:10:51 +08:00
Justin Lin cfbc386c16 refactor: update file-graph package structure and integrate with game session management 2025-04-23 17:04:00 +08:00
Justin Lin 92173bb7e9 refactor: migrate session management to TRPC and remove legacy API endpoints 2025-04-23 16:37:12 +08:00
Justin Lin b4b8f8baee feat: load responses and tasks from existing session 2025-04-23 16:17:10 +08:00
Justin Lin 2fcca0c4b9 refactor: update session management to handle tasks and responses in a single update 2025-04-23 16:03:39 +08:00
Justin Lin 66434ff897 fix: save new created session 2025-04-22 19:06:57 +08:00
Justin Lin a711e08328 refactor: update QuestMap component to use new node structure and simplify DAG class 2025-04-22 18:58:23 +08:00
Justin Lin 1616f62755 wip: migrate backend to new game package 2025-04-21 22:40:11 +08:00
Justin Lin 1d843f7355 refactor: remove unused quest-related schemas and consolidate exports 2025-04-21 21:42:54 +08:00
Justin Lin d2cdd1304a feat: getTasks 2025-04-21 18:31:33 +08:00
Justin Lin 254e4f75ed feat: include responses from Exceptions 2025-04-21 12:31:53 +08:00
Justin Lin 0f0f43b838 refactor: Create a new super class Event and prevent duplicate logic 2025-04-21 12:23:09 +08:00
Justin Lin 2dc40a2254 refactor: add new name "Event" for the set Stage and Exception 2025-04-21 11:58:05 +08:00
Justin Lin 6e804f0ed4 refactor: reuse satisfies function in condition 2025-04-21 11:53:32 +08:00
Justin Lin 3656868b66 feat: catch-all exceptions 2025-04-21 11:45:23 +08:00
Justin Lin cfce5ececa feat: add global exceptions 2025-04-21 11:41:07 +08:00
Justin Lin fb823814e0 feat: add stage exceptions 2025-04-21 11:19:59 +08:00
Justin Lin f7780c3d98 feat: add get responses 2025-04-18 15:17:25 +08:00
Justin Lin dae9e841ca feat: add run command 2025-04-18 15:04:28 +08:00
Justin Lin e622011b21 feat: add quest class and session getActiveStages 2025-04-18 14:54:10 +08:00
Justin Lin 471b781d85 refactor: separate schema to files 2025-04-18 14:33:41 +08:00
Justin Lin 57d8f24930 Merge branch 'game' into refactor-trpc 2025-04-18 14:27:41 +08:00
Justin Lin 6043226142 wip: migrating game handler 2025-04-18 14:27:36 +08:00
Justin Lin 61d1871e95 feat: parse all quest 2025-04-16 19:06:47 +08:00
Justin Lin ed4d04b658 feat: parse quest using zod, basic 2025-04-16 17:37:42 +08:00
Justin Lin 963655c1f7 wip: get active session 2025-04-16 16:58:24 +08:00
Justin Lin 423548804a feat: migreate get user profile to trpc 2025-04-16 16:40:03 +08:00
Justin Lin ac92950177 feat: migrate quest api to trpc 2025-04-16 16:24:29 +08:00
Justin Lin 55a41dd3b5 feat: integrate trpc to app 2025-04-16 16:02:23 +08:00
Justin Lin 529869671c feat: createContext 2025-04-16 15:36:12 +08:00
Justin Lin 6326b84a60 feat: init trpc 2025-04-16 15:27:00 +08:00
Justin Lin 8cc006e3a4 fix: check files using abs path (#175)
the docker user is changed from commander to root due to #168 pr.
Use absolute path instead of relative path to prevent false detection.
2025-02-15 20:55:03 +08:00
Justin Lin d6ae6d818d Fix network (#174) 2025-02-15 20:52:25 +08:00
wancat 6692ae2b9b fix: check files using abs path
(the docker user is changed due to feat-ssh pr)
2025-02-15 20:42:50 +08:00
Justin Lin fab02d03a9 fix: update env samples, use dash only for naming networks 2024-12-27 21:01:31 +08:00
Justin Lin 9e44ebe415 fix: remove unwanted error logging 2024-12-27 20:56:23 +08:00
Justin Lin 019caf58e4 fix: use a different docker network for dev to prevent "interna" settings conflicts 2024-12-27 20:56:05 +08:00
Justin Lin 19c44fbe52 wip: game schema 2024-10-10 16:22:20 +08:00
dependabot[bot] c254d6c948 chore(deps): bump express from 4.19.2 to 4.20.0
Bumps [express](https://github.com/expressjs/express) from 4.19.2 to 4.20.0.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.19.2...4.20.0)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-21 06:11:22 +00:00
Justin Lin e66598f1a7 chore: update dependencies 2024-08-28 14:52:45 +08:00
Justin Lin 2a868ead48 Merge branch 'main' into game 2024-08-28 14:52:13 +08:00
wancat b449ea455a feat: add Session and stage active check 2024-03-08 01:05:26 +08:00
wancat 5bea2ea78c feat: add stage condition checks 2024-03-08 00:47:50 +08:00
wancat 77fe2d37b3 feat: create stage 2024-03-08 00:38:49 +08:00
wancat 65ad72223b feat: add checkfiles into Condition 2024-03-08 00:24:51 +08:00
wancat d612b2d6af feat: add file matcher 2024-03-08 00:13:38 +08:00
wancat b5e20766a3 refactor: rename paths 2024-03-07 00:50:42 +08:00
wancat e5f5590a67 feat: add "or" and "not" matchers 2024-03-07 00:42:49 +08:00
wancat e83d913852 refactor: separate matchers 2024-03-07 00:25:50 +08:00
wancat 8280f7073d refactor: remove unnecessary patter matcher 2024-03-06 23:57:35 +08:00
wancat 4f3752060d feat: condition matcher 2024-03-06 23:54:03 +08:00
wancat cb26e1dcb0 feat: add output matcher 2024-03-06 23:32:23 +08:00
wancat 9eb08b45f4 feat: add pwdmatcher and update error matcher 2024-03-06 23:28:28 +08:00
wancat 3b4a808131 feat: create pattern and command matcher 2024-03-06 23:06:52 +08:00
wancat a8a19ca902 Merge branch 'ts-project-refs' into game 2024-03-06 22:39:49 +08:00
wancat 6967e230d0 feat: enable swc and ts-node in server dev 2024-02-29 00:33:41 +08:00
wancat 6c111a4475 feat: use babel to replace ts-jest (improve performance) 2024-02-28 23:32:06 +08:00
wancat 15278dfab2 fix: docker 2024-02-28 23:32:06 +08:00
wancat 0644783cc4 feat: use project references to build dependencies efficiently 2024-02-28 23:32:06 +08:00
413 changed files with 11980 additions and 15464 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
+4 -4
View File
@@ -3,6 +3,7 @@ PORT=3000
BASE_URL=https://example.com
SECRET_KEY=YOU_SHOULD_CHANGE_THIS
BACKEND_URL=http://backend:3000
DOCKER_NETWORK=linux-odyssey-players
MONGO_ROOT_PASSWORD=adminpassword
MONGO_USER=commander
@@ -23,14 +24,13 @@ ADMIN_PORT=3001
# TRUSTED_PROXIES=1.2.3.4
# valid configurations see isIP & isIPRange in https://github.com/validatorjs/validator.js?tab=readme-ov-file#validators
# RATE_LIMIT_MAX_FAILED_ATTEMPTS=5
# RATE_LIMIT_LOCKOUT_TIME=10
# GOOGLE_CLIENT_ID=
# GOOGLE_CLIENT_SECRET=
# GITHUB_CLIENT_ID=
# GITHUB_CLIENT_SECRET=
# SURVEY_URL=
# BUG_REPORT_URL=
# DOCKER_NETWORK=
# SURVEY_URL=
# BUG_REPORT_URL=
+5 -5
View File
@@ -1,8 +1,9 @@
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
# Optional
# BACKEND_URL=http://host.docker.internal:3000
@@ -11,14 +12,13 @@ SECRET_KEY=sample-secret
# TRUSTED_PROXIES=1.2.3.4
# valid configurations see isIP & isIPRange in https://github.com/validatorjs/validator.js?tab=readme-ov-file#validators
# RATE_LIMIT_MAX_FAILED_ATTEMPTS=5
# RATE_LIMIT_LOCKOUT_TIME=10
# GOOGLE_CLIENT_ID=
# GOOGLE_CLIENT_SECRET=
# GITHUB_CLIENT_ID=
# GITHUB_CLIENT_SECRET=
# SURVEY_URL=
# BUG_REPORT_URL=
# DOCKER_NETWORK=
# SURVEY_URL=
# BUG_REPORT_URL=
+2 -1
View File
@@ -2,4 +2,5 @@ vite.config.js
.gitignore
data
mongo-init.js
dist
dist
postgres-data
+36 -8
View File
@@ -2,7 +2,9 @@ module.exports = {
root: true,
env: {
node: true,
jest: true,
},
globals: {
Bun: 'readonly',
},
plugins: ['@typescript-eslint', 'cypress', 'vue'],
extends: [
@@ -20,9 +22,12 @@ module.exports = {
settings: {
'import/resolver': {
node: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
extensions: ['.js', '.ts'],
moduleDirectory: ['node_modules', 'packages', 'server/src'],
},
typescript: {
alwaysTryTypes: true,
},
typescript: {},
},
vue: {
version: '3.0', // Explicitly specify Vue 3
@@ -49,7 +54,7 @@ module.exports = {
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
'warn',
{
args: 'after-used',
argsIgnorePattern: '^_',
@@ -63,21 +68,44 @@ module.exports = {
// Allow missing file extensions
'import/extensions': [
'warn',
'off',
'ignorePackages',
{
js: 'off',
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
'no-unused-vars': 'warn',
'no-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 'error',
'no-empty-function': 'off',
'@typescript-eslint/no-empty-function': 'error',
'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error',
'no-restricted-imports': ['error', '../*'],
'import/no-relative-packages': 'off',
'no-await-in-loop': 'off',
},
overrides: [
{
files: ['**/tests/**/*.js', '**/tests/**/*.ts', '**/*.test.ts'], // Adjust the pattern to match your test files
files: ['**/tests/**/*.js', '**/tests/**/*.ts', '**/*.test.ts'],
rules: {
'import/extensions': 'off', // Turn off the rule for test files
'import/extensions': 'off',
'import/no-extraneous-dependencies': 'off',
},
},
{
files: ['server/**/*.ts'],
rules: {
'import/no-extraneous-dependencies': 'off',
},
},
{
files: ['**/packages/**/*.ts'],
rules: {
'no-restricted-imports': 'off',
'import/no-extraneous-dependencies': 'off',
},
},
+4 -3
View File
@@ -18,9 +18,9 @@ on:
secrets:
DOCKERHUB_USERNAME:
required: true
required: false
DOCKERHUB_TOKEN:
required: true
required: false
jobs:
build-and-push:
@@ -42,6 +42,7 @@ jobs:
type=semver,pattern={{version}}
- name: Login to Docker Hub
if: always()
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
@@ -53,5 +54,5 @@ jobs:
context: .
file: ${{ inputs.dockerfilePath }}
target: ${{ inputs.target }}
push: true
push: ${{ secrets.DOCKERHUB_USERNAME != '' }}
tags: ${{ steps.meta.outputs.tags }}
+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 -15
View File
@@ -2,15 +2,6 @@ name: CI Checks
on:
workflow_call:
secrets:
GOOGLE_CLIENT_ID:
required: true
GOOGLE_CLIENT_SECRET:
required: true
GH_CLIENT_ID:
required: true
GH_CLIENT_SECRET:
required: true
jobs:
ci:
@@ -20,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}}"
+3 -2
View File
@@ -1,6 +1,7 @@
name: E2E Tests
on: [push, pull_request]
on:
workflow_dispatch:
jobs:
e2e:
@@ -13,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:
-1
View File
@@ -12,7 +12,6 @@ concurrency:
jobs:
ci-checks:
uses: ./.github/workflows/ci-checks.yml
secrets: inherit
build:
needs: ci-checks
-1
View File
@@ -10,7 +10,6 @@ concurrency:
jobs:
ci-checks:
uses: ./.github/workflows/ci-checks.yml
secrets: inherit
build:
uses: ./.github/workflows/build.yml
-1
View File
@@ -12,7 +12,6 @@ concurrency:
jobs:
ci-checks:
uses: ./.github/workflows/ci-checks.yml
secrets: inherit
build:
needs: ci-checks
+6 -1
View File
@@ -1,4 +1,8 @@
config
.quest
tmp
services/terminal-service/terminal-service
bin
# Logs
logs
@@ -140,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"
}
+7 -1
View File
@@ -1,5 +1,11 @@
{
"editor.tabSize": 2,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
"editor.formatOnSave": true,
"yaml.schemas": {
"packages/game/quest.json": "quests/**/game.yml"
},
"[go]": {
"editor.defaultFormatter": "golang.go"
}
}
+41 -24
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,40 +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.
Build the whole project for the first time:
yarn build
This will build the typescript for each package and the server.
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`.
@@ -143,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:
@@ -163,13 +165,24 @@ Run Cypress in container, create brand-new containers along with it:
## Deployment
Create production env
cp .env.prod.sample .env.prod
Edit `.env.prod`
BASE_URL=https://yourdomain.com # IMPORTANT to make login work
SECRET_KEY=xxxx # Change it to something safe!
Start the service
# Build the images (only allowed for maintainers)
docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.prod.yml push
# 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
@@ -180,3 +193,7 @@ You can copy from `.env.sample`
**YOU MUST CHANGE THE SECRET_KEY** in `.env` file.
SECRET_KEY=your-secret-key
You can generate a random key by running
bun run setup
+16 -20
View File
@@ -1,31 +1,27 @@
# Base stage
FROM node:20-alpine as base
FROM oven/bun:1.3.14-alpine AS build
WORKDIR /app
COPY package.json yarn.lock tsconfig.json ./
COPY packages/file-graph/package.json ./packages/file-graph/package.json
COPY packages/utils/package.json ./packages/utils/package.json
COPY packages/constants/package.json ./packages/constants/package.json
COPY packages/models/package.json ./packages/models/package.json
COPY package.json bun.lock ./
COPY app/package.json ./app/package.json
RUN yarn install --frozen-lockfile
COPY server/package.json ./server/package.json
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
# Dev stage
FROM base as dev
WORKDIR /app/app
CMD [ "yarn", "dev:docker", "--host", "0.0.0.0" ]
# Build stage
FROM base as build
COPY packages/file-graph ./packages/file-graph
COPY packages/utils ./packages/utils
COPY packages/constants ./packages/constants
COPY packages/models ./packages/models
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
+18 -14
View File
@@ -5,8 +5,8 @@
"scripts": {
"dev": "vite",
"dev:docker": "API_TARGET=http://backend:3000 vite",
"build": "vue-tsc -b && vite build",
"type-check": "vue-tsc -b",
"build": "vue-tsc && vite build",
"type-check": "vue-tsc",
"preview": "vite preview"
},
"dependencies": {
@@ -16,18 +16,21 @@
"@fortawesome/free-regular-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/vue-fontawesome": "^3.0.3",
"@linux-odyssey/constants": "*",
"@linux-odyssey/file-graph": "*",
"@linux-odyssey/models": "*",
"@linux-odyssey/utils": "*",
"@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.6.0",
"dompurify": "^3.0.6",
"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",
@@ -37,13 +40,14 @@
},
"devDependencies": {
"@types/validator": "^13.11.9",
"@vitejs/plugin-vue": "^4.5.2",
"@vitejs/plugin-vue": "^5.2.2",
"@vue/compiler-sfc": "^3.3.13",
"@vue/tsconfig": "^0.7.0",
"autoprefixer": "^10.4.14",
"postcss": "^8.4.31",
"postcss": "^8.5.23",
"tailwindcss": "^3.3.3",
"typescript": "^5.3.3",
"vite": "^4.5.3",
"vue-tsc": "^2.0.10"
"typescript": "~5.7.2",
"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>
+1 -1
View File
@@ -22,7 +22,7 @@ function nodeClass() {
<template>
<a href="#" :class="nodeClass()">
<font-awesome-icon
v-if="node.type === 'folder'"
v-if="node.type === 'directory'"
:icon="['far', 'folder']"
class="text-text-primary size-8"
/>
+24 -4
View File
@@ -31,11 +31,31 @@ const html = computed(() => {
.markdown-content :deep(ol) {
list-style: decimal;
padding-left: 1em;
line-height: 1.2;
}
.markdown-content :deep(code) {
background-color: #282a33;
.markdown-content :deep(ul) {
list-style: disc;
padding-left: 1em;
line-height: 1.2;
}
.markdown-content :deep(pre) {
background-color: #2e3440;
border-radius: 0.5rem;
padding: 0.5rem;
font-size: 0.9rem;
color: #d8dee9;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border: 1px solid #4c566a;
line-height: 1.5;
font-family: 'monospace';
}
.markdown-content :deep(code:not(pre code)) {
background-color: #2e3440;
border-radius: 0.25rem;
padding: 0.25rem;
font-size: 0.875rem;
padding: 0.2rem 0.4rem;
font-size: 0.9rem;
color: #d8dee9;
font-family: 'monospace';
}
</style>
+17 -7
View File
@@ -1,9 +1,12 @@
<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 { getQuest } from '../utils/api'
import MarkdownText from './MarkdownText.vue'
import { trpc } from '../utils/trpc'
const { t, locale } = useI18n()
const props = defineProps({
questTitle: {
@@ -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 getQuest(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>
+94 -94
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 '@linux-odyssey/utils'
import { getQuests } from '../utils/api'
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,19 +68,18 @@ async function computeGraphData() {
if (!store.progress) return
try {
const quests = await getQuests()
const quests = await trpc.quests.getQuests.query({ locale: locale.value })
const dag = new DAG(quests)
const nodesValues = dag.getNodes()
const nodes = nodesValues.map((node) => ({
id: node._id,
id: node.id,
title: node.title,
x: marginX * node.layer * 2,
y:
marginY * node.index -
(marginX * dag.getLayer(node._id)) / 2 +
svgHeight.value / 2,
completed: store.progress[node._id]?.completed || false,
// 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>
+34 -11
View File
@@ -1,12 +1,16 @@
<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)
const length = computed(() => {
return sessionStore.session?.responses.length ?? 0
return sessionStore.session?.responses?.length ?? 0
})
const disabled = computed(() => {
@@ -14,6 +18,7 @@ const disabled = computed(() => {
})
watch(length, () => {
console.log('length update', length.value)
current.value = length.value - 1
})
@@ -28,6 +33,19 @@ const right = () => {
current.value += 1
}
}
const response = computed(() => {
if (!sessionStore.session) return null
if (current.value < 0) return null
if (current.value >= sessionStore.session.responses.length) return null
return sessionStore.session.responses[current.value]
})
watch(response, () => {
if (hintDetails.value) {
hintDetails.value.open = false
}
})
</script>
<template>
@@ -37,7 +55,9 @@ const right = () => {
: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"
@@ -62,27 +82,30 @@ const right = () => {
@click="right"
:disabled="disabled"
>
<font-awesome-icon :icon="['fas', 'arrow-right']" class="text-text" />
<font-awesome-icon
:icon="['fas', 'arrow-right']"
:class="disabled ? 'text-gray-600' : 'text-text'"
/>
</button>
</div>
</div>
<div id="hint" class="bg-bg p-8 overflow-y-auto">
<ul>
<li
v-for="response in sessionStore.session?.responses[current]"
v-if="response"
:key="response.type"
class="text-text font-xl whitespace-pre-wrap"
>
<div v-for="content in response.content" :key="content">
<MarkdownText :content="content" />
</div>
<MarkdownText :content="response.content" />
</li>
<li
v-for="hint in sessionStore.session?.hints[current]"
:key="hint"
v-if="response?.hint"
class="text-text-primary font-xl whitespace-pre-wrap"
>
<MarkdownText :content="hint" />
<details ref="hintDetails">
<summary class="cursor-pointer">{{ t('game.hint') }}</summary>
<MarkdownText :content="response.hint" />
</details>
</li>
</ul>
<br />
+8 -5
View File
@@ -1,12 +1,15 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { computed } from 'vue'
import MarkdownText from '../MarkdownText.vue'
import useSession from '../../store/session'
import { Task } from '../../types'
import { useSession } from '../../store/session'
const { t } = useI18n()
const sessionStore = useSession()
const tasks = computed(() => {
return sessionStore.session?.tasks.map((task: Task) => {
console.log('session', sessionStore.session)
return sessionStore.session?.tasks.map((task) => {
const prefix = task.completed ? '✓' : '➤'
const color = task.completed ? 'text-text-primary' : 'text-text'
return {
@@ -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>
+35 -11
View File
@@ -1,23 +1,47 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useTerminal } from '../../store/session'
import { useI18n } from 'vue-i18n'
import { onMounted, onUnmounted, ref } from 'vue'
import { useSession, useTerminal } from '../../store/session'
const { t } = useI18n()
const sessionStore = useSession()
const terminal = ref<HTMLElement | null>(null)
const term = useTerminal()
onMounted(() => {
const term = useTerminal()
if (!terminal.value) return
term.mount(terminal.value)
window.addEventListener('resize', () => term.resizeScreen())
const handleResize = () => term.resizeScreen()
window.addEventListener('resize', handleResize)
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
})
})
</script>
<template>
<font-awesome-icon :icon="['fas', 'terminal']" class="text-text p-1" />
<button id="Terminal" class="text-text h-[5%]">終端機</button>
<div
id="terminal"
ref="terminal"
class="bg-bg-secondary h-[calc(100%-5%)] p-0.5"
></div>
<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" />
<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"
ref="terminal"
class="bg-bg-secondary flex-grow overflow-hidden px-2"
style="height: calc(100vh - 40px)"
></div>
</div>
</template>
+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 { surveyUrl } from '../../config'
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,16 +23,21 @@ const handleLogout = async () => {
sessionStore.reset()
router.push({ name: 'login' })
} catch (err) {
toast.error('登出失敗')
toast.error(t('game_nav.sign_out_failed'))
console.error(err)
}
}
const openSurvey = async () => {
const surveyUrl = await trpc.links.surveyLink.query()
window.open(surveyUrl, '_blank')
}
onMounted(async () => {
try {
await userStore.loadUserProfile()
} catch (err) {
toast.error('無法讀取使用者資料')
toast.error(t('game_nav.load_user_profile_failed'))
console.error(err)
}
})
@@ -61,47 +68,46 @@ onMounted(async () => {
>
{{ userStore.username }}
</p>
<a
title="Survey"
:href="surveyUrl"
<button
:title="t('game_nav.survey')"
target="_blank"
class="md:h-5 md:w-5 px-1.5 w-auto"
@click="openSurvey"
>
<font-awesome-icon
:icon="['fas', 'file-invoice']"
class="text-text-primary inline"
/>
<span class="text-text sm:hidden px-2">Survey</span>
</a>
</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') {
+78 -51
View File
@@ -1,75 +1,100 @@
import { defineStore } from 'pinia'
import { FileGraph, FileObject } from '@linux-odyssey/file-graph'
import { IQuest } from '@linux-odyssey/models'
import { createSession, getActiveSession, getQuest } from '../utils/api'
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 { Session, StageResponse } from '../types'
import type { Session } from '../types'
import { trpc } from '../utils/trpc'
import { i18n } from '../i18n'
const socket = new Socket()
const term = new SocketTerminal(40, 80)
const term = new SocketTerminal()
let hasSetup = false
interface QuestDetailResponse {
id: string
title: string
instruction: string
requirements: string[]
}
interface SessionUpdate {
status: string
responses: IResponse[]
tasks: ITask[]
graphUpdate: FileGraphUpdateEvent
}
interface Store {
session: Session | null
questId: string
quest: IQuest | null
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 getQuest(questId)
async setQuest(questId: string, locale: QuestLocale) {
this.quest = await trpc.quests.getQuestDetail.query({
questId,
locale,
})
this.questId = questId
},
async setSession(session: Session) {
this.session = session
this.session.graph = new FileGraph(session.graph)
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(session)
await socket.connect(this.session)
await term.connect(
`/terminal/${session.containerName}/ws?token=${session.token}`
)
term.focus()
},
async createSession() {
const session = await createSession(this.questId)
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 getActiveSession(this.questId)
async getActiveSession(questId: string) {
const session = await trpc.session.getActiveSession.query({ questId })
if (session) {
this.setSession(session)
await this.setSession(session)
}
},
updateGraph(event: { discover?: FileObject[]; pwd?: string }) {
newUpdate(update: SessionUpdate) {
if (!this.session) return
if (event.discover) {
this.session.graph.discover(event.discover)
}
if (event.pwd) {
this.session.pwd = event.pwd
}
this.session.responses = update.responses
this.session.tasks = update.tasks
this.session.status = update.status
// if (
// response.status === 'finished' &&
// this.session.status !== 'finished'
// ) {
// this.finish()
// }
// this.session.status = response.status
},
newResponse(response: StageResponse) {
finish() {
if (!this.session) return
this.session.responses.push(response.responses)
this.session.hints.push(response.hints)
if (response.tasks) {
this.session.tasks = response.tasks
}
if (
response.status === 'finished' &&
this.session.status !== 'finished'
) {
this.finish()
}
this.session.status = response.status
this.session.status = 'finished'
},
finish() {},
reset() {
socket.reset()
term.reset()
@@ -77,17 +102,21 @@ const useSession = defineStore('session', {
},
setup() {
if (hasSetup) return
socket.on('terminal', (data: string) => {
term.write(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)
if (event.pwd) {
this.session.pwd = event.pwd
}
})
term.onData((data: string) => {
socket.emit('terminal', data)
})
socket.on('graph', (event: { discover: FileObject[]; pwd: string }) => {
this.updateGraph(event)
})
socket.on('response', (response: StageResponse) => {
this.newResponse(response)
socket.on('update', (update: SessionUpdate) => {
this.newUpdate(update)
})
hasSetup = true
},
@@ -101,5 +130,3 @@ const useSession = defineStore('session', {
export function useTerminal() {
return term
}
export default useSession
+2 -2
View File
@@ -1,5 +1,5 @@
import { defineStore } from 'pinia'
import { getUserProfile } from '../utils/api'
import { trpc } from '../utils/trpc'
interface IProgress {
quest: string
@@ -23,7 +23,7 @@ const useUserProfile = defineStore('userProfile', {
}),
actions: {
async loadUserProfile() {
const res = await getUserProfile()
const res = await trpc.users.getMyProfile.query()
this.$patch(res)
},
async resetUserProfile() {
+6 -6
View File
@@ -1,6 +1,5 @@
import { FileGraph } from '@linux-odyssey/file-graph'
// eslint-disable-next-line import/no-relative-packages
import { IResponse } from '@linux-odyssey/models'
import type { FileGraph } from '@odyssey/file-graph'
import type { IResponse, ITask } from '@odyssey/game'
export interface Task {
id: number
@@ -20,7 +19,8 @@ export interface Session {
status: string
graph: FileGraph
pwd: string
hints: string[][]
tasks: Task[]
responses: IResponse[][]
tasks: ITask[]
responses: IResponse[]
token: string
containerName: string
}
+4
View File
@@ -0,0 +1,4 @@
declare module '*.css' {
const content: string
export default content
}
-40
View File
@@ -1,8 +1,4 @@
import axios from 'axios'
import { IQuest } from '@linux-odyssey/models'
import { GetSessionsRequest } from '@linux-odyssey/constants'
import { Session } from '../types'
import { UserProfile } from '../store/userProfile'
const api = axios.create({
baseURL: '/api/v1',
@@ -12,39 +8,3 @@ const api = axios.create({
withCredentials: true,
})
export default api
export async function getUserProfile(): Promise<UserProfile> {
const res = await api.get<UserProfile>('/users/me')
return res.data
}
export async function getQuest(id: string): Promise<IQuest> {
const res = await api.get<IQuest>(`/quests/${id}`)
return res.data
}
export async function createSession(questId: string): Promise<Session> {
const res = await api.post<Session>('/sessions', { questId })
return res.data
}
export async function getSessions(
request: GetSessionsRequest
): Promise<Session[]> {
const res = await api.get<Session[]>('/sessions', { params: request })
return res.data
}
export async function getActiveSession(
questId: string
): Promise<Session | null> {
const res = await api.get<Session | null>('/sessions/active', {
params: { questId },
})
return res.data
}
export async function getQuests(): Promise<IQuest[]> {
const res = await api.get<IQuest[]>('/quests')
return res.data
}
+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') {
+2 -4
View File
@@ -1,5 +1,5 @@
import { io, Socket } from 'socket.io-client'
import { Session } from '../types'
import type { Session } from '../types'
type SocketCallback = (data: any) => void
@@ -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()
})
+59 -23
View File
@@ -1,47 +1,72 @@
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(rows: number, cols: number) {
constructor() {
this.term = new Terminal({
rows, // 行数
cols, // 不指定行数,自动回车后光标从下一行开始
convertEol: true, // 启用时,光标将设置为下一行的开头
// scrollback: 50, //终端中的回滚量
disableStdin: false, // 是否应禁用输入
// cursorStyle: "underline", //光标样式
cursorBlink: true, // 光标闪烁
convertEol: true,
scrollback: 1000,
fontSize: 16,
theme: {
foreground: '#ECECEC', // 字体
background: '#000000', // 背景色
cursor: 'help', // 设置光标
foreground: '#ECECEC',
background: '#000000',
cursor: 'help',
},
fontSize: 18,
fontWeight: 'normal',
})
this.fitAddon = new FitAddon()
this.term.loadAddon(this.fitAddon)
this.fitAddon.fit()
this.term.onData((data) => {
if (this.socket) {
this.socket.send(data)
}
})
}
write(message: string): void {
this.term.write(message)
}
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()
}
onData(callback: any): void {
this.term.onData(callback)
}
this.socket.onclose = () => {
console.log('Disconnected from terminal')
}
focus(): void {
this.term.focus()
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 {
this.fitAddon.fit()
try {
this.fitAddon.fit()
} catch (e) {
console.error('Failed to resize terminal:', e)
}
}
mount(reference: HTMLElement): void {
@@ -49,8 +74,19 @@ class SocketTerminal {
this.resizeScreen()
}
send(message: string): void {
if (this.socket) {
this.socket.send(message)
}
}
focus(): void {
this.term.focus()
}
reset(): void {
this.term.reset()
this.socket?.close()
}
}
+16
View File
@@ -0,0 +1,16 @@
import { createTRPCClient, httpBatchLink } from '@trpc/client'
import type { AppRouter } from '../../../server/src/routers'
export const trpc = createTRPCClient<AppRouter>({
links: [
httpBatchLink({
url: '/trpc',
// You can pass any HTTP headers you wish here
// async headers() {
// return {
// authorization: getAuthCookie(),
// }
// },
}),
],
})
+12 -7
View File
@@ -1,10 +1,14 @@
<script setup lang="ts">
import { isValidUsername } from '@linux-odyssey/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 '@linux-odyssey/utils'
import { passwordPolicy } from '@linux-odyssey/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>
+14
View File
@@ -0,0 +1,14 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}
+3 -26
View File
@@ -1,30 +1,7 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*.ts", "src/**/*.vue"],
"files": [],
"references": [
{ "path": "../packages/utils" },
{ "path": "../packages/constants" },
{ "path": "../packages/file-graph" },
{ "path": "../packages/models" }
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}
+24
View File
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}
+6
View File
@@ -5,7 +5,13 @@ import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
host: '0.0.0.0',
proxy: {
'/trpc': {
target: process.env.API_TARGET || 'http://localhost:3000',
changeOrigin: false,
xfwd: true,
},
'/api': {
target: process.env.API_TARGET || 'http://localhost:3000',
changeOrigin: false,
-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"
+1 -18
View File
@@ -1,27 +1,10 @@
server {
listen 80;
error_log /var/log/nginx/error.log debug;
location / {
root /usr/share/nginx/html;
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;
}
location /api-docs/ {
proxy_pass http://backend:3000;
}
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;
}
}
+48 -11
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
@@ -9,12 +27,16 @@ services:
dockerfile: app/Dockerfile
target: prod
networks:
internal:
ports:
- 8080:80
- internal
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
@@ -31,17 +53,32 @@ services:
- ./config:/app/config
- ./quests:/app/quests:ro
env_file:
- .env
- .env.prod
environment:
- 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:
@@ -51,7 +88,7 @@ services:
ports:
- '3001:3001'
env_file:
- .env
- .env.prod
db:
image: mongo:6
@@ -64,10 +101,10 @@ services:
- mongo:/data/db
- ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
env_file:
- .env
- .env.prod
base:
image: linuxodyssey/quest-base
image: linuxodyssey/quest-base:${IMAGE_TAG:-latest}
build:
context: .
dockerfile: ./quests/Dockerfile
+30 -6
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:
@@ -13,16 +31,22 @@ services:
base:
image: linuxodyssey/quest-base
networks:
- players
- players-dev
build:
context: .
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:
players:
name: linux-odyssey-players
players-dev:
name: linux-odyssey-players-dev
internal: false
external: true
+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
+27 -32
View File
@@ -9,53 +9,48 @@
"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",
"cli": "yarn workspace client start",
"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.14.0",
"@typescript-eslint/parser": "^6.14.0",
"@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.44.0",
"eslint": "^8.56.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.8.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-cypress": "^2.15.1",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-vue": "^9.15.1",
"jest": "^29.7.0",
"globals": "^16.0.0",
"prettier": "^3.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.3.3"
"typescript": "^5.3.3",
"vue-eslint-parser": "^9.4.2"
},
"dependencies": {
"latest": "^0.2.0",
"typescript-eslint": "^7.4.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"
}
}
-19
View File
@@ -1,19 +0,0 @@
FROM node:20-alpine as build
WORKDIR /app
COPY ./package.json yarn.lock tsconfig.json ./
COPY packages/analytics/package.json ./packages/analytics/package.json
COPY packages/models/package.json ./packages/models/package.json
RUN yarn install --frozen-lockfile
ENV HOST=0.0.0.0
ENV PORT=3001
EXPOSE 3001
# Production stage
FROM build as prod
COPY packages/analytics ./packages/analytics
COPY packages/models ./packages/models
ENV NODE_ENV=production
WORKDIR /app/packages/analytics
RUN yarn build
CMD [ "yarn", "start" ]
-6
View File
@@ -1,6 +0,0 @@
{
"watch": ["src", "views"],
"ext": "ts,handlebars,js",
"ignore": ["src/**/*.spec.ts"],
"exec": "node --loader ts-node/esm src/index.ts"
}
-32
View File
@@ -1,32 +0,0 @@
{
"name": "analytics",
"version": "1.0.0",
"main": "src/index.js",
"private": true,
"type": "module",
"license": "GPL",
"scripts": {
"start": "node dist/index.js",
"build": "tsc -b -f",
"watch": "tsc -b --watch",
"dev": "nodemon"
},
"dependencies": {
"@linux-odyssey/models": "*",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"express-basic-auth": "^1.2.1",
"express-handlebars": "^7.1.2",
"mongoose": "^8.0.3"
},
"devDependencies": {
"@swc/core": "^1.4.2",
"@swc/helpers": "^0.5.6",
"@types/express": "^4.17.21",
"@types/node": "^20.11.20",
"nodemon": "^3.1.0",
"regenerator-runtime": "^0.14.1",
"ts-node": "^10.9.2",
"typescript": "^5.3.3"
}
}
-12
View File
@@ -1,12 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "./dist"
},
"include": ["src"],
"references": [{ "path": "../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]
+7 -11
View File
@@ -1,17 +1,13 @@
{
"name": "@linux-odyssey/constants",
"type": "module",
"version": "1.0.0",
"name": "@odyssey/constants",
"version": "0.0.0",
"private": true,
"main": "dist/index.js",
"exports": "./dist/index.js",
"types": "dist/index.d.ts",
"license": "GPL",
"scripts": {
"build": "tsc",
"dev": "tsc -w"
"main": "index.ts",
"types": "index.ts",
"exports": {
".": "./index.ts"
},
"dependencies": {
"zod": "^3.23.8"
"zod": "^4.6.7"
}
}
-9
View File
@@ -1,9 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"composite": true,
"outDir": "./dist"
},
"include": ["*.js", "*.ts"],
"exclude": ["node_modules", "dist"]
}
+1
View File
@@ -0,0 +1 @@
export const toArray = (val: unknown) => (typeof val === 'string' ? [val] : val)
-98
View File
@@ -1,98 +0,0 @@
/* eslint-disable no-restricted-syntax */
const fs = require('fs').promises
const { exit } = require('process')
const minimist = require('minimist')
const axios = require('axios')
const { colorize, printResponses, printHints } = require('./print.js')
const discoverFiles = require('./discover.js')
const {
API_ENDPOINT,
TOKEN,
PWD,
CMD_NAME,
CMD_OUTPUT_FILE,
CMD_ERROR_FILE,
CMD_EXIT_CODE,
} = process.env
const api = axios.create({
baseURL: `${API_ENDPOINT}/api/v1`,
headers: {
Authorization: `Bearer ${TOKEN}`,
},
})
async function readOrNone(file) {
try {
return await fs.readFile(file, 'utf8')
} catch (_) {
return ''
}
}
const commandListeners = {
ls: [discoverFiles],
}
async function handleCommand(command) {
const argv = minimist(command.split(' '))
const name = argv._[0]
const listeners = commandListeners[name]
if (!listeners) return {}
return listeners.reduce(async (result, listener) => {
const res = await listener(argv)
return { ...res, ...result }
}, {})
}
async function handleResponse({ responses, hints, end }) {
if (responses) {
await printResponses(responses, 90)
}
if (hints) {
await printHints(hints, 90)
}
if (end) {
console.log(colorize('Quest completed!', 'blue'))
}
await api.post('/commands/completed')
}
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 res = await api.post('/commands', payload)
if (!res.data || !res.data.responses) return
await handleResponse(res.data)
} catch (err) {
if (err.response) {
console.error(err.response.data)
return
}
console.error(err.message)
}
}
main()
.then(exit)
.catch((err) => {
console.log(
'發生預期外的錯誤,請嘗試重新啟動 Quest,如果問題持續發生,請幫我們填寫右上角的錯誤回報表單。'
)
console.error(err)
exit(1)
})
-49
View File
@@ -1,49 +0,0 @@
const fs = require('fs').promises
const path = require('path')
async function collectFilesInfo(inputPath, level = 0, hiddenFiles = false) {
const stats = await fs.stat(inputPath)
const name = path.basename(inputPath)
const discovered = level <= 1 && (hiddenFiles || !name.startsWith('.'))
const files = [
{
path: inputPath,
name,
type: stats.isDirectory() ? 'folder' : 'file',
discovered,
},
]
if (stats.isDirectory() && level < 2) {
try {
let entries = await fs.readdir(inputPath)
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) => path.resolve(process.cwd(), p))
.map((p) => collectFilesInfo(p, 0, argv.a || argv.all))
)
return { discover: result.flat() }
} catch (_) {
return {}
}
}
module.exports = discoverFiles
-14
View File
@@ -1,14 +0,0 @@
{
"name": "container",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "",
"watch": ""
},
"dependencies": {
"axios": "^1.6.0",
"minimist": "^1.2.8"
}
}
-115
View File
@@ -1,115 +0,0 @@
/* eslint-disable no-restricted-syntax */
/* eslint-disable no-await-in-loop */
const readline = require('readline')
const RETURN_SYMBOL = '\u21B5'
// ANSI color map
const ANSI_COLORS = {
default: 0,
black: 30,
red: 31,
green: 32,
yellow: 33,
blue: 34,
magenta: 35,
cyan: 36,
white: 37,
}
function colorCode(color) {
return `\x1b[${ANSI_COLORS[color]}m`
}
function colorize(content, color) {
if (!color) return content
return `${colorCode(color)}${content}${colorCode('default')}`
}
process.stdin.setRawMode(true)
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false,
})
function waitForEnter() {
return new Promise((resolve) => {
rl.once('line', resolve)
})
}
function formatLine(content, color) {
let result = colorCode(color)
let codeBlock = false
for (const c of content) {
switch (c) {
case '`':
result += colorCode(codeBlock ? color : 'green')
codeBlock = !codeBlock
break
default:
result += c
}
}
return result + colorCode('default') + RETURN_SYMBOL
}
function printLine(content, delay, color) {
const printContent = formatLine(content, color)
return new Promise((resolve) => {
let i = 0
const timer = setInterval(() => {
process.stdout.write(printContent[i])
i += 1
if (i >= printContent.length) {
clearInterval(timer)
process.stdout.write('\n')
resolve()
}
}, delay)
waitForEnter().then(() => {
clearInterval(timer)
if (i >= printContent.length) return
process.stdout.write(printContent.slice(i))
process.stdout.write('\n')
resolve()
})
})
}
async function printResponses(responses, delay = 100) {
console.log()
console.log(colorize('==============================', 'green'))
for (const response of responses) {
const { type, content, speaker, color } = response
if (type === 'narrative') {
for (const line of content) {
await printLine(line, delay, color || 'cyan')
}
}
if (type === 'dialogue') {
console.log(colorize(`${speaker}:`, 'green'))
for (const line of content) {
await printLine(` ${line}`, delay, color || 'cyan')
}
}
console.log(colorize('------------------------------', 'green'))
console.log()
}
}
async function printHints(hints, delay = 100) {
for (const hint of hints) {
await printLine(hint, delay, 'yellow')
}
}
module.exports = {
printResponses,
printHints,
colorize,
}
File renamed without changes.
@@ -2,25 +2,28 @@ import { basename } from './utils.js'
export interface FileObject {
path: string
type: string
type: 'file' | 'directory'
discovered: boolean
empty?: boolean
}
export default class File implements FileObject {
path: string
name: string
type: string
type: 'file' | 'directory'
discovered: boolean
empty?: boolean
constructor(obj: FileObject) {
this.path = obj.path.trimEnd()
this.name = basename(obj.path)
this.type = obj.type
this.discovered = obj.discovered
this.empty = obj.empty && obj.type === 'directory'
}
isDirectory() {
return this.type === 'folder'
return this.type === 'directory'
}
contains(file: FileObject) {
@@ -1,10 +1,11 @@
import { FileObject } from './file.js'
import FileNode from './fileNode.js'
export interface Event {
export interface FileGraphUpdateEvent {
add?: FileObject[]
remove?: FileObject[]
discover?: FileObject[]
pwd?: string
}
export default class FileGraph extends FileNode {
@@ -20,7 +21,7 @@ export default class FileGraph extends FileNode {
remove(files: FileObject[]) {
// Logic to remove a file node from the graph
// If the file node is a folder, also remove all children
// If the file node is a directory, also remove all children
// If the file node doesn't exist, throw an error
files.forEach((file) => {
@@ -33,6 +34,10 @@ export default class FileGraph extends FileNode {
// Overwrite the file graph with the provided files
// Remove file nodes that don't exist anymore and add new ones
if (eventFiles.length === 0) {
return
}
const newNode = new FileNode(eventFiles[0])
eventFiles.slice(1).forEach((file) => {
@@ -42,19 +47,16 @@ export default class FileGraph extends FileNode {
this.merge(newNode)
}
handleEvent(event: Event) {
handleEvent(event: FileGraphUpdateEvent) {
// eslint-disable-next-line default-case
switch (true) {
case !!event.add:
this.add(event.add)
break
case !!event.remove:
this.remove(event.remove)
break
case !!event.discover:
this.discover(event.discover)
break
// Implement other cases if needed
if (event.add) {
this.add(event.add)
}
if (event.remove) {
this.remove(event.remove)
}
if (event.discover) {
this.discover(event.discover)
}
}
}
@@ -1,15 +1,18 @@
import File, { FileObject } from './file.js'
import {
DuplicateItemError,
ParentNotExistsError,
FileNotExistsError,
} from './errors.js'
import { ParentNotExistsError, FileNotExistsError } from './errors.js'
import { dirname } from './utils.js'
export default class FileNode extends File {
export interface IFileNode {
path: string
type: 'file' | 'directory'
discovered: boolean
children?: IFileNode[]
}
export default class FileNode extends File implements IFileNode {
children: FileNode[]
constructor(file: FileObject | FileNode) {
constructor(file: FileObject | IFileNode) {
super(file)
this.children = []
if ((<FileNode>file).children)
@@ -22,15 +25,24 @@ export default class FileNode extends File {
) {
const file = new FileNode(fileInput)
if (file.path === this.path) {
throw new DuplicateItemError(
`File ${file.path} already exists in the tree: ${this.toString()}`
)
if (!this.discovered) {
this.discovered = file.discovered
}
return
}
if (this.children.some((child) => child.path === file.path)) {
throw new DuplicateItemError(
`File ${file.path} already exists in the tree: ${this.toString()}`
)
let existing = false
for (const child of this.children) {
if (child.path === file.path) {
existing = true
if (!child.discovered) {
child.discovered = file.discovered
}
break
}
}
if (existing) {
return
}
const parentPath = dirname(file.path)
@@ -41,11 +53,11 @@ export default class FileNode extends File {
// Recursively call addChild on the correct child node
const childNode = this.children.find((child) => child.contains(file))
if (childNode) {
childNode.addChild(file)
childNode.addChild(file, { makeParents })
} else if (makeParents) {
const parent = new FileNode({
path: parentPath,
type: 'folder',
type: 'directory',
discovered: false,
children: [file],
})
@@ -88,6 +100,12 @@ export default class FileNode extends File {
// Update the state of this node
this.discovered = this.discovered || fileNode.discovered
// the provided directory is empty, remove all children
if (fileNode.empty) {
this.children = []
return
}
fileNode.children.forEach((child) => {
const existingChild = this.children.find((c) => c.path === child.path)
if (existingChild) {
@@ -133,4 +151,11 @@ export default class FileNode extends File {
.join('')
return `${name}\n${childrenString}`
}
include(filePath: string, type?: 'file' | 'directory'): boolean {
if (this.path === filePath) {
return type ? this.type === type : true
}
return this.children.some((child) => child.include(filePath, type))
}
}
+6
View File
@@ -0,0 +1,6 @@
export { default as File } from './file'
export type { FileObject } from './file'
export { default as FileNode } from './fileNode'
export type { IFileNode } from './fileNode'
export { default as FileGraph } from './fileGraph'
export type { FileGraphUpdateEvent } from './fileGraph'
+7 -11
View File
@@ -1,14 +1,10 @@
{
"name": "@linux-odyssey/file-graph",
"version": "1.0.0",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": "./dist/index.js",
"license": "MIT",
"scripts": {
"build": "tsc",
"dev": "tsc -w",
"test": "yarn build && jest"
"name": "@odyssey/file-graph",
"version": "0.0.0",
"private": true,
"main": "index.ts",
"types": "index.ts",
"exports": {
".": "./index.ts"
}
}
-3
View File
@@ -1,3 +0,0 @@
export { default as File, FileObject } from './file.js'
export { default as FileNode } from './fileNode.js'
export { default as FileGraph, Event } from './fileGraph.js'
+3 -3
View File
@@ -1,10 +1,10 @@
import { describe, test, expect } from '@jest/globals'
import File from '../src/file.js'
import { describe, test, expect, beforeEach } from 'bun:test'
import File from '../file.js'
describe('File', () => {
let file: File
beforeEach(() => {
file = new File({ path: '/home/user', type: 'folder', discovered: true })
file = new File({ path: '/home/user', type: 'directory', discovered: true })
})
const filesToCompare = [
+85 -20
View File
@@ -1,6 +1,7 @@
import { describe, test, expect } from '@jest/globals'
import FileGraph from '../src/fileGraph.js'
import FileNode from '../src/fileNode.js'
import { describe, test, expect, beforeEach } from 'bun:test'
import FileGraph from '../fileGraph.js'
import FileNode from '../fileNode.js'
import { FileObject } from '../file.js'
describe('FileGraph', () => {
let root: FileNode
@@ -8,7 +9,7 @@ describe('FileGraph', () => {
beforeEach(() => {
root = new FileNode({
path: '/',
type: 'folder',
type: 'directory',
discovered: true,
})
})
@@ -16,7 +17,7 @@ describe('FileGraph', () => {
test('add files to graph', () => {
const fileGraph = new FileGraph(root)
const filesToAdd = [
const filesToAdd: FileObject[] = [
{
path: '/home/user/file1.txt',
type: 'file',
@@ -24,7 +25,12 @@ describe('FileGraph', () => {
},
{
path: '/home/user/folder1',
type: 'folder',
type: 'directory',
discovered: true,
},
{
path: '/home/user/folder2/file2.txt',
type: 'file',
discovered: true,
},
]
@@ -32,7 +38,34 @@ describe('FileGraph', () => {
fileGraph.add(filesToAdd)
expect(fileGraph.children.length).toBe(1)
expect(fileGraph.children[0].children[0].children.length).toBe(2)
expect(fileGraph.children[0].children[0].children.length).toBe(3)
})
test('ignore files that already exist', () => {
const fileGraph = new FileGraph(root)
const filesToAdd: FileObject[] = [
{
path: '/home/user/folder1',
type: 'directory',
discovered: true,
},
{
path: '/home/user/folder1/file1.txt',
type: 'file',
discovered: true,
},
]
fileGraph.add(filesToAdd)
expect(fileGraph.children.length).toBe(1)
expect(fileGraph.children[0].children[0].children.length).toBe(1)
fileGraph.add([filesToAdd[1]])
expect(fileGraph.children.length).toBe(1)
expect(fileGraph.children[0].children[0].children.length).toBe(1)
})
test('remove files from graph', () => {
@@ -41,12 +74,12 @@ describe('FileGraph', () => {
const filesToAdd = [
{
path: '/home/user/folder1',
type: 'folder',
type: 'directory',
discovered: true,
},
{
path: '/home/user/folder2',
type: 'folder',
type: 'directory',
discovered: true,
},
{
@@ -61,22 +94,22 @@ describe('FileGraph', () => {
},
]
fileGraph.add(filesToAdd)
fileGraph.add(filesToAdd as FileObject[])
const filesToRemove = [
{
path: '/home/user/folder1/file1.txt',
type: 'folder',
type: 'directory',
discovered: true,
},
{
path: '/home/user/folder2',
type: 'folder',
type: 'directory',
discovered: true,
},
]
fileGraph.remove(filesToRemove)
fileGraph.remove(filesToRemove as FileObject[])
expect(fileGraph.children[0].children[0].children.length).toBe(1)
expect(fileGraph.children[0].children[0].children[0].name).toBe('folder1')
@@ -90,7 +123,7 @@ describe('FileGraph', () => {
const discoverFiles = [
{
path: '/home/user/folder1',
type: 'folder',
type: 'directory',
discovered: true,
},
{
@@ -110,7 +143,7 @@ describe('FileGraph', () => {
},
]
fileGraph.discover(discoverFiles)
fileGraph.discover(discoverFiles as FileObject[])
expect(fileGraph.children[0].children[0].children[0].children.length).toBe(
3
)
@@ -122,12 +155,12 @@ describe('FileGraph', () => {
const filesToAdd = [
{
path: '/home/user/folder1',
type: 'folder',
type: 'directory',
discovered: true,
},
{
path: '/home/user/folder2',
type: 'folder',
type: 'directory',
discovered: true,
},
{
@@ -142,12 +175,12 @@ describe('FileGraph', () => {
},
]
fileGraph.add(filesToAdd)
fileGraph.add(filesToAdd as FileObject[])
const newFiles = [
{
path: '/home/user/folder1',
type: 'folder',
type: 'directory',
discovered: true,
},
{
@@ -167,11 +200,43 @@ describe('FileGraph', () => {
},
]
fileGraph.discover(newFiles)
fileGraph.discover(newFiles as FileObject[])
expect(fileGraph.children[0].children[0].children.length).toBe(2)
expect(fileGraph.children[0].children[0].children[0].children.length).toBe(
3
)
})
test('discover a empty directory which children just being deleted', () => {
const fileGraph = new FileGraph(root)
const discoverFiles = [
{
path: '/home/user/folder1',
type: 'directory',
discovered: true,
},
{
path: '/home/user/folder1/file1.txt',
type: 'file',
discovered: true,
},
]
fileGraph.add(discoverFiles as FileObject[])
expect(fileGraph.include('/home/user/folder1/file1.txt', 'file')).toBe(true)
fileGraph.discover([
{
path: '/home/user/folder1',
type: 'directory',
discovered: true,
empty: true,
},
])
expect(fileGraph.include('/home/user/folder1/file1.txt', 'file')).toBe(
false
)
})
})
+91 -92
View File
@@ -1,7 +1,7 @@
import { describe, test, expect } from '@jest/globals'
import { DuplicateItemError, ParentNotExistsError } from '../src/errors.js'
import FileNode from '../src/fileNode.js'
import { FileObject } from '../src/file.js'
import { describe, test, expect, beforeEach } from 'bun:test'
import { ParentNotExistsError } from '../errors.js'
import FileNode, { IFileNode } from '../fileNode.js'
import { FileObject } from '../file.js'
function createNodeFromFiles(files: FileObject[]) {
const node = new FileNode(files[0])
@@ -42,17 +42,16 @@ describe('FileNode', () => {
beforeEach(() => {
rootNode = new FileNode({
path: '/home/rudeus',
name: 'rudeus',
type: 'folder',
type: 'directory',
discovered: true,
})
})
test('should throw error when adding duplicate item', () => {
const child = {
test('should override discovered when adding duplicate item', () => {
const child: FileObject = {
path: '/home/rudeus/test',
type: 'folder',
discovered: true,
type: 'directory',
discovered: false,
}
// Adding the child for the first time
@@ -61,16 +60,16 @@ describe('FileNode', () => {
expect(rootNode.children.length).toBe(1)
// Trying to add the same child again should throw an error
expect(() => {
rootNode.addChild(child)
}).toThrow(DuplicateItemError)
child.discovered = true
rootNode.addChild(child)
expect(rootNode.children[0].discovered).toBe(true)
})
test('should throw error when parent does not exist', () => {
const child = {
const child: FileObject = {
path: '/home/rudeus/alphabet/test',
name: 'test',
type: 'folder',
type: 'directory',
discovered: true,
}
@@ -81,22 +80,19 @@ describe('FileNode', () => {
})
test('adds nested children to the tree', () => {
const files = [
const files: FileObject[] = [
{
path: '/home/rudeus/forgotten_scroll.txt',
name: 'forgotten_scroll.txt',
type: 'file',
discovered: true,
},
{
path: '/home/rudeus/test',
name: 'test',
type: 'folder',
type: 'directory',
discovered: true,
},
{
path: '/home/rudeus/test/a',
name: 'a',
type: 'file',
discovered: false,
},
@@ -111,9 +107,8 @@ describe('FileNode', () => {
})
test('adds nested children to the tree with makeParents option', () => {
const file = {
const file: FileObject = {
path: '/home/rudeus/test/a/b/c/d/e',
name: 'a',
type: 'file',
discovered: false,
}
@@ -129,34 +124,34 @@ describe('FileNode', () => {
})
test('merge-subtree', () => {
const root = {
const root: FileObject = {
path: '/',
type: 'folder',
type: 'directory',
discovered: true,
}
const files1 = [
const files1: FileObject[] = [
root,
{ path: '/a', type: 'file', discovered: true },
{ path: '/b', type: 'folder', discovered: true },
{ path: '/b/c', type: 'folder', discovered: true },
{ path: '/b/d', type: 'file', discovered: true },
{ path: '/b/c/f', type: 'file', discovered: true },
{ path: '/a', type: 'file' as const, discovered: true },
{ path: '/b', type: 'directory' as const, discovered: true },
{ path: '/b/c', type: 'directory' as const, discovered: true },
{ path: '/b/d', type: 'file' as const, discovered: true },
{ path: '/b/c/f', type: 'file' as const, discovered: true },
]
const files2 = [
{ path: '/b', type: 'folder', discovered: true },
{ path: '/b/c', type: 'folder', discovered: true },
{ path: '/b/e', type: 'file', discovered: true },
{ path: '/b/c/g', type: 'file', discovered: true },
const files2: FileObject[] = [
{ path: '/b', type: 'directory' as const, discovered: true },
{ path: '/b/c', type: 'directory' as const, discovered: true },
{ path: '/b/e', type: 'file' as const, discovered: true },
{ path: '/b/c/g', type: 'file' as const, discovered: true },
]
const expected = [
const expected: FileObject[] = [
root,
{ path: '/a', type: 'file', discovered: true },
{ path: '/b', type: 'folder', discovered: true },
{ path: '/b/c', type: 'folder', discovered: true },
{ path: '/b/e', type: 'file', discovered: true },
{ path: '/b/c/g', type: 'file', discovered: true },
{ path: '/a', type: 'file' as const, discovered: true },
{ path: '/b', type: 'directory' as const, discovered: true },
{ path: '/b/c', type: 'directory' as const, discovered: true },
{ path: '/b/e', type: 'file' as const, discovered: true },
{ path: '/b/c/g', type: 'file' as const, discovered: true },
]
mergeTest(files1, files2, expected)
@@ -166,90 +161,94 @@ describe('FileNode', () => {
// Test if the node to merge is only the middle part of the tree
// (i.e. the node to merge doesn't contains all level of children)
// The original tree should keep the children that are not in the node to merge
const root = {
const root: FileObject = {
path: '/',
type: 'folder',
type: 'directory',
discovered: true,
}
const files1 = [
const files1: FileObject[] = [
root,
{ path: '/a', type: 'file', discovered: true },
{ path: '/b', type: 'folder', discovered: true },
{ path: '/b/c', type: 'folder', discovered: true },
{ path: '/b/d', type: 'file', discovered: true },
{ path: '/b/c/f', type: 'file', discovered: true },
{ path: '/a', type: 'file' as const, discovered: true },
{ path: '/b', type: 'directory' as const, discovered: true },
{ path: '/b/c', type: 'directory' as const, discovered: true },
{ path: '/b/d', type: 'file' as const, discovered: true },
{ path: '/b/c/f', type: 'file' as const, discovered: true },
]
const files2 = [
{ path: '/b', type: 'folder', discovered: true },
{ path: '/b/c', type: 'folder', discovered: true },
{ path: '/b/e', type: 'file', discovered: true },
const files2: FileObject[] = [
{ path: '/b', type: 'directory' as const, discovered: true },
{ path: '/b/c', type: 'directory' as const, discovered: true },
{ path: '/b/e', type: 'file' as const, discovered: true },
]
const expected = [
const expected: FileObject[] = [
root,
{ path: '/a', type: 'file', discovered: true },
{ path: '/b', type: 'folder', discovered: true },
{ path: '/b/c', type: 'folder', discovered: true },
{ path: '/b/e', type: 'file', discovered: true },
{ path: '/b/c/f', type: 'file', discovered: true },
{ path: '/a', type: 'file' as const, discovered: true },
{ path: '/b', type: 'directory' as const, discovered: true },
{ path: '/b/c', type: 'directory' as const, discovered: true },
{ path: '/b/e', type: 'file' as const, discovered: true },
{ path: '/b/c/f', type: 'file' as const, discovered: true },
]
mergeTest(files1, files2, expected)
})
test('merge-hidden', () => {
const root = {
const root: FileObject = {
path: '/',
type: 'folder',
type: 'directory',
discovered: true,
}
const files1 = [
const files1: FileObject[] = [
root,
{ path: '/a', type: 'file', discovered: true },
{ path: '/.b', type: 'file', discovered: false },
{ path: '/c', type: 'folder', discovered: true },
{ path: '/c/.d', type: 'file', discovered: false },
{ path: '/a', type: 'file' as const, discovered: true },
{ path: '/.b', type: 'file' as const, discovered: false },
{ path: '/c', type: 'directory' as const, discovered: true },
{ path: '/c/.d', type: 'file' as const, discovered: false },
]
const files2 = [
{ path: '/c', type: 'folder', discovered: true },
{ path: '/c/.d', type: 'file', discovered: true },
const files2: FileObject[] = [
{ path: '/c', type: 'directory' as const, discovered: true },
{ path: '/c/.d', type: 'file' as const, discovered: true },
]
const expected = [
const expected: FileObject[] = [
root,
{ path: '/a', type: 'file', discovered: true },
{ path: '/.b', type: 'file', discovered: false },
{ path: '/c', type: 'folder', discovered: true },
{ path: '/c/.d', type: 'file', discovered: true },
{ path: '/a', type: 'file' as const, discovered: true },
{ path: '/.b', type: 'file' as const, discovered: false },
{ path: '/c', type: 'directory' as const, discovered: true },
{ path: '/c/.d', type: 'file' as const, discovered: true },
]
mergeTest(files1, files2, expected)
})
test('remove-child', () => {
const root = {
const root: FileObject = {
path: '/',
type: 'folder',
type: 'directory',
discovered: true,
}
const files = [
const files: FileObject[] = [
root,
{ path: '/a', type: 'file', discovered: true },
{ path: '/b', type: 'folder', discovered: true },
{ path: '/b/c', type: 'folder', discovered: true },
{ path: '/b/d', type: 'file', discovered: true },
{ path: '/b/c/f', type: 'file', discovered: true },
{ path: '/a', type: 'file' as const, discovered: true },
{ path: '/b', type: 'directory' as const, discovered: true },
{ path: '/b/c', type: 'directory' as const, discovered: true },
{ path: '/b/d', type: 'file' as const, discovered: true },
{ path: '/b/c/f', type: 'file' as const, discovered: true },
]
const fileToRemove = { path: '/b/c', type: 'folder', discovered: true }
const fileToRemove: FileObject = {
path: '/b/c',
type: 'directory',
discovered: true,
}
const expected = [
const expected: FileObject[] = [
root,
{ path: '/a', type: 'file', discovered: true },
{ path: '/b', type: 'folder', discovered: true },
{ path: '/b/d', type: 'file', discovered: true },
{ path: '/a', type: 'file' as const, discovered: true },
{ path: '/b', type: 'directory' as const, discovered: true },
{ path: '/b/d', type: 'file' as const, discovered: true },
]
removeChildTest(files, fileToRemove, expected)
@@ -257,9 +256,9 @@ describe('FileNode', () => {
})
test('load nested fileNode', () => {
const data = {
const data: IFileNode = {
path: '/',
type: 'folder',
type: 'directory',
discovered: true,
children: [
{
@@ -269,12 +268,12 @@ test('load nested fileNode', () => {
},
{
path: '/b',
type: 'folder',
type: 'directory',
discovered: true,
children: [
{
path: '/b/c',
type: 'folder',
type: 'directory',
discovered: true,
children: [
{
-10
View File
@@ -1,10 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"composite": true,
"outDir": "./dist"
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
File renamed without changes.
+48
View File
@@ -0,0 +1,48 @@
import { Condition } from './condition/Condition'
import {
ICommand,
ICondition,
IFileExistenceChecker,
IRequirements,
IResponse,
} from './schema'
export class Event {
id: string
private condition: Condition
private requirements: string[]
constructor(
id: string,
condition: ICondition,
private response: IResponse,
requirements?: IRequirements
) {
this.id = id
this.condition = new Condition(condition)
this.requirements = requirements || []
}
async satisfies(
command: ICommand,
checker: IFileExistenceChecker
): Promise<boolean> {
return this.condition.satisfies(command, checker)
}
private checkRequirements(completed: string[]): boolean {
return this.requirements.every((req) => completed.includes(req))
}
private finished(completed: string[]): boolean {
return completed.includes(this.id)
}
active(completed: string[]): boolean {
return !this.finished(completed) && this.checkRequirements(completed)
}
getResponse(): IResponse {
return this.response
}
}
+18
View File
@@ -0,0 +1,18 @@
/* eslint-disable max-classes-per-file */
import { Event } from './Event'
import { IStageException, IGlobalException } from './schema/exception'
export class StageException extends Event {
readonly catchAll: boolean
constructor({ id, condition, response, catchAll }: IStageException) {
super(id, condition, response)
this.catchAll = catchAll
}
}
export class GlobalException extends Event {
constructor({ id, condition, response, requirements }: IGlobalException) {
super(id, condition, response, requirements)
}
}
+93
View File
@@ -0,0 +1,93 @@
/* eslint-disable no-await-in-loop */
import { Event } from './Event'
import { GlobalException } from './Exception'
import {
IQuest,
IFileExistenceChecker,
ICommand,
IResponse,
ITask,
} from './schema'
import { Stage } from './Stage'
export class Quest {
private quest: IQuest
private stages: Stage[]
private exceptions: GlobalException[] = []
private events: Map<string, Event> = new Map()
constructor(
quest: IQuest,
private checker: IFileExistenceChecker
) {
this.quest = quest
this.stages = quest.stages.map((stage) => new Stage(stage))
for (const stage of this.stages) {
this.events.set(stage.id, stage)
for (const exception of stage.getExceptions()) {
this.events.set(exception.id, exception)
}
}
for (const exception of quest.exceptions ?? []) {
const globalException = new GlobalException(exception)
this.exceptions.push(globalException)
this.events.set(globalException.id, globalException)
}
}
getActiveStages(completed: string[]) {
return this.stages.filter((stage) => stage.active(completed))
}
private getActiveExceptions(completed: string[]) {
return this.exceptions.filter((exception) => exception.active(completed))
}
async findSatisfiedEvent(
command: ICommand,
completed: string[]
): Promise<string | null> {
const stages = this.getActiveStages(completed)
let catchAllException: string | null = null
for (const stage of stages) {
const satisfies = await stage.satisfies(command, this.checker)
if (satisfies) {
return stage.id
}
}
for (const exception of stages.flatMap((stage) => stage.getExceptions())) {
if (exception.catchAll && !catchAllException) {
catchAllException = exception.id
} else if (await exception.satisfies(command, this.checker)) {
return exception.id
}
}
for (const exception of this.getActiveExceptions(completed)) {
if (await exception.satisfies(command, this.checker)) {
return exception.id
}
}
return catchAllException
}
getResponses(completed: string[]): IResponse[] {
return completed.map((id) => this.events.get(id)!.getResponse())
}
getTasks(completed: string[]): ITask[] {
const completedSet = new Set(completed)
const completedStages = this.stages
.filter((stage) => completedSet.has(stage.id))
.map((stage) => ({
id: stage.id,
name: stage.name,
completed: true,
}))
const activeStages = this.getActiveStages(completed).map((stage) => ({
id: stage.id,
name: stage.name,
completed: false,
}))
return [...completedStages, ...activeStages]
}
}
+67
View File
@@ -0,0 +1,67 @@
import { FileGraph, IFileNode } from '@odyssey/file-graph'
import { Quest } from './Quest'
import {
IQuest,
ICommand,
ISession,
IFileExistenceChecker,
IResponse,
ITask,
} from './schema'
export class GameSession {
private completed: string[] = []
private quest: Quest
private graph: FileGraph
constructor(
{ completedEvents, graph }: Partial<ISession>,
quest: IQuest,
checker: IFileExistenceChecker
) {
this.completed = completedEvents || []
this.quest = new Quest(quest, checker)
this.graph = new FileGraph(
graph ?? { path: '/', type: 'directory', discovered: false }
)
}
get completedEvents() {
return this.completed
}
complete(stageId: string) {
this.completed.push(stageId)
}
getActiveStages(): string[] {
return this.quest.getActiveStages(this.completed).map((stage) => stage.id)
}
async runCommand(command: ICommand) {
if (command.params) {
this.graph.handleEvent(command.params)
}
const stageId = await this.quest.findSatisfiedEvent(command, this.completed)
if (stageId) {
this.complete(stageId)
}
return stageId
}
isFinished() {
return this.getActiveStages().length === 0
}
getResponses(): IResponse[] {
return this.quest.getResponses(this.completed)
}
getTasks(): ITask[] {
return this.quest.getTasks(this.completed)
}
getGraph(): IFileNode {
return this.graph
}
}
+26
View File
@@ -0,0 +1,26 @@
import { IStage } from './schema'
import { StageException } from './Exception'
import { Event } from './Event'
export class Stage extends Event {
name: string
private exceptions: StageException[]
constructor({
id,
name,
condition,
requirements,
exceptions,
response,
}: IStage) {
super(id, condition, response, requirements)
this.name = name || ''
this.exceptions =
exceptions?.map((exception) => new StageException(exception)) || []
}
getExceptions(): StageException[] {
return this.exceptions
}
}
+8
View File
@@ -0,0 +1,8 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { zodToJsonSchema } from 'zod-to-json-schema'
import fs from 'fs'
import { questSchema } from './schema'
const jsonSchema = zodToJsonSchema(questSchema)
fs.writeFileSync('quest.json', JSON.stringify(jsonSchema, null, 2))
Loaded 100 of 413 files, more files were not shown because too many files have changed in this diff. Show more