diff --git a/.oxlintrc.json b/.oxlintrc.json index 9fa9d46..e28b7a8 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -11,6 +11,7 @@ "no-array-callback-reference": "off", "no-inline-comments": "off", "no-unsafe-assignment": "off", - "strict-boolean-expressions": "off" + "strict-boolean-expressions": "off", + "prefer-readonly-parameter-types": "off" } } diff --git a/README.md b/README.md index 22f33a3..6ec237e 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,11 @@ Run `ssm-secrets --help` or `ssm-secrets --help` for details. ### 🔐 Authenticate -Store AWS credentials in your system keyring. +Store AWS authentication data in your system keyring. + +#### Static credentials + +Store long-lived AWS credentials: ```bash ssm-secrets auth @@ -80,11 +84,34 @@ AWS Access Key ID: AWS Secret Access Key: ``` -These are securely saved using your OS’s secret store: +#### AWS SSO + +Store AWS SSO authentication state: + +```bash +ssm-secrets auth --sso-start-url https://d-zzzzzz.awsapps.com/start +``` + +Options: + +* `--region ` + AWS region for SSM and AWS SSO/OIDC endpoints. Defaults to `eu-central-1`. -* Linux: Secret Service / GNOME Keyring / KWallet -* macOS: Keychain Access -* Windows: Credential Manager +* `--account-id ` + Use a specific AWS SSO account instead of selecting interactively. + +* `--role-name ` + Use a specific AWS SSO role instead of selecting interactively. + +During SSO authentication, the CLI opens the AWS login URL in your browser and also prints the URL and device code as a fallback. Temporary AWS credentials, SSO tokens, client registration, account ID, role name, region, and start URL are stored in the system keyring. Later commands silently refresh credentials when possible. If silent refresh is no longer possible and browser refresh was allowed during auth, the command opens the browser again and continues after login. + +#### Wipe credentials + +Delete all stored credentials: + +```bash +ssm-secrets wipe-credentials +``` ### 📜 List parameters @@ -251,7 +278,11 @@ Credentials are stored securely in the system keyring via [`keyring-node`](https | macOS | macOS Keychain | | Windows | Credential Manager | -Nothing sensitive is stored in plaintext. +Nothing sensitive is stored in plaintext. Static AWS credentials and AWS SSO tokens are stored in the OS keyring. + +Current versions store credentials using keyring user with `/v2` suffix. For compatibility with older `ssm-secrets` versions, static auth also writes legacy static credentials to the default keyring target. Current versions prefer `v2` credentials and fall back to legacy static credentials when `v2` credentials are missing. + +SSO auth is stored only under the `/v2` suffix because older versions do not support SSO. If legacy static credentials exist, older versions can keep using them. `ssm-secrets wipe-credentials` deletes both `v2` and legacy credentials. ## 🧠 Example workflow diff --git a/package.json b/package.json index c1aedcc..dc506c3 100644 --- a/package.json +++ b/package.json @@ -39,20 +39,24 @@ "license": "MIT", "packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34", "dependencies": { - "@aws-sdk/client-ssm": "^3.990.0", - "@inquirer/input": "^5.0.6", - "@inquirer/password": "^5.0.6", - "@napi-rs/keyring": "^1.2.0", + "@aws-sdk/client-ssm": "^3.1056.0", + "@aws-sdk/client-sso": "^3.1056.0", + "@aws-sdk/client-sso-oidc": "^3.1056.0", + "@inquirer/confirm": "^6.1.1", + "@inquirer/input": "^5.1.2", + "@inquirer/password": "^5.1.1", + "@inquirer/select": "^5.2.1", + "@napi-rs/keyring": "^1.3.0", "commander": "^14.0.3", - "dotenv": "^17.3.1", - "zod": "^4.3.6" + "dotenv": "^17.4.2", + "zod": "^4.4.3" }, "devDependencies": { - "@stylistic/eslint-plugin": "^5.8.0", - "@types/node": "^24.10.13", - "@typescript-eslint/parser": "^8.55.0", - "eslint": "^9.39.2", - "oxlint": "^1.48.0", + "@stylistic/eslint-plugin": "^5.10.0", + "@types/node": "^24.13.2", + "@typescript-eslint/parser": "^8.61.0", + "eslint": "^9.39.4", + "oxlint": "^1.69.0", "oxlint-tsgolint": "^0.13.0", "typescript": "^5.9.3" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0442bc..30db255 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,42 +9,54 @@ importers: .: dependencies: '@aws-sdk/client-ssm': - specifier: ^3.990.0 - version: 3.990.0 + specifier: ^3.1056.0 + version: 3.1056.0 + '@aws-sdk/client-sso': + specifier: ^3.1056.0 + version: 3.1056.0 + '@aws-sdk/client-sso-oidc': + specifier: ^3.1056.0 + version: 3.1056.0 + '@inquirer/confirm': + specifier: ^6.1.1 + version: 6.1.1(@types/node@24.13.2) '@inquirer/input': - specifier: ^5.0.6 - version: 5.0.6(@types/node@24.10.13) + specifier: ^5.1.2 + version: 5.1.2(@types/node@24.13.2) '@inquirer/password': - specifier: ^5.0.6 - version: 5.0.6(@types/node@24.10.13) + specifier: ^5.1.1 + version: 5.1.1(@types/node@24.13.2) + '@inquirer/select': + specifier: ^5.2.1 + version: 5.2.1(@types/node@24.13.2) '@napi-rs/keyring': - specifier: ^1.2.0 - version: 1.2.0 + specifier: ^1.3.0 + version: 1.3.0 commander: specifier: ^14.0.3 version: 14.0.3 dotenv: - specifier: ^17.3.1 - version: 17.3.1 + specifier: ^17.4.2 + version: 17.4.2 zod: - specifier: ^4.3.6 - version: 4.3.6 + specifier: ^4.4.3 + version: 4.4.3 devDependencies: '@stylistic/eslint-plugin': - specifier: ^5.8.0 - version: 5.8.0(eslint@9.39.2) + specifier: ^5.10.0 + version: 5.10.0(eslint@9.39.4) '@types/node': - specifier: ^24.10.13 - version: 24.10.13 + specifier: ^24.13.2 + version: 24.13.2 '@typescript-eslint/parser': - specifier: ^8.55.0 - version: 8.55.0(eslint@9.39.2)(typescript@5.9.3) + specifier: ^8.61.0 + version: 8.61.0(eslint@9.39.4)(typescript@5.9.3) eslint: - specifier: ^9.39.2 - version: 9.39.2 + specifier: ^9.39.4 + version: 9.39.4 oxlint: - specifier: ^1.48.0 - version: 1.48.0(oxlint-tsgolint@0.13.0) + specifier: ^1.69.0 + version: 1.69.0(oxlint-tsgolint@0.13.0) oxlint-tsgolint: specifier: ^0.13.0 version: 0.13.0 @@ -54,6 +66,10 @@ importers: packages: + '@aws-crypto/crc32@5.2.0': + resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} + engines: {node: '>=16.0.0'} + '@aws-crypto/sha256-browser@5.2.0': resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} @@ -67,108 +83,80 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-ssm@3.990.0': - resolution: {integrity: sha512-SQFrsCsYqgpY6HyeUGfNPepFi0CBTuJri8t9+x3Cvs5zl425XfbdfQtbQi+ecbNO8QICMD45hkBO/iP3wATSpA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/client-sso@3.990.0': - resolution: {integrity: sha512-xTEaPjZwOqVjGbLOP7qzwbdOWJOo1ne2mUhTZwEBBkPvNk4aXB/vcYwWwrjoSWUqtit4+GDbO75ePc/S6TUJYQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/core@3.973.10': - resolution: {integrity: sha512-4u/FbyyT3JqzfsESI70iFg6e2yp87MB5kS2qcxIA66m52VSTN1fvuvbCY1h/LKq1LvuxIrlJ1ItcyjvcKoaPLg==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-env@3.972.8': - resolution: {integrity: sha512-r91OOPAcHnLCSxaeu/lzZAVRCZ/CtTNuwmJkUwpwSDshUrP7bkX1OmFn2nUMWd9kN53Q4cEo8b7226G4olt2Mg==} + '@aws-sdk/client-ssm@3.1056.0': + resolution: {integrity: sha512-S367Brp+IyAc76US26MlOgYXvcMJMqKQi1gR4GcUI5K7NgG/f3AsICXV9Hg+KjqurSyyb8B2w8SgDJ20VT/bNg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.10': - resolution: {integrity: sha512-DTtuyXSWB+KetzLcWaSahLJCtTUe/3SXtlGp4ik9PCe9xD6swHEkG8n8/BNsQ9dsihb9nhFvuUB4DpdBGDcvVg==} + '@aws-sdk/client-sso-oidc@3.1056.0': + resolution: {integrity: sha512-MaPK80FjdbbMQf7OmhWboU0M8CyfVtFGb6tJDm0eZQOchkVuZR0ai7SkvRq3r3Y+qjTEclbuzJzagje04l2FWQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.8': - resolution: {integrity: sha512-n2dMn21gvbBIEh00E8Nb+j01U/9rSqFIamWRdGm/mE5e+vHQ9g0cBNdrYFlM6AAiryKVHZmShWT9D1JAWJ3ISw==} + '@aws-sdk/client-sso@3.1056.0': + resolution: {integrity: sha512-ykznc7lMnCnpJvaSIyBRRVOXTIWSwnSQz7clMqkJ5/Me7c3Ar5+Uk0fST0jfQ5JN85mP484icprSJf+TqpMmxA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.8': - resolution: {integrity: sha512-rMFuVids8ICge/X9DF5pRdGMIvkVhDV9IQFQ8aTYk6iF0rl9jOUa1C3kjepxiXUlpgJQT++sLZkT9n0TMLHhQw==} + '@aws-sdk/core@3.974.15': + resolution: {integrity: sha512-UpA0rTGW/tHGITcCqHisbuuEPraYg9GG+mWmXjY5+RxZBMLGe6aL9oe0ix50LztwAcPIkGZLH0yWdMIkCM10hw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.9': - resolution: {integrity: sha512-LfJfO0ClRAq2WsSnA9JuUsNyIicD2eyputxSlSL0EiMrtxOxELLRG6ZVYDf/a1HCepaYPXeakH4y8D5OLCauag==} + '@aws-sdk/credential-provider-env@3.972.41': + resolution: {integrity: sha512-n1EbJ98yvPWWdHZZv8bRBMqqDQJrtgtxyJ4xLy2Uqrh25BCOZQ7nnS1CsFXvuH8r0b0KVHDZEGEH5FxmEMP8jg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.8': - resolution: {integrity: sha512-6cg26ffFltxM51OOS8NH7oE41EccaYiNlbd5VgUYwhiGCySLfHoGuGrLm2rMB4zhy+IO5nWIIG0HiodX8zdvHA==} + '@aws-sdk/credential-provider-http@3.972.43': + resolution: {integrity: sha512-TT76RN1NkI9WoyZqCNxOw6/WBMF7pYOTJcXbMokNFU+euSG40Kaf/t/FhDACVZWP+43wEM6ZynIPIkzS1wR1iA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.8': - resolution: {integrity: sha512-35kqmFOVU1n26SNv+U37sM8b2TzG8LyqAcd6iM9gprqxyHEh/8IM3gzN4Jzufs3qM6IrH8e43ryZWYdvfVzzKQ==} + '@aws-sdk/credential-provider-ini@3.972.45': + resolution: {integrity: sha512-sJe5ZWibO4s7RWjFQ8Zol76KxoJcIYyEZH1/wxQSBMSIAAxzaJ8cS/ITAaIHWUQvDKQdt18+cJAHKWB7n1Jmrg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.8': - resolution: {integrity: sha512-CZhN1bOc1J3ubQPqbmr5b4KaMJBgdDvYsmEIZuX++wFlzmZsKj1bwkaiTEb5U2V7kXuzLlpF5HJSOM9eY/6nGA==} + '@aws-sdk/credential-provider-login@3.972.45': + resolution: {integrity: sha512-MZQv4SNjByk1iOKmrqmzcUF/uCB05wjvEHyXKxmGQTUANTIVayX6HPUF0bzkWLvtnkH7sAn9kUCfkXbSpj9sDA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-host-header@3.972.3': - resolution: {integrity: sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA==} + '@aws-sdk/credential-provider-node@3.972.46': + resolution: {integrity: sha512-cS4w0jzDRb1jOlkiJS3y80OxddHzkky/MN9k3NYs5jganNKVLjF0lpvjlwS118oGMr3cdAfOlVdo8gLurTSE7w==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-logger@3.972.3': - resolution: {integrity: sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA==} + '@aws-sdk/credential-provider-process@3.972.41': + resolution: {integrity: sha512-7I/n1zkysouLOWvkEhjNEP4vMnD2v4kzzr3/3QBdrripEpn7ap1/I5DF3Hou1SUqkKWo1f3oPGMyFAA1FAMvsQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-recursion-detection@3.972.3': - resolution: {integrity: sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q==} + '@aws-sdk/credential-provider-sso@3.972.45': + resolution: {integrity: sha512-oHgbz/eFD8IKiksqDsz9ZMU4A59BpQq4QwJedBnGD80ZqYcHPPHZBwjBnxLVkB7iRVVHWpDclR8yWdD2PkQIUA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.10': - resolution: {integrity: sha512-bBEL8CAqPQkI91ZM5a9xnFAzedpzH6NYCOtNyLarRAzTUTFN2DKqaC60ugBa7pnU1jSi4mA7WAXBsrod7nJltg==} + '@aws-sdk/credential-provider-web-identity@3.972.45': + resolution: {integrity: sha512-CDhzKdb2onv5bpnjn/acgdNmJOQthPDLsPizU7rZflsEcgMMp8Mlri+U5hdxf8ldvZJpvM3vLU6D56vfJm5AMQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/nested-clients@3.990.0': - resolution: {integrity: sha512-3NA0s66vsy8g7hPh36ZsUgO4SiMyrhwcYvuuNK1PezO52vX3hXDW4pQrC6OQLGKGJV0o6tbEyQtXb/mPs8zg8w==} + '@aws-sdk/nested-clients@3.997.13': + resolution: {integrity: sha512-2pA6eyb5nSo/ZD2cayhOTEMoGQYgspq0RI05GDLkzQ3ajZ6isS6waV6E92Am/hz4LIlLUTrbwPLurJ/fuiHvkg==} engines: {node: '>=20.0.0'} - '@aws-sdk/region-config-resolver@3.972.3': - resolution: {integrity: sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==} + '@aws-sdk/signature-v4-multi-region@3.996.30': + resolution: {integrity: sha512-HULDLMVzkmTSEv6//7kx2kRevp/VYUpm8hJNNFbmhxDn0fUiGTxVcM9yg31TukvTq8nyOBDUN2gH0o5IRbKjdw==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.990.0': - resolution: {integrity: sha512-L3BtUb2v9XmYgQdfGBzbBtKMXaP5fV973y3Qdxeevs6oUTVXFmi/mV1+LnScA/1wVPJC9/hlK+1o5vbt7cG7EQ==} + '@aws-sdk/token-providers@3.1056.0': + resolution: {integrity: sha512-81duvlltQlsfn5K+o8zILcystBRdbT1G2JJYVCML5NZHBz4CL/zf+sAemCtBh/uh6RQUMyInGeZLQ7/8igZhbA==} engines: {node: '>=20.0.0'} - '@aws-sdk/types@3.973.1': - resolution: {integrity: sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg==} + '@aws-sdk/types@3.973.9': + resolution: {integrity: sha512-kuBfgQVdcz5Bmapc4A13YbpVw/pXkesfhetcFYwbntqas8sF41OHyd4o28+/TG2ZQdHBsv90Lsu5y6oitvYCdg==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-endpoints@3.990.0': - resolution: {integrity: sha512-kVwtDc9LNI3tQZHEMNbkLIOpeDK8sRSTuT8eMnzGY+O+JImPisfSTjdh+jw9OTznu+MYZjQsv0258sazVKunYg==} + '@aws-sdk/util-locate-window@3.965.5': + resolution: {integrity: sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-locate-window@3.893.0': - resolution: {integrity: sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg==} - engines: {node: '>=18.0.0'} - - '@aws-sdk/util-user-agent-browser@3.972.3': - resolution: {integrity: sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw==} - - '@aws-sdk/util-user-agent-node@3.972.8': - resolution: {integrity: sha512-XJZuT0LWsFCW1C8dEpPAXSa7h6Pb3krr2y//1X0Zidpcl0vmgY5nL/X0JuBZlntpBzaN3+U4hvKjuijyiiR8zw==} - engines: {node: '>=20.0.0'} - peerDependencies: - aws-crt: '>=1.0.0' - peerDependenciesMeta: - aws-crt: - optional: true - - '@aws-sdk/xml-builder@3.972.4': - resolution: {integrity: sha512-0zJ05ANfYqI6+rGqj8samZBFod0dPPousBjLEqg8WdxSgbMAkRgLyn81lP215Do0rFJ/17LIXwr7q0yK24mP6Q==} + '@aws-sdk/xml-builder@3.972.26': + resolution: {integrity: sha512-cDbrqvDS73whl6YAPSPq0U6whzG6UWI9PuWh0wrUuGoZexhWEqhdunbukV7iBoaWnFV1AODutM5hOD6rtn439g==} engines: {node: '>=20.0.0'} - '@aws/lambda-invoke-store@0.2.3': - resolution: {integrity: sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw==} + '@aws/lambda-invoke-store@0.2.4': + resolution: {integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==} engines: {node: '>=18.0.0'} '@eslint-community/eslint-utils@4.9.1': @@ -181,8 +169,8 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.21.1': - resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/config-helpers@0.4.2': @@ -193,12 +181,12 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.39.2': - resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.7': @@ -225,126 +213,147 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@inquirer/ansi@2.0.3': - resolution: {integrity: sha512-g44zhR3NIKVs0zUesa4iMzExmZpLUdTLRMCStqX3GE5NT6VkPcxQGJ+uC8tDgBUC/vB1rUhUd55cOf++4NZcmw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/ansi@2.0.7': + resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/core@11.1.3': - resolution: {integrity: sha512-TBAGPDGvpwFSQ4nkawQzq5/X7DhElANjvKeUtcjpVnBIfuH/OEu4M+79R3+bGPtwxST4DOIGRtF933mUH2bRVw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/confirm@6.1.1': + resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/figures@2.0.3': - resolution: {integrity: sha512-y09iGt3JKoOCBQ3w4YrSJdokcD8ciSlMIWsD+auPu+OZpfxLuyz+gICAQ6GCBOmJJt4KEQGHuZSVff2jiNOy7g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/core@11.2.1': + resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@2.0.7': + resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + + '@inquirer/input@5.1.2': + resolution: {integrity: sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@inquirer/input@5.0.6': - resolution: {integrity: sha512-RZsJcjMJA3QNI9q9OiAi1fAom+Pb8on6alJB1Teh5jjKaiG5C79P69cG955ZRfgPdxTmI4uyhf33+94Xj7xWig==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/password@5.1.1': + resolution: {integrity: sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/password@5.0.6': - resolution: {integrity: sha512-c4BT4SB79iYwPhtGVBSvrlTnn4oFSYnwocafmktpay8RK75T2c2+fLlR0i1Cxw0QOhdy/YULdmpHoy1sOrPzvA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/select@5.2.1': + resolution: {integrity: sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@inquirer/type@4.0.3': - resolution: {integrity: sha512-cKZN7qcXOpj1h+1eTTcGDVLaBIHNMT1Rz9JqJP5MnEJ0JhgVWllx7H/tahUp5YEK1qaByH2Itb8wLG/iScD5kw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/type@4.0.7': + resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: '@types/node': optional: true - '@napi-rs/keyring-darwin-arm64@1.2.0': - resolution: {integrity: sha512-CA83rDeyONDADO25JLZsh3eHY8yTEtm/RS6ecPsY+1v+dSawzT9GywBMu2r6uOp1IEhQs/xAfxgybGAFr17lSA==} + '@napi-rs/keyring-darwin-arm64@1.3.0': + resolution: {integrity: sha512-pl76hJvdYUBn6I24bXiOBMA9nbDapo3I5B+f3OorjDU4dUMSypXeKbOVehJe8fhgTiH24flMyTS3aAIy43xegQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@napi-rs/keyring-darwin-x64@1.2.0': - resolution: {integrity: sha512-dBHjtKRCj4ByfnfqIKIJLo3wueQNJhLRyuxtX/rR4K/XtcS7VLlRD01XXizjpre54vpmObj63w+ZpHG+mGM8uA==} + '@napi-rs/keyring-darwin-x64@1.3.0': + resolution: {integrity: sha512-YcJtEV5LA3cvA4z3BurgxH5IhTsW1JfIvcAAcqcecwk06Si9F9NqkxbZVIfDwQ8oRHgaBmT3zZJnLAotCrVahw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@napi-rs/keyring-freebsd-x64@1.2.0': - resolution: {integrity: sha512-DPZFr11pNJSnaoh0dzSUNF+T6ORhy3CkzUT3uGixbA71cAOPJ24iG8e8QrLOkuC/StWrAku3gBnth2XMWOcR3Q==} + '@napi-rs/keyring-freebsd-x64@1.3.0': + resolution: {integrity: sha512-vlLf31TGhfRAaxLDBhg8b89ss0HHD/lyNmL5F3UjSaz5CUXElsJmKYq9fqA/B+cZKUEUcLHHGhF0I/CqcFdaVw==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@napi-rs/keyring-linux-arm-gnueabihf@1.2.0': - resolution: {integrity: sha512-8xv6DyEMlvRdqJzp4F39RLUmmTQsLcGYYv/3eIfZNZN1O5257tHxTrFYqAsny659rJJK2EKeSa7PhrSibQqRWQ==} + '@napi-rs/keyring-linux-arm-gnueabihf@1.3.0': + resolution: {integrity: sha512-KiWdMMu/Inz/bHHIAGrnF7r54FZDYXuHO6UFF/rhIrshUsxbMG1Rl9lEymNtqqsVo927G0VYcb02FzWQ3iBQRQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@napi-rs/keyring-linux-arm64-gnu@1.2.0': - resolution: {integrity: sha512-Pu2V6Py+PBt7inryEecirl+t+ti8bhZphjP+W68iVaXHUxLdWmkgL9KI1VkbRHbx5k8K5Tew9OP218YfmVguIA==} + '@napi-rs/keyring-linux-arm64-gnu@1.3.0': + resolution: {integrity: sha512-eyKGpY40lm9Jvs1aD294XRH4y7+TlJM0YVAryZeXA6TX0mb4gMkxVXwSQv7MCwgah7raeUd0dKUb4BPAYIgcMg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@napi-rs/keyring-linux-arm64-musl@1.2.0': - resolution: {integrity: sha512-8TDymrpC4P1a9iDEaegT7RnrkmrJN5eNZh3Im3UEV5PPYGtrb82CRxsuFohthCWQW81O483u1bu+25+XA4nKUw==} + '@napi-rs/keyring-linux-arm64-musl@1.3.0': + resolution: {integrity: sha512-iIK6JWHXAJqDrEyLY3TmswwloVyt2vj+04TZnew+uSJ9gnDO8EwRbp3/iw3LpWaXiDO7VomGO6y8I0Id8uBZSw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@napi-rs/keyring-linux-riscv64-gnu@1.2.0': - resolution: {integrity: sha512-awsB5XI1MYL7fwfjMDGmKOWvNgJEO7mM7iVEMS0fO39f0kVJnOSjlu7RHcXAF0LOx+0VfF3oxbWqJmZbvRCRHw==} + '@napi-rs/keyring-linux-riscv64-gnu@1.3.0': + resolution: {integrity: sha512-/PGqrwn6EwgtK6vccASSXJRfOSP4vN1F4ASsIQ+7MdrK6hNvAJ1FZPrIuD5gGGdxezo3F++To2Wq7DbuGIeuNQ==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] - '@napi-rs/keyring-linux-x64-gnu@1.2.0': - resolution: {integrity: sha512-8E+7z4tbxSJXxIBqA+vfB1CGajpCDRyTyqXkBig5NtASrv4YXcntSo96Iah2QDR5zD3dSTsmbqJudcj9rKKuHQ==} + '@napi-rs/keyring-linux-x64-gnu@1.3.0': + resolution: {integrity: sha512-2PDK1WKWTu9lBGq9VvNEkSlQD3O7YwVpmnyN2M3cy4v7NJ/8gDMd9GXv3G+FVXN13uhp4gnnPBS+ScefmEeD2A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@napi-rs/keyring-linux-x64-musl@1.2.0': - resolution: {integrity: sha512-8RZ8yVEnmWr/3BxKgBSzmgntI7lNEsY7xouNfOsQkuVAiCNmxzJwETspzK3PQ2FHtDxgz5vHQDEBVGMyM4hUHA==} + '@napi-rs/keyring-linux-x64-musl@1.3.0': + resolution: {integrity: sha512-oJ2HkX8YUo46QBkn0pG+HuIKQNqr523q6vBobCn+P95s4C4K6/kLBqHY/1bg5J4ap31DzsznhnFKcfBNBsjCnw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@napi-rs/keyring-win32-arm64-msvc@1.2.0': - resolution: {integrity: sha512-AoqaDZpQ6KPE19VBLpxyORcp+yWmHI9Xs9Oo0PJ4mfHma4nFSLVdhAubJCxdlNptHe5va7ghGCHj3L9Akiv4cQ==} + '@napi-rs/keyring-win32-arm64-msvc@1.3.0': + resolution: {integrity: sha512-tOd3c/uAaeoE4ycVlmAdSvygz0Zt3zdca6Y7gokBeIbaRDWpjDIUOpU3MvML59XAaqyuKGsVVu0F/DZb1lHPmw==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@napi-rs/keyring-win32-ia32-msvc@1.2.0': - resolution: {integrity: sha512-EYL+EEI6bCsYi3LfwcQdnX3P/R76ENKNn+3PmpGheBsUFLuh0gQuP7aMVHM4rTw6UVe+L3vCLZSptq/oeacz0A==} + '@napi-rs/keyring-win32-ia32-msvc@1.3.0': + resolution: {integrity: sha512-sPSqeAFZMGqP1R++M2JTza7GQJJ/TpCo6JU6Vcd4jnebvOaEDs9b7eipakU1PJdSvhpC2yXMCNRk9gXfrhuwHQ==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] - '@napi-rs/keyring-win32-x64-msvc@1.2.0': - resolution: {integrity: sha512-xFlx/TsmqmCwNU9v+AVnEJgoEAlBYgzFF5Ihz1rMpPAt4qQWWkMd4sCyM1gMJ1A/GnRqRegDiQpwaxGUHFtFbA==} + '@napi-rs/keyring-win32-x64-msvc@1.3.0': + resolution: {integrity: sha512-4DnCWXwDc0HRKwyRlG5y0VhKZW2tNRQfKKfyj6IX/KWfDNyq9hn4n+GL1auyDcOO/v8PwnhmYo2+rOOqCkvvOg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@napi-rs/keyring@1.2.0': - resolution: {integrity: sha512-d0d4Oyxm+v980PEq1ZH2PmS6cvpMIRc17eYpiU47KgW+lzxklMu6+HOEOPmxrpnF/XQZ0+Q78I2mgMhbIIo/dg==} + '@napi-rs/keyring@1.3.0': + resolution: {integrity: sha512-WrOw/bcXm0f9qHkumlT1QlArXSTWqaY9sunsDpOk+yCCorCKMxvWT/a3xko4EYHVdeZoh00yI2TydXn6eyICDA==} engines: {node: '>= 10'} + '@nodable/entities@2.1.1': + resolution: {integrity: sha512-Pig3HxDIoMgjdEH8OCf/dkcTmLFjJRjWuq8jSnklu284/TKOPibSRERmOykiwmyXTtv61mP+44f3GMx0tLAyjg==} + '@oxlint-tsgolint/darwin-arm64@0.13.0': resolution: {integrity: sha512-OWQ3U+oDjjupmX0WU9oYyKF2iUOKDMLW/+zan0cd0vYIGId80xTRHHA8oXnREmK8dsMMP3nV3VXME3NH/hS0lw==} cpu: [arm64] @@ -375,301 +384,161 @@ packages: cpu: [x64] os: [win32] - '@oxlint/binding-android-arm-eabi@1.48.0': - resolution: {integrity: sha512-1Pz/stJvveO9ZO7ll4ZoEY3f6j2FiUgBLBcCRCiW6ylId9L9UKs+gn3X28m3eTnoiFCkhKwmJJ+VO6vwsu7Qtg==} + '@oxlint/binding-android-arm-eabi@1.69.0': + resolution: {integrity: sha512-DKQQbD5cZ/MYfDgDI7YGyGD9FSxABlsBsYFo5p26lloob543tP9+4N3guwdXIYJN+7HSZxLe8YJuwcOWw5qnHg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxlint/binding-android-arm64@1.48.0': - resolution: {integrity: sha512-Zc42RWGE8huo6Ht0lXKjd0NH2lWNmimQHUmD0JFcvShLOuwN+RSEE/kRakc2/0LIgOUuU/R7PaDMCOdQlPgNUQ==} + '@oxlint/binding-android-arm64@1.69.0': + resolution: {integrity: sha512-lEhb+I5pr4inux+JFwfCa1HRq3Os7NirEFQ0H1I35SVEHPm6byX0Ah47xmRha3qi6LAkxUcxViL8o/9PivjzBg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxlint/binding-darwin-arm64@1.48.0': - resolution: {integrity: sha512-jgZs563/4vaG5jH2RSt2TSh8A2jwsFdmhLXrElMdm3Mmto0HPf85FgInLSNi9HcwzQFvkYV8JofcoUg2GH1HTA==} + '@oxlint/binding-darwin-arm64@1.69.0': + resolution: {integrity: sha512-GY2YE8lOZW59BW1Ia1y+1gR0XyjrZRvVWHAr8LGeGhYHE0OQJ/7cRKXTkx1P+E9/6awEc3SX8a68SFTjh/E//A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-x64@1.48.0': - resolution: {integrity: sha512-kvo87BujEUjCJREuWDC4aPh1WoXCRFFWE4C7uF6wuoMw2f6N2hypA/cHHcYn9DdL8R2RrgUZPefC8JExyeIMKA==} + '@oxlint/binding-darwin-x64@1.69.0': + resolution: {integrity: sha512-ax1oZnOjHX3LB7myQyHEaQkDwfLb6str3/nSP6O7EVUviQGNkEGzGV0EqcBJWK+Ufwx0l4xPgyYayurvhAdl2Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxlint/binding-freebsd-x64@1.48.0': - resolution: {integrity: sha512-eyzzPaHQKn0RIM+ueDfgfJF2RU//Wp4oaKs2JVoVYcM5HjbCL36+O0S3wO5Xe1NWpcZIG3cEHc/SuOCDRqZDSg==} + '@oxlint/binding-freebsd-x64@1.69.0': + resolution: {integrity: sha512-kHWeHv4g2h8NY+mpCxzCtY4uerMJWTN/TSnNj1CPbakFpHEJ6cTya2wWV0pDSYWOJ2+0UiEbhn3AtXxHtsnKjg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxlint/binding-linux-arm-gnueabihf@1.48.0': - resolution: {integrity: sha512-p3kSloztK7GRO7FyO3u38UCjZxQTl92VaLDsMQAq0eGoiNmeeEF1KPeE4+Fr+LSkQhF8WvJKSuls6TwOlurdPA==} + '@oxlint/binding-linux-arm-gnueabihf@1.69.0': + resolution: {integrity: sha512-gq84vM1a1oEehXo27YCDzGVcxPsZDI1yswZwz2Da1/cbnWtrL16XZZnz0G/+gIU8edtHpfjxq5c+vWEHqJfWoQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.48.0': - resolution: {integrity: sha512-uWM+wiTqLW/V0ZmY/eyTWs8ykhIkzU+K2tz/8m35YepYEzohiUGRbnkpAFXj2ioXpQL+GUe5vmM3SLH6ozlfFw==} + '@oxlint/binding-linux-arm-musleabihf@1.69.0': + resolution: {integrity: sha512-kIqEa98JQ0VRyrcncxA417m2AzasqTlD+FyVT1AksjvjkqQcvm7pBWYvoW3/mpyOP2XYvi5nSCCTIe6De1yu5g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm64-gnu@1.48.0': - resolution: {integrity: sha512-OhQNPjs/OICaYqxYJjKKMaIY7p3nJ9IirXcFoHKD+CQE1BZFCeUUAknMzUeLclDCfudH9Vb/UgjFm8+ZM5puAg==} + '@oxlint/binding-linux-arm64-gnu@1.69.0': + resolution: {integrity: sha512-j+xYiXozxGWx2cpjCrwwGR4awTxPFsRv3JZrv23RCogEPMc4R7UqjHW47p/RG0aRlbWiROCJ8coUfCwy0dvzHA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxlint/binding-linux-arm64-musl@1.48.0': - resolution: {integrity: sha512-adu5txuwGvQ4C4fjYHJD+vnY+OCwCixBzn7J3KF3iWlVHBBImcosSv+Ye+fbMMJui4HGjifNXzonjKm9pXmOiw==} + '@oxlint/binding-linux-arm64-musl@1.69.0': + resolution: {integrity: sha512-xEPpNppTfN1l/nM7gYSf9iocscu/as+p/7vxkLeLEKnYU+09Dm+5V6IhDYDh+Uz6FajEupWwCLt5SOG0y1PCKg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxlint/binding-linux-ppc64-gnu@1.48.0': - resolution: {integrity: sha512-inlQQRUnHCny/7b7wA6NjEoJSSZPNea4qnDhWyeqBYWx8ukf2kzNDSiamfhOw6bfAYPm/PVlkVRYaNXQbkLeTQ==} + '@oxlint/binding-linux-ppc64-gnu@1.69.0': + resolution: {integrity: sha512-Ug0+eU7HJBlek+SjklYH62IlOMirEJsdxpihH0kSqX0XdrDD4NdHpQc10fK1JC35yn6KrrcN+uYzlHD38XAf8Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - '@oxlint/binding-linux-riscv64-gnu@1.48.0': - resolution: {integrity: sha512-YiJx6sW6bYebQDZRVWLKm/Drswx/hcjIgbLIhULSn0rRcBKc7d9V6mkqPjKDbhcxJgQD5Zi0yVccJiOdF40AWA==} + '@oxlint/binding-linux-riscv64-gnu@1.69.0': + resolution: {integrity: sha512-iEyI3GIg0l/s3G4qy2TlaaWKdzj4PJJStwtlocpDTC00PY9hZueotf6OKUj9+yfQh0lrpBW/pLMgTztbAHKJEg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxlint/binding-linux-riscv64-musl@1.48.0': - resolution: {integrity: sha512-zwSqxMgmb2ITamNfDv9Q9EKBc/4ZhCBP9gkg2hhcgR6sEVGPUDl1AKPC89CBKMxkmPUi3685C38EvqtZn5OtHw==} + '@oxlint/binding-linux-riscv64-musl@1.69.0': + resolution: {integrity: sha512-NjHjpiI4WIKSMwuoJSZi5VToPeoYOS1FR52HLIDG6lidMdqquusgtODb4iLk0+lb1q3Z0nv2/aPRcC/olmpQGg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxlint/binding-linux-s390x-gnu@1.48.0': - resolution: {integrity: sha512-c/+2oUWAOsQB5JTem0rW8ODlZllF6pAtGSGXoLSvPTonKI1vAwaKhD9Qw1X36jRbcI3Etkpu/9z/RRjMba8vFQ==} + '@oxlint/binding-linux-s390x-gnu@1.69.0': + resolution: {integrity: sha512-Ai/prDewoItkDXbp38gwGZi41DycZbUTZJ3UidwoHgQC0/DaqC2TGdtBTQLJ6hSD+SAxASzh8+/eSBPmxfOacA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@oxlint/binding-linux-x64-gnu@1.48.0': - resolution: {integrity: sha512-PhauDqeFW5DGed6QxCY5lXZYKSlcBdCXJnH03ZNU6QmDZ0BFM/zSy1oPT2MNb1Afx1G6yOOVk8ErjWsQ7c59ng==} + '@oxlint/binding-linux-x64-gnu@1.69.0': + resolution: {integrity: sha512-Gt3KHgp46mRKz4sJeaASmKvD8ayXookRw07RMf+NowhEztGGDZ7VrXpoW96XuKJLjFukWizOFVNjmYb/u7caNQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxlint/binding-linux-x64-musl@1.48.0': - resolution: {integrity: sha512-6d7LIFFZGiavbHndhf1cK9kG9qmy2Dmr37sV9Ep7j3H+ciFdKSuOzdLh85mEUYMih+b+esMDlF5DU0WQRZPQjw==} + '@oxlint/binding-linux-x64-musl@1.69.0': + resolution: {integrity: sha512-7tQhJ2+p/oHv1zcfnjYI7YVzC/7iBaVOfIvFYtxdJ5F45mWgEdrCyXZXZGfiLey5t/5JhOhsaMnnv1kAzckd7g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxlint/binding-openharmony-arm64@1.48.0': - resolution: {integrity: sha512-r+0KK9lK6vFp3tXAgDMOW32o12dxvKS3B9La1uYMGdWAMoSeu2RzG34KmzSpXu6MyLDl4aSVyZLFM8KGdEjwaw==} + '@oxlint/binding-openharmony-arm64@1.69.0': + resolution: {integrity: sha512-vmWz6TKp/3hfA4lksR0zHBv/6xuX1jhym6eqOjdH2DXsDDHZWcp2f0KG0VCAnlVbIrjk29G4wAWMXb/Hn1YobA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxlint/binding-win32-arm64-msvc@1.48.0': - resolution: {integrity: sha512-Nkw/MocyT3HSp0OJsKPXrcbxZqSPMTYnLLfsqsoiFKoL1ppVNL65MFa7vuTxJehPlBkjy+95gUgacZtuNMECrg==} + '@oxlint/binding-win32-arm64-msvc@1.69.0': + resolution: {integrity: sha512-9RExaLgmaw6IoIkU9cTpT71mLfI0xZ86iZH8x518LVsOkjquJMYqb9P7KpC8lgd1t0Dxs41p2pxynq4XR3Ttzw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.48.0': - resolution: {integrity: sha512-reO1SpefvRmeZSP+WeyWkQd1ArxxDD1MyKgMUKuB8lNuUoxk9QEohYtKnsfsxJuFwMT0JTr7p9wZjouA85GzGQ==} + '@oxlint/binding-win32-ia32-msvc@1.69.0': + resolution: {integrity: sha512-1907kRPF8/PrcIw1E7LMs9JbVrpgnt/MvFdss3an8oDkYNAACXzTntV3t3869ZZhMZxb2AzRGbz1pA/jdFatXA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.48.0': - resolution: {integrity: sha512-T6zwhfcsrorqAybkOglZdPkTLlEwipbtdO1qjE+flbawvwOMsISoyiuaa7vM7zEyfq1hmDvMq1ndvkYFioranA==} + '@oxlint/binding-win32-x64-msvc@1.69.0': + resolution: {integrity: sha512-w8SOXv3mT9Fi6jY8OXdXCfnvX/3KNLXGNr4HEz2TA7S4Mv/PYAOmpB8y/ge40mxvBMgGNaSaaDwZpAsQn7HtWA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@smithy/abort-controller@4.2.8': - resolution: {integrity: sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==} - engines: {node: '>=18.0.0'} - - '@smithy/config-resolver@4.4.6': - resolution: {integrity: sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==} - engines: {node: '>=18.0.0'} - - '@smithy/core@3.23.0': - resolution: {integrity: sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg==} - engines: {node: '>=18.0.0'} - - '@smithy/credential-provider-imds@4.2.8': - resolution: {integrity: sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==} - engines: {node: '>=18.0.0'} - - '@smithy/fetch-http-handler@5.3.9': - resolution: {integrity: sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==} + '@smithy/core@3.24.5': + resolution: {integrity: sha512-Kt8phUg45M15EjhYAbZ+fFikYneijLu9Liugz8ZsYz2i8j0hzGv27LWKpEHYRfvj+LyCOSijpcR/2i8RouV+cA==} engines: {node: '>=18.0.0'} - '@smithy/hash-node@4.2.8': - resolution: {integrity: sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==} + '@smithy/credential-provider-imds@4.3.6': + resolution: {integrity: sha512-tHhdiWZfG1ZIh2YcRfPJmY2gHcBmqbAzqm3ER4TIDFYsSEqTD5tICT7cgQ/kI8LRakxp12myOYyK68XPn7MnHw==} engines: {node: '>=18.0.0'} - '@smithy/invalid-dependency@4.2.8': - resolution: {integrity: sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==} + '@smithy/fetch-http-handler@5.4.5': + resolution: {integrity: sha512-SK3VMeH0fibgdTg2QeB+O4p7Yy/2E5HBOHJeC58FshkDdeuX8lOgO7PfjYfLyPLP1ch55j91cQqKBzDS0mRjSQ==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} - '@smithy/is-array-buffer@4.2.0': - resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-content-length@4.2.8': - resolution: {integrity: sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-endpoint@4.4.14': - resolution: {integrity: sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-retry@4.4.31': - resolution: {integrity: sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-serde@4.2.9': - resolution: {integrity: sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==} - engines: {node: '>=18.0.0'} - - '@smithy/middleware-stack@4.2.8': - resolution: {integrity: sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==} - engines: {node: '>=18.0.0'} - - '@smithy/node-config-provider@4.3.8': - resolution: {integrity: sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==} - engines: {node: '>=18.0.0'} - - '@smithy/node-http-handler@4.4.10': - resolution: {integrity: sha512-u4YeUwOWRZaHbWaebvrs3UhwQwj+2VNmcVCwXcYTvPIuVyM7Ex1ftAj+fdbG/P4AkBwLq/+SKn+ydOI4ZJE9PA==} - engines: {node: '>=18.0.0'} - - '@smithy/property-provider@4.2.8': - resolution: {integrity: sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==} - engines: {node: '>=18.0.0'} - - '@smithy/protocol-http@5.3.8': - resolution: {integrity: sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==} - engines: {node: '>=18.0.0'} - - '@smithy/querystring-builder@4.2.8': - resolution: {integrity: sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==} - engines: {node: '>=18.0.0'} - - '@smithy/querystring-parser@4.2.8': - resolution: {integrity: sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==} - engines: {node: '>=18.0.0'} - - '@smithy/service-error-classification@4.2.8': - resolution: {integrity: sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==} - engines: {node: '>=18.0.0'} - - '@smithy/shared-ini-file-loader@4.4.3': - resolution: {integrity: sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==} - engines: {node: '>=18.0.0'} - - '@smithy/signature-v4@5.3.8': - resolution: {integrity: sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==} - engines: {node: '>=18.0.0'} - - '@smithy/smithy-client@4.11.3': - resolution: {integrity: sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg==} - engines: {node: '>=18.0.0'} - - '@smithy/types@4.12.0': - resolution: {integrity: sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==} - engines: {node: '>=18.0.0'} - - '@smithy/url-parser@4.2.8': - resolution: {integrity: sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==} - engines: {node: '>=18.0.0'} - - '@smithy/util-base64@4.3.0': - resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==} + '@smithy/node-http-handler@4.7.5': + resolution: {integrity: sha512-3dA9TQ+ybRSZ/m0wnbZhiBy4Dezjgq1Ib/ZZrYTpJDBgpoLLU/SDzZc/g0x0MNAdOJe1wPcM+x2PBRmoOur+Sw==} engines: {node: '>=18.0.0'} - '@smithy/util-body-length-browser@4.2.0': - resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==} + '@smithy/signature-v4@5.4.5': + resolution: {integrity: sha512-QBJKWGqIknH0dc9LWpfH1mkdokAx6iXYN3UcQ3eY6uIEyScuoQAhfl94ge7ozUy9WgFUdE8xsvwBjaYBbWmPNA==} engines: {node: '>=18.0.0'} - '@smithy/util-body-length-node@4.2.1': - resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==} + '@smithy/types@4.14.2': + resolution: {integrity: sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==} engines: {node: '>=18.0.0'} '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} - '@smithy/util-buffer-from@4.2.0': - resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} - engines: {node: '>=18.0.0'} - - '@smithy/util-config-provider@4.2.0': - resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} - engines: {node: '>=18.0.0'} - - '@smithy/util-defaults-mode-browser@4.3.30': - resolution: {integrity: sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng==} - engines: {node: '>=18.0.0'} - - '@smithy/util-defaults-mode-node@4.2.33': - resolution: {integrity: sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA==} - engines: {node: '>=18.0.0'} - - '@smithy/util-endpoints@3.2.8': - resolution: {integrity: sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==} - engines: {node: '>=18.0.0'} - - '@smithy/util-hex-encoding@4.2.0': - resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} - engines: {node: '>=18.0.0'} - - '@smithy/util-middleware@4.2.8': - resolution: {integrity: sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==} - engines: {node: '>=18.0.0'} - - '@smithy/util-retry@4.2.8': - resolution: {integrity: sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==} - engines: {node: '>=18.0.0'} - - '@smithy/util-stream@4.5.12': - resolution: {integrity: sha512-D8tgkrmhAX/UNeCZbqbEO3uqyghUnEmmoO9YEvRuwxjlkKKUE7FOgCJnqpTlQPe9MApdWPky58mNQQHbnCzoNg==} - engines: {node: '>=18.0.0'} - - '@smithy/util-uri-escape@4.2.0': - resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==} - engines: {node: '>=18.0.0'} - '@smithy/util-utf8@2.3.0': resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} - '@smithy/util-utf8@4.2.0': - resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} - engines: {node: '>=18.0.0'} - - '@smithy/util-waiter@4.2.8': - resolution: {integrity: sha512-n+lahlMWk+aejGuax7DPWtqav8HYnWxQwR+LCG2BgCUmaGcTe9qZCFsmw8TMg9iG75HOwhrJCX9TCJRLH+Yzqg==} - engines: {node: '>=18.0.0'} - - '@smithy/uuid@1.1.0': - resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} - engines: {node: '>=18.0.0'} - - '@stylistic/eslint-plugin@5.8.0': - resolution: {integrity: sha512-WNPVF/FfBAjyi3OA7gok8swRiImNLKI4dmV3iK/GC/0xSJR7eCzBFsw9hLZVgb1+MYNLy7aDsjohxN1hA/FIfQ==} + '@stylistic/eslint-plugin@5.10.0': + resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: '>=9.0.0' + eslint: ^9.0.0 || ^10.0.0 '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -677,44 +546,44 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@24.10.13': - resolution: {integrity: sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==} + '@types/node@24.13.2': + resolution: {integrity: sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==} - '@typescript-eslint/parser@8.55.0': - resolution: {integrity: sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==} + '@typescript-eslint/parser@8.61.0': + resolution: {integrity: sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.55.0': - resolution: {integrity: sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==} + '@typescript-eslint/project-service@8.61.0': + resolution: {integrity: sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.55.0': - resolution: {integrity: sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==} + '@typescript-eslint/scope-manager@8.61.0': + resolution: {integrity: sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.55.0': - resolution: {integrity: sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==} + '@typescript-eslint/tsconfig-utils@8.61.0': + resolution: {integrity: sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.55.0': - resolution: {integrity: sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==} + '@typescript-eslint/types@8.61.0': + resolution: {integrity: sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.55.0': - resolution: {integrity: sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==} + '@typescript-eslint/typescript-estree@8.61.0': + resolution: {integrity: sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <6.0.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.55.0': - resolution: {integrity: sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==} + '@typescript-eslint/visitor-keys@8.61.0': + resolution: {integrity: sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} acorn-jsx@5.3.2: @@ -727,8 +596,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} @@ -740,14 +609,19 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + bowser@2.14.1: resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + brace-expansion@1.1.15: + resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} @@ -791,8 +665,8 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dotenv@17.3.1: - resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} engines: {node: '>=12'} escape-string-regexp@4.0.0: @@ -811,8 +685,12 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.39.2: - resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -856,11 +734,14 @@ packages: fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-wrap-ansi@0.2.0: - resolution: {integrity: sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==} + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + + fast-xml-builder@1.2.0: + resolution: {integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==} - fast-xml-parser@5.3.4: - resolution: {integrity: sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==} + fast-xml-parser@5.7.3: + resolution: {integrity: sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==} hasBin: true fdir@6.5.0: @@ -884,8 +765,8 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} @@ -922,8 +803,8 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} hasBin: true json-buffer@3.0.1: @@ -949,12 +830,12 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -974,15 +855,18 @@ packages: resolution: {integrity: sha512-VUOWP5T9R9RwuPLKvNgvhsjdPFVhr2k8no8ea84+KhDtYPmk9L/3StNP3WClyPOKJOT8bFlO3eyhTKxXK9+Oog==} hasBin: true - oxlint@1.48.0: - resolution: {integrity: sha512-m5vyVBgPtPhVCJc3xI//8je9lRc8bYuYB4R/1PH3VPGOjA4vjVhkHtyJukdEjYEjwrw4Qf1eIf+pP9xvfhfMow==} + oxlint@1.69.0: + resolution: {integrity: sha512-ypZkK/aDc5NQV8zIR6s2H2Tl3aNW8FmJ1m9+2qsaYuRenl8vgnHNCGwTHviWJdUQzglOlHFchgopdtGhSy17Rw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - oxlint-tsgolint: '>=0.12.2' + oxlint-tsgolint: '>=0.22.1' + vite-plus: '*' peerDependenciesMeta: oxlint-tsgolint: optional: true + vite-plus: + optional: true p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} @@ -1000,12 +884,16 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-expression-matcher@1.5.0: + resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==} + engines: {node: '>=14.0.0'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} prelude-ls@1.2.1: @@ -1020,8 +908,8 @@ packages: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} engines: {node: '>=10'} hasBin: true @@ -1041,19 +929,19 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strnum@2.1.2: - resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + strnum@2.3.0: + resolution: {integrity: sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==} supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -1070,8 +958,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -1085,29 +973,39 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + xml-naming@0.1.0: + resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==} + engines: {node: '>=16.0.0'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - zod@4.3.6: - resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} snapshots: + '@aws-crypto/crc32@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.9 + tslib: 2.8.1 + '@aws-crypto/sha256-browser@5.2.0': dependencies: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-locate-window': 3.893.0 + '@aws-sdk/types': 3.973.9 + '@aws-sdk/util-locate-window': 3.965.5 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.1 + '@aws-sdk/types': 3.973.9 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -1116,364 +1014,201 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.973.1 + '@aws-sdk/types': 3.973.9 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-ssm@3.990.0': + '@aws-sdk/client-ssm@3.1056.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.10 - '@aws-sdk/credential-provider-node': 3.972.9 - '@aws-sdk/middleware-host-header': 3.972.3 - '@aws-sdk/middleware-logger': 3.972.3 - '@aws-sdk/middleware-recursion-detection': 3.972.3 - '@aws-sdk/middleware-user-agent': 3.972.10 - '@aws-sdk/region-config-resolver': 3.972.3 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.990.0 - '@aws-sdk/util-user-agent-browser': 3.972.3 - '@aws-sdk/util-user-agent-node': 3.972.8 - '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.23.0 - '@smithy/fetch-http-handler': 5.3.9 - '@smithy/hash-node': 4.2.8 - '@smithy/invalid-dependency': 4.2.8 - '@smithy/middleware-content-length': 4.2.8 - '@smithy/middleware-endpoint': 4.4.14 - '@smithy/middleware-retry': 4.4.31 - '@smithy/middleware-serde': 4.2.9 - '@smithy/middleware-stack': 4.2.8 - '@smithy/node-config-provider': 4.3.8 - '@smithy/node-http-handler': 4.4.10 - '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/url-parser': 4.2.8 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.30 - '@smithy/util-defaults-mode-node': 4.2.33 - '@smithy/util-endpoints': 3.2.8 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-retry': 4.2.8 - '@smithy/util-utf8': 4.2.0 - '@smithy/util-waiter': 4.2.8 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/credential-provider-node': 3.972.46 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/fetch-http-handler': 5.4.5 + '@smithy/node-http-handler': 4.7.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - '@aws-sdk/client-sso@3.990.0': + '@aws-sdk/client-sso-oidc@3.1056.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.10 - '@aws-sdk/middleware-host-header': 3.972.3 - '@aws-sdk/middleware-logger': 3.972.3 - '@aws-sdk/middleware-recursion-detection': 3.972.3 - '@aws-sdk/middleware-user-agent': 3.972.10 - '@aws-sdk/region-config-resolver': 3.972.3 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.990.0 - '@aws-sdk/util-user-agent-browser': 3.972.3 - '@aws-sdk/util-user-agent-node': 3.972.8 - '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.23.0 - '@smithy/fetch-http-handler': 5.3.9 - '@smithy/hash-node': 4.2.8 - '@smithy/invalid-dependency': 4.2.8 - '@smithy/middleware-content-length': 4.2.8 - '@smithy/middleware-endpoint': 4.4.14 - '@smithy/middleware-retry': 4.4.31 - '@smithy/middleware-serde': 4.2.9 - '@smithy/middleware-stack': 4.2.8 - '@smithy/node-config-provider': 4.3.8 - '@smithy/node-http-handler': 4.4.10 - '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/url-parser': 4.2.8 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.30 - '@smithy/util-defaults-mode-node': 4.2.33 - '@smithy/util-endpoints': 3.2.8 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-retry': 4.2.8 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/core@3.973.10': - dependencies: - '@aws-sdk/types': 3.973.1 - '@aws-sdk/xml-builder': 3.972.4 - '@smithy/core': 3.23.0 - '@smithy/node-config-provider': 4.3.8 - '@smithy/property-provider': 4.2.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/signature-v4': 5.3.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/util-base64': 4.3.0 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-utf8': 4.2.0 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/credential-provider-node': 3.972.46 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/fetch-http-handler': 5.4.5 + '@smithy/node-http-handler': 4.7.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.8': + '@aws-sdk/client-sso@3.1056.0': dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-http@3.972.10': - dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/types': 3.973.1 - '@smithy/fetch-http-handler': 5.3.9 - '@smithy/node-http-handler': 4.4.10 - '@smithy/property-provider': 4.2.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/util-stream': 4.5.12 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-ini@3.972.8': - dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/credential-provider-env': 3.972.8 - '@aws-sdk/credential-provider-http': 3.972.10 - '@aws-sdk/credential-provider-login': 3.972.8 - '@aws-sdk/credential-provider-process': 3.972.8 - '@aws-sdk/credential-provider-sso': 3.972.8 - '@aws-sdk/credential-provider-web-identity': 3.972.8 - '@aws-sdk/nested-clients': 3.990.0 - '@aws-sdk/types': 3.973.1 - '@smithy/credential-provider-imds': 4.2.8 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/fetch-http-handler': 5.4.5 + '@smithy/node-http-handler': 4.7.5 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/core@3.974.15': + dependencies: + '@aws-sdk/types': 3.973.9 + '@aws-sdk/xml-builder': 3.972.26 + '@aws/lambda-invoke-store': 0.2.4 + '@smithy/core': 3.24.5 + '@smithy/signature-v4': 5.4.5 + '@smithy/types': 4.14.2 + bowser: 2.14.1 tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - '@aws-sdk/credential-provider-login@3.972.8': + '@aws-sdk/credential-provider-env@3.972.41': dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/nested-clients': 3.990.0 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/credential-provider-node@3.972.9': - dependencies: - '@aws-sdk/credential-provider-env': 3.972.8 - '@aws-sdk/credential-provider-http': 3.972.10 - '@aws-sdk/credential-provider-ini': 3.972.8 - '@aws-sdk/credential-provider-process': 3.972.8 - '@aws-sdk/credential-provider-sso': 3.972.8 - '@aws-sdk/credential-provider-web-identity': 3.972.8 - '@aws-sdk/types': 3.973.1 - '@smithy/credential-provider-imds': 4.2.8 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - '@aws-sdk/credential-provider-process@3.972.8': + '@aws-sdk/credential-provider-http@3.972.43': dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/fetch-http-handler': 5.4.5 + '@smithy/node-http-handler': 4.7.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.8': + '@aws-sdk/credential-provider-ini@3.972.45': dependencies: - '@aws-sdk/client-sso': 3.990.0 - '@aws-sdk/core': 3.973.10 - '@aws-sdk/token-providers': 3.990.0 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/credential-provider-env': 3.972.41 + '@aws-sdk/credential-provider-http': 3.972.43 + '@aws-sdk/credential-provider-login': 3.972.45 + '@aws-sdk/credential-provider-process': 3.972.41 + '@aws-sdk/credential-provider-sso': 3.972.45 + '@aws-sdk/credential-provider-web-identity': 3.972.45 + '@aws-sdk/nested-clients': 3.997.13 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/credential-provider-imds': 4.3.6 + '@smithy/types': 4.14.2 tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.8': + '@aws-sdk/credential-provider-login@3.972.45': dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/nested-clients': 3.990.0 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/nested-clients': 3.997.13 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - '@aws-sdk/middleware-host-header@3.972.3': + '@aws-sdk/credential-provider-node@3.972.46': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 + '@aws-sdk/credential-provider-env': 3.972.41 + '@aws-sdk/credential-provider-http': 3.972.43 + '@aws-sdk/credential-provider-ini': 3.972.45 + '@aws-sdk/credential-provider-process': 3.972.41 + '@aws-sdk/credential-provider-sso': 3.972.45 + '@aws-sdk/credential-provider-web-identity': 3.972.45 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/credential-provider-imds': 4.3.6 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.972.3': + '@aws-sdk/credential-provider-process@3.972.41': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/types': 4.12.0 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.972.3': + '@aws-sdk/credential-provider-sso@3.972.45': dependencies: - '@aws-sdk/types': 3.973.1 - '@aws/lambda-invoke-store': 0.2.3 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/nested-clients': 3.997.13 + '@aws-sdk/token-providers': 3.1056.0 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.10': + '@aws-sdk/credential-provider-web-identity@3.972.45': dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.990.0 - '@smithy/core': 3.23.0 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/nested-clients': 3.997.13 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.990.0': + '@aws-sdk/nested-clients@3.997.13': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.10 - '@aws-sdk/middleware-host-header': 3.972.3 - '@aws-sdk/middleware-logger': 3.972.3 - '@aws-sdk/middleware-recursion-detection': 3.972.3 - '@aws-sdk/middleware-user-agent': 3.972.10 - '@aws-sdk/region-config-resolver': 3.972.3 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.990.0 - '@aws-sdk/util-user-agent-browser': 3.972.3 - '@aws-sdk/util-user-agent-node': 3.972.8 - '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.23.0 - '@smithy/fetch-http-handler': 5.3.9 - '@smithy/hash-node': 4.2.8 - '@smithy/invalid-dependency': 4.2.8 - '@smithy/middleware-content-length': 4.2.8 - '@smithy/middleware-endpoint': 4.4.14 - '@smithy/middleware-retry': 4.4.31 - '@smithy/middleware-serde': 4.2.9 - '@smithy/middleware-stack': 4.2.8 - '@smithy/node-config-provider': 4.3.8 - '@smithy/node-http-handler': 4.4.10 - '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/url-parser': 4.2.8 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.30 - '@smithy/util-defaults-mode-node': 4.2.33 - '@smithy/util-endpoints': 3.2.8 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-retry': 4.2.8 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/region-config-resolver@3.972.3': - dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/config-resolver': 4.4.6 - '@smithy/node-config-provider': 4.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@aws-sdk/token-providers@3.990.0': - dependencies: - '@aws-sdk/core': 3.973.10 - '@aws-sdk/nested-clients': 3.990.0 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/types@3.973.1': - dependencies: - '@smithy/types': 4.12.0 + '@aws-sdk/core': 3.974.15 + '@aws-sdk/signature-v4-multi-region': 3.996.30 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/fetch-http-handler': 5.4.5 + '@smithy/node-http-handler': 4.7.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.990.0': + '@aws-sdk/signature-v4-multi-region@3.996.30': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/types': 4.12.0 - '@smithy/url-parser': 4.2.8 - '@smithy/util-endpoints': 3.2.8 + '@aws-sdk/types': 3.973.9 + '@smithy/signature-v4': 5.4.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/util-locate-window@3.893.0': + '@aws-sdk/token-providers@3.1056.0': dependencies: + '@aws-sdk/core': 3.974.15 + '@aws-sdk/nested-clients': 3.997.13 + '@aws-sdk/types': 3.973.9 + '@smithy/core': 3.24.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.972.3': + '@aws-sdk/types@3.973.9': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/types': 4.12.0 - bowser: 2.14.1 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.972.8': + '@aws-sdk/util-locate-window@3.965.5': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.10 - '@aws-sdk/types': 3.973.1 - '@smithy/node-config-provider': 4.3.8 - '@smithy/types': 4.12.0 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.4': + '@aws-sdk/xml-builder@3.972.26': dependencies: - '@smithy/types': 4.12.0 - fast-xml-parser: 5.3.4 + '@smithy/types': 4.14.2 + fast-xml-parser: 5.7.3 tslib: 2.8.1 - '@aws/lambda-invoke-store@0.2.3': {} + '@aws/lambda-invoke-store@0.2.4': {} - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2)': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': dependencies: - eslint: 9.39.2 + eslint: 9.39.4 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/config-array@0.21.1': + '@eslint/config-array@0.21.2': dependencies: '@eslint/object-schema': 2.1.7 debug: 4.4.3 - minimatch: 3.1.2 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -1485,21 +1220,21 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.1': + '@eslint/eslintrc@3.3.5': dependencies: - ajv: 6.12.6 + ajv: 6.15.0 debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.1 - minimatch: 3.1.2 + js-yaml: 4.2.0 + minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.39.2': {} + '@eslint/js@9.39.4': {} '@eslint/object-schema@2.1.7': {} @@ -1519,91 +1254,109 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@inquirer/ansi@2.0.3': {} + '@inquirer/ansi@2.0.7': {} + + '@inquirer/confirm@6.1.1(@types/node@24.13.2)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) + optionalDependencies: + '@types/node': 24.13.2 - '@inquirer/core@11.1.3(@types/node@24.10.13)': + '@inquirer/core@11.2.1(@types/node@24.13.2)': dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@24.10.13) + '@inquirer/ansi': 2.0.7 + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.13.2) cli-width: 4.1.0 - fast-wrap-ansi: 0.2.0 + fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.10.13 + '@types/node': 24.13.2 - '@inquirer/figures@2.0.3': {} + '@inquirer/figures@2.0.7': {} + + '@inquirer/input@5.1.2(@types/node@24.13.2)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) + optionalDependencies: + '@types/node': 24.13.2 - '@inquirer/input@5.0.6(@types/node@24.10.13)': + '@inquirer/password@5.1.1(@types/node@24.13.2)': dependencies: - '@inquirer/core': 11.1.3(@types/node@24.10.13) - '@inquirer/type': 4.0.3(@types/node@24.10.13) + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.10.13 + '@types/node': 24.13.2 - '@inquirer/password@5.0.6(@types/node@24.10.13)': + '@inquirer/select@5.2.1(@types/node@24.13.2)': dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.3(@types/node@24.10.13) - '@inquirer/type': 4.0.3(@types/node@24.10.13) + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.10.13 + '@types/node': 24.13.2 - '@inquirer/type@4.0.3(@types/node@24.10.13)': + '@inquirer/type@4.0.7(@types/node@24.13.2)': optionalDependencies: - '@types/node': 24.10.13 + '@types/node': 24.13.2 - '@napi-rs/keyring-darwin-arm64@1.2.0': + '@napi-rs/keyring-darwin-arm64@1.3.0': optional: true - '@napi-rs/keyring-darwin-x64@1.2.0': + '@napi-rs/keyring-darwin-x64@1.3.0': optional: true - '@napi-rs/keyring-freebsd-x64@1.2.0': + '@napi-rs/keyring-freebsd-x64@1.3.0': optional: true - '@napi-rs/keyring-linux-arm-gnueabihf@1.2.0': + '@napi-rs/keyring-linux-arm-gnueabihf@1.3.0': optional: true - '@napi-rs/keyring-linux-arm64-gnu@1.2.0': + '@napi-rs/keyring-linux-arm64-gnu@1.3.0': optional: true - '@napi-rs/keyring-linux-arm64-musl@1.2.0': + '@napi-rs/keyring-linux-arm64-musl@1.3.0': optional: true - '@napi-rs/keyring-linux-riscv64-gnu@1.2.0': + '@napi-rs/keyring-linux-riscv64-gnu@1.3.0': optional: true - '@napi-rs/keyring-linux-x64-gnu@1.2.0': + '@napi-rs/keyring-linux-x64-gnu@1.3.0': optional: true - '@napi-rs/keyring-linux-x64-musl@1.2.0': + '@napi-rs/keyring-linux-x64-musl@1.3.0': optional: true - '@napi-rs/keyring-win32-arm64-msvc@1.2.0': + '@napi-rs/keyring-win32-arm64-msvc@1.3.0': optional: true - '@napi-rs/keyring-win32-ia32-msvc@1.2.0': + '@napi-rs/keyring-win32-ia32-msvc@1.3.0': optional: true - '@napi-rs/keyring-win32-x64-msvc@1.2.0': + '@napi-rs/keyring-win32-x64-msvc@1.3.0': optional: true - '@napi-rs/keyring@1.2.0': + '@napi-rs/keyring@1.3.0': optionalDependencies: - '@napi-rs/keyring-darwin-arm64': 1.2.0 - '@napi-rs/keyring-darwin-x64': 1.2.0 - '@napi-rs/keyring-freebsd-x64': 1.2.0 - '@napi-rs/keyring-linux-arm-gnueabihf': 1.2.0 - '@napi-rs/keyring-linux-arm64-gnu': 1.2.0 - '@napi-rs/keyring-linux-arm64-musl': 1.2.0 - '@napi-rs/keyring-linux-riscv64-gnu': 1.2.0 - '@napi-rs/keyring-linux-x64-gnu': 1.2.0 - '@napi-rs/keyring-linux-x64-musl': 1.2.0 - '@napi-rs/keyring-win32-arm64-msvc': 1.2.0 - '@napi-rs/keyring-win32-ia32-msvc': 1.2.0 - '@napi-rs/keyring-win32-x64-msvc': 1.2.0 + '@napi-rs/keyring-darwin-arm64': 1.3.0 + '@napi-rs/keyring-darwin-x64': 1.3.0 + '@napi-rs/keyring-freebsd-x64': 1.3.0 + '@napi-rs/keyring-linux-arm-gnueabihf': 1.3.0 + '@napi-rs/keyring-linux-arm64-gnu': 1.3.0 + '@napi-rs/keyring-linux-arm64-musl': 1.3.0 + '@napi-rs/keyring-linux-riscv64-gnu': 1.3.0 + '@napi-rs/keyring-linux-x64-gnu': 1.3.0 + '@napi-rs/keyring-linux-x64-musl': 1.3.0 + '@napi-rs/keyring-win32-arm64-msvc': 1.3.0 + '@napi-rs/keyring-win32-ia32-msvc': 1.3.0 + '@napi-rs/keyring-win32-x64-msvc': 1.3.0 + + '@nodable/entities@2.1.1': {} '@oxlint-tsgolint/darwin-arm64@0.13.0': optional: true @@ -1623,253 +1376,98 @@ snapshots: '@oxlint-tsgolint/win32-x64@0.13.0': optional: true - '@oxlint/binding-android-arm-eabi@1.48.0': + '@oxlint/binding-android-arm-eabi@1.69.0': optional: true - '@oxlint/binding-android-arm64@1.48.0': + '@oxlint/binding-android-arm64@1.69.0': optional: true - '@oxlint/binding-darwin-arm64@1.48.0': + '@oxlint/binding-darwin-arm64@1.69.0': optional: true - '@oxlint/binding-darwin-x64@1.48.0': + '@oxlint/binding-darwin-x64@1.69.0': optional: true - '@oxlint/binding-freebsd-x64@1.48.0': + '@oxlint/binding-freebsd-x64@1.69.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.48.0': + '@oxlint/binding-linux-arm-gnueabihf@1.69.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.48.0': + '@oxlint/binding-linux-arm-musleabihf@1.69.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.48.0': + '@oxlint/binding-linux-arm64-gnu@1.69.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.48.0': + '@oxlint/binding-linux-arm64-musl@1.69.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.48.0': + '@oxlint/binding-linux-ppc64-gnu@1.69.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.48.0': + '@oxlint/binding-linux-riscv64-gnu@1.69.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.48.0': + '@oxlint/binding-linux-riscv64-musl@1.69.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.48.0': + '@oxlint/binding-linux-s390x-gnu@1.69.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.48.0': + '@oxlint/binding-linux-x64-gnu@1.69.0': optional: true - '@oxlint/binding-linux-x64-musl@1.48.0': + '@oxlint/binding-linux-x64-musl@1.69.0': optional: true - '@oxlint/binding-openharmony-arm64@1.48.0': + '@oxlint/binding-openharmony-arm64@1.69.0': optional: true - '@oxlint/binding-win32-arm64-msvc@1.48.0': + '@oxlint/binding-win32-arm64-msvc@1.69.0': optional: true - '@oxlint/binding-win32-ia32-msvc@1.48.0': + '@oxlint/binding-win32-ia32-msvc@1.69.0': optional: true - '@oxlint/binding-win32-x64-msvc@1.48.0': + '@oxlint/binding-win32-x64-msvc@1.69.0': optional: true - '@smithy/abort-controller@4.2.8': - dependencies: - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/config-resolver@4.4.6': - dependencies: - '@smithy/node-config-provider': 4.3.8 - '@smithy/types': 4.12.0 - '@smithy/util-config-provider': 4.2.0 - '@smithy/util-endpoints': 3.2.8 - '@smithy/util-middleware': 4.2.8 - tslib: 2.8.1 - - '@smithy/core@3.23.0': - dependencies: - '@smithy/middleware-serde': 4.2.9 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-stream': 4.5.12 - '@smithy/util-utf8': 4.2.0 - '@smithy/uuid': 1.1.0 - tslib: 2.8.1 - - '@smithy/credential-provider-imds@4.2.8': - dependencies: - '@smithy/node-config-provider': 4.3.8 - '@smithy/property-provider': 4.2.8 - '@smithy/types': 4.12.0 - '@smithy/url-parser': 4.2.8 - tslib: 2.8.1 - - '@smithy/fetch-http-handler@5.3.9': + '@smithy/core@3.24.5': dependencies: - '@smithy/protocol-http': 5.3.8 - '@smithy/querystring-builder': 4.2.8 - '@smithy/types': 4.12.0 - '@smithy/util-base64': 4.3.0 + '@aws-crypto/crc32': 5.2.0 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@smithy/hash-node@4.2.8': + '@smithy/credential-provider-imds@4.3.6': dependencies: - '@smithy/types': 4.12.0 - '@smithy/util-buffer-from': 4.2.0 - '@smithy/util-utf8': 4.2.0 + '@smithy/core': 3.24.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@smithy/invalid-dependency@4.2.8': + '@smithy/fetch-http-handler@5.4.5': dependencies: - '@smithy/types': 4.12.0 + '@smithy/core': 3.24.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': dependencies: tslib: 2.8.1 - '@smithy/is-array-buffer@4.2.0': - dependencies: - tslib: 2.8.1 - - '@smithy/middleware-content-length@4.2.8': - dependencies: - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/middleware-endpoint@4.4.14': - dependencies: - '@smithy/core': 3.23.0 - '@smithy/middleware-serde': 4.2.9 - '@smithy/node-config-provider': 4.3.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - '@smithy/url-parser': 4.2.8 - '@smithy/util-middleware': 4.2.8 - tslib: 2.8.1 - - '@smithy/middleware-retry@4.4.31': - dependencies: - '@smithy/node-config-provider': 4.3.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/service-error-classification': 4.2.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-retry': 4.2.8 - '@smithy/uuid': 1.1.0 - tslib: 2.8.1 - - '@smithy/middleware-serde@4.2.9': - dependencies: - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/middleware-stack@4.2.8': - dependencies: - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/node-config-provider@4.3.8': - dependencies: - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/node-http-handler@4.4.10': - dependencies: - '@smithy/abort-controller': 4.2.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/querystring-builder': 4.2.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/property-provider@4.2.8': - dependencies: - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/protocol-http@5.3.8': - dependencies: - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/querystring-builder@4.2.8': - dependencies: - '@smithy/types': 4.12.0 - '@smithy/util-uri-escape': 4.2.0 - tslib: 2.8.1 - - '@smithy/querystring-parser@4.2.8': - dependencies: - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/service-error-classification@4.2.8': + '@smithy/node-http-handler@4.7.5': dependencies: - '@smithy/types': 4.12.0 - - '@smithy/shared-ini-file-loader@4.4.3': - dependencies: - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/signature-v4@5.3.8': - dependencies: - '@smithy/is-array-buffer': 4.2.0 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - '@smithy/util-hex-encoding': 4.2.0 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-uri-escape': 4.2.0 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 - - '@smithy/smithy-client@4.11.3': - dependencies: - '@smithy/core': 3.23.0 - '@smithy/middleware-endpoint': 4.4.14 - '@smithy/middleware-stack': 4.2.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - '@smithy/util-stream': 4.5.12 - tslib: 2.8.1 - - '@smithy/types@4.12.0': - dependencies: - tslib: 2.8.1 - - '@smithy/url-parser@4.2.8': - dependencies: - '@smithy/querystring-parser': 4.2.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/util-base64@4.3.0': - dependencies: - '@smithy/util-buffer-from': 4.2.0 - '@smithy/util-utf8': 4.2.0 + '@smithy/core': 3.24.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@smithy/util-body-length-browser@4.2.0': + '@smithy/signature-v4@5.4.5': dependencies: + '@smithy/core': 3.24.5 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@smithy/util-body-length-node@4.2.1': + '@smithy/types@4.14.2': dependencies: tslib: 2.8.1 @@ -1878,157 +1476,80 @@ snapshots: '@smithy/is-array-buffer': 2.2.0 tslib: 2.8.1 - '@smithy/util-buffer-from@4.2.0': - dependencies: - '@smithy/is-array-buffer': 4.2.0 - tslib: 2.8.1 - - '@smithy/util-config-provider@4.2.0': - dependencies: - tslib: 2.8.1 - - '@smithy/util-defaults-mode-browser@4.3.30': - dependencies: - '@smithy/property-provider': 4.2.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/util-defaults-mode-node@4.2.33': - dependencies: - '@smithy/config-resolver': 4.4.6 - '@smithy/credential-provider-imds': 4.2.8 - '@smithy/node-config-provider': 4.3.8 - '@smithy/property-provider': 4.2.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/util-endpoints@3.2.8': - dependencies: - '@smithy/node-config-provider': 4.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/util-hex-encoding@4.2.0': - dependencies: - tslib: 2.8.1 - - '@smithy/util-middleware@4.2.8': - dependencies: - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/util-retry@4.2.8': - dependencies: - '@smithy/service-error-classification': 4.2.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/util-stream@4.5.12': - dependencies: - '@smithy/fetch-http-handler': 5.3.9 - '@smithy/node-http-handler': 4.4.10 - '@smithy/types': 4.12.0 - '@smithy/util-base64': 4.3.0 - '@smithy/util-buffer-from': 4.2.0 - '@smithy/util-hex-encoding': 4.2.0 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 - - '@smithy/util-uri-escape@4.2.0': - dependencies: - tslib: 2.8.1 - '@smithy/util-utf8@2.3.0': dependencies: '@smithy/util-buffer-from': 2.2.0 tslib: 2.8.1 - '@smithy/util-utf8@4.2.0': - dependencies: - '@smithy/util-buffer-from': 4.2.0 - tslib: 2.8.1 - - '@smithy/util-waiter@4.2.8': - dependencies: - '@smithy/abort-controller': 4.2.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - - '@smithy/uuid@1.1.0': - dependencies: - tslib: 2.8.1 - - '@stylistic/eslint-plugin@5.8.0(eslint@9.39.2)': + '@stylistic/eslint-plugin@5.10.0(eslint@9.39.4)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2) - '@typescript-eslint/types': 8.55.0 - eslint: 9.39.2 + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@typescript-eslint/types': 8.61.0 + eslint: 9.39.4 eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 - picomatch: 4.0.3 + picomatch: 4.0.4 '@types/estree@1.0.8': {} '@types/json-schema@7.0.15': {} - '@types/node@24.10.13': + '@types/node@24.13.2': dependencies: - undici-types: 7.16.0 + undici-types: 7.18.2 - '@typescript-eslint/parser@8.55.0(eslint@9.39.2)(typescript@5.9.3)': + '@typescript-eslint/parser@8.61.0(eslint@9.39.4)(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.55.0 - '@typescript-eslint/types': 8.55.0 - '@typescript-eslint/typescript-estree': 8.55.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.55.0 + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3 - eslint: 9.39.2 + eslint: 9.39.4 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.55.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.61.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.55.0(typescript@5.9.3) - '@typescript-eslint/types': 8.55.0 + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@5.9.3) + '@typescript-eslint/types': 8.61.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.55.0': + '@typescript-eslint/scope-manager@8.61.0': dependencies: - '@typescript-eslint/types': 8.55.0 - '@typescript-eslint/visitor-keys': 8.55.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 - '@typescript-eslint/tsconfig-utils@8.55.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.61.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/types@8.55.0': {} + '@typescript-eslint/types@8.61.0': {} - '@typescript-eslint/typescript-estree@8.55.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.61.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.55.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.55.0(typescript@5.9.3) - '@typescript-eslint/types': 8.55.0 - '@typescript-eslint/visitor-keys': 8.55.0 + '@typescript-eslint/project-service': 8.61.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@5.9.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3 - minimatch: 9.0.5 - semver: 7.7.4 - tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) + minimatch: 10.2.5 + semver: 7.8.4 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.55.0': + '@typescript-eslint/visitor-keys@8.61.0': dependencies: - '@typescript-eslint/types': 8.55.0 - eslint-visitor-keys: 4.2.1 + '@typescript-eslint/types': 8.61.0 + eslint-visitor-keys: 5.0.1 acorn-jsx@5.3.2(acorn@8.15.0): dependencies: @@ -2036,7 +1557,7 @@ snapshots: acorn@8.15.0: {} - ajv@6.12.6: + ajv@6.15.0: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 @@ -2051,16 +1572,18 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + bowser@2.14.1: {} - brace-expansion@1.1.12: + brace-expansion@1.1.15: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.2: + brace-expansion@5.0.6: dependencies: - balanced-match: 1.0.2 + balanced-match: 4.0.4 callsites@3.1.0: {} @@ -2093,7 +1616,7 @@ snapshots: deep-is@0.1.4: {} - dotenv@17.3.1: {} + dotenv@17.4.2: {} escape-string-regexp@4.0.0: {} @@ -2106,21 +1629,23 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.39.2: + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4: dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.1 + '@eslint/config-array': 0.21.2 '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.39.2 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 - ajv: 6.12.6 + ajv: 6.15.0 chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.3 @@ -2139,7 +1664,7 @@ snapshots: is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 - minimatch: 3.1.2 + minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 transitivePeerDependencies: @@ -2175,17 +1700,25 @@ snapshots: dependencies: fast-string-truncated-width: 3.0.3 - fast-wrap-ansi@0.2.0: + fast-wrap-ansi@0.2.2: dependencies: fast-string-width: 3.0.2 - fast-xml-parser@5.3.4: + fast-xml-builder@1.2.0: dependencies: - strnum: 2.1.2 + path-expression-matcher: 1.5.0 + xml-naming: 0.1.0 - fdir@6.5.0(picomatch@4.0.3): + fast-xml-parser@5.7.3: + dependencies: + '@nodable/entities': 2.1.1 + fast-xml-builder: 1.2.0 + path-expression-matcher: 1.5.0 + strnum: 2.3.0 + + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: - picomatch: 4.0.3 + picomatch: 4.0.4 file-entry-cache@8.0.0: dependencies: @@ -2198,10 +1731,10 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.3.3 + flatted: 3.4.2 keyv: 4.5.4 - flatted@3.3.3: {} + flatted@3.4.2: {} glob-parent@6.0.2: dependencies: @@ -2228,7 +1761,7 @@ snapshots: isexe@2.0.0: {} - js-yaml@4.1.1: + js-yaml@4.2.0: dependencies: argparse: 2.0.1 @@ -2253,13 +1786,13 @@ snapshots: lodash.merge@4.6.2: {} - minimatch@3.1.2: + minimatch@10.2.5: dependencies: - brace-expansion: 1.1.12 + brace-expansion: 5.0.6 - minimatch@9.0.5: + minimatch@3.1.5: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 1.1.15 ms@2.1.3: {} @@ -2285,27 +1818,27 @@ snapshots: '@oxlint-tsgolint/win32-arm64': 0.13.0 '@oxlint-tsgolint/win32-x64': 0.13.0 - oxlint@1.48.0(oxlint-tsgolint@0.13.0): + oxlint@1.69.0(oxlint-tsgolint@0.13.0): optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.48.0 - '@oxlint/binding-android-arm64': 1.48.0 - '@oxlint/binding-darwin-arm64': 1.48.0 - '@oxlint/binding-darwin-x64': 1.48.0 - '@oxlint/binding-freebsd-x64': 1.48.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.48.0 - '@oxlint/binding-linux-arm-musleabihf': 1.48.0 - '@oxlint/binding-linux-arm64-gnu': 1.48.0 - '@oxlint/binding-linux-arm64-musl': 1.48.0 - '@oxlint/binding-linux-ppc64-gnu': 1.48.0 - '@oxlint/binding-linux-riscv64-gnu': 1.48.0 - '@oxlint/binding-linux-riscv64-musl': 1.48.0 - '@oxlint/binding-linux-s390x-gnu': 1.48.0 - '@oxlint/binding-linux-x64-gnu': 1.48.0 - '@oxlint/binding-linux-x64-musl': 1.48.0 - '@oxlint/binding-openharmony-arm64': 1.48.0 - '@oxlint/binding-win32-arm64-msvc': 1.48.0 - '@oxlint/binding-win32-ia32-msvc': 1.48.0 - '@oxlint/binding-win32-x64-msvc': 1.48.0 + '@oxlint/binding-android-arm-eabi': 1.69.0 + '@oxlint/binding-android-arm64': 1.69.0 + '@oxlint/binding-darwin-arm64': 1.69.0 + '@oxlint/binding-darwin-x64': 1.69.0 + '@oxlint/binding-freebsd-x64': 1.69.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.69.0 + '@oxlint/binding-linux-arm-musleabihf': 1.69.0 + '@oxlint/binding-linux-arm64-gnu': 1.69.0 + '@oxlint/binding-linux-arm64-musl': 1.69.0 + '@oxlint/binding-linux-ppc64-gnu': 1.69.0 + '@oxlint/binding-linux-riscv64-gnu': 1.69.0 + '@oxlint/binding-linux-riscv64-musl': 1.69.0 + '@oxlint/binding-linux-s390x-gnu': 1.69.0 + '@oxlint/binding-linux-x64-gnu': 1.69.0 + '@oxlint/binding-linux-x64-musl': 1.69.0 + '@oxlint/binding-openharmony-arm64': 1.69.0 + '@oxlint/binding-win32-arm64-msvc': 1.69.0 + '@oxlint/binding-win32-ia32-msvc': 1.69.0 + '@oxlint/binding-win32-x64-msvc': 1.69.0 oxlint-tsgolint: 0.13.0 p-limit@3.1.0: @@ -2322,9 +1855,11 @@ snapshots: path-exists@4.0.0: {} + path-expression-matcher@1.5.0: {} + path-key@3.1.1: {} - picomatch@4.0.3: {} + picomatch@4.0.4: {} prelude-ls@1.2.1: {} @@ -2332,7 +1867,7 @@ snapshots: resolve-from@4.0.0: {} - semver@7.7.4: {} + semver@7.8.4: {} shebang-command@2.0.0: dependencies: @@ -2344,18 +1879,18 @@ snapshots: strip-json-comments@3.1.1: {} - strnum@2.1.2: {} + strnum@2.3.0: {} supports-color@7.2.0: dependencies: has-flag: 4.0.0 - tinyglobby@0.2.15: + tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 - ts-api-utils@2.4.0(typescript@5.9.3): + ts-api-utils@2.5.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -2367,7 +1902,7 @@ snapshots: typescript@5.9.3: {} - undici-types@7.16.0: {} + undici-types@7.18.2: {} uri-js@4.4.1: dependencies: @@ -2379,6 +1914,8 @@ snapshots: word-wrap@1.2.5: {} + xml-naming@0.1.0: {} + yocto-queue@0.1.0: {} - zod@4.3.6: {} + zod@4.4.3: {} diff --git a/src/aws.ts b/src/aws.ts index 003f37e..f4f9cc8 100644 --- a/src/aws.ts +++ b/src/aws.ts @@ -1,16 +1,14 @@ import type { Parameter } from '@aws-sdk/client-ssm' import { DeleteParameterCommand, GetParameterCommand, PutParameterCommand, SSMClient, paginateGetParametersByPath } from '@aws-sdk/client-ssm' -import { getCredentials } from './keyring.js' +import { getAwsCredentials, getCredentialsRegion } from './credentials.js' import { normalizePath, normalizePathAndName } from './utils.js' export function getClient(): SSMClient { - const credentials = getCredentials() + const region = getCredentialsRegion() return new SSMClient({ - credentials: { - accessKeyId: credentials.accessKeyId, - secretAccessKey: credentials.secretAccessKey, - }, region: credentials.region, + credentials: getAwsCredentials, + region, }) } diff --git a/src/browser.ts b/src/browser.ts new file mode 100644 index 0000000..271ac77 --- /dev/null +++ b/src/browser.ts @@ -0,0 +1,46 @@ +import { spawn } from 'node:child_process' + +export function openHttpsUrl(url: string): boolean { + if (!isSafeHttpsUrl(url)) { + return false + } + + const command = getOpenCommand(url) + if (!command) { + return false + } + + try { + const child = spawn(command.command, command.args, { detached: true, stdio: 'ignore' }) + child.unref() + return true + } + catch { + return false + } +} + +export function isSafeHttpsUrl(url: string): boolean { + try { + return new URL(url).protocol === 'https:' + } + catch { + return false + } +} + +function getOpenCommand(url: string): { args: string[], command: string } | undefined { + if (process.platform === 'darwin') { + return { args: [url], command: 'open' } + } + + if (process.platform === 'win32') { + return { args: ['/c', 'start', '""', url], command: 'cmd' } + } + + if (process.platform === 'linux') { + return { args: [url], command: 'xdg-open' } + } + + return undefined +} diff --git a/src/cli.ts b/src/cli.ts index 07667b4..185a660 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -7,6 +7,7 @@ import { getCommand } from './commands/get.js' import { putCommand } from './commands/put.js' import { deleteCommand } from './commands/delete.js' import { execCommand } from './commands/exec.js' +import { wipeCredentialsCommand } from './commands/wipe-credentials.js' const program = new Command() program.name('ssm-secrets').description('Simple AWS SSM secrets manager CLI').version(packageJson.version) @@ -17,6 +18,7 @@ getCommand(program) putCommand(program) deleteCommand(program) execCommand(program) +wipeCredentialsCommand(program) try { await program.parseAsync(process.argv) diff --git a/src/commands/auth.ts b/src/commands/auth.ts index fb2e8eb..bf7e6c8 100644 --- a/src/commands/auth.ts +++ b/src/commands/auth.ts @@ -1,21 +1,45 @@ import { Command } from 'commander' import promptInput from '@inquirer/input' import promptPassword from '@inquirer/password' -import { writeCredentials } from '../keyring.js' +import { inputSsoCredentials, inputStaticCredentials } from '../credentials.js' const SUMMARY = 'Authenticate and store AWS credentials securely' const DESCRIPTION = `${SUMMARY}. -This will use the OS-specific keyring to store the Region, Access Key ID and Secret Access Key provided via an interactive prompt. +This will use the OS-specific keyring to store static AWS credentials or AWS SSO authentication state. For more details, visit https://github.com/Brooooooklyn/keyring-node or its underlying library https://github.com/open-source-cooperative/keyring-rs` +const DEFAULT_REGION = 'eu-central-1' + +interface AuthCommandOptions { + accountId?: string + region: string + roleName?: string + ssoStartUrl?: string +} + export function authCommand(program: Command) { program .command('auth') .summary(SUMMARY) .description(DESCRIPTION) - .action(async () => { + .option('--region ', 'AWS region') + .option('--sso-start-url ', 'AWS SSO start URL') + .option('--account-id ', 'AWS SSO account ID') + .option('--role-name ', 'AWS SSO role name') + .action(async (options: AuthCommandOptions) => { + if (options.ssoStartUrl) { + await inputSsoCredentials({ + accountId: options.accountId, + region: options.region || DEFAULT_REGION, + roleName: options.roleName, + startUrl: options.ssoStartUrl, + }) + console.log('✅ SSO credentials securely stored in system keyring') + return + } + const answers = { - region: await promptInput({ message: 'AWS Region:', default: 'eu-central-1' }), + region: options.region ?? await promptInput({ message: 'AWS Region:', default: DEFAULT_REGION }), accessKeyId: await promptInput({ message: 'AWS Access Key ID:', required: true }), secretAccessKey: await promptPassword({ message: 'AWS Secret Access Key:', @@ -24,7 +48,7 @@ export function authCommand(program: Command) { }), } - writeCredentials(answers) - console.log('✅ Credentials securely stored in system keyring') + inputStaticCredentials(answers) + console.log('✅ Static credentials securely stored in system keyring') }) } diff --git a/src/commands/wipe-credentials.ts b/src/commands/wipe-credentials.ts new file mode 100644 index 0000000..f2383be --- /dev/null +++ b/src/commands/wipe-credentials.ts @@ -0,0 +1,16 @@ +import { Command } from 'commander' +import { deleteCredentials } from '../keyring.js' + +const SUMMARY = 'Delete stored AWS credentials' +const DESCRIPTION = `${SUMMARY}.` + +export function wipeCredentialsCommand(program: Command) { + program + .command('wipe-credentials') + .summary(SUMMARY) + .description(DESCRIPTION) + .action(() => { + const deleted = deleteCredentials() + console.log(deleted ? '✅ Credentials deleted' : 'No credentials found') + }) +} diff --git a/src/credentials.ts b/src/credentials.ts new file mode 100644 index 0000000..c1306f2 --- /dev/null +++ b/src/credentials.ts @@ -0,0 +1,266 @@ +import promptConfirm from '@inquirer/confirm' +import promptSelect from '@inquirer/select' +import type { SsoCredentials, StaticCredentials } from './keyring.js' +import { getCredentials, writeCredentials } from './keyring.js' +import { openHttpsUrl } from './browser.js' +import { createTokenFromDeviceCode, getErrorReason, getRoleCredentials, listAccounts, listRoles, refreshAccessToken, registerClient, startDeviceAuthorization } from './sso.js' + +const EXPIRY_BUFFER_MS = 60 * 1000 + +export interface AwsCredentials { + accessKeyId: string + secretAccessKey: string + sessionToken?: string +} + +interface SsoAuthOptions { + accountId?: string + allowBrowserRefresh?: boolean + region: string + roleName?: string + startUrl: string +} + +export function getCredentialsRegion(): string { + return getCredentials().region +} + +export function getAwsCredentials(): Promise { + const credentials = getCredentials() + + if (credentials.mode === 'static') { + return Promise.resolve({ + accessKeyId: credentials.accessKeyId, + secretAccessKey: credentials.secretAccessKey, + }) + } + + return resolveSsoCredentials(credentials) +} + +/** Stores the static credentials provided by the user */ +export function inputStaticCredentials(credentials: Omit) { + writeCredentials({ mode: 'static', ...credentials }) +} + +/** + * Handles the initial SSO login flow using the parameters provided by the user. + * Only `region` and `startUrl` are required for this flow. + */ +export async function inputSsoCredentials(options: SsoAuthOptions) { + const startUrl = normalizeStartUrl(options.startUrl) + const allowBrowserRefresh = options.allowBrowserRefresh ?? await promptConfirm({ + default: true, + message: 'Allow ssm-secrets to open browser automatically when SSO credentials expire?', + }) + + const client = await registerClient(options.region) + const token = await runDeviceAuthorization({ + clientId: client.clientId, + clientSecret: client.clientSecret, + region: options.region, + startUrl, + }) + + const accountId = options.accountId ?? await selectAccount(options.region, token.accessToken) + const roleName = options.roleName ?? await selectRole(options.region, token.accessToken, accountId) + const stsCredentials = await getRoleCredentials(options.region, token.accessToken, accountId, roleName) + + writeCredentials({ + mode: 'sso', + accessToken: token.accessToken, + accessTokenExpiresAt: token.accessTokenExpiresAt, + accountId, + allowBrowserRefresh, + clientId: client.clientId, + clientSecret: client.clientSecret, + clientSecretExpiresAt: client.clientSecretExpiresAt, + refreshToken: token.refreshToken, + region: options.region, + roleName, + startUrl, + stsCredentials, + }) +} + +/** + * Obtain the set of fresh STS credentials. + * When STS credentials have not expired yet, use them as-is. + * When STS credentials have already expired, use the access token to refresh them. + * Since the access token itself has time-to-live, its refresh is handled as well. + */ +async function resolveSsoCredentials(credentials: SsoCredentials): Promise { + if (isFresh(credentials.stsCredentials?.expiresAt)) { + return credentials.stsCredentials + } + + const refreshedCredentials = await getSsoCredentialsWithFreshToken(credentials) + if (!refreshedCredentials.accessToken) { + throw new Error('AWS SSO access token refresh failed.') + } + + const stsCredentials = await getRoleCredentials( + refreshedCredentials.region, + refreshedCredentials.accessToken, + refreshedCredentials.accountId, + refreshedCredentials.roleName, + ) + const updatedCredentials = { ...refreshedCredentials, stsCredentials } + writeCredentials(updatedCredentials) + return stsCredentials +} + +/** + * Obtain the fresh access token. + * When it hasn't expired yet, it will be returned as-is. + * When it has expired but the refresh token has not, the latter will be used to request a new access token. + * When both have expired, browser refresh will be triggered depending on user's `allowBrowserRefresh` preference. + */ +async function getSsoCredentialsWithFreshToken(credentials: SsoCredentials): Promise { + if (isFresh(credentials.accessTokenExpiresAt) && credentials.accessToken) { + return credentials + } + + if (isFresh(credentials.clientSecretExpiresAt, true) && credentials.refreshToken) { + try { + const token = await refreshAccessToken(credentials.region, credentials.clientId, credentials.clientSecret, credentials.refreshToken) + const updatedCredentials = { + ...credentials, + accessToken: token.accessToken, + accessTokenExpiresAt: token.accessTokenExpiresAt, + refreshToken: token.refreshToken, + } + writeCredentials(updatedCredentials) + return updatedCredentials + } + catch (e) { + const reason = getErrorReason(e) + const reasonSuffix = reason ? ` Reason: ${reason}` : '' + console.warn(`Unable to automatically refresh the access token, falling back to interactive refresh.${reasonSuffix}`) + } + } + + return runInteractiveSsoRefresh(credentials) +} + +/** + * Obtains the new access token using the interactive (browser-based) flow. + * Additionally handles the SSO client refresh for the cases when it expired. + */ +async function runInteractiveSsoRefresh(credentials: SsoCredentials): Promise { + if (!credentials.allowBrowserRefresh) { + throw new Error(`AWS SSO credentials expired. Run the following command to refresh them:\nssm-secrets auth --sso-start-url ${credentials.startUrl}`) + } + + const client = isFresh(credentials.clientSecretExpiresAt) + ? { + clientId: credentials.clientId, + clientSecret: credentials.clientSecret, + clientSecretExpiresAt: credentials.clientSecretExpiresAt, + } + : await registerClient(credentials.region) + + const token = await runDeviceAuthorization({ + clientId: client.clientId, + clientSecret: client.clientSecret, + region: credentials.region, + startUrl: credentials.startUrl, + }) + + const updatedCredentials = { + ...credentials, + accessToken: token.accessToken, + accessTokenExpiresAt: token.accessTokenExpiresAt, + clientId: client.clientId, + clientSecret: client.clientSecret, + clientSecretExpiresAt: client.clientSecretExpiresAt, + refreshToken: token.refreshToken, + } + writeCredentials(updatedCredentials) + return updatedCredentials +} + +/** + * Handles the device authorization flow by opening a browser and actively polling the token. + */ +async function runDeviceAuthorization(options: { clientId: string, clientSecret: string, region: string, startUrl: string }) { + const authorization = await startDeviceAuthorization(options.region, options.clientId, options.clientSecret, options.startUrl) + + const opened = openHttpsUrl(authorization.verificationUriComplete) + console.error(opened ? 'Opened AWS SSO login in browser.' : 'Could not open browser automatically, please open the link below yourself.') + console.error(`Link: ${authorization.verificationUriComplete}`) + console.error(`Code: ${authorization.userCode}`) + + return createTokenFromDeviceCode( + options.region, + options.clientId, + options.clientSecret, + authorization.deviceCode, + authorization.interval, + authorization.expiresIn, + ) +} + +/** + * Selects the only account available for the given access token, + * or prompts the user when multiple accounts are present. + */ +async function selectAccount(region: string, accessToken: string): Promise { + const accounts = await listAccounts(region, accessToken) + if (accounts.length === 0) { + throw new Error('AWS SSO returned no accounts.') + } + + if (accounts.length === 1) { + const accountId = accounts[0].accountId + console.warn('Selecting the only account available with accountId', accountId) + return accountId + } + + return promptSelect({ + choices: accounts.map(account => ({ + name: [account.accountName, account.accountId, account.emailAddress].filter(Boolean).join(' | '), + value: account.accountId, + })), + message: 'Select AWS SSO account:', + }) +} + +/** + * Selects the only role available for the given account and access token, + * or prompts the user when multiple roles are present. + */ +async function selectRole(region: string, accessToken: string, accountId: string): Promise { + const roles = await listRoles(region, accessToken, accountId) + if (roles.length === 0) { + throw new Error(`AWS SSO returned no roles for account ${accountId}.`) + } + + if (roles.length === 1) { + const roleName = roles[0].roleName + console.warn('Selecting the only role available with roleName', roleName) + return roleName + } + + return promptSelect({ + choices: roles.map(role => ({ name: role.roleName, value: role.roleName })), + message: 'Select AWS SSO role:', + }) +} + +function normalizeStartUrl(startUrl: string): string { + const url = new URL(startUrl) + if (url.protocol !== 'https:') { + throw new Error('AWS SSO start URL must use https.') + } + return url.href +} + +function isFresh(expiresAt: number | undefined, isInSeconds = false): expiresAt is number { + if (typeof expiresAt !== 'number') { + return false + } + + const expiresAtMs = isInSeconds ? expiresAt * 1000 : expiresAt + return expiresAtMs - EXPIRY_BUFFER_MS > Date.now() +} diff --git a/src/index.ts b/src/index.ts index 8c87c38..a373b83 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ export { listParameters, getParameter, putParameter, deleteParameter } from './aws.js' -export { writeCredentials, getCredentials, deleteCredentials } from './keyring.js' +export { getAwsCredentials, inputSsoCredentials, inputStaticCredentials } from './credentials.js' +export { deleteCredentials, getCredentials, writeCredentials } from './keyring.js' export { prettifyParameter, normalizePath, normalizePathAndName, formatEnv } from './utils.js' diff --git a/src/keyring.ts b/src/keyring.ts index ce8d4b9..60b5f04 100644 --- a/src/keyring.ts +++ b/src/keyring.ts @@ -1,25 +1,83 @@ import { Entry } from '@napi-rs/keyring' import { z } from 'zod' +const CURRENT_SCHEMA_VERSION = 2 + const KEYRING_SERVICE_NAME = 'aws-ssm-secrets' -const KEYRING_USER_NAME = 'aws-ssm-secrets' +const LEGACY_KEYRING_USER_NAME = 'aws-ssm-secrets' +const CURRENT_KEYRING_USER_NAME = `aws-ssm-secrets/v${CURRENT_SCHEMA_VERSION}` const ADD_CREDENTIALS_CMD = 'ssm-secrets auth' -const credentialsSchema = z.object({ +const legacyCredentialsSchema = z.object({ accessKeyId: z.string().nonempty(), region: z.string().nonempty(), secretAccessKey: z.string().nonempty(), }) -type Credentials = z.infer + +const legacySchemaToV2 = legacyCredentialsSchema.transform(credentials => ({ + mode: 'static' as const, + ...credentials, +})) + +const staticCredentialsSchema = legacyCredentialsSchema.extend({ + mode: z.literal('static'), +}) + +const ssoCredentialsSchema = z.object({ + mode: z.literal('sso'), + accessToken: z.string().optional(), + accessTokenExpiresAt: z.number().optional(), + accountId: z.string().nonempty(), + allowBrowserRefresh: z.boolean(), + clientId: z.string().nonempty(), + clientSecret: z.string().nonempty(), + clientSecretExpiresAt: z.number(), + refreshToken: z.string().optional(), + region: z.string().nonempty(), + roleName: z.string().nonempty(), + startUrl: z.string().nonempty(), + stsCredentials: z.object({ + accessKeyId: z.string().nonempty(), + expiresAt: z.number(), + secretAccessKey: z.string().nonempty(), + sessionToken: z.string().nonempty(), + }).optional(), +}) + +const storedCredentialsSchema = z.discriminatedUnion('mode', [staticCredentialsSchema, ssoCredentialsSchema]) + +export type StaticCredentials = z.infer +export type SsoCredentials = z.infer +export type StoredCredentials = z.infer +type LegacyCredentials = z.infer /** * Gets credentials from the OS keyring. */ -export function getCredentials(): Credentials { - const credentialsJson = getEntry().getPassword() - if (!credentialsJson) { +export function getCredentials(): StoredCredentials { + const currentCredentialsJson = getCurrentEntry().getPassword() + if (currentCredentialsJson) { + return parseCurrentCredentials(currentCredentialsJson) + } + + const legacyCredentialsJson = getLegacyEntry().getPassword() + if (!legacyCredentialsJson) { throw new Error(`No credentials in keyring. Run \`${ADD_CREDENTIALS_CMD}\` first.`) } - const credentials = credentialsSchema.safeParse(JSON.parse(credentialsJson)) + return parseLegacyCredentials(legacyCredentialsJson) +} + +function parseCurrentCredentials(credentialsJson: string): StoredCredentials { + const parsedCredentials: unknown = JSON.parse(credentialsJson) + const credentials = storedCredentialsSchema.safeParse(parsedCredentials) + if (!credentials.success) { + throw new Error(`Credentials have invalid format. Run \`${ADD_CREDENTIALS_CMD}\` to refresh them.`) + } + + return credentials.data +} + +function parseLegacyCredentials(credentialsJson: string): StoredCredentials { + const credentials = legacySchemaToV2.safeParse(JSON.parse(credentialsJson)) if (!credentials.success) { throw new Error(`Credentials have invalid format. Run \`${ADD_CREDENTIALS_CMD}\` to refresh them.`) } @@ -30,22 +88,38 @@ export function getCredentials(): Credentials { /** * Writes credentials into the OS keyring. */ -export function writeCredentials(credentials: Credentials) { - const validatedCredentials = credentialsSchema.safeParse(credentials) +export function writeCredentials(credentials: StoredCredentials) { + const validatedCredentials = storedCredentialsSchema.safeParse(credentials) if (!validatedCredentials.success) { throw new Error('Credentials have invalid format.') } - getEntry().setPassword(JSON.stringify(validatedCredentials.data)) + getCurrentEntry().setPassword(JSON.stringify(validatedCredentials.data)) + + // Write static credentials to legacy storage as well for compatibility purposes + if (validatedCredentials.data.mode === 'static') { + writeLegacyCredentials(validatedCredentials.data) + } } /** * Deletes credentials from the OS keyring. */ export function deleteCredentials(): boolean { - return getEntry().deletePassword() + const currentDeleted = getCurrentEntry().deletePassword() + const legacyDeleted = getLegacyEntry().deletePassword() + return currentDeleted || legacyDeleted +} + +function writeLegacyCredentials(credentials: LegacyCredentials) { + const legacyCredentials = legacyCredentialsSchema.parse(credentials) + getLegacyEntry().setPassword(JSON.stringify(legacyCredentials)) +} + +function getCurrentEntry(): Entry { + return new Entry(KEYRING_SERVICE_NAME, CURRENT_KEYRING_USER_NAME) } -function getEntry(): Entry { - return new Entry(KEYRING_SERVICE_NAME, KEYRING_USER_NAME) +function getLegacyEntry(): Entry { + return new Entry(KEYRING_SERVICE_NAME, LEGACY_KEYRING_USER_NAME) } diff --git a/src/sso.ts b/src/sso.ts new file mode 100644 index 0000000..476d190 --- /dev/null +++ b/src/sso.ts @@ -0,0 +1,247 @@ +import { GetRoleCredentialsCommand, ListAccountRolesCommand, ListAccountsCommand, SSOClient } from '@aws-sdk/client-sso' +import { AuthorizationPendingException, CreateTokenCommand, InvalidGrantException, RegisterClientCommand, SlowDownException, SSOOIDCClient, StartDeviceAuthorizationCommand } from '@aws-sdk/client-sso-oidc' + +export interface RegisteredClient { + clientId: string + clientSecret: string + clientSecretExpiresAt: number +} + +export interface DeviceAuthorization { + deviceCode: string + expiresIn: number + interval: number + userCode: string + verificationUri: string + verificationUriComplete: string +} + +export interface SsoToken { + accessToken: string + accessTokenExpiresAt: number + refreshToken?: string +} + +export interface SsoAccount { + accountId: string + accountName?: string + emailAddress?: string +} + +export interface SsoRole { + accountId: string + roleName: string +} + +export interface RoleCredentials { + accessKeyId: string + expiresAt: number + secretAccessKey: string + sessionToken: string +} + +const DEVICE_CODE_GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:device_code' +const REFRESH_TOKEN_GRANT_TYPE = 'refresh_token' + +export async function registerClient(region: string): Promise { + const client = getOidcClient(region) + const result = await client.send(new RegisterClientCommand({ + clientName: 'ssm-secrets', + clientType: 'public', + scopes: ['sso:account:access'], + })) + + if (!result.clientId || !result.clientSecret || !result.clientSecretExpiresAt) { + throw new Error('AWS SSO client registration returned incomplete data.') + } + + return { + clientId: result.clientId, + clientSecret: result.clientSecret, + clientSecretExpiresAt: result.clientSecretExpiresAt, + } +} + +export async function startDeviceAuthorization( + region: string, + clientId: string, + clientSecret: string, + startUrl: string, +): Promise { + const client = getOidcClient(region) + const result = await client.send(new StartDeviceAuthorizationCommand({ + clientId, + clientSecret, + startUrl, + })) + + if (!result.deviceCode || !result.userCode || !result.verificationUri || !result.verificationUriComplete || !result.expiresIn || !result.interval) { + throw new Error('AWS SSO device authorization returned incomplete data.') + } + + return { + deviceCode: result.deviceCode, + expiresIn: result.expiresIn, + interval: result.interval, + userCode: result.userCode, + verificationUri: result.verificationUri, + verificationUriComplete: result.verificationUriComplete, + } +} + +export async function createTokenFromDeviceCode( + region: string, + clientId: string, + clientSecret: string, + deviceCode: string, + intervalSeconds: number, + expiresInSeconds: number, +): Promise { + const client = getOidcClient(region) + const expiresAt = Date.now() + expiresInSeconds * 1000 + + let pollIntervalSeconds = intervalSeconds + + while (Date.now() < expiresAt) { + // oxlint-disable-next-line no-await-in-loop -- AWS device authorization requires sequential polling. + await sleep(pollIntervalSeconds * 1000) + + try { + // oxlint-disable-next-line no-await-in-loop -- AWS device authorization requires sequential polling. + const result = await client.send(new CreateTokenCommand({ + clientId, + clientSecret, + deviceCode, + grantType: DEVICE_CODE_GRANT_TYPE, + })) + + return parseTokenResult(result.accessToken, result.expiresIn, result.refreshToken) + } + catch (error) { + if (error instanceof AuthorizationPendingException) { + continue + } + if (error instanceof SlowDownException) { + pollIntervalSeconds += 5 + continue + } + throw error + } + } + + throw new Error('AWS SSO device authorization expired before login completed.') +} + +export async function refreshAccessToken( + region: string, + clientId: string, + clientSecret: string, + refreshToken: string, +): Promise { + const client = getOidcClient(region) + const result = await client.send(new CreateTokenCommand({ + clientId, + clientSecret, + grantType: REFRESH_TOKEN_GRANT_TYPE, + refreshToken, + })) + + return parseTokenResult(result.accessToken, result.expiresIn, result.refreshToken ?? refreshToken) +} + +export async function listAccounts(region: string, accessToken: string): Promise { + const client = getSsoClient(region) + const accounts: SsoAccount[] = [] + let nextToken: string | undefined + + do { + // oxlint-disable-next-line no-await-in-loop -- AWS pagination is sequential. + const result = await client.send(new ListAccountsCommand({ accessToken, nextToken })) + accounts.push(...(result.accountList ?? []).map(account => ({ + accountId: required(account.accountId, 'AWS SSO account is missing account ID.'), + accountName: account.accountName, + emailAddress: account.emailAddress, + }))) + nextToken = result.nextToken + } while (nextToken) + + return accounts +} + +export async function listRoles(region: string, accessToken: string, accountId: string): Promise { + const client = getSsoClient(region) + const roles: SsoRole[] = [] + let nextToken: string | undefined + + do { + // oxlint-disable-next-line no-await-in-loop -- AWS pagination is sequential. + const result = await client.send(new ListAccountRolesCommand({ accessToken, accountId, nextToken })) + roles.push(...(result.roleList ?? []).map(role => ({ + accountId: required(role.accountId, 'AWS SSO role is missing account ID.'), + roleName: required(role.roleName, 'AWS SSO role is missing role name.'), + }))) + nextToken = result.nextToken + } while (nextToken) + + return roles +} + +export async function getRoleCredentials(region: string, accessToken: string, accountId: string, roleName: string): Promise { + const client = getSsoClient(region) + const result = await client.send(new GetRoleCredentialsCommand({ accessToken, accountId, roleName })) + const credentials = result.roleCredentials + + if (!credentials?.accessKeyId || !credentials.secretAccessKey || !credentials.sessionToken || !credentials.expiration) { + throw new Error('AWS SSO role credentials response is incomplete.') + } + + return { + accessKeyId: credentials.accessKeyId, + expiresAt: credentials.expiration, + secretAccessKey: credentials.secretAccessKey, + sessionToken: credentials.sessionToken, + } +} + +export function getErrorReason(e: unknown): string | undefined { + if (e instanceof InvalidGrantException) { + return e.error_description + } + else if (e instanceof Error) { + return e.message + } + return undefined +} + +function getOidcClient(region: string): SSOOIDCClient { + return new SSOOIDCClient({ region }) +} + +function getSsoClient(region: string): SSOClient { + return new SSOClient({ region }) +} + +function parseTokenResult(accessToken: string | undefined, expiresIn: number | undefined, refreshToken: string | undefined): SsoToken { + if (!accessToken || !expiresIn) { + throw new Error('AWS SSO token response is incomplete.') + } + + return { + accessToken, + accessTokenExpiresAt: Date.now() + expiresIn * 1000, + refreshToken, + } +} + +function required(value: string | undefined, errorMessage: string): string { + if (!value) { + throw new Error(errorMessage) + } + return value +} + +function sleep(milliseconds: number): Promise { + return new Promise((resolve) => { + setTimeout(resolve, milliseconds) + }) +} diff --git a/src/utils.ts b/src/utils.ts index a5d20a0..f85b083 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -36,7 +36,7 @@ export function normalizePathAndName(path: string, name: string): string { */ export function formatEnv(parameter: SimplifiedParameter): string | undefined { if (!parameter.Name) { - return + return undefined } const name = escapeEnvName(parameter.Name).toUpperCase() @@ -45,7 +45,7 @@ export function formatEnv(parameter: SimplifiedParameter): string | undefined { } function escapeEnvName(name: string): string { - if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) { + if (/^[A-Za-z_][A-Za-z0-9_]*$/u.test(name)) { return name } // quote the name @@ -55,9 +55,9 @@ function escapeEnvName(name: string): string { // Adapted from https://github.com/xxorax/node-shell-escape function escapeEnvValue(value: string): string { let s = value - if (/[^A-Za-z0-9_/:=-]/.test(s)) { + if (/[^A-Za-z0-9_/:=-]/u.test(s)) { s = `'${s.replaceAll('\'', String.raw`'\''`)}'` - s = s.replaceAll(/^(?:'')+/g, '') // unduplicate single-quote at the beginning + s = s.replaceAll(/^(?:'')+/gu, '') // unduplicate single-quote at the beginning .replaceAll('\\\\\'\'\'', String.raw`\'`) // remove non-escaped single-quote if there are enclosed between 2 escaped } return s