diff --git a/.gitignore b/.gitignore index 4bbfe89..eada6b8 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ ui-debug.log *~ *swo *swp + +# TEMPORARY - or unnecesary if done +apps/mnswpr/MIGRATION.md diff --git a/.husky/pre-commit b/.husky/pre-commit index 7fe0373..bd4e307 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,2 +1,11 @@ echo "pre-commit..." -npm run lint \ No newline at end of file +npm run lint + +# Secret scan of staged files โ€” blocks committing tokens, private keys, or a +# stray .env.production before it ever reaches history. Config: .secretlintrc.json +# / .secretlintignore. Full-tree scan: `pnpm run scan:secrets`. +staged=$(git diff --cached --name-only --diff-filter=ACM) +if [ -n "$staged" ]; then + echo "secret-scan (staged files)..." + printf '%s\n' "$staged" | xargs -r -d '\n' npx secretlint --secretlintignore .secretlintignore +fi diff --git a/.secretlintignore b/.secretlintignore new file mode 100644 index 0000000..4c47fae --- /dev/null +++ b/.secretlintignore @@ -0,0 +1,5 @@ +# Paths secretlint should not scan (vendored, generated, or lockfiles). +node_modules +dist +pnpm-lock.yaml +*.log diff --git a/.secretlintrc.json b/.secretlintrc.json new file mode 100644 index 0000000..7a1a5df --- /dev/null +++ b/.secretlintrc.json @@ -0,0 +1,7 @@ +{ + "rules": [ + { + "id": "@secretlint/secretlint-rule-preset-recommend" + } + ] +} diff --git a/apps/mnswpr/MIGRATION.md b/apps/mnswpr/MIGRATION.md deleted file mode 100644 index 53c47b6..0000000 --- a/apps/mnswpr/MIGRATION.md +++ /dev/null @@ -1,96 +0,0 @@ -# ๐Ÿงน Leaderboard Migration Checklist - -Manual steps to finish the leaderboard rollout for **mnswpr**. **All code changes -are already applied** in the working tree โ€” these are the external actions on -Firebase and Netlify that have to be done by hand. - -> All commands below run from this app directory (`apps/mnswpr`) unless noted. - -> One project (`secure-moment-188701`), one difference between environments: the -> **collection namespace**. Production uses `mw-*`, dev/test uses `mw-test-*`. -> Full rationale: [`docs/leaderboard-env-migration.md`](docs/leaderboard-env-migration.md). - ---- - -## โœ… Step 1 โ€” Deploy Firestore rules + indexes - -From this app directory (`apps/mnswpr`): - -```bash -pnpm -F mnswpr exec firebase login -pnpm -F mnswpr exec firebase deploy --only firestore:rules,firestore:indexes --project prod -``` - -- Uses committed [`firestore.rules`](firestore.rules) + [`firestore.indexes.json`](firestore.indexes.json). -- `prod` โ†’ `secure-moment-188701` (via [`.firebaserc`](.firebaserc)). -- โš ๏ธ Deploying **replaces** the console rules. The committed rules cover every - collection (`mw-*` and `mw-test-*`), so it's safe โ€” but review first. -- No composite indexes to build โ€” rolling windows (`time_stamp >=`) and all-time - (`orderBy score`) use Firestore's automatic single-field indexes. - -## โœ… Step 2 โ€” Set Netlify environment variables - -In the Netlify site settings, add: - -| Variable | Value | -| --- | --- | -| `VITE_FIREBASE_API_KEY` โ€ฆ (all 8) | **same as [`.env.development`](.env.development)** (same project) | -| `VITE_LB_NAMESPACE` | **`mw`** โ† makes production use the `mw-*` collections | - -> Local dev already uses `mw-test` via the committed `.env.development` โ€” nothing -> to do there. - -## โœ… Step 3 โ€” (Optional) Seed the test config doc - -Create `mw-test-config/configuration` in Firestore with the same `passingStatus` -and `message` as the prod `mw-config/configuration`. - -Skip it and the test board still works โ€” the default qualifier just accepts all -wins in test. - -## โœ… Step 4 โ€” Seed the dev database with sample scores - -> โš ๏ธ **Must run _after_ Step 1.** The seed writes to `mw-test-scores`, which is -> only allowed once the generalized rules are deployed โ€” otherwise every write -> returns `permission-denied`. (No indexes to wait on โ€” the windows use -> automatic single-field indexes.) - -Populate the dev boards so they aren't empty while developing, from this app -directory (`apps/mnswpr`): - -```bash -node scripts/seed-dev-scores.js -``` - -- Uses [`scripts/seed-dev-scores.js`](scripts/seed-dev-scores.js) โ€” ~12 sample - scores per level, timestamps spread across today / this week / this month / - older so **all four tabs** populate. -- Dev-only and idempotent-ish (re-running just adds more rows); it never touches - the production `mw-*` collections. - -> ๐Ÿ’ก **Local dev uses the emulator by default โ€” this cloud seed is optional.** -> `pnpm dev` points at the local **Firestore emulator** (needs a JDK): run -> `pnpm emulators` + `pnpm seed:emulator` from the workspace root and you're set -> โ€” no deploy, no cloud. The cloud seed above is only needed for a hosted/preview -> environment. To opt out of the emulator, set `VITE_FIRESTORE_EMULATOR=` empty -> in `.env.local`. -> See [`docs/firebase-leaderboards.md`](docs/firebase-leaderboards.md#local-firestore-emulator-default-for-local-dev). - -## โœ… Step 5 โ€” Verify - -| Environment | How | Expected | -| --- | --- | --- | -| **Production** (`mw`) | Win a game on the live site | Score shows; doc in `mw-scores/{level}/games` | -| **Local dev** (`mw-test`) | `pnpm dev` (after Step 4) | Board shows sample scores; winning adds to `mw-test-scores/{level}/games`; prod `mw-scores` untouched | -| **Rules** | Read both boards | Reads succeed; a malformed write is rejected | - ---- - -## ๐Ÿ“Œ Still open (not blocking) - -- **Nothing is committed yet** โ€” all changes are in the working tree. -- **`scripts/export-legends.js`** still hard-codes the (dev = prod) Firebase keys - from the one-off Legends export. It's identical to `.env.development`; can - be de-duped to read from the env file on request. -- **Legends** is already frozen into static HTML ([`legends.html`](legends.html)) - โ€” no action needed. diff --git a/apps/mnswpr/firestore.rules b/apps/mnswpr/firestore.rules index 351f517..16f00a8 100644 --- a/apps/mnswpr/firestore.rules +++ b/apps/mnswpr/firestore.rules @@ -4,13 +4,10 @@ rules_version = '2' // rules are the enforced schema: public reads for the boards, validated // create-only writes for scores, no client writes to server config. // -// SECURITY MODEL: the Firebase web config is public (it ships to every browser), -// so these rules โ€” not secrecy of the config or the codebase โ€” are what protect -// the data. No collection allows a client to UPDATE or DELETE existing docs, so -// no client (with or without the source) can wipe the production boards. The -// powerful vectors (Admin SDK / service-account keys, and IAM console access) -// bypass rules entirely โ€” keep those out of the repo and locked down in GCP. -// See docs/firebase-leaderboards.md ("Protecting production data"). +// The Firebase web config that ships in the client is public by design (it is +// not a secret); these rules โ€” not secrecy โ€” are what govern access. No +// collection allows a client to update or delete existing docs. Keep any +// admin/service-account credentials out of the repo and locked down in GCP. // // Rules match by namespace SUFFIX (regex) rather than a literal prefix, so the // same set covers production (`mw-*`) and test (`mw-test-*`) collections in the @@ -19,7 +16,7 @@ rules_version = '2' // block is guarded by a regex on the captured collection name. // // Deploy with (see docs/firebase-leaderboards.md): -// npx firebase deploy --only firestore:rules --project prod +// pnpm -F mnswpr exec firebase deploy --only firestore:rules --project prod service cloud.firestore { match /databases/{database}/documents { @@ -36,13 +33,15 @@ service cloud.firestore { allow write: if false; } - // Per-browser personal archive. Write-only from the client (the app never - // reads it back), append/merge only, and NEVER deletable. This is the only - // client-writable collection, so denying delete/read here removes the last - // way a client could destroy or harvest data. + // Per-browser personal archive. Not readable by clients, append/merge only, + // and never deletable. The doc is a map of gameId -> game object (one doc + // per day, merged as games finish); the entry-count cap keeps a single doc + // bounded (Firestore already limits any doc to 1 MiB). 500 is far above any + // real day of play. match /{all}/{browserId}/games/{session} { allow read: if false; - allow create, update: if all.matches('mw(-[a-z]+)?-all'); + allow create, update: if all.matches('mw(-[a-z]+)?-all') + && request.resource.data.size() <= 500; allow delete: if false; } diff --git a/package.json b/package.json index 2ad1a04..e55aab8 100644 --- a/package.json +++ b/package.json @@ -20,17 +20,20 @@ "postinstall": "node scripts/ensure-java.mjs", "prepare": "husky", "lint": "eslint .", - "lint:fix": "eslint . --fix" + "lint:fix": "eslint . --fix", + "scan:secrets": "secretlint --secretlintignore .secretlintignore \"**/*\"" }, "devDependencies": { "@eslint/css": "^1.1.0", "@eslint/js": "^10.0.1", + "@secretlint/secretlint-rule-preset-recommend": "^13.0.2", "@stylistic/eslint-plugin": "^5.10.0", "bumpp": "^11.0.1", "eslint": "^10.1.0", "globals": "^17.4.0", "husky": "^9.1.7", "jsdom": "^29.1.1", + "secretlint": "^13.0.2", "simple-git": "^3.33.0", "vite": "^8.0.3", "vitest": "^4.1.9" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 584c18e..c60cae0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,16 +13,19 @@ importers: version: 1.1.0 '@eslint/js': specifier: ^10.0.1 - version: 10.0.1(eslint@10.1.0(jiti@2.6.1)) + version: 10.0.1(eslint@10.1.0(jiti@2.6.1)(supports-color@10.2.2)) + '@secretlint/secretlint-rule-preset-recommend': + specifier: ^13.0.2 + version: 13.0.2 '@stylistic/eslint-plugin': specifier: ^5.10.0 - version: 5.10.0(eslint@10.1.0(jiti@2.6.1)) + version: 5.10.0(eslint@10.1.0(jiti@2.6.1)(supports-color@10.2.2)) bumpp: specifier: ^11.0.1 version: 11.0.1 eslint: specifier: ^10.1.0 - version: 10.1.0(jiti@2.6.1) + version: 10.1.0(jiti@2.6.1)(supports-color@10.2.2) globals: specifier: ^17.4.0 version: 17.4.0 @@ -32,9 +35,12 @@ importers: jsdom: specifier: ^29.1.1 version: 29.1.1 + secretlint: + specifier: ^13.0.2 + version: 13.0.2 simple-git: specifier: ^3.33.0 - version: 3.33.0 + version: 3.33.0(supports-color@10.2.2) vite: specifier: ^8.0.3 version: 8.0.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@25.5.2)(jiti@2.6.1)(yaml@2.8.3) @@ -58,10 +64,10 @@ importers: version: 12.11.0 firebase-tools: specifier: ^15.22.4 - version: 15.22.4(@types/node@25.5.2) + version: 15.22.4(@types/node@25.5.2)(supports-color@10.2.2) netlify-cli: specifier: ^26.1.0 - version: 26.1.0(@types/node@25.5.2)(picomatch@4.0.4) + version: 26.1.0(@types/node@25.5.2)(picomatch@4.0.4)(supports-color@10.2.2) web-component-base: specifier: ^4.1.2 version: 4.1.2 @@ -110,6 +116,12 @@ packages: '@asamuzakjp/nwsapi@2.3.9': resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@azu/format-text@1.0.2': + resolution: {integrity: sha512-Swi4N7Edy1Eqq82GxgEECXSSLyn6GOb5htRFPzBDdUkECGXtlf12ynO5oJSpWKPwCaUssOu7NfhDcCWpIC6Ywg==} + + '@azu/style-format@1.0.1': + resolution: {integrity: sha512-AHcTojlNBdD/3/KxIKlg8sxIWHfOtQszLvOpagLTO+bjC3u7SAszu1lf//u7JJC50aUSH+BVWDD/KvaA6Gfn5g==} + '@babel/code-frame@7.29.7': resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} @@ -1742,6 +1754,48 @@ packages: '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@secretlint/config-creator@13.0.2': + resolution: {integrity: sha512-wEHE/x7jeaWnDqVhzUg3qLsnl3NOQTA2fVnxwc0Z7dn3SOSh5sEKFr6xTp/LhZxyuHnKJltlcF085UDUFOoqYQ==} + engines: {node: '>=22.0.0'} + + '@secretlint/config-loader@13.0.2': + resolution: {integrity: sha512-r0ZVJ3oGUwWqoFPwhR9RK/fnp358TImaa72UhrBdBiuzMvAcPtE6EbnAYhbj0Yr5QS6ns+GI11jV344MLqkhTg==} + engines: {node: '>=22.0.0'} + + '@secretlint/core@13.0.2': + resolution: {integrity: sha512-15vg+zCmjQuDFVoOPNt0TyEu0Z95eir2MO19++wG82yM/vbPtFu/m9qd6oh54ZOBXgMcchdGDTxMwJNDnCLxcA==} + engines: {node: '>=22.0.0'} + + '@secretlint/formatter@13.0.2': + resolution: {integrity: sha512-DoU+aEsqPQxiWTQBNkTvQDmGTWB+TQS4UC6XEliWYv4KHpMV81O52jOE7XKS7QUoDMD4dbjh5wUTAgNO1dpzEg==} + engines: {node: '>=22.0.0'} + + '@secretlint/node@13.0.2': + resolution: {integrity: sha512-xAK+0INjjMASH5guHLSozl++6kDyeOTy4FNC6dhPA7ieebCmHe/+QiAsr4KP9yDRZoh/uRmEno2NMDy5lgQpkA==} + engines: {node: '>=22.0.0'} + + '@secretlint/profiler@13.0.2': + resolution: {integrity: sha512-vGaLZCoi9KewOF+sM0iIEBviWaH9mls1HmQFBgEPq4fnvmVO4PfKIkVr4CcAFm3Msg4NjzFE2RBAGwRR+5HEmQ==} + + '@secretlint/resolver@13.0.2': + resolution: {integrity: sha512-Ko50V0P3YAtEO20xBTczOzguBVk6+taSqkoAPHoOSdsTsSq1gzeYggY1UC8vVEHPGyRp/mb2QOuwIShdJZ8JFg==} + + '@secretlint/secretlint-rule-preset-recommend@13.0.2': + resolution: {integrity: sha512-D03Kw51qOgffj9zNlJFZUarVmP8zGcCZNi7A14+vZtHskbbBPEsS/f09idb48rrlMSaRMBN29IkqfbmPyL9xtw==} + engines: {node: '>=22.0.0'} + + '@secretlint/source-creator@13.0.2': + resolution: {integrity: sha512-tSooHad8QL+lqHP88zH9F8GMoR7bHUqPja5M/QnNHGnvOq/8OT1V8t1uigm6jlD03oJWNLwwF8QeHIedWKJ13g==} + engines: {node: '>=22.0.0'} + + '@secretlint/types@13.0.2': + resolution: {integrity: sha512-cAZjr6ZTKgSuJMLyTGDrUEtK3XEZa+JStIkD+DmdkT32VGAN+dQJiYr1So3XJopsKSrqhP5kjZKT8WWtftZIpQ==} + engines: {node: '>=22.0.0'} + + '@secretlint/walker@13.0.2': + resolution: {integrity: sha512-9GtWeTb763Ilr/nbRzdFidfZTBtbNEsz/BKrilgqLpKR9EqSWe9eYWDQaLIYb4PddIhwOgHuahRrX2BYATNcLQ==} + engines: {node: '>=22.0.0'} + '@sindresorhus/is@4.6.0': resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} @@ -1775,6 +1829,21 @@ packages: peerDependencies: acorn: ^8.9.0 + '@textlint/ast-node-types@15.7.1': + resolution: {integrity: sha512-Wii5UgUKFEh9Uv6wbq1zr4/Kf+dtjiUuzPrrXzKp8H+ifkvKNzi23V4Nz+6wVyHQn5T28AFuc8VH8OtzvGYecA==} + + '@textlint/linter-formatter@15.7.1': + resolution: {integrity: sha512-TdwZ/debWYFD05K3CcoHtwvnCrza29wZxD+BjDTk/V5N7iRqkK1dTTHSD4A8AIgROLiDkHJmIKQbasbmsg8AvA==} + + '@textlint/module-interop@15.7.1': + resolution: {integrity: sha512-Jg+sQW2L/cRJypk59wtcMUVVpt8vmit5ZMT3gUnFwevP3A6Qp1HfOtUy9ObT4hBX3lOSGT/ekcCDxR1pL7uH1g==} + + '@textlint/resolver@15.7.1': + resolution: {integrity: sha512-8XnO0pgF6mXnm41VvWmBbEIdGPhiCUt31uLZkOis1ECeg/1SoUcIT6Mx/F0e1rukq8l0UlOSeY9a31CsvRMK0g==} + + '@textlint/types@15.7.1': + resolution: {integrity: sha512-Vye/GmFNBTgVzZFtIFJTmLB+s2A7oIADxNG6r9UhfPuY+Czv0z5G3xeyFZZudPlfxURsKUyPIU5XsjOFqVp33A==} + '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} @@ -2106,6 +2175,10 @@ packages: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} @@ -2229,6 +2302,10 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + binaryextensions@6.11.0: + resolution: {integrity: sha512-sXnYK/Ij80TO3lcqZVV2YgfKN5QjUWIRk/XSm2J/4bd/lPko3lvk0O4ZppH6m+6hB2/GTu+ptNwVFe1xh+QLQw==} + engines: {node: '>=4'} + bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} @@ -2246,6 +2323,9 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + boundary@2.0.0: + resolution: {integrity: sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==} + boxen@5.1.2: resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} engines: {node: '>=10'} @@ -2887,6 +2967,10 @@ packages: ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + editions@6.22.0: + resolution: {integrity: sha512-UgGlf8IW75je7HZjNDpJdCv4cGJWIi6yumFdZ0R7A8/CIhQiWUjyGLCxdHpd8bmyD1gnkfUNK0oeOXqUS2cpfQ==} + engines: {ecmascript: '>= es5', node: '>=4'} + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -4077,6 +4161,10 @@ packages: isomorphic-fetch@3.0.0: resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} + istextorbinary@9.5.0: + resolution: {integrity: sha512-5mbUj3SiZXCuRf9fT3ibzbSSEWiy63gFfksmGfdOzujPjW3k+z8WvIBxcJHBoQNlaZaiyB25deviif2+osLmLw==} + engines: {node: '>=4'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -4146,6 +4234,11 @@ packages: json-with-bigint@3.5.8: resolution: {integrity: sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} @@ -4347,6 +4440,9 @@ packages: lodash.transform@4.6.0: resolution: {integrity: sha512-LO37ZnhmBVx0GvOU/caQuipEh4GN82TcWv3yHlebGDgOxbxiwwzW5Pcx2AcvpIv2WmvmSMoC492yQFNhy/l/UQ==} + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + lodash@4.18.1: resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} @@ -5079,6 +5175,13 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + pluralize@2.0.0: + resolution: {integrity: sha512-TqNZzQCD4S42De9IfnnBvILN7HAW7riLqsCyp8lgjXeysyPlX5HhqKAcJHHHb9XskE4/a+7VGC9zzx8Ls0jOAw==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + portfinder@1.0.38: resolution: {integrity: sha512-rEwq/ZHlJIKw++XtLAO8PPuOQA/zaPJOZJ37BVuN97nLpMJeuDVLVGRwbFoBgLudgdTMP2hdRJP++H+8QOA3vg==} engines: {node: '>= 10.12'} @@ -5260,6 +5363,9 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} + rc-config-loader@4.1.4: + resolution: {integrity: sha512-3GiwEzklkbXTDp52UR5nT8iXgYAx1V9ZG/kDZT7p60u2GCv2XTwQq4NzinMoMpNtXhmt3WkhYXcj6HH8HdwCEQ==} + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -5469,6 +5575,11 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} + secretlint@13.0.2: + resolution: {integrity: sha512-veYNpVC+Yw9H/EWzdGyEsYHqCFXgKOinGEMbRffvnkHoWnE0CongrCnWXZJ1bkYmirlhemq/gkiOZ5zdHcHCQg==} + engines: {node: '>=22.0.0'} + hasBin: true + secure-json-parse@4.1.0: resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} @@ -5575,6 +5686,10 @@ packages: slashes@3.0.12: resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==} + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + slice-ansi@8.0.0: resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} engines: {node: '>=20'} @@ -5728,6 +5843,9 @@ packages: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} + structured-source@4.0.0: + resolution: {integrity: sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA==} + stubborn-fs@2.0.0: resolution: {integrity: sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==} @@ -5770,6 +5888,10 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + table@6.9.0: + resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} + engines: {node: '>=10.0.0'} + tagged-tag@1.0.0: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} engines: {node: '>=20'} @@ -5805,6 +5927,13 @@ packages: text-hex@1.0.0: resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + textextensions@6.11.0: + resolution: {integrity: sha512-tXJwSr9355kFJI3lbCkPpUH5cP8/M0GGy2xLO34aZCjMXBaK3SoPnZwr/oWmo1FdCnELcs4npdCIOFtq9W3ruQ==} + engines: {node: '>=4'} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -6180,6 +6309,10 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + version-range@4.15.0: + resolution: {integrity: sha512-Ck0EJbAGxHwprkzFO966t4/5QkRuzh+/I1RxhLgUKKwEn+Cd8NwM60mE3AqBZg5gYODoXW0EFsQvbZjRlvdqbg==} + engines: {node: '>=4'} + vite@8.0.3: resolution: {integrity: sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6548,6 +6681,12 @@ snapshots: '@asamuzakjp/nwsapi@2.3.9': {} + '@azu/format-text@1.0.2': {} + + '@azu/style-format@1.0.1': + dependencies: + '@azu/format-text': 1.0.2 + '@babel/code-frame@7.29.7': dependencies: '@babel/helper-validator-identifier': 7.29.7 @@ -6752,14 +6891,14 @@ snapshots: '@esbuild/win32-x64@0.28.0': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.1.0(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.9.1(eslint@10.1.0(jiti@2.6.1)(supports-color@10.2.2))': dependencies: - eslint: 10.1.0(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1)(supports-color@10.2.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/config-array@0.23.3': + '@eslint/config-array@0.23.3(supports-color@10.2.2)': dependencies: '@eslint/object-schema': 3.0.3 debug: 4.4.3(supports-color@10.2.2) @@ -6786,9 +6925,9 @@ snapshots: '@eslint/css-tree': 3.6.9 '@eslint/plugin-kit': 0.6.1 - '@eslint/js@10.0.1(eslint@10.1.0(jiti@2.6.1))': + '@eslint/js@10.0.1(eslint@10.1.0(jiti@2.6.1)(supports-color@10.2.2))': optionalDependencies: - eslint: 10.1.0(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1)(supports-color@10.2.2) '@eslint/object-schema@3.0.3': {} @@ -7500,7 +7639,7 @@ snapshots: '@jsdevtools/ono@7.1.3': {} - '@kwsites/file-exists@1.1.1': + '@kwsites/file-exists@1.1.1(supports-color@10.2.2)': dependencies: debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: @@ -7714,7 +7853,7 @@ snapshots: semver: 7.7.4 tmp-promise: 3.0.3 - '@netlify/dev@4.18.9': + '@netlify/dev@4.18.9(supports-color@10.2.2)': dependencies: '@netlify/ai': 0.4.2 '@netlify/blobs': 10.7.9(supports-color@10.2.2) @@ -7722,9 +7861,9 @@ snapshots: '@netlify/database-dev': 0.10.1 '@netlify/dev-utils': 4.4.6 '@netlify/edge-functions-dev': 1.0.22 - '@netlify/functions-dev': 1.3.1 + '@netlify/functions-dev': 1.3.1(supports-color@10.2.2) '@netlify/headers': 2.1.11 - '@netlify/images': 1.3.10(@netlify/blobs@10.7.9) + '@netlify/images': 1.3.10(@netlify/blobs@10.7.9(supports-color@10.2.2)) '@netlify/redirects': 3.1.13 '@netlify/runtime': 4.1.25 '@netlify/static': 3.1.10 @@ -7797,7 +7936,7 @@ snapshots: dependencies: '@netlify/types': 2.8.0 - '@netlify/functions-dev@1.3.1': + '@netlify/functions-dev@1.3.1(supports-color@10.2.2)': dependencies: '@netlify/blobs': 10.7.9(supports-color@10.2.2) '@netlify/dev-utils': 4.4.6 @@ -7805,7 +7944,7 @@ snapshots: '@netlify/zip-it-and-ship-it': 14.7.1(supports-color@10.2.2) cron-parser: 4.9.0 decache: 4.6.2 - extract-zip: 2.0.1 + extract-zip: 2.0.1(supports-color@10.2.2) is-stream: 4.0.1 jwt-decode: 4.0.0 lambda-local: 2.2.0 @@ -7857,9 +7996,9 @@ snapshots: dependencies: '@netlify/headers-parser': 9.0.3 - '@netlify/images@1.3.10(@netlify/blobs@10.7.9)': + '@netlify/images@1.3.10(@netlify/blobs@10.7.9(supports-color@10.2.2))': dependencies: - ipx: 3.1.1(@netlify/blobs@10.7.9) + ipx: 3.1.1(@netlify/blobs@10.7.9(supports-color@10.2.2)) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -8249,7 +8388,7 @@ snapshots: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 - '@pnpm/tabtab@0.5.4': + '@pnpm/tabtab@0.5.4(supports-color@10.2.2)': dependencies: debug: 4.4.3(supports-color@10.2.2) enquirer: 2.4.1 @@ -8355,6 +8494,77 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} + '@secretlint/config-creator@13.0.2': + dependencies: + '@secretlint/types': 13.0.2 + + '@secretlint/config-loader@13.0.2': + dependencies: + '@secretlint/profiler': 13.0.2 + '@secretlint/resolver': 13.0.2 + '@secretlint/types': 13.0.2 + ajv: 8.20.0 + debug: 4.4.3(supports-color@10.2.2) + rc-config-loader: 4.1.4 + transitivePeerDependencies: + - supports-color + + '@secretlint/core@13.0.2': + dependencies: + '@secretlint/profiler': 13.0.2 + '@secretlint/types': 13.0.2 + debug: 4.4.3(supports-color@10.2.2) + structured-source: 4.0.0 + transitivePeerDependencies: + - supports-color + + '@secretlint/formatter@13.0.2': + dependencies: + '@secretlint/resolver': 13.0.2 + '@secretlint/types': 13.0.2 + '@textlint/linter-formatter': 15.7.1 + '@textlint/module-interop': 15.7.1 + '@textlint/types': 15.7.1 + chalk: 5.6.2 + debug: 4.4.3(supports-color@10.2.2) + pluralize: 8.0.0 + strip-ansi: 7.2.0 + table: 6.9.0 + terminal-link: 5.0.0 + transitivePeerDependencies: + - supports-color + + '@secretlint/node@13.0.2': + dependencies: + '@secretlint/config-loader': 13.0.2 + '@secretlint/core': 13.0.2 + '@secretlint/formatter': 13.0.2 + '@secretlint/profiler': 13.0.2 + '@secretlint/source-creator': 13.0.2 + '@secretlint/types': 13.0.2 + debug: 4.4.3(supports-color@10.2.2) + p-map: 7.0.5 + transitivePeerDependencies: + - supports-color + + '@secretlint/profiler@13.0.2': {} + + '@secretlint/resolver@13.0.2': {} + + '@secretlint/secretlint-rule-preset-recommend@13.0.2': {} + + '@secretlint/source-creator@13.0.2': + dependencies: + '@secretlint/types': 13.0.2 + istextorbinary: 9.5.0 + + '@secretlint/types@13.0.2': {} + + '@secretlint/walker@13.0.2': + dependencies: + ignore: 7.0.5 + picomatch: 4.0.4 + '@sindresorhus/is@4.6.0': {} '@sindresorhus/merge-streams@2.3.0': {} @@ -8375,11 +8585,11 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.1.0(jiti@2.6.1))': + '@stylistic/eslint-plugin@5.10.0(eslint@10.1.0(jiti@2.6.1)(supports-color@10.2.2))': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)(supports-color@10.2.2)) '@typescript-eslint/types': 8.58.0 - eslint: 10.1.0(jiti@2.6.1) + eslint: 10.1.0(jiti@2.6.1)(supports-color@10.2.2) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -8389,6 +8599,35 @@ snapshots: dependencies: acorn: 8.16.0 + '@textlint/ast-node-types@15.7.1': {} + + '@textlint/linter-formatter@15.7.1': + dependencies: + '@azu/format-text': 1.0.2 + '@azu/style-format': 1.0.1 + '@textlint/module-interop': 15.7.1 + '@textlint/resolver': 15.7.1 + '@textlint/types': 15.7.1 + chalk: 4.1.2 + debug: 4.4.3(supports-color@10.2.2) + js-yaml: 4.3.0 + lodash: 4.18.1 + pluralize: 2.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + table: 6.9.0 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + '@textlint/module-interop@15.7.1': {} + + '@textlint/resolver@15.7.1': {} + + '@textlint/types@15.7.1': + dependencies: + '@textlint/ast-node-types': 15.7.1 + '@tootallnate/quickjs-emscripten@0.23.0': {} '@tsconfig/node10@1.0.12': {} @@ -8766,6 +9005,8 @@ snapshots: dependencies: tslib: 2.8.1 + astral-regex@2.0.0: {} + async-function@1.0.0: {} async-lock@1.4.1: {} @@ -8866,6 +9107,10 @@ snapshots: binary-extensions@2.3.0: {} + binaryextensions@6.11.0: + dependencies: + editions: 6.22.0 + bindings@1.5.0: dependencies: file-uri-to-path: 1.0.0 @@ -8909,6 +9154,8 @@ snapshots: boolbase@1.0.0: {} + boundary@2.0.0: {} + boxen@5.1.2: dependencies: ansi-align: 3.0.1 @@ -9550,6 +9797,10 @@ snapshots: dependencies: safe-buffer: 5.2.1 + editions@6.22.0: + dependencies: + version-range: 4.15.0 + ee-first@1.1.1: {} emoji-regex@10.6.0: {} @@ -9762,11 +10013,11 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.1.0(jiti@2.6.1): + eslint@10.1.0(jiti@2.6.1)(supports-color@10.2.2): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)(supports-color@10.2.2)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.23.3 + '@eslint/config-array': 0.23.3(supports-color@10.2.2) '@eslint/config-helpers': 0.5.3 '@eslint/core': 1.1.1 '@eslint/plugin-kit': 0.6.1 @@ -9989,7 +10240,7 @@ snapshots: extend@3.0.2: {} - extract-zip@2.0.1: + extract-zip@2.0.1(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) get-stream: 5.2.0 @@ -10162,7 +10413,7 @@ snapshots: locate-path: 8.0.0 unicorn-magic: 0.3.0 - firebase-tools@15.22.4(@types/node@25.5.2): + firebase-tools@15.22.4(@types/node@25.5.2)(supports-color@10.2.2): dependencies: '@apphosting/common': 0.0.8 '@electric-sql/pglite': 0.3.16 @@ -10213,9 +10464,9 @@ snapshots: pg: 8.22.0 pg-gateway: 0.3.0-beta.4 pglite-2: '@electric-sql/pglite@0.2.17' - portfinder: 1.0.38 + portfinder: 1.0.38(supports-color@10.2.2) progress: 2.0.3 - proxy-agent: 6.5.0 + proxy-agent: 6.5.0(supports-color@10.2.2) retry: 0.13.1 semver: 7.7.4 sql-formatter: 15.8.2 @@ -10226,7 +10477,7 @@ snapshots: tcp-port-used: 1.0.3 tmp: 0.2.7 triple-beam: 1.4.1 - universal-analytics: 0.5.4 + universal-analytics: 0.5.4(supports-color@10.2.2) update-notifier-cjs: 5.1.7 winston: 3.19.0 winston-transport: 4.9.0 @@ -10291,7 +10542,7 @@ snapshots: dependencies: from2: 2.3.0 - follow-redirects@1.16.0(debug@4.4.3): + follow-redirects@1.16.0(debug@4.4.3(supports-color@10.2.2)): optionalDependencies: debug: 4.4.3(supports-color@10.2.2) @@ -10461,7 +10712,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-uri@6.0.5: + get-uri@6.0.5(supports-color@10.2.2): dependencies: basic-ftp: 5.3.1 data-uri-to-buffer: 6.0.2 @@ -10714,21 +10965,21 @@ snapshots: transitivePeerDependencies: - supports-color - http-proxy-middleware@3.0.7: + http-proxy-middleware@3.0.7(supports-color@10.2.2): dependencies: '@types/http-proxy': 1.17.17 debug: 4.4.3(supports-color@10.2.2) - http-proxy: 1.18.1(debug@4.4.3) + http-proxy: 1.18.1(debug@4.4.3(supports-color@10.2.2)) is-glob: 4.0.3 is-plain-object: 5.0.0 micromatch: 4.0.8 transitivePeerDependencies: - supports-color - http-proxy@1.18.1(debug@4.4.3): + http-proxy@1.18.1(debug@4.4.3(supports-color@10.2.2)): dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.16.0(debug@4.4.3) + follow-redirects: 1.16.0(debug@4.4.3(supports-color@10.2.2)) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -10742,7 +10993,7 @@ snapshots: transitivePeerDependencies: - supports-color - https-proxy-agent@8.0.0: + https-proxy-agent@8.0.0(supports-color@10.2.2): dependencies: agent-base: 8.0.0 debug: 4.4.3(supports-color@10.2.2) @@ -10844,7 +11095,7 @@ snapshots: ipaddr.js@2.4.0: {} - ipx@3.1.1(@netlify/blobs@10.7.9): + ipx@3.1.1(@netlify/blobs@10.7.9(supports-color@10.2.2)): dependencies: '@fastify/accept-negotiator': 2.0.1 citty: 0.1.6 @@ -10860,7 +11111,7 @@ snapshots: sharp: 0.34.5 svgo: 4.0.1 ufo: 1.6.4 - unstorage: 1.17.5(@netlify/blobs@10.7.9) + unstorage: 1.17.5(@netlify/blobs@10.7.9(supports-color@10.2.2)) xss: 1.0.15 transitivePeerDependencies: - '@azure/app-configuration' @@ -11113,6 +11364,12 @@ snapshots: transitivePeerDependencies: - encoding + istextorbinary@9.5.0: + dependencies: + binaryextensions: 6.11.0 + editions: 6.22.0 + textextensions: 6.11.0 + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -11195,6 +11452,8 @@ snapshots: json-with-bigint@3.5.8: {} + json5@2.2.3: {} + jsonc-parser@3.3.1: {} jsonfile@6.2.1: @@ -11390,6 +11649,8 @@ snapshots: lodash.transform@4.6.0: {} + lodash.truncate@4.4.2: {} + lodash@4.18.1: {} log-process-errors@11.0.1: @@ -11639,7 +11900,7 @@ snapshots: negotiator@1.0.0: {} - netlify-cli@26.1.0(@types/node@25.5.2)(picomatch@4.0.4): + netlify-cli@26.1.0(@types/node@25.5.2)(picomatch@4.0.4)(supports-color@10.2.2): dependencies: '@fastify/static': 9.1.3 '@netlify/ai': 0.4.2 @@ -11648,19 +11909,19 @@ snapshots: '@netlify/build': 35.15.0(@opentelemetry/api@1.9.1)(@types/node@25.5.2)(picomatch@4.0.4) '@netlify/build-info': 10.5.1 '@netlify/config': 24.6.0 - '@netlify/dev': 4.18.9 + '@netlify/dev': 4.18.9(supports-color@10.2.2) '@netlify/dev-utils': 4.4.6 '@netlify/edge-bundler': 14.10.3 '@netlify/edge-functions': 3.0.8 '@netlify/edge-functions-bootstrap': 2.17.1 '@netlify/headers-parser': 9.0.3 - '@netlify/images': 1.3.10(@netlify/blobs@10.7.9) + '@netlify/images': 1.3.10(@netlify/blobs@10.7.9(supports-color@10.2.2)) '@netlify/local-functions-proxy': 2.0.3 '@netlify/redirect-parser': 15.0.4 '@netlify/zip-it-and-ship-it': 14.7.1(supports-color@10.2.2) '@octokit/rest': 22.0.1 '@opentelemetry/api': 1.9.1 - '@pnpm/tabtab': 0.5.4 + '@pnpm/tabtab': 0.5.4(supports-color@10.2.2) ansi-escapes: 7.3.0 ansi-to-html: 0.7.2 ascii-table: 0.0.9 @@ -11693,9 +11954,9 @@ snapshots: get-port: 5.1.1 git-repo-info: 2.1.1 gitconfiglocal: 2.1.0 - http-proxy: 1.18.1(debug@4.4.3) - http-proxy-middleware: 3.0.7 - https-proxy-agent: 8.0.0 + http-proxy: 1.18.1(debug@4.4.3(supports-color@10.2.2)) + http-proxy-middleware: 3.0.7(supports-color@10.2.2) + https-proxy-agent: 8.0.0(supports-color@10.2.2) inquirer: 8.2.7(@types/node@25.5.2) inquirer-autocomplete-prompt: 1.4.0(inquirer@8.2.7(@types/node@25.5.2)) is-docker: 4.0.0 @@ -12044,12 +12305,12 @@ snapshots: p-wait-for@6.0.0: {} - pac-proxy-agent@7.2.0: + pac-proxy-agent@7.2.0(supports-color@10.2.2): dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.4 debug: 4.4.3(supports-color@10.2.2) - get-uri: 6.0.5 + get-uri: 6.0.5(supports-color@10.2.2) http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6(supports-color@10.2.2) pac-resolver: 7.0.1 @@ -12225,7 +12486,11 @@ snapshots: mlly: 1.8.2 pathe: 2.0.3 - portfinder@1.0.38: + pluralize@2.0.0: {} + + pluralize@8.0.0: {} + + portfinder@1.0.38(supports-color@10.2.2): dependencies: async: 3.2.6 debug: 4.4.3(supports-color@10.2.2) @@ -12353,14 +12618,14 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 - proxy-agent@6.5.0: + proxy-agent@6.5.0(supports-color@10.2.2): dependencies: agent-base: 7.1.4 debug: 4.4.3(supports-color@10.2.2) http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6(supports-color@10.2.2) lru-cache: 7.18.3 - pac-proxy-agent: 7.2.0 + pac-proxy-agent: 7.2.0(supports-color@10.2.2) proxy-from-env: 1.1.0 socks-proxy-agent: 8.0.5 transitivePeerDependencies: @@ -12432,6 +12697,15 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 + rc-config-loader@4.1.4: + dependencies: + debug: 4.4.3(supports-color@10.2.2) + js-yaml: 4.3.0 + json5: 2.2.3 + require-from-string: 2.0.2 + transitivePeerDependencies: + - supports-color + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -12694,6 +12968,19 @@ snapshots: dependencies: xmlchars: 2.2.0 + secretlint@13.0.2: + dependencies: + '@secretlint/config-creator': 13.0.2 + '@secretlint/formatter': 13.0.2 + '@secretlint/node': 13.0.2 + '@secretlint/profiler': 13.0.2 + '@secretlint/resolver': 13.0.2 + '@secretlint/walker': 13.0.2 + debug: 4.4.3(supports-color@10.2.2) + read-pkg: 10.1.0 + transitivePeerDependencies: + - supports-color + secure-json-parse@4.1.0: {} semver-diff@3.1.1: @@ -12857,9 +13144,9 @@ snapshots: signal-exit@4.1.0: {} - simple-git@3.33.0: + simple-git@3.33.0(supports-color@10.2.2): dependencies: - '@kwsites/file-exists': 1.1.1 + '@kwsites/file-exists': 1.1.1(supports-color@10.2.2) '@kwsites/promise-deferred': 1.1.1 debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: @@ -12873,6 +13160,12 @@ snapshots: slashes@3.0.12: {} + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + slice-ansi@8.0.0: dependencies: ansi-styles: 6.2.3 @@ -13044,6 +13337,10 @@ snapshots: strip-json-comments@2.0.1: {} + structured-source@4.0.0: + dependencies: + boundary: 2.0.0 + stubborn-fs@2.0.0: dependencies: stubborn-utils: 1.0.2 @@ -13107,6 +13404,14 @@ snapshots: symbol-tree@3.2.4: {} + table@6.9.0: + dependencies: + ajv: 8.20.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + tagged-tag@1.0.0: {} tar-stream@3.2.0: @@ -13169,6 +13474,12 @@ snapshots: text-hex@1.0.0: {} + text-table@0.2.0: {} + + textextensions@6.11.0: + dependencies: + editions: 6.22.0 + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -13382,7 +13693,7 @@ snapshots: dependencies: crypto-random-string: 2.0.0 - universal-analytics@0.5.4: + universal-analytics@0.5.4(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) uuid: 14.0.1 @@ -13405,7 +13716,7 @@ snapshots: unpipe@1.0.0: {} - unstorage@1.17.5(@netlify/blobs@10.7.9): + unstorage@1.17.5(@netlify/blobs@10.7.9(supports-color@10.2.2)): dependencies: anymatch: 3.1.3 chokidar: 5.0.0 @@ -13495,6 +13806,8 @@ snapshots: vary@1.1.2: {} + version-range@4.15.0: {} + vite@8.0.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@25.5.2)(jiti@2.6.1)(yaml@2.8.3): dependencies: lightningcss: 1.32.0