diff --git a/README.md b/README.md index becf0f2f..d8b9d3c6 100644 --- a/README.md +++ b/README.md @@ -83,11 +83,12 @@ **[실시간 서비스 상태 보기](https://aka-page.betteruptime.com/)** -

Cloudflare Workers 호출량 (2026-08-10 ~ 2026-09-08, 30일)

+

Cloudflare 요청 수 (2026-08-10 ~ 2026-09-08, 30일)

-Cloudflare Workers 호출량 그래프 (2026-08-10 ~ 2026-09-08) +Cloudflare 요청 수 그래프 (2026-08-10 ~ 2026-09-08) 기준 워커: daiso-mcp · 마지막 갱신: 2026-09-09 03:45 KST +
집계: Worker 실행 + 루트 GET 리디렉션 요청 · 사용자 수와 다릅니다. diff --git a/assets/analytics/workers-invocations.json b/assets/analytics/workers-invocations.json index 375494fb..a6ac0a78 100644 --- a/assets/analytics/workers-invocations.json +++ b/assets/analytics/workers-invocations.json @@ -1,8 +1,9 @@ { + "accountId": "6353b3b978a6ebc8ee4b2953509da274", "scriptName": "daiso-mcp", "metric": "workersInvocationsAdaptive.requests + httpRequestsAdaptiveGroups.count", "aggregation": "script-level plus redirected root GET", - "includedTraffic": "Worker invocations for daiso-mcp plus redirected GET / traffic on mcp.aka.page where zone analytics retention permits.", + "includedTraffic": "Worker invocations for daiso-mcp plus redirected GET / traffic on mcp.aka.page, retaining complete historical daily totals.", "rootRedirect": { "zoneId": "c987d32286724a5a1fd5586cec7756c1", "host": "mcp.aka.page", @@ -11,23 +12,24 @@ "rootRequestsRetentionDays": 7 }, "timezone": "Asia/Seoul", + "coverageVersion": 1, "days": 30, "startDate": "2026-08-10", "endDate": "2026-09-08", "updatedAt": "2026-09-08T18:45:16.570Z", - "renderedAt": "2026-09-08T18:45:16.570Z", - "total": 16546459, - "average": 551549, - "median": 187001, + "renderedAt": "2026-09-09T09:35:24.062Z", + "total": 59226067, + "average": 1974202, + "median": 1961683, "peak": { - "date": "2026-09-08", - "requests": 2820280 + "date": "2026-08-14", + "requests": 3063834 }, - "recent7Total": 12596889, - "recent7Average": 1799556, - "previous7Total": 1020439, - "weekOverWeekDiff": 11576450, - "weekOverWeekPercent": 1134.4578166847798, + "recent7Total": 12781738, + "recent7Average": 1825963, + "previous7Total": 12474864, + "weekOverWeekDiff": 306874, + "weekOverWeekPercent": 2.459938641415249, "latest": { "date": "2026-09-08", "requests": 2820280 @@ -41,99 +43,99 @@ "points": [ { "date": "2026-08-10", - "requests": 140090 + "requests": 2482869 }, { "date": "2026-08-11", - "requests": 126647 + "requests": 2183677 }, { "date": "2026-08-12", - "requests": 137894 + "requests": 2443491 }, { "date": "2026-08-13", - "requests": 170133 + "requests": 2595363 }, { "date": "2026-08-14", - "requests": 206298 + "requests": 3063834 }, { "date": "2026-08-15", - "requests": 169162 + "requests": 2370520 }, { "date": "2026-08-16", - "requests": 170065 + "requests": 2018530 }, { "date": "2026-08-17", - "requests": 203591 + "requests": 1273637 }, { "date": "2026-08-18", - "requests": 217502 + "requests": 2157416 }, { "date": "2026-08-19", - "requests": 238271 + "requests": 2508367 }, { "date": "2026-08-20", - "requests": 192381 + "requests": 2533868 }, { "date": "2026-08-21", - "requests": 183848 + "requests": 2645579 }, { "date": "2026-08-22", - "requests": 187086 + "requests": 837045 }, { "date": "2026-08-23", - "requests": 186915 + "requests": 872927 }, { "date": "2026-08-24", - "requests": 215169 + "requests": 2281357 }, { "date": "2026-08-25", - "requests": 184079 + "requests": 1700985 }, { "date": "2026-08-26", - "requests": 196154 + "requests": 1811819 }, { "date": "2026-08-27", - "requests": 175418 + "requests": 1750102 }, { "date": "2026-08-28", - "requests": 171532 + "requests": 1932412 }, { "date": "2026-08-29", - "requests": 126391 + "requests": 1990954 }, { "date": "2026-08-30", - "requests": 109463 + "requests": 1250744 }, { "date": "2026-08-31", - "requests": 142067 + "requests": 1889143 }, { "date": "2026-09-01", - "requests": 99414 + "requests": 1849690 }, { "date": "2026-09-02", - "requests": 1644260 + "requests": 1829109 }, { "date": "2026-09-03", diff --git a/assets/analytics/workers-invocations.png b/assets/analytics/workers-invocations.png index 1e0cc8e9..7db10368 100644 Binary files a/assets/analytics/workers-invocations.png and b/assets/analytics/workers-invocations.png differ diff --git a/docs/traffic-history-recovery-2026-09-09.md b/docs/traffic-history-recovery-2026-09-09.md new file mode 100644 index 00000000..75a127de --- /dev/null +++ b/docs/traffic-history-recovery-2026-09-09.md @@ -0,0 +1,48 @@ +# 요청 수 집계 복구 기록 + +기존 차트는 매일 최근 30일을 다시 조회하면서 루트 GET 요청은 Cloudflare 보존기간인 최근 7일만 합산했습니다. 보존기간을 벗어난 날짜는 Worker 실행만 남았고, 경계 날짜는 하루의 일부 요청만 포함했습니다. 그 결과 서로 다른 기준의 날짜로 주간 증가율을 계산했습니다. + +예를 들어 8월 31일은 당시 완전한 관측에서는 1,889,143건이지만 9월 9일 생성된 원래 파일에서는 142,067건으로 감소했습니다. 복구 전 표시된 주간 증가율 1,134.46%는 실제 트래픽 증가율로 해석할 수 없습니다. + +## 복구 방법 + +`assets/analytics/workers-invocations.json`의 Git 이력을 조회했습니다. 각 날짜에 대해 관측 시각이 해당 KST 날짜의 종료 이후이고, `updatedAt - rootRequestsRetentionDays`가 해당 날짜의 시작 이전인 가장 최근 스냅샷을 선택했습니다. 같은 scriptName, metric, timezone, rootRedirect 설정의 기록만 사용했습니다. 현재 운영 계정은 Cloudflare 계정 API로 확인해 `accountId`에 기록했습니다. + +8월 10일부터 9월 8일까지 30일 모두 완전한 관측을 찾았습니다. 복구한 파일에는 `coverageVersion: 1`을 부여했습니다. 이후 실행은 출처가 같은 완전한 기록을 보존하고, 관측할 수 없는 날짜에 믿을 수 있는 기록이 없으면 기존 산출물을 덮어쓰지 않고 실패합니다. + +복구 후 최근 7일은 12,781,738건, 직전 7일은 12,474,864건으로 증가율은 약 2.46%입니다. 이 지표는 Worker 실행과 루트 GET 리디렉션 요청의 합계이며 사용자 수 또는 유료 원본 API 호출 수가 아닙니다. Cloudflare adaptive 집계의 관측값을 보존한 것으로 정확한 전수 로그를 복원한 것은 아닙니다. + +아래 표는 복구된 날짜별 값과 원본 Git 커밋입니다. 커밋의 JSON에서 관측 시각과 설정을 확인할 수 있습니다. + +| KST 날짜 | 요청 수 | 원본 커밋 | +|---|---:|---| +| 2026-08-10 | 2,482,869 | [1cb55e0](https://github.com/hmmhmmhm/daiso-mcp/blob/1cb55e07b57e73354baed1624ab4053ba41a9b40/assets/analytics/workers-invocations.json) | +| 2026-08-11 | 2,183,677 | [f775279](https://github.com/hmmhmmhm/daiso-mcp/blob/f7752791a0aa7cc996b984d13666f25d0a28faab/assets/analytics/workers-invocations.json) | +| 2026-08-12 | 2,443,491 | [deaa38a](https://github.com/hmmhmmhm/daiso-mcp/blob/deaa38a3dc845afc0f48e5e29e723478b5310bed/assets/analytics/workers-invocations.json) | +| 2026-08-13 | 2,595,363 | [917bd1a](https://github.com/hmmhmmhm/daiso-mcp/blob/917bd1aaa30c760e6e1379aae9b6f61bf8394b3f/assets/analytics/workers-invocations.json) | +| 2026-08-14 | 3,063,834 | [917bd1a](https://github.com/hmmhmmhm/daiso-mcp/blob/917bd1aaa30c760e6e1379aae9b6f61bf8394b3f/assets/analytics/workers-invocations.json) | +| 2026-08-15 | 2,370,520 | [d2b4c39](https://github.com/hmmhmmhm/daiso-mcp/blob/d2b4c399945a6dc6f6b4d7d9ec06c39a7dcfcf46/assets/analytics/workers-invocations.json) | +| 2026-08-16 | 2,018,530 | [638c7b8](https://github.com/hmmhmmhm/daiso-mcp/blob/638c7b8db2b85b98d139e79c94c30490713338b4/assets/analytics/workers-invocations.json) | +| 2026-08-17 | 1,273,637 | [ab4c11c](https://github.com/hmmhmmhm/daiso-mcp/blob/ab4c11c2c2d6a8a535f0966e67cd57e8b54c9047/assets/analytics/workers-invocations.json) | +| 2026-08-18 | 2,157,416 | [7d45f67](https://github.com/hmmhmmhm/daiso-mcp/blob/7d45f67af572932c509867224b7f29cef1d6efa4/assets/analytics/workers-invocations.json) | +| 2026-08-19 | 2,508,367 | [7df7c58](https://github.com/hmmhmmhm/daiso-mcp/blob/7df7c58109e09b10b8395e4116652a7d3bb3cf05/assets/analytics/workers-invocations.json) | +| 2026-08-20 | 2,533,868 | [d3cb49f](https://github.com/hmmhmmhm/daiso-mcp/blob/d3cb49f11e7538509329d2cfc98b94dd05550c71/assets/analytics/workers-invocations.json) | +| 2026-08-21 | 2,645,579 | [bd95adf](https://github.com/hmmhmmhm/daiso-mcp/blob/bd95adf7bb522cdc1705ebd4576f5b2ab4cbc753/assets/analytics/workers-invocations.json) | +| 2026-08-22 | 837,045 | [a791bd1](https://github.com/hmmhmmhm/daiso-mcp/blob/a791bd1e13bce8ddfa03330bc90def67e7f09c81/assets/analytics/workers-invocations.json) | +| 2026-08-23 | 872,927 | [60d3a1c](https://github.com/hmmhmmhm/daiso-mcp/blob/60d3a1c231bc3dc216fd76a66e67f8a3912dbc21/assets/analytics/workers-invocations.json) | +| 2026-08-24 | 2,281,357 | [4b03c55](https://github.com/hmmhmmhm/daiso-mcp/blob/4b03c5576f978fc17aa1b70ef81d81595b3a4eb7/assets/analytics/workers-invocations.json) | +| 2026-08-25 | 1,700,985 | [2a49b56](https://github.com/hmmhmmhm/daiso-mcp/blob/2a49b56247e764a50c3bcdeba4fc3026cec96f9b/assets/analytics/workers-invocations.json) | +| 2026-08-26 | 1,811,819 | [7471139](https://github.com/hmmhmmhm/daiso-mcp/blob/747113963fbf383c24abaaf9efffc5fb4a1d8585/assets/analytics/workers-invocations.json) | +| 2026-08-27 | 1,750,102 | [3404b8c](https://github.com/hmmhmmhm/daiso-mcp/blob/3404b8cd4bca760bf4db8dae81b4977e5a039026/assets/analytics/workers-invocations.json) | +| 2026-08-28 | 1,932,412 | [860c159](https://github.com/hmmhmmhm/daiso-mcp/blob/860c159adca11701f3245c485d6dde4c407c70e8/assets/analytics/workers-invocations.json) | +| 2026-08-29 | 1,990,954 | [c32aad0](https://github.com/hmmhmmhm/daiso-mcp/blob/c32aad0de93a7ca278de79bdcd94a42ffb17fe47/assets/analytics/workers-invocations.json) | +| 2026-08-30 | 1,250,744 | [13cb7b6](https://github.com/hmmhmmhm/daiso-mcp/blob/13cb7b6b7c2253974a2857a7cba049fdf5463c4e/assets/analytics/workers-invocations.json) | +| 2026-08-31 | 1,889,143 | [0566392](https://github.com/hmmhmmhm/daiso-mcp/blob/05663929907217c7d3d792a05358355dba14e85a/assets/analytics/workers-invocations.json) | +| 2026-09-01 | 1,849,690 | [1603076](https://github.com/hmmhmmhm/daiso-mcp/blob/16030767448043e242158fb927ad306ff3cc6589/assets/analytics/workers-invocations.json) | +| 2026-09-02 | 1,829,109 | [5f98b88](https://github.com/hmmhmmhm/daiso-mcp/blob/5f98b8867fafb758e9f2a0e008258b10941c5600/assets/analytics/workers-invocations.json) | +| 2026-09-03 | 1,838,457 | [cc5ab53](https://github.com/hmmhmmhm/daiso-mcp/blob/cc5ab53456741c03fcaf39e7f254493754eced05/assets/analytics/workers-invocations.json) | +| 2026-09-04 | 1,518,200 | [cc5ab53](https://github.com/hmmhmmhm/daiso-mcp/blob/cc5ab53456741c03fcaf39e7f254493754eced05/assets/analytics/workers-invocations.json) | +| 2026-09-05 | 1,406,113 | [cc5ab53](https://github.com/hmmhmmhm/daiso-mcp/blob/cc5ab53456741c03fcaf39e7f254493754eced05/assets/analytics/workers-invocations.json) | +| 2026-09-06 | 1,297,625 | [cc5ab53](https://github.com/hmmhmmhm/daiso-mcp/blob/cc5ab53456741c03fcaf39e7f254493754eced05/assets/analytics/workers-invocations.json) | +| 2026-09-07 | 2,071,954 | [cc5ab53](https://github.com/hmmhmmhm/daiso-mcp/blob/cc5ab53456741c03fcaf39e7f254493754eced05/assets/analytics/workers-invocations.json) | +| 2026-09-08 | 2,820,280 | [cc5ab53](https://github.com/hmmhmmhm/daiso-mcp/blob/cc5ab53456741c03fcaf39e7f254493754eced05/assets/analytics/workers-invocations.json) | diff --git a/package-lock.json b/package-lock.json index 64a4b4a1..82879eda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.29.0", - "hono": "^4.12.32", + "hono": "^4.13.7", "proj4": "^2.20.9", "workers-mcp": "^0.0.13" }, @@ -22,18 +22,18 @@ "@cloudflare/workers-types": "^5.20260724.1", "@eslint/js": "^10.0.1", "@types/node": "^26.1.0", - "@vitest/coverage-v8": "^4.1.7", + "@vitest/coverage-v8": "^4.1.11", "eslint": "^10.8.0", "eslint-config-prettier": "^10.1.8", "globals": "^17.7.0", "jiti": "^2.7.0", "playwright": "^1.62.0", "prettier": "^3.9.6", - "sharp": "^0.35.3", + "sharp": "^0.35.4", "tsx": "^4.23.1", "typescript": "6.0.3", "typescript-eslint": "^8.65.0", - "vitest": "^4.1.7", + "vitest": "^4.1.11", "wrangler": "^4.114.0" }, "engines": { @@ -165,9 +165,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -185,9 +182,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -205,9 +199,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -225,9 +216,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -408,7 +396,8 @@ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-5.20260724.1.tgz", "integrity": "sha512-gl0brZ60JhkZU3INgr1jsxaFEiWf3AB9RsCjLTMwT5RKspWRUpsFd0wxwbys7gb8Ywkfq9tORhw0y9G+7bDUYw==", "dev": true, - "license": "MIT OR Apache-2.0" + "license": "MIT OR Apache-2.0", + "peer": true }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", @@ -423,33 +412,10 @@ "node": ">=12" } }, - "node_modules/@emnapi/core": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", - "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.2", - "tslib": "^2.4.0" - } - }, "node_modules/@emnapi/runtime": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", - "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", - "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", "dev": true, "license": "MIT", "optional": true, @@ -1014,29 +980,43 @@ } }, "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanfs/core": "^0.19.1", + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", "@humanwhocodes/retry": "^0.4.0" }, "engines": { "node": ">=18.18.0" } }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -1076,9 +1056,9 @@ } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz", - "integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", + "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==", "cpu": [ "arm64" ], @@ -1095,13 +1075,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.3.2" + "@img/sharp-libvips-darwin-arm64": "1.3.3" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz", - "integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", + "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==", "cpu": [ "x64" ], @@ -1118,13 +1098,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.3.2" + "@img/sharp-libvips-darwin-x64": "1.3.3" } }, "node_modules/@img/sharp-freebsd-wasm32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz", - "integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", + "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -1132,7 +1112,7 @@ "freebsd" ], "dependencies": { - "@img/sharp-wasm32": "0.35.3" + "@img/sharp-wasm32": "0.35.4" }, "engines": { "node": ">=20.9.0" @@ -1142,9 +1122,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz", - "integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", + "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==", "cpu": [ "arm64" ], @@ -1159,9 +1139,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz", - "integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", + "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==", "cpu": [ "x64" ], @@ -1176,9 +1156,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz", - "integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", + "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==", "cpu": [ "arm" ], @@ -1193,9 +1173,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz", - "integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", + "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==", "cpu": [ "arm64" ], @@ -1210,9 +1190,9 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz", - "integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", + "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==", "cpu": [ "ppc64" ], @@ -1227,9 +1207,9 @@ } }, "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz", - "integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", + "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==", "cpu": [ "riscv64" ], @@ -1244,9 +1224,9 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz", - "integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", + "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==", "cpu": [ "s390x" ], @@ -1261,9 +1241,9 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz", - "integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", + "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==", "cpu": [ "x64" ], @@ -1278,9 +1258,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz", - "integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", + "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==", "cpu": [ "arm64" ], @@ -1295,9 +1275,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz", - "integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", + "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==", "cpu": [ "x64" ], @@ -1312,9 +1292,9 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz", - "integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", + "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==", "cpu": [ "arm" ], @@ -1331,13 +1311,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.3.2" + "@img/sharp-libvips-linux-arm": "1.3.3" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz", - "integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", + "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==", "cpu": [ "arm64" ], @@ -1354,13 +1334,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.3.2" + "@img/sharp-libvips-linux-arm64": "1.3.3" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz", - "integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", + "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==", "cpu": [ "ppc64" ], @@ -1377,13 +1357,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.3.2" + "@img/sharp-libvips-linux-ppc64": "1.3.3" } }, "node_modules/@img/sharp-linux-riscv64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz", - "integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", + "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==", "cpu": [ "riscv64" ], @@ -1400,13 +1380,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.3.2" + "@img/sharp-libvips-linux-riscv64": "1.3.3" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz", - "integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", + "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==", "cpu": [ "s390x" ], @@ -1423,13 +1403,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.3.2" + "@img/sharp-libvips-linux-s390x": "1.3.3" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz", - "integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", + "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==", "cpu": [ "x64" ], @@ -1446,13 +1426,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.3.2" + "@img/sharp-libvips-linux-x64": "1.3.3" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz", - "integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", + "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==", "cpu": [ "arm64" ], @@ -1469,13 +1449,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.3.2" + "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz", - "integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", + "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==", "cpu": [ "x64" ], @@ -1492,18 +1472,18 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.3.2" + "@img/sharp-libvips-linuxmusl-x64": "1.3.3" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz", - "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", + "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==", "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.11.1" + "@emnapi/runtime": "^1.11.3" }, "engines": { "node": ">=20.9.0" @@ -1512,21 +1492,10 @@ "url": "https://opencollective.com/libvips" } }, - "node_modules/@img/sharp-wasm32/node_modules/@emnapi/runtime": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", - "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@img/sharp-webcontainers-wasm32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz", - "integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", + "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==", "cpu": [ "wasm32" ], @@ -1534,7 +1503,7 @@ "license": "Apache-2.0", "optional": true, "dependencies": { - "@img/sharp-wasm32": "0.35.3" + "@img/sharp-wasm32": "0.35.4" }, "engines": { "node": ">=20.9.0" @@ -1544,9 +1513,9 @@ } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz", - "integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", + "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==", "cpu": [ "arm64" ], @@ -1564,9 +1533,9 @@ } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz", - "integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", + "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==", "cpu": [ "ia32" ], @@ -1584,9 +1553,9 @@ } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz", - "integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", + "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==", "cpu": [ "x64" ], @@ -1683,25 +1652,6 @@ } } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", - "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.3" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1738,13 +1688,13 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.139.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", - "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", + "version": "0.148.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz", + "integrity": "sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==", "dev": true, "license": "MIT", "funding": { - "url": "https://github.com/sponsors/Boshen" + "url": "https://github.com/sponsors/oxc-project" } }, "node_modules/@poppinss/colors": { @@ -1789,10 +1739,27 @@ "dev": true, "license": "MIT" }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz", + "integrity": "sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", - "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.7.tgz", + "integrity": "sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==", "cpu": [ "arm64" ], @@ -1807,9 +1774,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", - "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.7.tgz", + "integrity": "sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==", "cpu": [ "arm64" ], @@ -1824,9 +1791,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", - "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.7.tgz", + "integrity": "sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==", "cpu": [ "x64" ], @@ -1841,9 +1808,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", - "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.7.tgz", + "integrity": "sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==", "cpu": [ "x64" ], @@ -1858,9 +1825,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", - "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.7.tgz", + "integrity": "sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==", "cpu": [ "arm" ], @@ -1875,16 +1842,13 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", - "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.7.tgz", + "integrity": "sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==", "cpu": [ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1895,16 +1859,13 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", - "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.7.tgz", + "integrity": "sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==", "cpu": [ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1915,16 +1876,13 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", - "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.7.tgz", + "integrity": "sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==", "cpu": [ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1935,16 +1893,13 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", - "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.7.tgz", + "integrity": "sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==", "cpu": [ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1955,16 +1910,13 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", - "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.7.tgz", + "integrity": "sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==", "cpu": [ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1975,16 +1927,13 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", - "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.7.tgz", + "integrity": "sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==", "cpu": [ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1995,9 +1944,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", - "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.7.tgz", + "integrity": "sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==", "cpu": [ "arm64" ], @@ -2011,29 +1960,10 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", - "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.11.1", - "@emnapi/runtime": "1.11.1", - "@napi-rs/wasm-runtime": "^1.1.6" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", - "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.7.tgz", + "integrity": "sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==", "cpu": [ "arm64" ], @@ -2048,9 +1978,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", - "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.7.tgz", + "integrity": "sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==", "cpu": [ "x64" ], @@ -2104,17 +2034,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", - "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@types/chai": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", @@ -2165,6 +2084,7 @@ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "license": "MIT", + "peer": true, "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" @@ -2182,6 +2102,7 @@ "integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~8.3.0" } @@ -2231,6 +2152,7 @@ "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.65.0", "@typescript-eslint/types": "8.65.0", @@ -2417,14 +2339,15 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz", - "integrity": "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.11.tgz", + "integrity": "sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.10", + "@vitest/utils": "4.1.11", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", @@ -2438,8 +2361,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.1.10", - "vitest": "4.1.10" + "@vitest/browser": "4.1.11", + "vitest": "4.1.11" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -2448,16 +2371,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", - "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", + "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -2466,13 +2389,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", - "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", + "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.10", + "@vitest/spy": "4.1.11", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -2493,9 +2416,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", - "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", + "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", "dev": true, "license": "MIT", "dependencies": { @@ -2506,13 +2429,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", - "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", + "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.10", + "@vitest/utils": "4.1.11", "pathe": "^2.0.3" }, "funding": { @@ -2520,14 +2443,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", - "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", + "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/pretty-format": "4.1.11", + "@vitest/utils": "4.1.11", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -2536,9 +2459,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", - "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", + "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", "dev": true, "license": "MIT", "funding": { @@ -2546,13 +2469,13 @@ } }, "node_modules/@vitest/utils": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", - "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", + "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.10", + "@vitest/pretty-format": "4.1.11", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -2579,6 +2502,7 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2738,9 +2662,9 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", - "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, "license": "MIT", "dependencies": { @@ -3060,16 +2984,16 @@ } }, "node_modules/es-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", - "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", "dev": true, "license": "MIT" }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -3144,6 +3068,7 @@ "integrity": "sha512-nuKKvN+oIBO0koN7Tm7dlkmnkc21mtt0QJLwAKzjLq14y6lRTdVG36MZHJ8eQHwdJMwZbQNMlPOYedMq/oVJvQ==", "dev": true, "license": "MIT", + "peer": true, "workspaces": [ "packages/*" ], @@ -3387,9 +3312,9 @@ } }, "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3401,6 +3326,7 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", + "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -3494,9 +3420,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", - "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.7.tgz", + "integrity": "sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==", "funding": [ { "type": "github", @@ -3781,9 +3707,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -3793,10 +3719,11 @@ } }, "node_modules/hono": { - "version": "4.12.32", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.32.tgz", - "integrity": "sha512-XcuyW9qE2kJn07PkecMOBd5Vq/hMy7mmGw+idz1yblbg9N17ijJODrvPkn7/dwL3Kulj8LcRJ69DLOWf91dRUg==", + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.7.tgz", + "integrity": "sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=16.9.0" } @@ -3871,9 +3798,9 @@ "license": "ISC" }, "node_modules/ip-address": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", - "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.0.tgz", + "integrity": "sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA==", "license": "MIT", "engines": { "node": ">= 12" @@ -3975,6 +3902,7 @@ "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -4162,9 +4090,9 @@ } }, "node_modules/lightningcss": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -4178,23 +4106,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.32.0", - "lightningcss-darwin-arm64": "1.32.0", - "lightningcss-darwin-x64": "1.32.0", - "lightningcss-freebsd-x64": "1.32.0", - "lightningcss-linux-arm-gnueabihf": "1.32.0", - "lightningcss-linux-arm64-gnu": "1.32.0", - "lightningcss-linux-arm64-musl": "1.32.0", - "lightningcss-linux-x64-gnu": "1.32.0", - "lightningcss-linux-x64-musl": "1.32.0", - "lightningcss-win32-arm64-msvc": "1.32.0", - "lightningcss-win32-x64-msvc": "1.32.0" + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", - "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", "cpu": [ "arm64" ], @@ -4213,9 +4141,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", - "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", "cpu": [ "arm64" ], @@ -4234,9 +4162,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", - "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", "cpu": [ "x64" ], @@ -4255,9 +4183,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", - "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", "cpu": [ "x64" ], @@ -4276,9 +4204,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", - "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", "cpu": [ "arm" ], @@ -4297,16 +4225,13 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", - "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", "cpu": [ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -4321,16 +4246,13 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", - "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", "cpu": [ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -4345,16 +4267,13 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", "cpu": [ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -4369,16 +4288,13 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", "cpu": [ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -4393,9 +4309,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", - "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", "cpu": [ "arm64" ], @@ -4414,9 +4330,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", - "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", "cpu": [ "x64" ], @@ -4528,6 +4444,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -4707,9 +4624,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.16", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", - "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "dev": true, "funding": [ { @@ -4828,15 +4745,18 @@ } }, "node_modules/obug": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz", + "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" ], - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } }, "node_modules/on-finished": { "version": "2.4.1", @@ -5029,9 +4949,9 @@ } }, "node_modules/postcss": { - "version": "8.5.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.18.tgz", - "integrity": "sha512-xdB1oSLHbz1vRWgCDalrCqEFTWzFlhqFC5tIHLMOSUIjhm3XXQ1qrFy8S/ESr1JYRRXqM3c1QFiMZUJdUTqyMQ==", + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", "dev": true, "funding": [ { @@ -5049,7 +4969,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.18", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -5137,12 +5057,13 @@ } }, "node_modules/qs": { - "version": "6.15.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", - "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", + "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -5224,13 +5145,13 @@ } }, "node_modules/rolldown": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", - "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.7.tgz", + "integrity": "sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.139.0", + "@oxc-project/types": "=0.148.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -5240,21 +5161,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.1.5", - "@rolldown/binding-darwin-arm64": "1.1.5", - "@rolldown/binding-darwin-x64": "1.1.5", - "@rolldown/binding-freebsd-x64": "1.1.5", - "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", - "@rolldown/binding-linux-arm64-gnu": "1.1.5", - "@rolldown/binding-linux-arm64-musl": "1.1.5", - "@rolldown/binding-linux-ppc64-gnu": "1.1.5", - "@rolldown/binding-linux-s390x-gnu": "1.1.5", - "@rolldown/binding-linux-x64-gnu": "1.1.5", - "@rolldown/binding-linux-x64-musl": "1.1.5", - "@rolldown/binding-openharmony-arm64": "1.1.5", - "@rolldown/binding-wasm32-wasi": "1.1.5", - "@rolldown/binding-win32-arm64-msvc": "1.1.5", - "@rolldown/binding-win32-x64-msvc": "1.1.5" + "@rolldown/binding-android-arm-eabi": "1.2.7", + "@rolldown/binding-android-arm64": "1.2.7", + "@rolldown/binding-darwin-arm64": "1.2.7", + "@rolldown/binding-darwin-x64": "1.2.7", + "@rolldown/binding-freebsd-x64": "1.2.7", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.7", + "@rolldown/binding-linux-arm64-gnu": "1.2.7", + "@rolldown/binding-linux-arm64-musl": "1.2.7", + "@rolldown/binding-linux-ppc64-gnu": "1.2.7", + "@rolldown/binding-linux-s390x-gnu": "1.2.7", + "@rolldown/binding-linux-x64-gnu": "1.2.7", + "@rolldown/binding-linux-x64-musl": "1.2.7", + "@rolldown/binding-openharmony-arm64": "1.2.7", + "@rolldown/binding-win32-arm64-msvc": "1.2.7", + "@rolldown/binding-win32-x64-msvc": "1.2.7" } }, "node_modules/router": { @@ -5367,9 +5288,9 @@ "license": "ISC" }, "node_modules/sharp": { - "version": "0.35.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz", - "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==", + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz", + "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5384,31 +5305,31 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.35.3", - "@img/sharp-darwin-x64": "0.35.3", - "@img/sharp-freebsd-wasm32": "0.35.3", - "@img/sharp-libvips-darwin-arm64": "1.3.2", - "@img/sharp-libvips-darwin-x64": "1.3.2", - "@img/sharp-libvips-linux-arm": "1.3.2", - "@img/sharp-libvips-linux-arm64": "1.3.2", - "@img/sharp-libvips-linux-ppc64": "1.3.2", - "@img/sharp-libvips-linux-riscv64": "1.3.2", - "@img/sharp-libvips-linux-s390x": "1.3.2", - "@img/sharp-libvips-linux-x64": "1.3.2", - "@img/sharp-libvips-linuxmusl-arm64": "1.3.2", - "@img/sharp-libvips-linuxmusl-x64": "1.3.2", - "@img/sharp-linux-arm": "0.35.3", - "@img/sharp-linux-arm64": "0.35.3", - "@img/sharp-linux-ppc64": "0.35.3", - "@img/sharp-linux-riscv64": "0.35.3", - "@img/sharp-linux-s390x": "0.35.3", - "@img/sharp-linux-x64": "0.35.3", - "@img/sharp-linuxmusl-arm64": "0.35.3", - "@img/sharp-linuxmusl-x64": "0.35.3", - "@img/sharp-webcontainers-wasm32": "0.35.3", - "@img/sharp-win32-arm64": "0.35.3", - "@img/sharp-win32-ia32": "0.35.3", - "@img/sharp-win32-x64": "0.35.3" + "@img/sharp-darwin-arm64": "0.35.4", + "@img/sharp-darwin-x64": "0.35.4", + "@img/sharp-freebsd-wasm32": "0.35.4", + "@img/sharp-libvips-darwin-arm64": "1.3.3", + "@img/sharp-libvips-darwin-x64": "1.3.3", + "@img/sharp-libvips-linux-arm": "1.3.3", + "@img/sharp-libvips-linux-arm64": "1.3.3", + "@img/sharp-libvips-linux-ppc64": "1.3.3", + "@img/sharp-libvips-linux-riscv64": "1.3.3", + "@img/sharp-libvips-linux-s390x": "1.3.3", + "@img/sharp-libvips-linux-x64": "1.3.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", + "@img/sharp-libvips-linuxmusl-x64": "1.3.3", + "@img/sharp-linux-arm": "0.35.4", + "@img/sharp-linux-arm64": "0.35.4", + "@img/sharp-linux-ppc64": "0.35.4", + "@img/sharp-linux-riscv64": "0.35.4", + "@img/sharp-linux-s390x": "0.35.4", + "@img/sharp-linux-x64": "0.35.4", + "@img/sharp-linuxmusl-arm64": "0.35.4", + "@img/sharp-linuxmusl-x64": "0.35.4", + "@img/sharp-webcontainers-wasm32": "0.35.4", + "@img/sharp-win32-arm64": "0.35.4", + "@img/sharp-win32-ia32": "0.35.4", + "@img/sharp-win32-x64": "0.35.4" }, "peerDependenciesMeta": { "@types/node": { @@ -5438,14 +5359,14 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -5457,13 +5378,13 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -5549,9 +5470,9 @@ } }, "node_modules/std-env": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", - "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", "dev": true, "license": "MIT" }, @@ -5588,9 +5509,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.2.tgz", - "integrity": "sha512-M/Q0B2cp4K7kynaT/vnED1j8TlLY+Pp7C6Wl2bl/7u/F0mUVwdyOpwomQb8JpYLitHUssAJRmLZdMCGsrx7i+g==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", "dev": true, "license": "MIT", "engines": { @@ -5638,6 +5559,7 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -5646,9 +5568,9 @@ } }, "node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", + "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", "dev": true, "license": "MIT", "engines": { @@ -5808,6 +5730,7 @@ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5853,9 +5776,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", - "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.1.tgz", + "integrity": "sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==", "dev": true, "license": "MIT", "engines": { @@ -5875,6 +5798,7 @@ "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "pathe": "^2.0.3" } @@ -5917,16 +5841,16 @@ } }, "node_modules/vite": { - "version": "8.1.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz", - "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", + "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", "dev": true, "license": "MIT", "dependencies": { - "lightningcss": "^1.32.0", + "lightningcss": "^1.33.0", "picomatch": "^4.0.5", - "postcss": "^8.5.16", - "rolldown": "~1.1.4", + "postcss": "^8.5.26", + "rolldown": "~1.2.4", "tinyglobby": "^0.2.17" }, "bin": { @@ -5943,7 +5867,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.3.0", + "@vitejs/devtools": "^0.4.0 || ^0.5.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", @@ -5995,9 +5919,9 @@ } }, "node_modules/vite/node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, "license": "MIT", "engines": { @@ -6008,19 +5932,20 @@ } }, "node_modules/vitest": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", - "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz", + "integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@vitest/expect": "4.1.10", - "@vitest/mocker": "4.1.10", - "@vitest/pretty-format": "4.1.10", - "@vitest/runner": "4.1.10", - "@vitest/snapshot": "4.1.10", - "@vitest/spy": "4.1.10", - "@vitest/utils": "4.1.10", + "@vitest/expect": "4.1.11", + "@vitest/mocker": "4.1.11", + "@vitest/pretty-format": "4.1.11", + "@vitest/runner": "4.1.11", + "@vitest/snapshot": "4.1.11", + "@vitest/spy": "4.1.11", + "@vitest/utils": "4.1.11", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -6048,12 +5973,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.10", - "@vitest/browser-preview": "4.1.10", - "@vitest/browser-webdriverio": "4.1.10", - "@vitest/coverage-istanbul": "4.1.10", - "@vitest/coverage-v8": "4.1.10", - "@vitest/ui": "4.1.10", + "@vitest/browser-playwright": "4.1.11", + "@vitest/browser-preview": "4.1.11", + "@vitest/browser-webdriverio": "4.1.11", + "@vitest/coverage-istanbul": "4.1.11", + "@vitest/coverage-v8": "4.1.11", + "@vitest/ui": "4.1.11", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -6098,9 +6023,9 @@ } }, "node_modules/vitest/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, "license": "MIT", "engines": { @@ -6177,6 +6102,7 @@ "dev": true, "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "bin": { "workerd": "bin/workerd" }, @@ -6351,6 +6277,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index a96a9c9a..80174b5b 100644 --- a/package.json +++ b/package.json @@ -84,18 +84,18 @@ "@cloudflare/workers-types": "^5.20260724.1", "@eslint/js": "^10.0.1", "@types/node": "^26.1.0", - "@vitest/coverage-v8": "^4.1.7", + "@vitest/coverage-v8": "^4.1.11", "eslint": "^10.8.0", "eslint-config-prettier": "^10.1.8", "globals": "^17.7.0", "jiti": "^2.7.0", "playwright": "^1.62.0", "prettier": "^3.9.6", - "sharp": "^0.35.3", + "sharp": "^0.35.4", "tsx": "^4.23.1", "typescript": "6.0.3", "typescript-eslint": "^8.65.0", - "vitest": "^4.1.7", + "vitest": "^4.1.11", "wrangler": "^4.114.0" }, "overrides": { @@ -103,12 +103,13 @@ "@hono/node-server": "2.0.11" }, "miniflare": { - "sharp": "0.35.3" + "sharp": "0.35.4", + "undici": "7.29.1" } }, "dependencies": { "@modelcontextprotocol/sdk": "^1.29.0", - "hono": "^4.12.32", + "hono": "^4.13.7", "proj4": "^2.20.9", "workers-mcp": "^0.0.13" } diff --git a/scripts/ops/update-workers-invocations-chart.ts b/scripts/ops/update-workers-invocations-chart.ts index 3154e60d..3d52d85d 100644 --- a/scripts/ops/update-workers-invocations-chart.ts +++ b/scripts/ops/update-workers-invocations-chart.ts @@ -42,7 +42,10 @@ const CHART_START_DATE = process.env.WORKERS_CHART_START_DATE?.trim() || undefin const CHART_DAYS = Number.parseInt(process.env.WORKERS_CHART_DAYS ?? '30', 10); const CHART_CONCURRENCY = Number.parseInt(process.env.WORKERS_CHART_CONCURRENCY ?? '4', 10); const INPUT_JSON_PATH = process.env.WORKERS_CHART_INPUT_JSON; -const ROOT_REQUESTS_RETENTION_DAYS = Number.parseInt(process.env.WORKERS_CHART_ROOT_REQUESTS_RETENTION_DAYS ?? '7', 10); +const ROOT_REQUESTS_RETENTION_DAYS = Number.parseInt( + process.env.WORKERS_CHART_ROOT_REQUESTS_RETENTION_DAYS ?? '7', + 10, +); const ROOT_REDIRECT_START = process.env.WORKERS_CHART_ROOT_REDIRECT_START ? new Date(process.env.WORKERS_CHART_ROOT_REDIRECT_START) : undefined; @@ -143,7 +146,9 @@ function renderRecent14Panel(points, chartArea) { const innerBottom = y + height - 20; const toX = (index) => x + 18 + (index / Math.max(recent.length - 1, 1)) * (width - 36); const toY = (value) => innerBottom - ((value - min) / range) * (innerBottom - innerTop); - const recentPath = linePath(recent.map((point, index) => ({ x: toX(index), y: toY(point.requests) }))); + const recentPath = linePath( + recent.map((point, index) => ({ x: toX(index), y: toY(point.requests) })), + ); const latest = recent[recent.length - 1]; return ` @@ -211,7 +216,7 @@ async function renderChart(points, summary, metadata) { .recent-label { font-size: 12px; font-weight: 700; fill: ${WORKERS_CHART_ACCENT_COLORS.recent14Label}; } - ${escapeXml(`Cloudflare Workers Invocations (${metadata.startDate} ~ ${metadata.endDate}, ${labels.length} days)`)} + ${escapeXml(`Cloudflare Requests (${metadata.startDate} ~ ${metadata.endDate}, ${labels.length} days)`)} ${escapeXml(`Updated: ${metadata.updatedAtText}`)} Requests @@ -270,8 +275,12 @@ async function renderChart(points, summary, metadata) { } async function updateReadme(section) { - const readme = await fs.readFile(README_PATH, 'utf8'); + const readme = (await fs.readFile(README_PATH, 'utf8')).replaceAll('\r\n', '\n'); const pattern = new RegExp(`${README_START}[\\s\\S]*?${README_END}`, 'm'); + if (pattern.test(readme)) { + await fs.writeFile(README_PATH, readme.replace(pattern, section), 'utf8'); + return; + } const withoutSection = readme.replace(pattern, '').replace(/\n{3,}/g, '\n\n'); const badgesAnchor = '\n\n
\n\n
\n\n>; if (INPUT_JSON_PATH) { - const inputPayload = await readInputPayload(INPUT_JSON_PATH); + inputPayload = await readInputPayload(INPUT_JSON_PATH); points = inputPayload.points; scriptName = inputPayload.scriptName ?? scriptName; startDate = inputPayload.startDate ?? points[0]?.date ?? startDate; @@ -306,7 +316,14 @@ async function main() { const endDateExclusive = parseKstDateText(todayKstDate); endDate = formatKstDate(new Date(endDateExclusive.getTime() - 86400000)); startDate = startDate ?? calculateStartDateFromDays(endDate, CHART_DAYS); - const rootRequestsRetentionStart = calculateRetentionStart(renderedAt, ROOT_REQUESTS_RETENTION_DAYS); + const rootRequestsRetentionStart = calculateRetentionStart( + renderedAt, + ROOT_REQUESTS_RETENTION_DAYS, + ); + const previousPayload = await readInputPayload(DATA_PATH).catch((error) => { + if (error.code === 'ENOENT') return undefined; + throw error; + }); points = await fetchDailyWorkerInvocations({ accountId: ACCOUNT_ID, @@ -321,6 +338,7 @@ async function main() { rootRedirectPath: ROOT_REDIRECT_PATH, rootRedirectStart: ROOT_REDIRECT_START, rootRequestsRetentionStart, + previousPayload, concurrency: Number.isFinite(CHART_CONCURRENCY) && CHART_CONCURRENCY > 0 ? CHART_CONCURRENCY : 4, }); @@ -334,15 +352,15 @@ async function main() { }); await fs.writeFile(CHART_PATH, chartBuffer); const payload = { + accountId: ACCOUNT_ID, scriptName, metric: ROOT_REDIRECT_START ? 'workersInvocationsAdaptive.requests + httpRequestsAdaptiveGroups.count' : 'workersInvocationsAdaptive.requests', aggregation: ROOT_REDIRECT_START ? 'script-level plus redirected root GET' : 'script-level', - includedTraffic: - ROOT_REDIRECT_START - ? `Worker invocations for ${scriptName} plus redirected GET ${ROOT_REDIRECT_PATH} traffic on ${ROOT_REDIRECT_HOST} where zone analytics retention permits.` - : 'All invocations for this Worker script are counted across routes and domains, including GET / on mcp.aka.page.', + includedTraffic: ROOT_REDIRECT_START + ? `Worker invocations for ${scriptName} plus redirected GET ${ROOT_REDIRECT_PATH} traffic on ${ROOT_REDIRECT_HOST}, retaining complete historical daily totals.` + : 'All invocations for this Worker script are counted across routes and domains, including GET / on mcp.aka.page.', rootRedirect: ROOT_REDIRECT_START && ZONE_ID ? { @@ -354,6 +372,19 @@ async function main() { } : null, timezone: 'Asia/Seoul', + coverageVersion: 1, + // 오프라인 렌더링에서는 원본 지표와 완전성 정보를 그대로 유지합니다. + ...(inputPayload + ? { + accountId: inputPayload.accountId, + metric: inputPayload.metric, + aggregation: inputPayload.aggregation, + includedTraffic: inputPayload.includedTraffic, + rootRedirect: inputPayload.rootRedirect, + timezone: inputPayload.timezone, + coverageVersion: inputPayload.coverageVersion, + } + : {}), days: points.length, startDate, endDate, @@ -366,11 +397,12 @@ async function main() { const section = buildReadmeSection({ scriptName, - updatedAt: formatKstDateTime(renderedAt), + updatedAt: formatKstDateTime(new Date(updatedAt)), days: points.length, startDate, endDate, cacheKey: payload.renderedAt, + includesRootRedirect: Boolean(payload.rootRedirect), }); await updateReadme(section); diff --git a/scripts/ops/workers-chart-data.ts b/scripts/ops/workers-chart-data.ts index 966c59f0..3b9a6ad6 100644 --- a/scripts/ops/workers-chart-data.ts +++ b/scripts/ops/workers-chart-data.ts @@ -2,6 +2,42 @@ import { buildKstDateRangeBetween, parseKstDateText } from './workers-chart-help const DEFAULT_ROOT_REQUESTS_RETENTION_MS = 7 * 86400000; +// 보존기간 밖의 날짜는 같은 지표를 완전히 관측한 스냅샷에서만 복구합니다. +function findCompleteCachedPoint(payload, window, source, requiredRootStart) { + if ( + !source.accountId || + payload?.accountId !== source.accountId || + payload?.scriptName !== source.scriptName || + payload?.timezone !== 'Asia/Seoul' || + payload?.metric !== 'workersInvocationsAdaptive.requests + httpRequestsAdaptiveGroups.count' || + payload?.rootRedirect?.zoneId !== source.zoneId || + payload?.rootRedirect?.host !== source.rootRedirectHost || + payload?.rootRedirect?.path !== source.rootRedirectPath || + payload?.rootRedirect?.start !== source.rootRedirectStart.toISOString() + ) + return undefined; + + const point = Array.isArray(payload.points) + ? payload.points.find((point) => point.date === window.date) + : undefined; + if (!point || !Number.isFinite(point.requests) || point.requests < 0) return undefined; + + if (payload.coverageVersion === 1) return { date: window.date, requests: point.requests }; + if (payload.coverageVersion !== undefined) return undefined; + + // 기존 형식은 기록 당시 하루 전체가 보존기간 안에 있었는지 검증합니다. + const observedAt = new Date(payload.updatedAt).getTime(); + const retentionDays = payload.rootRedirect.rootRequestsRetentionDays; + if ( + Number.isFinite(retentionDays) && + retentionDays > 0 && + observedAt >= window.end.getTime() && + observedAt - retentionDays * 86400000 <= requiredRootStart.getTime() + ) + return { date: window.date, requests: point.requests }; + return undefined; +} + const WORKER_INVOCATIONS_QUERY = ` query WorkerInvocations($accountTag: string, $scriptName: string, $start: Time!, $end: Time!) { viewer { @@ -228,6 +264,7 @@ export async function fetchRootGetRequestsForWindow({ * @param {string} [params.rootRedirectPath] * @param {Date} [params.rootRedirectStart] * @param {Date} [params.rootRequestsRetentionStart] + * @param {object} [params.previousPayload] * @param {number} [params.concurrency] * @param {typeof fetch} [params.fetchImpl] * @returns {Promise>} @@ -245,6 +282,7 @@ export async function fetchDailyWorkerInvocations({ rootRedirectPath = '/', rootRedirectStart, rootRequestsRetentionStart = new Date(Date.now() - DEFAULT_ROOT_REQUESTS_RETENTION_MS), + previousPayload, concurrency = 4, fetchImpl = fetch, }) { @@ -258,6 +296,33 @@ export async function fetchDailyWorkerInvocations({ const index = nextIndex; nextIndex += 1; const window = windows[index]; + const requiredRootStart = rootRedirectStart > window.start ? rootRedirectStart : window.start; + if ( + rootRedirectStart && + requiredRootStart < window.end && + (!zoneId || rootRequestsRetentionStart > requiredRootStart) + ) { + const cachedPoint = findCompleteCachedPoint( + previousPayload, + window, + { + accountId, + scriptName, + zoneId, + rootRedirectHost, + rootRedirectPath, + rootRedirectStart, + }, + requiredRootStart, + ); + if (!cachedPoint) { + throw new Error( + `Incomplete daily traffic: ${window.date}; complete root GET history is unavailable.`, + ); + } + points[index] = cachedPoint; + continue; + } const requests = await fetchWorkerInvocationsForWindow({ accountId, apiToken, @@ -268,11 +333,8 @@ export async function fetchDailyWorkerInvocations({ end: window.end, fetchImpl, }); - const redirectStart = [window.start, rootRedirectStart, rootRequestsRetentionStart] - .filter((date) => date instanceof Date) - .reduce((latest, date) => (date > latest ? date : latest), window.start); const redirectedRootRequests = - zoneId && rootRedirectStart && redirectStart < window.end + zoneId && rootRedirectStart && requiredRootStart < window.end ? await fetchRootGetRequestsForWindow({ apiToken, apiEmail, @@ -280,7 +342,7 @@ export async function fetchDailyWorkerInvocations({ zoneId, host: rootRedirectHost, path: rootRedirectPath, - start: redirectStart, + start: requiredRootStart, end: window.end, fetchImpl, }) diff --git a/scripts/ops/workers-chart-helpers.ts b/scripts/ops/workers-chart-helpers.ts index efb34af7..f2e5f2de 100644 --- a/scripts/ops/workers-chart-helpers.ts +++ b/scripts/ops/workers-chart-helpers.ts @@ -285,14 +285,23 @@ export function calculateSummary(points) { }; } -export function buildReadmeSection({ scriptName, updatedAt, days, startDate, endDate, cacheKey }) { +export function buildReadmeSection({ + scriptName, + updatedAt, + days, + startDate, + endDate, + cacheKey, + includesRootRedirect = false, +}) { return [ '', - `

Cloudflare Workers 호출량 (${startDate} ~ ${endDate}, ${days}일)

`, + `

Cloudflare 요청 수 (${startDate} ~ ${endDate}, ${days}일)

`, '', - `Cloudflare Workers 호출량 그래프 (${startDate} ~ ${endDate})`, + `Cloudflare 요청 수 그래프 (${startDate} ~ ${endDate})`, '', `기준 워커: ${scriptName} · 마지막 갱신: ${updatedAt}`, + `
집계: ${includesRootRedirect ? 'Worker 실행 + 루트 GET 리디렉션 요청' : 'Worker 실행'} · 사용자 수와 다릅니다.`, '', '', '', diff --git a/src/services/feedback/tools/submitDeveloperRequest.ts b/src/services/feedback/tools/submitDeveloperRequest.ts index 2b6b536a..adeb16f5 100644 --- a/src/services/feedback/tools/submitDeveloperRequest.ts +++ b/src/services/feedback/tools/submitDeveloperRequest.ts @@ -11,7 +11,8 @@ const jsonValueSchema: z.ZodType = z.lazy(() => z.boolean(), z.null(), z.array(jsonValueSchema), - z.record(z.string(), jsonValueSchema), + // JSON 객체의 키는 항상 문자열이므로 HA가 지원하지 않는 중복 제약만 생략한다. + z.record(z.string(), jsonValueSchema).meta({ propertyNames: undefined }), ]), ); @@ -47,6 +48,7 @@ export function createSubmitDeveloperRequestTool(config: DeveloperRequestConfig) .describe('요청 출처'), userContext: z .record(z.string(), jsonValueSchema) + .meta({ propertyNames: undefined }) .optional() .describe('추가 컨텍스트 JSON'), }, diff --git a/tests/app/cli.test.ts b/tests/app/cli.test.ts index bcb58094..a7ebd952 100644 --- a/tests/app/cli.test.ts +++ b/tests/app/cli.test.ts @@ -3,6 +3,8 @@ */ import { describe, expect, it, vi } from 'vitest'; +import { resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; import { isDirectExecution, runCli } from '../../src/cli.js'; import { COMMAND_DETAIL, @@ -1286,8 +1288,10 @@ describe('CLI', () => { }); it('직접 실행 여부를 올바르게 판별한다', () => { - expect(isDirectExecution('', 'file:///tmp/test.js')).toBe(false); - expect(isDirectExecution('/tmp/test.js', 'file:///tmp/test.js')).toBe(true); - expect(isDirectExecution('/tmp/other.js', 'file:///tmp/test.js')).toBe(false); + const scriptPath = resolve('tmp/test.js'); + const scriptUrl = pathToFileURL(scriptPath).href; + expect(isDirectExecution('', scriptUrl)).toBe(false); + expect(isDirectExecution(scriptPath, scriptUrl)).toBe(true); + expect(isDirectExecution(resolve('tmp/other.js'), scriptUrl)).toBe(false); }); }); diff --git a/tests/scripts/repository-config.test.ts b/tests/scripts/repository-config.test.ts index 82571bd1..9e36c4f5 100644 --- a/tests/scripts/repository-config.test.ts +++ b/tests/scripts/repository-config.test.ts @@ -16,7 +16,7 @@ const setupNodeWorkflows = [ ]; function readText(path: string): string { - return readFileSync(path, 'utf8'); + return readFileSync(path, 'utf8').replaceAll('\r\n', '\n'); } describe('repository maintenance configuration', () => { @@ -62,7 +62,7 @@ describe('repository maintenance configuration', () => { overrides?: Record>; }; - expect(pkg.overrides?.miniflare).toEqual({ sharp: '0.35.3' }); + expect(pkg.overrides?.miniflare).toEqual({ sharp: '0.35.4', undici: '7.29.1' }); }); it('brace-expansion은 취약점이 수정된 5.0.8 이상을 사용한다', () => { diff --git a/tests/scripts/workers-chart-data.test.ts b/tests/scripts/workers-chart-data.test.ts index b5a13cc8..9a9a1992 100644 --- a/tests/scripts/workers-chart-data.test.ts +++ b/tests/scripts/workers-chart-data.test.ts @@ -353,7 +353,9 @@ describe('fetchDailyWorkerInvocations', () => { viewer: { accounts: [ { - workersInvocationsAdaptive: [{ sum: { requests: start.includes('06-03') ? 100 : 200 } }], + workersInvocationsAdaptive: [ + { sum: { requests: start.includes('06-03') ? 100 : 200 } }, + ], }, ], }, @@ -371,12 +373,26 @@ describe('fetchDailyWorkerInvocations', () => { zoneId: 'zone-id', rootRedirectStart: new Date('2026-05-27T07:24:50.000Z'), rootRequestsRetentionStart: new Date('2026-06-04T15:00:00.000Z'), + previousPayload: { + accountId: 'account-id', + scriptName: 'daiso-mcp', + timezone: 'Asia/Seoul', + coverageVersion: 1, + metric: 'workersInvocationsAdaptive.requests + httpRequestsAdaptiveGroups.count', + rootRedirect: { + zoneId: 'zone-id', + host: 'mcp.aka.page', + path: '/', + start: '2026-05-27T07:24:50.000Z', + }, + points: [{ date: '2026-06-04', requests: 999 }], + }, fetchImpl: mockFetch, concurrency: 1, }); expect(points).toEqual([ - { date: '2026-06-04', requests: 100 }, + { date: '2026-06-04', requests: 999 }, { date: '2026-06-05', requests: 225 }, ]); diff --git a/tests/scripts/workers-chart-entrypoint.test.ts b/tests/scripts/workers-chart-entrypoint.test.ts new file mode 100644 index 00000000..0df4ff6d --- /dev/null +++ b/tests/scripts/workers-chart-entrypoint.test.ts @@ -0,0 +1,135 @@ +import { execFileSync } from 'node:child_process'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { afterEach, describe, expect, it } from 'vitest'; +import { formatKstDate, parseKstDateText } from '../../scripts/ops/workers-chart-helpers.ts'; + +const temporaryRoots: string[] = []; +afterEach(async () => { + await Promise.all(temporaryRoots.map((root) => fs.rm(root, { recursive: true, force: true }))); + temporaryRoots.length = 0; +}); +async function fixture() { + const root = await fs.mkdtemp(path.join(process.cwd(), '.chart-test-')); + temporaryRoots.push(root); + await fs.mkdir(path.join(root, 'scripts/ops'), { recursive: true }); + await fs.mkdir(path.join(root, 'assets/analytics'), { recursive: true }); + for (const name of [ + 'workers-chart-data.ts', + 'workers-chart-helpers.ts', + 'update-workers-invocations-chart.ts', + ]) { + await fs.copyFile(path.join('scripts/ops', name), path.join(root, 'scripts/ops', name)); + } + await fs.writeFile(path.join(root, 'README.md'), '# Test\n'); + const date = formatKstDate( + new Date(parseKstDateText(formatKstDate(new Date())).getTime() - 86400000), + ); + const payload = { + accountId: 'account', + scriptName: 'daiso-mcp', + metric: 'workersInvocationsAdaptive.requests + httpRequestsAdaptiveGroups.count', + aggregation: 'script-level plus redirected root GET', + includedTraffic: 'complete test traffic', + timezone: 'Asia/Seoul', + coverageVersion: 1, + rootRedirect: { + zoneId: 'zone', + host: 'mcp.aka.page', + path: '/', + start: '2026-05-27T07:24:50.000Z', + rootRequestsRetentionDays: 1, + }, + updatedAt: new Date().toISOString(), + startDate: date, + endDate: date, + points: [{ date, requests: 1234 }], + }; + const dataPath = path.join(root, 'assets/analytics/workers-invocations.json'); + await fs.writeFile(dataPath, JSON.stringify(payload)); + await fs.writeFile( + path.join(root, 'no-network.mjs'), + 'globalThis.fetch = () => { throw new Error("Unexpected network request"); };', + ); + return { root, payload, dataPath }; +} +function run(root: string, overrides: Record) { + const env = { ...process.env }; + for (const key of Object.keys(env)) + if ( + key.startsWith('CLOUDFLARE_') || + key.startsWith('WORKERS_CHART_') || + key === 'CF_WORKER_SCRIPT_NAME' + ) + delete env[key]; + execFileSync( + process.execPath, + [ + '--import', + pathToFileURL(path.join(root, 'no-network.mjs')).href, + path.join(root, 'scripts/ops/update-workers-invocations-chart.ts'), + ], + { env: { ...env, ...overrides }, stdio: 'pipe' }, + ); +} +describe('workers chart entrypoint', () => { + it('불완전한 기록이면 오류로 종료하고 기존 산출물을 보존한다', async () => { + const { root, payload, dataPath } = await fixture(); + const incomplete = { + ...payload, + coverageVersion: undefined, + updatedAt: '2026-05-01T00:00:00Z', + }; + const original = JSON.stringify(incomplete); + await fs.writeFile(dataPath, original); + expect(() => + run(root, { + CLOUDFLARE_ACCOUNT_ID: 'account', + CLOUDFLARE_API_TOKEN: 'token', + CLOUDFLARE_ZONE_ID: 'zone', + WORKERS_CHART_DAYS: '1', + WORKERS_CHART_ROOT_REQUESTS_RETENTION_DAYS: '1', + WORKERS_CHART_ROOT_REDIRECT_START: payload.rootRedirect.start, + }), + ).toThrow('Incomplete daily traffic'); + expect(await fs.readFile(dataPath, 'utf8')).toBe(original); + expect(await fs.readFile(path.join(root, 'README.md'), 'utf8')).toBe('# Test\n'); + }); + it('실시간 실행에서 저장된 완전한 날짜를 읽고 보존한다', async () => { + const { root, payload, dataPath } = await fixture(); + run(root, { + CLOUDFLARE_ACCOUNT_ID: 'account', + CLOUDFLARE_API_TOKEN: 'token', + CLOUDFLARE_ZONE_ID: 'zone', + WORKERS_CHART_DAYS: '1', + WORKERS_CHART_ROOT_REQUESTS_RETENTION_DAYS: '1', + WORKERS_CHART_ROOT_REDIRECT_START: payload.rootRedirect.start, + }); + const output = JSON.parse(await fs.readFile(dataPath, 'utf8')); + expect(output.points).toEqual(payload.points); + expect(output.coverageVersion).toBe(1); + expect(output.accountId).toBe('account'); + }); + it('오프라인 렌더링은 인증 없이 원본 출처와 완전성 정보를 유지한다', async () => { + const { root, payload, dataPath } = await fixture(); + run(root, { WORKERS_CHART_INPUT_JSON: dataPath }); + const output = JSON.parse(await fs.readFile(dataPath, 'utf8')); + expect(output).toMatchObject(payload); + expect( + (await fs.stat(path.join(root, 'assets/analytics/workers-invocations.png'))).size, + ).toBeGreaterThan(0); + }); + it('CRLF 문서에서도 기존 차트 위치와 앞뒤 내용을 보존한다', async () => { + const { root, dataPath } = await fixture(); + await fs.writeFile( + path.join(root, 'README.md'), + '# Header\r\n\r\n\r\nold\r\n\r\n\r\n## Footer\r\n', + ); + run(root, { WORKERS_CHART_INPUT_JSON: dataPath }); + const readme = await fs.readFile(path.join(root, 'README.md'), 'utf8'); + expect(readme.startsWith('# Header\n\n')).toBe(true); + expect(readme.endsWith('\n\n## Footer\n')).toBe(true); + expect(readme).toContain('Worker 실행 + 루트 GET 리디렉션 요청'); + }); +}); diff --git a/tests/scripts/workers-chart-retention.test.ts b/tests/scripts/workers-chart-retention.test.ts new file mode 100644 index 00000000..9fac4c65 --- /dev/null +++ b/tests/scripts/workers-chart-retention.test.ts @@ -0,0 +1,106 @@ +import { describe, expect, it, vi } from 'vitest'; +import { fetchDailyWorkerInvocations } from '../../scripts/ops/workers-chart-data.ts'; + +const options = { + accountId: 'account', + apiToken: 'token', + scriptName: 'daiso-mcp', + startDateText: '2026-09-01', + endDateText: '2026-09-01', + zoneId: 'zone', + rootRedirectStart: new Date('2026-05-27T07:24:50.000Z'), + rootRequestsRetentionStart: new Date('2026-09-01T00:00:00.000Z'), +}; +function cache() { + return { + accountId: 'account', + scriptName: 'daiso-mcp', + timezone: 'Asia/Seoul', + metric: 'workersInvocationsAdaptive.requests + httpRequestsAdaptiveGroups.count', + coverageVersion: 1, + rootRedirect: { + zoneId: 'zone', + host: 'mcp.aka.page', + path: '/', + start: options.rootRedirectStart.toISOString(), + rootRequestsRetentionDays: 7, + }, + updatedAt: '2026-09-08T00:00:00.000Z', + points: [{ date: '2026-09-01', requests: 1234 }], + }; +} +function fetcher() { + return vi.fn(async (_url, init) => { + const root = JSON.parse(init.body).query.includes('RootGetRequests'); + return new Response( + JSON.stringify({ + data: { + viewer: root + ? { zones: [{ httpRequestsAdaptiveGroups: [{ count: 25 }] }] } + : { accounts: [{ workersInvocationsAdaptive: [{ sum: { requests: 100 } }] }] }, + }, + }), + ); + }); +} +describe('root GET retention', () => { + it.each(['2026-09-01T00:00:00Z', '2026-09-02T00:00:00Z'])( + '보존 경계 %s에서 완전한 과거 합계를 보존한다', + async (boundary) => { + const fetchImpl = fetcher(); + expect( + await fetchDailyWorkerInvocations({ + ...options, + rootRequestsRetentionStart: new Date(boundary), + previousPayload: cache(), + fetchImpl, + }), + ).toEqual(cache().points); + expect(fetchImpl).not.toHaveBeenCalled(); + }, + ); + it('전체 날짜를 조회할 수 있으면 캐시보다 최신 합계를 사용한다', async () => { + expect( + await fetchDailyWorkerInvocations({ + ...options, + rootRequestsRetentionStart: new Date('2026-08-31T15:00:00Z'), + previousPayload: cache(), + fetchImpl: fetcher(), + }), + ).toEqual([{ date: '2026-09-01', requests: 125 }]); + }); + it.each([ + undefined, + { ...cache(), accountId: 'other-account' }, + { ...cache(), accountId: undefined }, + { + ...cache(), + accountId: undefined, + coverageVersion: undefined, + updatedAt: '2026-09-02T00:00:00Z', + }, + { ...cache(), metric: 'workersInvocationsAdaptive.requests' }, + { ...cache(), scriptName: 'other' }, + { ...cache(), timezone: 'UTC' }, + { ...cache(), rootRedirect: { ...cache().rootRedirect, host: 'other' } }, + { ...cache(), points: [{ date: '2026-09-01', requests: -1 }] }, + ])('완전한 동일 출처 캐시가 없으면 부분 합계 출력을 거부한다', async (previousPayload) => { + await expect( + fetchDailyWorkerInvocations({ ...options, previousPayload, fetchImpl: fetcher() }), + ).rejects.toThrow('Incomplete daily traffic: 2026-09-01'); + }); + it('기존 스냅샷도 관측 시점에 완전한 창이었을 때만 사용한다', async () => { + const previousPayload = { + ...cache(), + coverageVersion: undefined, + updatedAt: '2026-09-02T00:00:00Z', + }; + expect( + await fetchDailyWorkerInvocations({ ...options, previousPayload, fetchImpl: fetcher() }), + ).toEqual(cache().points); + previousPayload.updatedAt = '2026-09-08T00:00:00Z'; + await expect( + fetchDailyWorkerInvocations({ ...options, previousPayload, fetchImpl: fetcher() }), + ).rejects.toThrow('Incomplete daily traffic'); + }); +}); diff --git a/tests/services/feedback/index.test.ts b/tests/services/feedback/index.test.ts index e72ab278..cddbe952 100644 --- a/tests/services/feedback/index.test.ts +++ b/tests/services/feedback/index.test.ts @@ -21,7 +21,7 @@ describe('createFeedbackService', () => { expect(service.getTools().map((tool) => tool.name)).toEqual(['submit_developer_request']); }); - it('Home Assistant가 변환할 수 있는 userContext JSON Schema를 생성한다', () => { + it('userContext JSON Schema에 재귀 JSON 값 정의를 포함한다', () => { const service = createFeedbackService(); const tool = service.getTools()[0]; if (!tool) throw new Error('submit_developer_request 도구가 없습니다.'); diff --git a/tests/services/feedback/schema.test.ts b/tests/services/feedback/schema.test.ts new file mode 100644 index 00000000..425cc4d4 --- /dev/null +++ b/tests/services/feedback/schema.test.ts @@ -0,0 +1,58 @@ +import { Client } from '@modelcontextprotocol/sdk/client/index.js'; +import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js'; +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { describe, expect, it } from 'vitest'; +import * as z from 'zod'; +import { ServiceRegistry } from '../../../src/core/registry.js'; +import { createFeedbackService } from '../../../src/services/feedback/index.js'; + +describe('개발자 요청 JSON Schema 호환성', () => { + it('실제 tools/list에서 Home Assistant가 거부하는 propertyNames를 내보내지 않는다', async () => { + const server = new McpServer({ name: 'schema-server', version: '1.0.0' }); + const client = new Client({ name: 'schema-client', version: '1.0.0' }); + const registry = new ServiceRegistry(); + registry.register(createFeedbackService); + registry.applyToServer(server); + const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); + + try { + await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]); + const { tools } = await client.listTools(); + const schema = tools.find((tool) => tool.name === 'submit_developer_request')?.inputSchema; + expect(schema).toBeDefined(); + // HA 2026.9.0b0의 probatio 0.11.2는 재귀 참조를 지원하지만 propertyNames는 거부한다. + expect(JSON.stringify(schema)).not.toContain('"propertyNames"'); + expect(schema?.properties?.userContext).toMatchObject({ + type: 'object', + additionalProperties: { $ref: expect.stringMatching(/^#\/definitions\//) }, + }); + } finally { + await client.close(); + await server.close(); + } + }); + + it('임의 키와 중첩 JSON 값을 그대로 보존한다', () => { + const tool = createFeedbackService().getTools()[0]; + const schema = z.object(tool.metadata.inputSchema); + const userContext = { + '': [{ nested: [null, true, false, 2, 1.5, 'text', {}, []] }], + '한글 키': { child: { value: 'preserved' } }, + }; + expect(schema.parse({ title: '제목', description: '설명', userContext }).userContext).toEqual( + userContext, + ); + }); + + it.each([undefined, () => 'value', Symbol('value'), 1n, NaN, Infinity, new Date()])( + '중첩된 비 JSON 값 %s를 거부한다', + (value) => { + const tool = createFeedbackService().getTools()[0]; + const schema = z.object(tool.metadata.inputSchema); + expect( + schema.safeParse({ title: '제목', description: '설명', userContext: { nested: { value } } }) + .success, + ).toBe(false); + }, + ); +});