diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index b56dc56..d059623 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -44,3 +44,6 @@ jobs: - name: Typecheck run: pnpm typecheck + + - name: Knip + run: pnpm exec knip diff --git a/README.md b/README.md index 941a41f..38d3835 100644 --- a/README.md +++ b/README.md @@ -45,3 +45,7 @@ caido-dev watch [path] [--config ] - **Description**: Start the development server and watch for changes. - **Options**: - `-c, --config `: Path to the `caido.config.ts` file. + +## README Assets + +Plugin packages always include the root `README.md`. Local README images are converted to compressed WebP data URIs during packaging, with each image limited to about 125 KiB and the final README limited to about 2 MiB. External `http` and `https` URLs are removed from README links and images, while `data:` URIs and fragment links are preserved. diff --git a/knip.json b/knip.json new file mode 100644 index 0000000..d500aec --- /dev/null +++ b/knip.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://unpkg.com/knip@6/schema.json", + "entry": ["src/**/*.spec.ts", "playgrounds/**/*.spec.ts"], + "project": ["src/**/*.ts", "playgrounds/**/*.ts", "*.config.ts"], + "ignore": [ + "playgrounds/**/caido.config.ts", + "playgrounds/**/packages/**" + ] +} diff --git a/package.json b/package.json index 4690ec0..27d3ff6 100644 --- a/package.json +++ b/package.json @@ -41,18 +41,25 @@ "glob": "11.0.1", "jiti": "2.4.2", "jszip": "3.10.1", - "ws": "8.18.0", - "zod": "3.24.1", + "parse5": "^8.0.1", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "sharp": "^0.34.5", + "tsup": "8.3.5", + "unified": "^11.0.5", + "unist-util-visit": "^5.1.0", "vite": "6.0.7", - "tsup": "8.3.5" + "ws": "8.18.0", + "zod": "3.24.1" }, "devDependencies": { "@caido/eslint-config": "0.0.6", "@types/express": "5.0.0", + "@types/mdast": "^4.0.4", "@types/node": "22.10.2", "@types/ws": "8.5.13", "eslint": "9.17.0", - "tsup": "8.3.5", + "knip": "^6.7.0", "tsx": "4.19.2", "typescript": "5.7.2", "vitest": "3.0.5" diff --git a/playgrounds/build-backend/README.md b/playgrounds/build-backend/README.md new file mode 100644 index 0000000..f3d61ac --- /dev/null +++ b/playgrounds/build-backend/README.md @@ -0,0 +1,8 @@ +# Backend Plugin Playground + +This is a test playground for building backend plugins. + +![Test Asset](assets/test.png) +![External Image](https://example.com/image.png) + +The plugin includes a backend plugin with assets. diff --git a/playgrounds/build-backend/__tests__/build-backend.spec.ts b/playgrounds/build-backend/__tests__/build-backend.spec.ts index bf97b72..8f1d07b 100644 --- a/playgrounds/build-backend/__tests__/build-backend.spec.ts +++ b/playgrounds/build-backend/__tests__/build-backend.spec.ts @@ -83,4 +83,29 @@ describe("build-backend", () => { expect(assetContent).toBeUndefined(); }); + + it("should have README.md file", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + expect(readmeContent).toContain("Backend Plugin Playground"); + }); + + it("should inline README image links as WebP data URIs", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + expect(readmeContent).toContain("data:image/webp;base64,"); + expect(readmeContent).not.toContain("assets/test.png"); + }); + + it("should remove external image URLs (http, https)", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + // Verify that external URLs are removed (set to empty string) + // The README has: ![External Image](https://example.com/image.png) + // After transformation, it should be: ![](...) + expect(readmeContent).toMatch(/!\[External Image\]\(\)/); + }); }); diff --git a/playgrounds/build-backend/assets/test.png b/playgrounds/build-backend/assets/test.png new file mode 100644 index 0000000..e0ccec7 Binary files /dev/null and b/playgrounds/build-backend/assets/test.png differ diff --git a/playgrounds/build-frontend/README.md b/playgrounds/build-frontend/README.md new file mode 100644 index 0000000..6a62399 --- /dev/null +++ b/playgrounds/build-frontend/README.md @@ -0,0 +1,58 @@ +# Frontend Build Playground + +This directory serves as a test fixture for validating frontend plugin build behavior in `@caido-community/dev`. + +## Purpose + +It demonstrates a minimal frontend Caido plugin configuration and is used in integration tests to verify: + +- Vite-based frontend builds +- Asset bundling +- README and referenced asset inclusion in final plugin packages + +## Test Asset Reference + +The following image reference is used to test automatic asset detection from README content: + +![Test Asset](assets/test.png) + +## Link Test Cases + +Local link that should be preserved: + +[Local Doc](assets/test.txt) + +External link that should be removed: + +[External Link](https://example.com/docs) + +Fragment-only link that should be preserved: + +[Jump to section](#purpose) + +## Reference-Style Definition Test Cases + +Reference-style image and link using definitions: + +![Ref Image][ref-image] +[Ref Link][ref-link] + +[ref-image]: assets/test.png +[ref-link]: https://example.com/docs + +## HTML Test Cases + +Raw HTML with local and external URLs: + +HTML Local Image +HTML External Image +HTML Local Link +HTML External Link + +## External URL Test Cases + +The following images test external URL handling (should be removed): + +![External HTTP](http://example.com/image.png) +![External HTTPS](https://example.com/image.png) +![Data URI](data:image/png;base64,abc123) diff --git a/playgrounds/build-frontend/__tests__/build-frontend.spec.ts b/playgrounds/build-frontend/__tests__/build-frontend.spec.ts index 4edb181..1cffa2c 100644 --- a/playgrounds/build-frontend/__tests__/build-frontend.spec.ts +++ b/playgrounds/build-frontend/__tests__/build-frontend.spec.ts @@ -5,6 +5,89 @@ import { describe, expect, it } from "vitest"; import { getZipFileContent } from "../../../playgrounds/utils"; describe("build-frontend", () => { + it("should have README.md file", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + expect(readmeContent).toContain("Frontend Build Playground"); + }); + + it("should inline README image links as WebP data URIs", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + expect(readmeContent).toContain("data:image/webp;base64,"); + expect(readmeContent).not.toContain("assets/test.png"); + }); + + it("should remove external image URLs", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + // External URLs should be removed (set to empty string) + expect(readmeContent).not.toContain("http://example.com/image.png"); + expect(readmeContent).not.toContain("https://example.com/image.png"); + // data: URIs should be kept as-is (not removed) + expect(readmeContent).toContain("data:image/png;base64,abc123"); + // Image syntax should still exist but with empty URLs (alt text preserved) + expect(readmeContent).toContain("![External HTTP]()"); + expect(readmeContent).toContain("![External HTTPS]()"); + expect(readmeContent).toContain( + "![Data URI](data:image/png;base64,abc123)", + ); + }); + + it("should preserve local markdown link URLs", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + expect(readmeContent).toContain("[Local Doc](assets/test.txt)"); + }); + + it("should remove external markdown link URLs", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + // External link URL should be removed but link text preserved + expect(readmeContent).not.toContain("https://example.com/docs"); + expect(readmeContent).toContain("[External Link]()"); + }); + + it("should preserve fragment-only links", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + // Same-document anchors should be preserved as-is + expect(readmeContent).toContain("[Jump to section](#purpose)"); + }); + + it("should inline reference-style image definition URLs", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + expect(readmeContent).toMatch(/\[ref-image\]:\s*data:image\/webp;base64,/); + // [ref-link]: https://example.com/docs is external and should be removed + expect(readmeContent).not.toContain("https://example.com/docs"); + }); + + it("should inline local HTML image src attributes and preserve href attributes", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + expect(readmeContent).toMatch(/src="data:image\/webp;base64,/); + expect(readmeContent).toContain('href="assets/test.txt"'); + }); + + it("should remove external URLs in HTML attributes", async () => { + const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); + const readmeContent = await getZipFileContent(zipPath, "README.md"); + expect(readmeContent).toBeDefined(); + // External URLs in HTML should be emptied + expect(readmeContent).not.toContain("https://example.com/image.png"); + expect(readmeContent).not.toContain("https://example.com/docs"); + expect(readmeContent).toContain('src=""'); + expect(readmeContent).toContain('href=""'); + }); it("should have manifest.json file", async () => { const zipPath = path.resolve(__dirname, "../dist/plugin_package.zip"); diff --git a/playgrounds/build-frontend/assets/test.png b/playgrounds/build-frontend/assets/test.png new file mode 100644 index 0000000..e0ccec7 Binary files /dev/null and b/playgrounds/build-frontend/assets/test.png differ diff --git a/playgrounds/setup.ts b/playgrounds/setup.ts index c56f87d..246765e 100644 --- a/playgrounds/setup.ts +++ b/playgrounds/setup.ts @@ -1,12 +1,20 @@ -import { execSync } from "child_process"; +import { execFileSync, execSync } from "child_process"; import path from "path"; import { afterAll, beforeAll, expect } from "vitest"; +function hasPathSegment(filePath: string, segment: string) { + return filePath.split(/[\\/]+/).includes(segment); +} + beforeAll(({ file }) => { // Get the test file path from the current test file const testPath = file.filepath; + if (!hasPathSegment(testPath, "playgrounds")) { + return; + } + // Find the playground directory (parent of __tests__ directory) const playgroundDir = path.dirname(path.dirname(testPath)); @@ -18,9 +26,13 @@ beforeAll(({ file }) => { // Run pnpm build in the playground directory console.log(`Building playground in ${playgroundDir}...`); - execSync("node ../../dist/cli.js build", { - cwd: playgroundDir, - }); + execFileSync( + process.execPath, + [path.join("..", "..", "dist", "cli.js"), "build"], + { + cwd: playgroundDir, + }, + ); }); afterAll(() => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7b5cf1f..aff4812 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,12 +32,30 @@ importers: jszip: specifier: 3.10.1 version: 3.10.1 + parse5: + specifier: ^8.0.1 + version: 8.0.1 + remark-parse: + specifier: ^11.0.0 + version: 11.0.0 + remark-stringify: + specifier: ^11.0.0 + version: 11.0.0 + sharp: + specifier: ^0.34.5 + version: 0.34.5 tsup: specifier: 8.3.5 - version: 8.3.5(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.2) + version: 8.3.5(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.8.3) + unified: + specifier: ^11.0.5 + version: 11.0.5 + unist-util-visit: + specifier: ^5.1.0 + version: 5.1.0 vite: specifier: 6.0.7 - version: 6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2) + version: 6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3) ws: specifier: 8.18.0 version: 8.18.0 @@ -51,6 +69,9 @@ importers: '@types/express': specifier: 5.0.0 version: 5.0.0 + '@types/mdast': + specifier: ^4.0.4 + version: 4.0.4 '@types/node': specifier: 22.10.2 version: 22.10.2 @@ -60,6 +81,9 @@ importers: eslint: specifier: 9.17.0 version: 9.17.0(jiti@2.4.2) + knip: + specifier: ^6.7.0 + version: 6.7.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.10.0) tsx: specifier: 4.19.2 version: 4.19.2 @@ -68,7 +92,7 @@ importers: version: 5.7.2 vitest: specifier: 3.0.5 - version: 3.0.5(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2) + version: 3.0.5(@types/debug@4.1.13)(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3) packages: @@ -81,6 +105,18 @@ packages: '@caido/plugin-manifest@0.3.0': resolution: {integrity: sha512-HRGHf65K2sfSdaEUwkCNDlurJ4zL0bOUg/Db4u6CrwjTTzmg2gOzP6SzLRj+69gWmxOm5LUjhInNHaMIRmQkHw==} + '@emnapi/core@1.9.2': + resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/runtime@1.9.2': + resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@esbuild/aix-ppc64@0.23.1': resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} engines: {node: '>=18'} @@ -429,6 +465,159 @@ packages: resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} engines: {node: '>=18.18'} + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -454,6 +643,12 @@ packages: '@mdn/browser-compat-data@5.6.27': resolution: {integrity: sha512-72sl6Xbr9RVH5iUoQmb2Bv6zXt9qN7kXZmLYhYuQclC+ZaWfILiQ7ej0k8KZXRSAlgPinN67myIn9odCqvqu+w==} + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -466,6 +661,244 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@oxc-parser/binding-android-arm-eabi@0.127.0': + resolution: {integrity: sha512-0LC7ye4hvqbIKxAzThzvswgHLFu2AURKzYLeSVvLdu2TBOYWQDmHnTqPLeA597BcUCxiLqLsS4CJ5uoI5WYWCQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm64@0.127.0': + resolution: {integrity: sha512-b5jtVTH6AU5CJXHNdj7Jj9IEiR9yVjjnwHzPJhGyHGPdcsZSzBCkS9GBbV33niRMvKthDwQRFRJfI4a+k4PvYg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.127.0': + resolution: {integrity: sha512-obCE8B7ISKkJidjlhv9xRGJPOSDG2Yu6PRga9Ruaz35uintHxbp1Ki/Yc71wx4rj3Edrm0a1kzG1TAwit0wFpg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.127.0': + resolution: {integrity: sha512-JL6Xb5IwPQT8rUzlpsX7E+AgfcdNklXNPFp8pjCQQ5MQOQo5rtEB2ui+3Hgg9Sn7Y9Egj6YOLLiHhLpdAe12Aw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-freebsd-x64@0.127.0': + resolution: {integrity: sha512-SDQ/3MQFw58fqQz3Z1PhSKFF3JoCF4gmlNjziDm8X02tTahCw0qJbd7FGPDKw1i4VTBZene9JPyC3mHtSvi+wA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.127.0': + resolution: {integrity: sha512-Av+D1MIqzV0YMGPT9we2SIZaMKD7Cxs4CvXSx/yxaWHewZjYEjScpOf5igc8IILASViw4WTnjlwUdI1KzVtDHQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.127.0': + resolution: {integrity: sha512-Cs2fdJ8cPpFdeebj6p4dag8A4+56hPvZ0AhQQzlaLswGz1tz7bXt1nETLeorrM9+AMcWFFkqxcXwDGfTVidY8g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.127.0': + resolution: {integrity: sha512-qdOfTcT6SY8gsJrrV92uyEUyjqMGPpIB5JZUG6QN5dukYd+7/j0kX6MwK1DgQj39jtUYixxPiaRUiEN1+0CXgQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-arm64-musl@0.127.0': + resolution: {integrity: sha512-EoTCZneNFU/P2qrpEM+RHmQwt+CvDkyGESG6qhr7KaegXLZwePfbrkCDfAk8/rhxbDUVGsZILX+2tqPzFtoFWA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-ppc64-gnu@0.127.0': + resolution: {integrity: sha512-zALjmZYgxFLHjXeudcDF0xFGNydTAtkAeXAr2EuC17ywCyFxcmQra4w0BMde0Yi/re4Bi4iwEoEXtYN7l6eBLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-gnu@0.127.0': + resolution: {integrity: sha512-fPP8M6zQLS7Jz7o9d5ArUSuAuSK3e+WCYVrCpdzeCOejidtZExJ9tjhDrAd3HEPqARBCPmdpqxESPFqy44vkBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-musl@0.127.0': + resolution: {integrity: sha512-7IcC4Ao02oGpfnjt+X/oF4U2mllo2qoSkw5xxiXNKL9MCTsTiAC6616beOuehdxGcnz1bRoPC1RQ2f1GQDdN+g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-s390x-gnu@0.127.0': + resolution: {integrity: sha512-pbXIhiNFHoqWeqDNLiJ9JkpHz1IM9k4DXa66x+1GTWMG7iLxtkXgE53iiuKSXwmk3zIYmaPVfBvgcAhS583K4Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-gnu@0.127.0': + resolution: {integrity: sha512-MYCguB9RvBvlSd6gbuNI7QwiLoCCAlGnlRJFPrzLI6U1/9wkC/WK6LtBAUln55H1Ctqw45PWmqrobKoMhsYQzQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-musl@0.127.0': + resolution: {integrity: sha512-5eY0B/bxf1xIUxb4NOTvOI3KWtBQfPWYyKAzgcrCt0mDibSZygVpO1Pz8bkeiSZ5Jj9+M09dkggG3H8I5d0Uyg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-openharmony-arm64@0.127.0': + resolution: {integrity: sha512-Gld0ajrFTUXNtdw20fVBuTQx66FA75nIVg+//pPfR3sXkuABB4mTBhl3r9JNzrJpgW//qiwxf0nWXUWGJSL3UQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-wasm32-wasi@0.127.0': + resolution: {integrity: sha512-T6KVD7rhLzFlwGRXMnxUFfkCZD8FHnb968wVXW1mXzgRFc5RNXOBY2mPPDZ77x5Ln76ltLMgtPg0cOkU1NSrEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.127.0': + resolution: {integrity: sha512-Ujvw4X+LD1CCGULcsQcvb4YNVoBGqt+JHgNNzGGaCImELiZLk477ifUH53gIbE7EKd933NdTi25JWEr9K2HwXw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.127.0': + resolution: {integrity: sha512-0cwxKO7KHQQQfo4Uf4B2SQrhgm+cJaP9OvFFhx52Tkg4bezsacu83GB2/In5bC415Ueeym+kXdnge/57rbSfTw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.127.0': + resolution: {integrity: sha512-rOrnSQSCbhI2kowr9XxE7m9a8oQXnBHjnS6j95LxxAnEZ0+Fz20WlRXG4ondQb+ejjt2KOsa65sE6++L6kUd+w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-project/types@0.127.0': + resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} + + '@oxc-resolver/binding-android-arm-eabi@11.19.1': + resolution: {integrity: sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==} + cpu: [arm] + os: [android] + + '@oxc-resolver/binding-android-arm64@11.19.1': + resolution: {integrity: sha512-oolbkRX+m7Pq2LNjr/kKgYeC7bRDMVTWPgxBGMjSpZi/+UskVo4jsMU3MLheZV55jL6c3rNelPl4oD60ggYmqA==} + cpu: [arm64] + os: [android] + + '@oxc-resolver/binding-darwin-arm64@11.19.1': + resolution: {integrity: sha512-nUC6d2i3R5B12sUW4O646qD5cnMXf2oBGPLIIeaRfU9doJRORAbE2SGv4eW6rMqhD+G7nf2Y8TTJTLiiO3Q/dQ==} + cpu: [arm64] + os: [darwin] + + '@oxc-resolver/binding-darwin-x64@11.19.1': + resolution: {integrity: sha512-cV50vE5+uAgNcFa3QY1JOeKDSkM/9ReIcc/9wn4TavhW/itkDGrXhw9jaKnkQnGbjJ198Yh5nbX/Gr2mr4Z5jQ==} + cpu: [x64] + os: [darwin] + + '@oxc-resolver/binding-freebsd-x64@11.19.1': + resolution: {integrity: sha512-xZOQiYGFxtk48PBKff+Zwoym7ScPAIVp4c14lfLxizO2LTTTJe5sx9vQNGrBymrf/vatSPNMD4FgsaaRigPkqw==} + cpu: [x64] + os: [freebsd] + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.19.1': + resolution: {integrity: sha512-lXZYWAC6kaGe/ky2su94e9jN9t6M0/6c+GrSlCqL//XO1cxi5lpAhnJYdyrKfm0ZEr/c7RNyAx3P7FSBcBd5+A==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm-musleabihf@11.19.1': + resolution: {integrity: sha512-veG1kKsuK5+t2IsO9q0DErYVSw2azvCVvWHnfTOS73WE0STdLLB7Q1bB9WR+yHPQM76ASkFyRbogWo1GR1+WbQ==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm64-gnu@11.19.1': + resolution: {integrity: sha512-heV2+jmXyYnUrpUXSPugqWDRpnsQcDm2AX4wzTuvgdlZfoNYO0O3W2AVpJYaDn9AG4JdM6Kxom8+foE7/BcSig==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-arm64-musl@11.19.1': + resolution: {integrity: sha512-jvo2Pjs1c9KPxMuMPIeQsgu0mOJF9rEb3y3TdpsrqwxRM+AN6/nDDwv45n5ZrUnQMsdBy5gIabioMKnQfWo9ew==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-ppc64-gnu@11.19.1': + resolution: {integrity: sha512-vLmdNxWCdN7Uo5suays6A/+ywBby2PWBBPXctWPg5V0+eVuzsJxgAn6MMB4mPlshskYbppjpN2Zg83ArHze9gQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-gnu@11.19.1': + resolution: {integrity: sha512-/b+WgR+VTSBxzgOhDO7TlMXC1ufPIMR6Vj1zN+/x+MnyXGW7prTLzU9eW85Aj7Th7CCEG9ArCbTeqxCzFWdg2w==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-musl@11.19.1': + resolution: {integrity: sha512-YlRdeWb9j42p29ROh+h4eg/OQ3dTJlpHSa+84pUM9+p6i3djtPz1q55yLJhgW9XfDch7FN1pQ/Vd6YP+xfRIuw==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-s390x-gnu@11.19.1': + resolution: {integrity: sha512-EDpafVOQWF8/MJynsjOGFThcqhRHy417sRyLfQmeiamJ8qVhSKAn2Dn2VVKUGCjVB9C46VGjhNo7nOPUi1x6uA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-gnu@11.19.1': + resolution: {integrity: sha512-NxjZe+rqWhr+RT8/Ik+5ptA3oz7tUw361Wa5RWQXKnfqwSSHdHyrw6IdcTfYuml9dM856AlKWZIUXDmA9kkiBQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-musl@11.19.1': + resolution: {integrity: sha512-cM/hQwsO3ReJg5kR+SpI69DMfvNCp+A/eVR4b4YClE5bVZwz8rh2Nh05InhwI5HR/9cArbEkzMjcKgTHS6UaNw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-openharmony-arm64@11.19.1': + resolution: {integrity: sha512-QF080IowFB0+9Rh6RcD19bdgh49BpQHUW5TajG1qvWHvmrQznTZZjYlgE2ltLXyKY+qs4F/v5xuX1XS7Is+3qA==} + cpu: [arm64] + os: [openharmony] + + '@oxc-resolver/binding-wasm32-wasi@11.19.1': + resolution: {integrity: sha512-w8UCKhX826cP/ZLokXDS6+milN8y4X7zidsAttEdWlVoamTNf6lhBJldaWr3ukTDiye7s4HRcuPEPOXNC432Vg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-resolver/binding-win32-arm64-msvc@11.19.1': + resolution: {integrity: sha512-nJ4AsUVZrVKwnU/QRdzPCCrO0TrabBqgJ8pJhXITdZGYOV28TIYystV1VFLbQ7DtAcaBHpocT5/ZJnF78YJPtQ==} + cpu: [arm64] + os: [win32] + + '@oxc-resolver/binding-win32-ia32-msvc@11.19.1': + resolution: {integrity: sha512-EW+ND5q2Tl+a3pH81l1QbfgbF3HmqgwLfDfVithRFheac8OTcnbXt/JxqD2GbDkb7xYEqy1zNaVFRr3oeG8npA==} + cpu: [ia32] + os: [win32] + + '@oxc-resolver/binding-win32-x64-msvc@11.19.1': + resolution: {integrity: sha512-6hIU3RQu45B+VNTY4Ru8ppFwjVS/S5qwYyGhBotmjxfEKk41I2DlGtRfGJndZ5+6lneE2pwloqunlOyZuX/XAw==} + cpu: [x64] + os: [win32] + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -508,51 +941,61 @@ packages: resolution: {integrity: sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.29.1': resolution: {integrity: sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.29.1': resolution: {integrity: sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.29.1': resolution: {integrity: sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loongarch64-gnu@4.29.1': resolution: {integrity: sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-powerpc64le-gnu@4.29.1': resolution: {integrity: sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.29.1': resolution: {integrity: sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-s390x-gnu@4.29.1': resolution: {integrity: sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.29.1': resolution: {integrity: sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.29.1': resolution: {integrity: sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.29.1': resolution: {integrity: sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==} @@ -578,12 +1021,18 @@ packages: peerDependencies: eslint: '>=8.40.0' + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/body-parser@1.19.5': resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} @@ -602,9 +1051,15 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@22.10.2': resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==} @@ -620,6 +1075,9 @@ packages: '@types/serve-static@1.15.7': resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/ws@8.5.13': resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} @@ -809,6 +1267,9 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -879,6 +1340,9 @@ packages: resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + character-parser@2.2.0: resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} @@ -994,6 +1458,9 @@ packages: supports-color: optional: true + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -1013,10 +1480,21 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -1052,6 +1530,10 @@ packages: resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} engines: {node: '>=10.13.0'} + entities@8.0.0: + resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} + engines: {node: '>=20.19.0'} + es-abstract@1.23.9: resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} engines: {node: '>= 0.4'} @@ -1258,6 +1740,9 @@ packages: resolution: {integrity: sha512-V4UkHQc+B7ldh1YC84HCXHwf60M4BOMvp9rkvTUWCK5apqDC1Esnbid4wm6nFyVuDy8XMfETsJw5lsIGBWyo0A==} engines: {node: '>= 18'} + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1280,6 +1765,9 @@ packages: fastq@1.18.0: resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} + fd-package-json@2.0.0: + resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} + fdir@6.4.2: resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} peerDependencies: @@ -1288,6 +1776,15 @@ packages: picomatch: optional: true + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -1318,6 +1815,11 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + formatly@0.3.0: + resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==} + engines: {node: '>=18.3.0'} + hasBin: true + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -1357,6 +1859,9 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + get-tsconfig@4.8.1: resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} @@ -1535,6 +2040,10 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} @@ -1594,6 +2103,10 @@ packages: resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} hasBin: true + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -1624,6 +2137,11 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + knip@6.7.0: + resolution: {integrity: sha512-ckL51NDH1YJxnv1kNB0iUdDngB4f/e9Igz8uIqYfmNDoyOFmmk1V0WFv3LQ7/hzC63b2Z9X41gGUE9eOWrZpaA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -1658,6 +2176,9 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + loupe@3.1.2: resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} @@ -1675,6 +2196,18 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -1695,6 +2228,69 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -1806,6 +2402,13 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + oxc-parser@0.127.0: + resolution: {integrity: sha512-bkgD4qHlN7WxLdX8bLXdaU54TtQtAIg/ZBAfm0aje/mo3MRDo3P0hZSgr4U7O3xfX+fQmR5AP04JS/TGcZLcFA==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-resolver@11.19.1: + resolution: {integrity: sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg==} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -1824,6 +2427,9 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse5@8.0.1: + resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -1869,7 +2475,11 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} - pirates@4.0.6: + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -1963,6 +2573,12 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} @@ -2029,6 +2645,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + send@1.1.0: resolution: {integrity: sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==} engines: {node: '>= 18'} @@ -2055,6 +2676,10 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2086,6 +2711,10 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + smol-toml@1.6.1: + resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} + engines: {node: '>= 18'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2143,6 +2772,10 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -2181,6 +2814,10 @@ packages: resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + tinypool@1.0.2: resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -2208,6 +2845,9 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + ts-api-utils@1.4.3: resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} engines: {node: '>=16'} @@ -2297,6 +2937,10 @@ packages: engines: {node: '>=14.17'} hasBin: true + unbash@3.0.0: + resolution: {integrity: sha512-FeFPZ/WFT0mbRCuydiZzpPFlrYN8ZUpphQKoq4EeElVIYjYyGzPMxQR/simUwCOJIyVhpFk4RbtyO7RuMpMnHA==} + engines: {node: '>=14'} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -2304,6 +2948,21 @@ packages: undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -2328,6 +2987,12 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@3.0.5: resolution: {integrity: sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -2412,6 +3077,10 @@ packages: peerDependencies: eslint: '>=6.0.0' + walk-up-path@4.0.0: + resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} + engines: {node: 20 || >=22} + webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} @@ -2475,6 +3144,11 @@ packages: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} + yaml@2.8.3: + resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} + engines: {node: '>= 14.6'} + hasBin: true + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -2482,6 +3156,12 @@ packages: zod@3.24.1: resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: '@caido/eslint-config@0.0.6(@typescript-eslint/parser@8.18.2(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2))(eslint@9.17.0(jiti@2.4.2))(prettier@3.4.2)(typescript@5.7.2)': @@ -2511,6 +3191,27 @@ snapshots: dependencies: ajv: 8.17.1 + '@emnapi/core@1.9.2': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.23.1': optional: true @@ -2556,201 +3257,442 @@ snapshots: '@esbuild/freebsd-x64@0.23.1': optional: true - '@esbuild/freebsd-x64@0.24.2': + '@esbuild/freebsd-x64@0.24.2': + optional: true + + '@esbuild/linux-arm64@0.23.1': + optional: true + + '@esbuild/linux-arm64@0.24.2': + optional: true + + '@esbuild/linux-arm@0.23.1': + optional: true + + '@esbuild/linux-arm@0.24.2': + optional: true + + '@esbuild/linux-ia32@0.23.1': + optional: true + + '@esbuild/linux-ia32@0.24.2': + optional: true + + '@esbuild/linux-loong64@0.23.1': + optional: true + + '@esbuild/linux-loong64@0.24.2': + optional: true + + '@esbuild/linux-mips64el@0.23.1': + optional: true + + '@esbuild/linux-mips64el@0.24.2': + optional: true + + '@esbuild/linux-ppc64@0.23.1': + optional: true + + '@esbuild/linux-ppc64@0.24.2': + optional: true + + '@esbuild/linux-riscv64@0.23.1': + optional: true + + '@esbuild/linux-riscv64@0.24.2': + optional: true + + '@esbuild/linux-s390x@0.23.1': + optional: true + + '@esbuild/linux-s390x@0.24.2': + optional: true + + '@esbuild/linux-x64@0.23.1': + optional: true + + '@esbuild/linux-x64@0.24.2': + optional: true + + '@esbuild/netbsd-arm64@0.24.2': + optional: true + + '@esbuild/netbsd-x64@0.23.1': + optional: true + + '@esbuild/netbsd-x64@0.24.2': + optional: true + + '@esbuild/openbsd-arm64@0.23.1': + optional: true + + '@esbuild/openbsd-arm64@0.24.2': + optional: true + + '@esbuild/openbsd-x64@0.23.1': + optional: true + + '@esbuild/openbsd-x64@0.24.2': + optional: true + + '@esbuild/sunos-x64@0.23.1': + optional: true + + '@esbuild/sunos-x64@0.24.2': + optional: true + + '@esbuild/win32-arm64@0.23.1': + optional: true + + '@esbuild/win32-arm64@0.24.2': + optional: true + + '@esbuild/win32-ia32@0.23.1': + optional: true + + '@esbuild/win32-ia32@0.24.2': + optional: true + + '@esbuild/win32-x64@0.23.1': + optional: true + + '@esbuild/win32-x64@0.24.2': + optional: true + + '@eslint-community/eslint-utils@4.4.1(eslint@9.17.0(jiti@2.4.2))': + dependencies: + eslint: 9.17.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.19.1': + dependencies: + '@eslint/object-schema': 2.1.5 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.9.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.2.0': + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.17.0': {} + + '@eslint/object-schema@2.1.5': {} + + '@eslint/plugin-kit@0.2.4': + dependencies: + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.1': {} + + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.10.0 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@mdn/browser-compat-data@5.6.27': {} + + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.18.0 + + '@oxc-parser/binding-android-arm-eabi@0.127.0': optional: true - '@esbuild/linux-arm64@0.23.1': + '@oxc-parser/binding-android-arm64@0.127.0': optional: true - '@esbuild/linux-arm64@0.24.2': + '@oxc-parser/binding-darwin-arm64@0.127.0': optional: true - '@esbuild/linux-arm@0.23.1': + '@oxc-parser/binding-darwin-x64@0.127.0': optional: true - '@esbuild/linux-arm@0.24.2': + '@oxc-parser/binding-freebsd-x64@0.127.0': optional: true - '@esbuild/linux-ia32@0.23.1': + '@oxc-parser/binding-linux-arm-gnueabihf@0.127.0': optional: true - '@esbuild/linux-ia32@0.24.2': + '@oxc-parser/binding-linux-arm-musleabihf@0.127.0': optional: true - '@esbuild/linux-loong64@0.23.1': + '@oxc-parser/binding-linux-arm64-gnu@0.127.0': optional: true - '@esbuild/linux-loong64@0.24.2': + '@oxc-parser/binding-linux-arm64-musl@0.127.0': optional: true - '@esbuild/linux-mips64el@0.23.1': + '@oxc-parser/binding-linux-ppc64-gnu@0.127.0': optional: true - '@esbuild/linux-mips64el@0.24.2': + '@oxc-parser/binding-linux-riscv64-gnu@0.127.0': optional: true - '@esbuild/linux-ppc64@0.23.1': + '@oxc-parser/binding-linux-riscv64-musl@0.127.0': optional: true - '@esbuild/linux-ppc64@0.24.2': + '@oxc-parser/binding-linux-s390x-gnu@0.127.0': optional: true - '@esbuild/linux-riscv64@0.23.1': + '@oxc-parser/binding-linux-x64-gnu@0.127.0': optional: true - '@esbuild/linux-riscv64@0.24.2': + '@oxc-parser/binding-linux-x64-musl@0.127.0': optional: true - '@esbuild/linux-s390x@0.23.1': + '@oxc-parser/binding-openharmony-arm64@0.127.0': optional: true - '@esbuild/linux-s390x@0.24.2': + '@oxc-parser/binding-wasm32-wasi@0.127.0': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) optional: true - '@esbuild/linux-x64@0.23.1': + '@oxc-parser/binding-win32-arm64-msvc@0.127.0': optional: true - '@esbuild/linux-x64@0.24.2': + '@oxc-parser/binding-win32-ia32-msvc@0.127.0': optional: true - '@esbuild/netbsd-arm64@0.24.2': + '@oxc-parser/binding-win32-x64-msvc@0.127.0': optional: true - '@esbuild/netbsd-x64@0.23.1': - optional: true + '@oxc-project/types@0.127.0': {} - '@esbuild/netbsd-x64@0.24.2': + '@oxc-resolver/binding-android-arm-eabi@11.19.1': optional: true - '@esbuild/openbsd-arm64@0.23.1': + '@oxc-resolver/binding-android-arm64@11.19.1': optional: true - '@esbuild/openbsd-arm64@0.24.2': + '@oxc-resolver/binding-darwin-arm64@11.19.1': optional: true - '@esbuild/openbsd-x64@0.23.1': + '@oxc-resolver/binding-darwin-x64@11.19.1': optional: true - '@esbuild/openbsd-x64@0.24.2': + '@oxc-resolver/binding-freebsd-x64@11.19.1': optional: true - '@esbuild/sunos-x64@0.23.1': + '@oxc-resolver/binding-linux-arm-gnueabihf@11.19.1': optional: true - '@esbuild/sunos-x64@0.24.2': + '@oxc-resolver/binding-linux-arm-musleabihf@11.19.1': optional: true - '@esbuild/win32-arm64@0.23.1': + '@oxc-resolver/binding-linux-arm64-gnu@11.19.1': optional: true - '@esbuild/win32-arm64@0.24.2': + '@oxc-resolver/binding-linux-arm64-musl@11.19.1': optional: true - '@esbuild/win32-ia32@0.23.1': + '@oxc-resolver/binding-linux-ppc64-gnu@11.19.1': optional: true - '@esbuild/win32-ia32@0.24.2': + '@oxc-resolver/binding-linux-riscv64-gnu@11.19.1': optional: true - '@esbuild/win32-x64@0.23.1': + '@oxc-resolver/binding-linux-riscv64-musl@11.19.1': optional: true - '@esbuild/win32-x64@0.24.2': + '@oxc-resolver/binding-linux-s390x-gnu@11.19.1': optional: true - '@eslint-community/eslint-utils@4.4.1(eslint@9.17.0(jiti@2.4.2))': - dependencies: - eslint: 9.17.0(jiti@2.4.2) - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} + '@oxc-resolver/binding-linux-x64-gnu@11.19.1': + optional: true - '@eslint/config-array@0.19.1': - dependencies: - '@eslint/object-schema': 2.1.5 - debug: 4.4.0 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + '@oxc-resolver/binding-linux-x64-musl@11.19.1': + optional: true - '@eslint/core@0.9.1': - dependencies: - '@types/json-schema': 7.0.15 + '@oxc-resolver/binding-openharmony-arm64@11.19.1': + optional: true - '@eslint/eslintrc@3.2.0': + '@oxc-resolver/binding-wasm32-wasi@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.10.0)': dependencies: - ajv: 6.12.6 - debug: 4.4.0 - espree: 10.3.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.10.0) transitivePeerDependencies: - - supports-color - - '@eslint/js@9.17.0': {} - - '@eslint/object-schema@2.1.5': {} - - '@eslint/plugin-kit@0.2.4': - dependencies: - levn: 0.4.1 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.6': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.3.1': {} - - '@humanwhocodes/retry@0.4.1': {} - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@jridgewell/gen-mapping@0.3.8': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - - '@mdn/browser-compat-data@5.6.27': {} + - '@emnapi/core' + - '@emnapi/runtime' + optional: true - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 + '@oxc-resolver/binding-win32-arm64-msvc@11.19.1': + optional: true - '@nodelib/fs.stat@2.0.5': {} + '@oxc-resolver/binding-win32-ia32-msvc@11.19.1': + optional: true - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.18.0 + '@oxc-resolver/binding-win32-x64-msvc@11.19.1': + optional: true '@pkgjs/parseargs@0.11.0': optional: true @@ -2828,6 +3770,11 @@ snapshots: - supports-color - typescript + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 @@ -2837,6 +3784,10 @@ snapshots: dependencies: '@types/node': 22.10.2 + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/estree@1.0.6': {} '@types/express-serve-static-core@5.0.3': @@ -2859,8 +3810,14 @@ snapshots: '@types/json5@0.0.29': {} + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/mime@1.3.5': {} + '@types/ms@2.1.0': {} + '@types/node@22.10.2': dependencies: undici-types: 6.20.0 @@ -2880,6 +3837,8 @@ snapshots: '@types/node': 22.10.2 '@types/send': 0.17.4 + '@types/unist@3.0.3': {} + '@types/ws@8.5.13': dependencies: '@types/node': 22.10.2 @@ -3005,13 +3964,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 2.0.0 - '@vitest/mocker@3.0.5(vite@6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2))': + '@vitest/mocker@3.0.5(vite@6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3))': dependencies: '@vitest/spy': 3.0.5 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2) + vite: 6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3) '@vitest/pretty-format@3.0.5': dependencies: @@ -3138,6 +4097,8 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 + bail@2.0.2: {} + balanced-match@1.0.2: {} body-parser@2.0.2: @@ -3222,6 +4183,8 @@ snapshots: chalk@5.4.1: {} + character-entities@2.0.2: {} + character-parser@2.2.0: dependencies: is-regex: 1.2.1 @@ -3304,6 +4267,10 @@ snapshots: dependencies: ms: 2.1.3 + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + deep-eql@5.0.2: {} deep-is@0.1.4: {} @@ -3322,8 +4289,16 @@ snapshots: depd@2.0.0: {} + dequal@2.0.3: {} + destroy@1.2.0: {} + detect-libc@2.1.2: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -3353,6 +4328,8 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.1 + entities@8.0.0: {} + es-abstract@1.23.9: dependencies: array-buffer-byte-length: 1.0.2 @@ -3736,6 +4713,8 @@ snapshots: transitivePeerDependencies: - supports-color + extend@3.0.2: {} + fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} @@ -3758,10 +4737,18 @@ snapshots: dependencies: reusify: 1.0.4 + fd-package-json@2.0.0: + dependencies: + walk-up-path: 4.0.0 + fdir@6.4.2(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -3803,6 +4790,10 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + formatly@0.3.0: + dependencies: + fd-package-json: 2.0.0 + forwarded@0.2.0: {} fresh@0.5.2: {} @@ -3849,6 +4840,10 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.2.7 + get-tsconfig@4.14.0: + dependencies: + resolve-pkg-maps: 1.0.0 + get-tsconfig@4.8.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -4029,6 +5024,8 @@ snapshots: is-number@7.0.0: {} + is-plain-obj@4.1.0: {} + is-promise@4.0.0: {} is-regex@1.2.1: @@ -4088,6 +5085,8 @@ snapshots: jiti@2.4.2: {} + jiti@2.6.1: {} + joycon@3.1.1: {} js-yaml@4.1.0: @@ -4117,6 +5116,26 @@ snapshots: dependencies: json-buffer: 3.0.1 + knip@6.7.0(@emnapi/core@1.9.2)(@emnapi/runtime@1.10.0): + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + formatly: 0.3.0 + get-tsconfig: 4.14.0 + jiti: 2.6.1 + minimist: 1.2.8 + oxc-parser: 0.127.0 + oxc-resolver: 11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.10.0) + picomatch: 4.0.4 + smol-toml: 1.6.1 + strip-json-comments: 5.0.3 + tinyglobby: 0.2.16 + unbash: 3.0.0 + yaml: 2.8.3 + zod: 4.3.6 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -4144,6 +5163,8 @@ snapshots: lodash@4.17.21: {} + longest-streak@3.1.0: {} + loupe@3.1.2: {} lru-cache@10.4.3: {} @@ -4156,6 +5177,44 @@ snapshots: math-intrinsics@1.1.0: {} + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + media-typer@0.3.0: {} media-typer@1.1.0: {} @@ -4166,6 +5225,139 @@ snapshots: methods@1.1.2: {} + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.0 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -4281,6 +5473,57 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + oxc-parser@0.127.0: + dependencies: + '@oxc-project/types': 0.127.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.127.0 + '@oxc-parser/binding-android-arm64': 0.127.0 + '@oxc-parser/binding-darwin-arm64': 0.127.0 + '@oxc-parser/binding-darwin-x64': 0.127.0 + '@oxc-parser/binding-freebsd-x64': 0.127.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.127.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.127.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.127.0 + '@oxc-parser/binding-linux-arm64-musl': 0.127.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.127.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.127.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.127.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.127.0 + '@oxc-parser/binding-linux-x64-gnu': 0.127.0 + '@oxc-parser/binding-linux-x64-musl': 0.127.0 + '@oxc-parser/binding-openharmony-arm64': 0.127.0 + '@oxc-parser/binding-wasm32-wasi': 0.127.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.127.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.127.0 + '@oxc-parser/binding-win32-x64-msvc': 0.127.0 + + oxc-resolver@11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.10.0): + optionalDependencies: + '@oxc-resolver/binding-android-arm-eabi': 11.19.1 + '@oxc-resolver/binding-android-arm64': 11.19.1 + '@oxc-resolver/binding-darwin-arm64': 11.19.1 + '@oxc-resolver/binding-darwin-x64': 11.19.1 + '@oxc-resolver/binding-freebsd-x64': 11.19.1 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.19.1 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.19.1 + '@oxc-resolver/binding-linux-arm64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-arm64-musl': 11.19.1 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-riscv64-musl': 11.19.1 + '@oxc-resolver/binding-linux-s390x-gnu': 11.19.1 + '@oxc-resolver/binding-linux-x64-gnu': 11.19.1 + '@oxc-resolver/binding-linux-x64-musl': 11.19.1 + '@oxc-resolver/binding-openharmony-arm64': 11.19.1 + '@oxc-resolver/binding-wasm32-wasi': 11.19.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.10.0) + '@oxc-resolver/binding-win32-arm64-msvc': 11.19.1 + '@oxc-resolver/binding-win32-ia32-msvc': 11.19.1 + '@oxc-resolver/binding-win32-x64-msvc': 11.19.1 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -4297,6 +5540,10 @@ snapshots: dependencies: callsites: 3.1.0 + parse5@8.0.1: + dependencies: + entities: 8.0.0 + parseurl@1.3.3: {} path-exists@4.0.0: {} @@ -4327,17 +5574,20 @@ snapshots: picomatch@4.0.2: {} + picomatch@4.0.4: {} + pirates@4.0.6: {} possible-typed-array-names@1.0.0: {} - postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2): + postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(yaml@2.8.3): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 2.4.2 postcss: 8.4.49 tsx: 4.19.2 + yaml: 2.8.3 postcss-selector-parser@6.1.2: dependencies: @@ -4422,6 +5672,21 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + require-from-string@2.0.2: {} resolve-from@4.0.0: {} @@ -4506,6 +5771,8 @@ snapshots: semver@7.6.3: {} + semver@7.7.4: {} + send@1.1.0: dependencies: debug: 4.4.0 @@ -4558,6 +5825,37 @@ snapshots: setprototypeof@1.2.0: {} + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -4596,6 +5894,8 @@ snapshots: signal-exit@4.1.0: {} + smol-toml@1.6.1: {} + source-map-js@1.2.1: {} source-map@0.8.0-beta.0: @@ -4659,6 +5959,8 @@ snapshots: strip-json-comments@3.1.1: {} + strip-json-comments@5.0.3: {} + sucrase@3.35.0: dependencies: '@jridgewell/gen-mapping': 0.3.8 @@ -4699,6 +6001,11 @@ snapshots: fdir: 6.4.2(picomatch@4.0.2) picomatch: 4.0.2 + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + tinypool@1.0.2: {} tinyrainbow@2.0.0: {} @@ -4717,6 +6024,8 @@ snapshots: tree-kill@1.2.2: {} + trough@2.2.0: {} + ts-api-utils@1.4.3(typescript@5.7.2): dependencies: typescript: 5.7.2 @@ -4736,7 +6045,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.3.5(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.2): + tsup@8.3.5(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.8.3): dependencies: bundle-require: 5.1.0(esbuild@0.24.2) cac: 6.7.14 @@ -4746,7 +6055,7 @@ snapshots: esbuild: 0.24.2 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2) + postcss-load-config: 6.0.1(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(yaml@2.8.3) resolve-from: 5.0.0 rollup: 4.29.1 source-map: 0.8.0-beta.0 @@ -4832,6 +6141,8 @@ snapshots: typescript@5.7.2: {} + unbash@3.0.0: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.3 @@ -4841,6 +6152,35 @@ snapshots: undici-types@6.20.0: {} + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + unpipe@1.0.0: {} update-browserslist-db@1.1.1(browserslist@4.24.3): @@ -4859,13 +6199,23 @@ snapshots: vary@1.1.2: {} - vite-node@3.0.5(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2): + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite-node@3.0.5(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 2.0.3 - vite: 6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2) + vite: 6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3) transitivePeerDependencies: - '@types/node' - jiti @@ -4880,7 +6230,7 @@ snapshots: - tsx - yaml - vite@6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2): + vite@6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3): dependencies: esbuild: 0.24.2 postcss: 8.4.49 @@ -4890,11 +6240,12 @@ snapshots: fsevents: 2.3.3 jiti: 2.4.2 tsx: 4.19.2 + yaml: 2.8.3 - vitest@3.0.5(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2): + vitest@3.0.5(@types/debug@4.1.13)(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3): dependencies: '@vitest/expect': 3.0.5 - '@vitest/mocker': 3.0.5(vite@6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)) + '@vitest/mocker': 3.0.5(vite@6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3)) '@vitest/pretty-format': 3.0.5 '@vitest/runner': 3.0.5 '@vitest/snapshot': 3.0.5 @@ -4910,10 +6261,11 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2) - vite-node: 3.0.5(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2) + vite: 6.0.7(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3) + vite-node: 3.0.5(@types/node@22.10.2)(jiti@2.4.2)(tsx@4.19.2)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: + '@types/debug': 4.1.13 '@types/node': 22.10.2 transitivePeerDependencies: - jiti @@ -4947,6 +6299,8 @@ snapshots: transitivePeerDependencies: - supports-color + walk-up-path@4.0.0: {} + webidl-conversions@4.0.2: {} whatwg-url@7.1.0: @@ -5024,6 +6378,12 @@ snapshots: xml-name-validator@4.0.0: {} + yaml@2.8.3: {} + yocto-queue@0.1.0: {} zod@3.24.1: {} + + zod@4.3.6: {} + + zwitch@2.0.4: {} diff --git a/src/build/frontend.ts b/src/build/frontend.ts index 267b23b..fcee34f 100644 --- a/src/build/frontend.ts +++ b/src/build/frontend.ts @@ -49,7 +49,7 @@ export async function buildFrontendPlugin( const viteConfig = createViteConfig(cwd, pluginConfig); await build(viteConfig); - const hasCss = existsSync(`${pluginRoot}/dist/index.css`); + const hasCss = existsSync(path.join(pluginRoot, "dist", "index.css")); logInfo("Frontend plugin built successfully"); return { diff --git a/src/bundle/index.ts b/src/bundle/index.ts index 50e84f3..5ecd6b9 100644 --- a/src/bundle/index.ts +++ b/src/bundle/index.ts @@ -10,6 +10,7 @@ import { addDirectoryToZip, logInfo, logSuccess } from "../utils"; import { bundleBackendPlugin } from "./backend"; import { bundleFrontendPlugin } from "./frontend"; +import { transformReadmeImages } from "./readme-assets"; /** * Creates the dist directories. @@ -51,6 +52,21 @@ export async function bundlePackage(options: { // Create dist directories const { distDir, pluginPackageDir } = await createDistDirectories(cwd); + // Copy README.md (always included, always at root) + const readmePath = path.join(cwd, "README.md"); + try { + await fs.access(readmePath); + } catch { + throw new Error("README.md is required but not found in project root"); + } + + // Inline local README images and remove external README URLs. + const transformedReadme = await transformReadmeImages(readmePath); + + // Write transformed README to package directory + const readmeDest = path.join(pluginPackageDir, "README.md"); + await fs.writeFile(readmeDest, transformedReadme); + // Create manifest const manifest = createManifest({ config }); diff --git a/src/bundle/readme-assets.spec.ts b/src/bundle/readme-assets.spec.ts new file mode 100644 index 0000000..2592350 --- /dev/null +++ b/src/bundle/readme-assets.spec.ts @@ -0,0 +1,186 @@ +import fs from "fs/promises"; +import os from "os"; +import path from "path"; + +import sharp from "sharp"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; + +import { + compressImageToWebpDataUri, + transformReadmeImages, +} from "./readme-assets"; + +const DATA_URI_PREFIX = "data:image/webp;base64,"; +const MAX_INLINED_IMAGE_BYTES = 125 * 1024; +const itUnix = process.platform === "win32" ? it.skip : it; +const itWindows = process.platform === "win32" ? it : it.skip; + +function decodeWebpDataUri(dataUri: string): Buffer { + expect(dataUri.startsWith(DATA_URI_PREFIX)).toBe(true); + return Buffer.from(dataUri.slice(DATA_URI_PREFIX.length), "base64"); +} + +async function writePng(filePath: string, width = 256, height = 256) { + await sharp({ + create: { + width, + height, + channels: 4, + background: { r: 255, g: 0, b: 0, alpha: 1 }, + }, + }) + .png() + .toFile(filePath); +} + +describe("compressImageToWebpDataUri", () => { + let tempDir: string; + + beforeEach(async () => { + tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "readme-assets-")); + }); + + afterEach(async () => { + await fs.rm(tempDir, { recursive: true, force: true }); + }); + + it("converts a local image to a WebP data URI under the per-image limit", async () => { + await writePng(path.join(tempDir, "image.png")); + + const dataUri = await compressImageToWebpDataUri(tempDir, "image.png"); + const webp = decodeWebpDataUri(dataUri); + const metadata = await sharp(webp).metadata(); + + expect(webp.byteLength).toBeLessThanOrEqual(MAX_INLINED_IMAGE_BYTES); + expect(metadata.format).toBe("webp"); + expect(metadata.width).toBe(256); + expect(metadata.height).toBe(256); + }); + + it("resolves encoded local paths and ignores query and fragment markers", async () => { + const assetDir = path.join(tempDir, "asset dir"); + await fs.mkdir(assetDir); + await writePng(path.join(assetDir, "test image.png"), 16, 16); + + const dataUri = await compressImageToWebpDataUri( + tempDir, + "asset%20dir/test%20image.png?raw=true#preview", + ); + const metadata = await sharp(decodeWebpDataUri(dataUri)).metadata(); + + expect(metadata.format).toBe("webp"); + expect(metadata.width).toBe(16); + expect(metadata.height).toBe(16); + }); + + it("transforms raw HTML URLs with HTML parsing", async () => { + await writePng(path.join(tempDir, "local-image.png"), 16, 16); + await fs.writeFile( + path.join(tempDir, "README.md"), + [ + "Local image", + "External docs", + "Data image", + "Section", + ].join("\n"), + ); + + const content = await transformReadmeImages( + path.join(tempDir, "README.md"), + ); + + expect(content).toContain('src="data:image/webp;base64,'); + expect(content).toContain('href=""'); + expect(content).toContain('src="data:image/png;base64,abc123"'); + expect(content).toContain('href="#section"'); + }); + + itWindows("resolves README image paths with Windows separators", async () => { + const assetDir = path.join(tempDir, "asset-dir"); + await fs.mkdir(assetDir); + await writePng(path.join(assetDir, "test-image.png"), 16, 16); + + const dataUri = await compressImageToWebpDataUri( + tempDir, + "asset-dir\\test-image.png", + ); + const metadata = await sharp(decodeWebpDataUri(dataUri)).metadata(); + + expect(metadata.format).toBe("webp"); + expect(metadata.width).toBe(16); + expect(metadata.height).toBe(16); + }); + + it("rejects README image paths that resolve outside the README directory", async () => { + const outsideDir = await fs.mkdtemp( + path.join(os.tmpdir(), "readme-assets-outside-"), + ); + + try { + await writePng(path.join(outsideDir, "outside.png"), 16, 16); + + await expect( + compressImageToWebpDataUri( + tempDir, + path.relative(tempDir, path.join(outsideDir, "outside.png")), + ), + ).rejects.toThrow("escapes project root"); + } finally { + await fs.rm(outsideDir, { recursive: true, force: true }); + } + }); + + itWindows( + "rejects README image paths with Windows separators that resolve outside the README directory", + async () => { + const outsideDir = await fs.mkdtemp( + path.join(os.tmpdir(), "readme-assets-outside-"), + ); + + try { + await writePng(path.join(outsideDir, "outside.png"), 16, 16); + + await expect( + compressImageToWebpDataUri( + tempDir, + path.win32.relative(tempDir, path.join(outsideDir, "outside.png")), + ), + ).rejects.toThrow("escapes project root"); + } finally { + await fs.rm(outsideDir, { recursive: true, force: true }); + } + }, + ); + + itUnix("rejects README image paths that are symlinks", async () => { + await writePng(path.join(tempDir, "image.png"), 16, 16); + await fs.symlink( + path.join(tempDir, "image.png"), + path.join(tempDir, "image-link.png"), + ); + + await expect( + compressImageToWebpDataUri(tempDir, "image-link.png"), + ).rejects.toThrow("escapes project root"); + }); + + itUnix( + "rejects README image paths that escape through parent symlinks", + async () => { + const outsideDir = await fs.mkdtemp( + path.join(os.tmpdir(), "readme-assets-outside-"), + ); + + try { + await writePng(path.join(outsideDir, "outside.png"), 16, 16); + await fs.symlink(outsideDir, path.join(tempDir, "linked-assets")); + + await expect( + compressImageToWebpDataUri(tempDir, "linked-assets/outside.png"), + ).rejects.toThrow("escapes project root"); + } finally { + await fs.rm(outsideDir, { recursive: true, force: true }); + } + }, + ); +}); diff --git a/src/bundle/readme-assets.ts b/src/bundle/readme-assets.ts new file mode 100644 index 0000000..c4b3a20 --- /dev/null +++ b/src/bundle/readme-assets.ts @@ -0,0 +1,318 @@ +import fs from "fs/promises"; +import path from "path"; + +import type { Definition, Html, Image, Link } from "mdast"; +import { type DefaultTreeAdapterMap, parseFragment, serialize } from "parse5"; +import remarkParse from "remark-parse"; +import remarkStringify from "remark-stringify"; +import sharp from "sharp"; +import { unified } from "unified"; +import { visit } from "unist-util-visit"; + +import { logInfo } from "../utils"; + +const MAX_INLINED_IMAGE_BYTES = 100 * 1024; // 133Kb base64 encoded +const MAX_README_BYTES = 2 * 1024 * 1024; // 2 Mb +const WEBP_MIME_TYPE = "image/webp"; +const IMAGE_EXTENSIONS = new Set([ + ".avif", + ".gif", + ".jpeg", + ".jpg", + ".png", + ".svg", + ".tif", + ".tiff", + ".webp", +]); + +type UrlNode = Image | Link | Definition; +type HtmlNode = DefaultTreeAdapterMap["node"]; +type HtmlParentNode = DefaultTreeAdapterMap["parentNode"]; +type HtmlElement = DefaultTreeAdapterMap["element"]; +type HtmlTemplate = DefaultTreeAdapterMap["template"]; + +/** + * Checks if a URL is external (http or https). + * data: URIs and fragment identifiers are not considered external. + */ +function isExternalUrl(url: string): boolean { + if (url.startsWith("data:") || url.startsWith("#")) { + return false; + } + try { + const parsed = new URL(url); + return parsed.protocol === "http:" || parsed.protocol === "https:"; + } catch { + return false; + } +} + +function getLocalPathname(url: string): string { + const markerIndex = url.search(/[?#]/); + return markerIndex === -1 ? url : url.slice(0, markerIndex); +} + +function decodeLocalPathname(url: string): string { + try { + return decodeURIComponent(getLocalPathname(url)); + } catch { + return getLocalPathname(url); + } +} + +function isLocalImageUrl(url: string): boolean { + const pathname = decodeLocalPathname(url); + return IMAGE_EXTENSIONS.has(path.extname(pathname).toLowerCase()); +} + +function normalizePathForComparison(filePath: string): string { + const normalizedPath = path.resolve(filePath); + return process.platform === "win32" + ? normalizedPath.toLowerCase() + : normalizedPath; +} + +function isPathInDirectory(directory: string, filePath: string): boolean { + const normalizedDirectory = normalizePathForComparison(directory); + const normalizedFilePath = normalizePathForComparison(filePath); + const directoryWithSeparator = normalizedDirectory.endsWith(path.sep) + ? normalizedDirectory + : `${normalizedDirectory}${path.sep}`; + + return normalizedFilePath.startsWith(directoryWithSeparator); +} + +async function resolveReadmeAssetPath( + readmeDir: string, + url: string, +): Promise { + const assetPath = path.resolve(readmeDir, decodeLocalPathname(url)); + const assetStats = await fs.lstat(assetPath); + + if (assetStats.isSymbolicLink()) { + throw new Error(`README asset path escapes project root: ${url}`); + } + + const [realReadmeDir, realAssetPath] = await Promise.all([ + fs.realpath(readmeDir), + fs.realpath(assetPath), + ]); + + if (!isPathInDirectory(realReadmeDir, realAssetPath)) { + throw new Error(`README asset path escapes project root: ${url}`); + } + + return realAssetPath; +} + +export async function compressImageToWebpDataUri( + readmeDir: string, + originalUrl: string, +): Promise { + const assetPath = await resolveReadmeAssetPath(readmeDir, originalUrl); + const input = await fs.readFile(assetPath); + + let bestBuffer: Buffer | undefined; + for (const quality of [80, 70, 60, 50, 40, 30, 20]) { + const output = await sharp(input, { + animated: true, + limitInputPixels: false, + }) + .webp({ quality, effort: 6 }) + .toBuffer(); + + bestBuffer = output; + + if (output.byteLength <= MAX_INLINED_IMAGE_BYTES) { + break; + } + } + + if (bestBuffer === undefined) { + throw new Error(`Unable to process README image: ${originalUrl}`); + } + + if (bestBuffer.byteLength > MAX_INLINED_IMAGE_BYTES) { + throw new Error( + `README image ${originalUrl} is ${bestBuffer.byteLength} bytes after compression, which exceeds the ${MAX_INLINED_IMAGE_BYTES} byte limit`, + ); + } + + logInfo( + `Inlined README image as WebP: ${originalUrl} (${bestBuffer.byteLength} bytes)`, + ); + + return `data:${WEBP_MIME_TYPE};base64,${bestBuffer.toString("base64")}`; +} + +/** + * Transforms a URL on a markdown node. External URLs are removed. Local image + * URLs are inlined as compressed WebP data URIs. Other local links are left as-is. + */ +async function transformNodeUrl( + node: UrlNode, + readmeDir: string, + kind: string, +): Promise { + const originalUrl = node.url; + + if ( + !originalUrl || + originalUrl.startsWith("#") || + originalUrl.startsWith("data:") + ) { + return; + } + + if (isExternalUrl(originalUrl)) { + logInfo(`Warning: Skipping external ${kind} URL in README: ${originalUrl}`); + node.url = ""; + return; + } + + if (!isLocalImageUrl(originalUrl)) { + return; + } + + node.url = await compressImageToWebpDataUri(readmeDir, originalUrl); +} + +function isHtmlElement(node: HtmlNode): node is HtmlElement { + return "attrs" in node; +} + +function isHtmlParentNode(node: HtmlNode): node is HtmlParentNode { + return "childNodes" in node; +} + +function isHtmlTemplate(node: HtmlNode): node is HtmlTemplate { + return "content" in node; +} + +/** + * Transforms URLs found in raw HTML nodes (e.g., , ). + * External URLs are removed, and local image src attributes are inlined as + * compressed WebP data URIs. + */ +async function transformHtmlNode(node: Html, readmeDir: string): Promise { + const fragment = parseFragment(node.value); + + async function transformElementAttributes(element: HtmlElement) { + for (const attr of element.attrs) { + const attrName = attr.name.toLowerCase(); + if (attrName !== "src" && attrName !== "href") { + continue; + } + + const kind = attrName === "src" ? "image" : "link"; + if ( + !attr.value || + attr.value.startsWith("#") || + attr.value.startsWith("data:") + ) { + continue; + } + + if (isExternalUrl(attr.value)) { + logInfo( + `Warning: Skipping external ${kind} URL in README HTML: ${attr.value}`, + ); + attr.value = ""; + } else if (attrName === "src" && isLocalImageUrl(attr.value)) { + attr.value = await compressImageToWebpDataUri(readmeDir, attr.value); + } + } + } + + async function walkHtmlNodes(parentNode: HtmlParentNode) { + for (const childNode of parentNode.childNodes) { + if (isHtmlElement(childNode)) { + await transformElementAttributes(childNode); + } + + if (isHtmlParentNode(childNode)) { + await walkHtmlNodes(childNode); + } + + if (isHtmlTemplate(childNode)) { + await walkHtmlNodes(childNode.content); + } + } + } + + await walkHtmlNodes(fragment); + + node.value = serialize(fragment); +} + +/** + * Transforms local image references in README.md to compressed WebP data URIs. + * Uses remark to parse the markdown AST and handles multiple node types: + * - `image`: ![alt](path) + * - `link`: [text](path) + * - `definition`: [ref]: path (reference-style images/links) + * - `html`: and in raw HTML blocks + * + * External URLs (http, https) are removed to prevent loading external resources. + * data: URIs are preserved as they are self-contained. + * Fragment-only links (#anchor) are preserved as same-document anchors. + * + * @param readmePath - Absolute path to the project's README.md. + * @returns Modified README content with transformed URLs. + */ +export async function transformReadmeImages( + readmePath: string, +): Promise { + const content = await fs.readFile(readmePath, "utf-8"); + const readmeDir = path.dirname(readmePath); + + const processor = unified().use(remarkParse).use(remarkStringify); + const ast = processor.parse(content); + + const imageNodes: Image[] = []; + const linkNodes: Link[] = []; + const definitionNodes: Definition[] = []; + const htmlNodes: Html[] = []; + + visit(ast, (node) => { + switch (node.type) { + case "image": + imageNodes.push(node); + break; + case "link": + linkNodes.push(node); + break; + case "definition": + definitionNodes.push(node); + break; + case "html": + htmlNodes.push(node); + break; + default: + break; + } + }); + + for (const node of imageNodes) { + await transformNodeUrl(node, readmeDir, "image"); + } + for (const node of linkNodes) { + await transformNodeUrl(node, readmeDir, "link"); + } + for (const node of definitionNodes) { + await transformNodeUrl(node, readmeDir, "definition"); + } + for (const node of htmlNodes) { + await transformHtmlNode(node, readmeDir); + } + + const modifiedContent = processor.stringify(ast); + if (Buffer.byteLength(modifiedContent, "utf-8") > MAX_README_BYTES) { + throw new Error( + `README.md is ${Buffer.byteLength(modifiedContent, "utf-8")} bytes after inlining images, which exceeds the ${MAX_README_BYTES} byte limit`, + ); + } + + return modifiedContent; +} diff --git a/src/commands/watch.ts b/src/commands/watch.ts index 315eb8c..16e5551 100644 --- a/src/commands/watch.ts +++ b/src/commands/watch.ts @@ -2,10 +2,9 @@ import fs from "fs/promises"; import { createServer } from "http"; import path from "path"; -import { Glob } from "glob"; - import { watch as chokidarWatch } from "chokidar"; import express, { type Request, type Response } from "express"; +import { Glob } from "glob"; import { type WebSocket, WebSocketServer } from "ws"; import { loadConfig } from "../config"; @@ -18,6 +17,11 @@ import { logError, logInfo, slash } from "../utils"; import { build } from "./build"; +function isIgnoredPath(filePath: string) { + const segments = slash(filePath).split("/"); + return segments.includes("dist") || segments.includes("node_modules"); +} + export async function watch(options: { path?: string; config?: string }) { const { path: cwd = process.cwd(), config: configPath } = options; @@ -113,7 +117,7 @@ export async function watch(options: { path?: string; config?: string }) { ]; const watcher = chokidarWatch(filesToWatch, { ignoreInitial: true, - ignored: (f) => f.includes("dist/") || f.includes("node_modules/"), + ignored: isIgnoredPath, }); watcher.on("all", async (event: string, filePath: string) => { diff --git a/src/types.ts b/src/types.ts index fab91cb..6764f81 100644 --- a/src/types.ts +++ b/src/types.ts @@ -21,13 +21,13 @@ export type BackendBuildOutput = { export type BuildOutput = FrontendBuildOutput | BackendBuildOutput; -export const backendReferenceConfigSchema = z.strictObject({ id: z.string() }); +const backendReferenceConfigSchema = z.strictObject({ id: z.string() }); const viteSchema: z.ZodType = z.record(z.string(), z.unknown()); -export const assetsConfigSchema = z.array(z.string()).optional(); +const assetsConfigSchema = z.array(z.string()).optional(); -export const frontendPluginConfigSchema = z.strictObject({ +const frontendPluginConfigSchema = z.strictObject({ kind: z.literal("frontend"), id: z.string(), name: z.string().optional(), @@ -37,7 +37,7 @@ export const frontendPluginConfigSchema = z.strictObject({ vite: viteSchema.optional(), }); -export const backendPluginConfigSchema = z.strictObject({ +const backendPluginConfigSchema = z.strictObject({ kind: z.literal("backend"), id: z.string(), name: z.string().optional(), @@ -45,7 +45,7 @@ export const backendPluginConfigSchema = z.strictObject({ assets: assetsConfigSchema, }); -export const workflowPluginConfigSchema = z.strictObject({ +const workflowPluginConfigSchema = z.strictObject({ kind: z.literal("workflow"), id: z.string(), name: z.string(), @@ -53,11 +53,11 @@ export const workflowPluginConfigSchema = z.strictObject({ definition: z.string(), }); -export const linksConfigSchema = z.strictObject({ +const linksConfigSchema = z.strictObject({ sponsor: z.string().url().optional(), }); -export const watchConfigSchema = z.strictObject({ +const watchConfigSchema = z.strictObject({ port: z.number().optional(), }); @@ -83,13 +83,8 @@ export const caidoConfigSchema = z.strictObject({ }); // Type inference -export type BackendReferenceConfig = z.infer< - typeof backendReferenceConfigSchema ->; export type FrontendPluginConfig = z.infer; export type BackendPluginConfig = z.infer; -export type WorkflowPluginConfig = z.infer; -export type WatchConfig = z.infer; export type CaidoConfig = z.infer; export type ConnectedMessage = { diff --git a/vitest.config.ts b/vitest.config.ts index 3de1164..c6b4144 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from 'vitest/config' export default defineConfig({ test: { - include: ['./playgrounds/**/*.spec.ts'], + include: ['./src/**/*.spec.ts', './playgrounds/**/*.spec.ts'], setupFiles: ['./playgrounds/setup.ts'], }, })