diff --git a/package-lock.json b/package-lock.json index e4c6e81..8dfe88f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,11 @@ "name": "@logfox/cli", "version": "0.0.1", "dependencies": { + "@aws-sdk/client-cloudwatch-logs": "3.997.0", + "@aws-sdk/client-iam": "3.997.0", + "@aws-sdk/client-lambda": "3.997.0", + "@aws-sdk/client-sts": "3.997.0", + "@inquirer/prompts": "8.3.0", "commander": "12.1.0", "open": "10.1.0" }, @@ -20,6 +25,782 @@ "typescript": "5.8.3" } }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-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.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-cloudwatch-logs": { + "version": "3.997.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.997.0.tgz", + "integrity": "sha512-u0h34MhUdCOhmLcSBQVygxqpwS6AsYMjl5Brj/bFgsQpSh9zVy32ZSHROCvXKfvV3webY///WP44ZiXuSgQzZA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/credential-provider-node": "^3.972.12", + "@aws-sdk/middleware-host-header": "^3.972.4", + "@aws-sdk/middleware-logger": "^3.972.4", + "@aws-sdk/middleware-recursion-detection": "^3.972.4", + "@aws-sdk/middleware-user-agent": "^3.972.13", + "@aws-sdk/region-config-resolver": "^3.972.4", + "@aws-sdk/types": "^3.973.2", + "@aws-sdk/util-endpoints": "^3.996.1", + "@aws-sdk/util-user-agent-browser": "^3.972.4", + "@aws-sdk/util-user-agent-node": "^3.972.12", + "@smithy/config-resolver": "^4.4.7", + "@smithy/core": "^3.23.4", + "@smithy/eventstream-serde-browser": "^4.2.9", + "@smithy/eventstream-serde-config-resolver": "^4.3.9", + "@smithy/eventstream-serde-node": "^4.2.9", + "@smithy/fetch-http-handler": "^5.3.10", + "@smithy/hash-node": "^4.2.9", + "@smithy/invalid-dependency": "^4.2.9", + "@smithy/middleware-content-length": "^4.2.9", + "@smithy/middleware-endpoint": "^4.4.18", + "@smithy/middleware-retry": "^4.4.35", + "@smithy/middleware-serde": "^4.2.10", + "@smithy/middleware-stack": "^4.2.9", + "@smithy/node-config-provider": "^4.3.9", + "@smithy/node-http-handler": "^4.4.11", + "@smithy/protocol-http": "^5.3.9", + "@smithy/smithy-client": "^4.11.7", + "@smithy/types": "^4.12.1", + "@smithy/url-parser": "^4.2.9", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.34", + "@smithy/util-defaults-mode-node": "^4.2.37", + "@smithy/util-endpoints": "^3.2.9", + "@smithy/util-middleware": "^4.2.9", + "@smithy/util-retry": "^4.2.9", + "@smithy/util-utf8": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-iam": { + "version": "3.997.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-iam/-/client-iam-3.997.0.tgz", + "integrity": "sha512-y2O5hiR22jXsd/aTn0PAqpshye/nh2GuAUehoq39U3lqzd7APa2/2TihYUJwF6rAYZ68VRt1XQzfYC7cU82mPw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/credential-provider-node": "^3.972.12", + "@aws-sdk/middleware-host-header": "^3.972.4", + "@aws-sdk/middleware-logger": "^3.972.4", + "@aws-sdk/middleware-recursion-detection": "^3.972.4", + "@aws-sdk/middleware-user-agent": "^3.972.13", + "@aws-sdk/region-config-resolver": "^3.972.4", + "@aws-sdk/types": "^3.973.2", + "@aws-sdk/util-endpoints": "^3.996.1", + "@aws-sdk/util-user-agent-browser": "^3.972.4", + "@aws-sdk/util-user-agent-node": "^3.972.12", + "@smithy/config-resolver": "^4.4.7", + "@smithy/core": "^3.23.4", + "@smithy/fetch-http-handler": "^5.3.10", + "@smithy/hash-node": "^4.2.9", + "@smithy/invalid-dependency": "^4.2.9", + "@smithy/middleware-content-length": "^4.2.9", + "@smithy/middleware-endpoint": "^4.4.18", + "@smithy/middleware-retry": "^4.4.35", + "@smithy/middleware-serde": "^4.2.10", + "@smithy/middleware-stack": "^4.2.9", + "@smithy/node-config-provider": "^4.3.9", + "@smithy/node-http-handler": "^4.4.11", + "@smithy/protocol-http": "^5.3.9", + "@smithy/smithy-client": "^4.11.7", + "@smithy/types": "^4.12.1", + "@smithy/url-parser": "^4.2.9", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.34", + "@smithy/util-defaults-mode-node": "^4.2.37", + "@smithy/util-endpoints": "^3.2.9", + "@smithy/util-middleware": "^4.2.9", + "@smithy/util-retry": "^4.2.9", + "@smithy/util-utf8": "^4.2.1", + "@smithy/util-waiter": "^4.2.9", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda": { + "version": "3.997.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.997.0.tgz", + "integrity": "sha512-I/ThzsUILruu3Z+nhZIEy117uLSFNDhQuKaaVED1eBYY2uUkHbo4kbjv53a/acuLeEepffA3M3MBKPmvWFP3Sw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/credential-provider-node": "^3.972.12", + "@aws-sdk/middleware-host-header": "^3.972.4", + "@aws-sdk/middleware-logger": "^3.972.4", + "@aws-sdk/middleware-recursion-detection": "^3.972.4", + "@aws-sdk/middleware-user-agent": "^3.972.13", + "@aws-sdk/region-config-resolver": "^3.972.4", + "@aws-sdk/types": "^3.973.2", + "@aws-sdk/util-endpoints": "^3.996.1", + "@aws-sdk/util-user-agent-browser": "^3.972.4", + "@aws-sdk/util-user-agent-node": "^3.972.12", + "@smithy/config-resolver": "^4.4.7", + "@smithy/core": "^3.23.4", + "@smithy/eventstream-serde-browser": "^4.2.9", + "@smithy/eventstream-serde-config-resolver": "^4.3.9", + "@smithy/eventstream-serde-node": "^4.2.9", + "@smithy/fetch-http-handler": "^5.3.10", + "@smithy/hash-node": "^4.2.9", + "@smithy/invalid-dependency": "^4.2.9", + "@smithy/middleware-content-length": "^4.2.9", + "@smithy/middleware-endpoint": "^4.4.18", + "@smithy/middleware-retry": "^4.4.35", + "@smithy/middleware-serde": "^4.2.10", + "@smithy/middleware-stack": "^4.2.9", + "@smithy/node-config-provider": "^4.3.9", + "@smithy/node-http-handler": "^4.4.11", + "@smithy/protocol-http": "^5.3.9", + "@smithy/smithy-client": "^4.11.7", + "@smithy/types": "^4.12.1", + "@smithy/url-parser": "^4.2.9", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.34", + "@smithy/util-defaults-mode-node": "^4.2.37", + "@smithy/util-endpoints": "^3.2.9", + "@smithy/util-middleware": "^4.2.9", + "@smithy/util-retry": "^4.2.9", + "@smithy/util-stream": "^4.5.14", + "@smithy/util-utf8": "^4.2.1", + "@smithy/util-waiter": "^4.2.9", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sts": { + "version": "3.997.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.997.0.tgz", + "integrity": "sha512-kgS1aOYAqjyNYYk4sIbfTIU/n8EzHD644LP7eU6mCkEyiKtTu/7Wa8lBRgzpfcWUmfHEzGBswHt4P1MkP7Eqog==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/credential-provider-node": "^3.972.12", + "@aws-sdk/middleware-host-header": "^3.972.4", + "@aws-sdk/middleware-logger": "^3.972.4", + "@aws-sdk/middleware-recursion-detection": "^3.972.4", + "@aws-sdk/middleware-user-agent": "^3.972.13", + "@aws-sdk/region-config-resolver": "^3.972.4", + "@aws-sdk/types": "^3.973.2", + "@aws-sdk/util-endpoints": "^3.996.1", + "@aws-sdk/util-user-agent-browser": "^3.972.4", + "@aws-sdk/util-user-agent-node": "^3.972.12", + "@smithy/config-resolver": "^4.4.7", + "@smithy/core": "^3.23.4", + "@smithy/fetch-http-handler": "^5.3.10", + "@smithy/hash-node": "^4.2.9", + "@smithy/invalid-dependency": "^4.2.9", + "@smithy/middleware-content-length": "^4.2.9", + "@smithy/middleware-endpoint": "^4.4.18", + "@smithy/middleware-retry": "^4.4.35", + "@smithy/middleware-serde": "^4.2.10", + "@smithy/middleware-stack": "^4.2.9", + "@smithy/node-config-provider": "^4.3.9", + "@smithy/node-http-handler": "^4.4.11", + "@smithy/protocol-http": "^5.3.9", + "@smithy/smithy-client": "^4.11.7", + "@smithy/types": "^4.12.1", + "@smithy/url-parser": "^4.2.9", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.34", + "@smithy/util-defaults-mode-node": "^4.2.37", + "@smithy/util-endpoints": "^3.2.9", + "@smithy/util-middleware": "^4.2.9", + "@smithy/util-retry": "^4.2.9", + "@smithy/util-utf8": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.973.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.13.tgz", + "integrity": "sha512-eCFiLyBhJR7c/i8hZOETdzj2wsLFzi2L/w9/jajOgwmGqO8xrUExqkTZqdjROkwU62owqeqSuw4sIzlCv1E/ww==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.2", + "@aws-sdk/xml-builder": "^3.972.6", + "@smithy/core": "^3.23.4", + "@smithy/node-config-provider": "^4.3.9", + "@smithy/property-provider": "^4.2.9", + "@smithy/protocol-http": "^5.3.9", + "@smithy/signature-v4": "^5.3.9", + "@smithy/smithy-client": "^4.11.7", + "@smithy/types": "^4.12.1", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-middleware": "^4.2.9", + "@smithy/util-utf8": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.11.tgz", + "integrity": "sha512-hbyoFuVm3qOAGfIPS9t7jCs8GFLFoaOs8ZmYp/chqciuHDyEGv+J365ip7YSvXSrxxUbeW9NyB1hTLt40NBMRg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/types": "^3.973.2", + "@smithy/property-provider": "^4.2.9", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.972.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.13.tgz", + "integrity": "sha512-a864QxQWFkdCZ5wQF0QZNKTbqAc/DFQNeARp4gOyZZdql5RHjj4CppUSfwAzS9cpw2IPY3eeJjWqLZ1QiDB/6w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/types": "^3.973.2", + "@smithy/fetch-http-handler": "^5.3.10", + "@smithy/node-http-handler": "^4.4.11", + "@smithy/property-provider": "^4.2.9", + "@smithy/protocol-http": "^5.3.9", + "@smithy/smithy-client": "^4.11.7", + "@smithy/types": "^4.12.1", + "@smithy/util-stream": "^4.5.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.11.tgz", + "integrity": "sha512-kvPFn626ABLzxmjFMoqMRtmFKMeiUdWPhwxhmuPu233tqHnNuXzHv0MtrZlkzHd+rwlh9j0zCbQo89B54wIazQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/credential-provider-env": "^3.972.11", + "@aws-sdk/credential-provider-http": "^3.972.13", + "@aws-sdk/credential-provider-login": "^3.972.11", + "@aws-sdk/credential-provider-process": "^3.972.11", + "@aws-sdk/credential-provider-sso": "^3.972.11", + "@aws-sdk/credential-provider-web-identity": "^3.972.11", + "@aws-sdk/nested-clients": "^3.996.1", + "@aws-sdk/types": "^3.973.2", + "@smithy/credential-provider-imds": "^4.2.9", + "@smithy/property-provider": "^4.2.9", + "@smithy/shared-ini-file-loader": "^4.4.4", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.11.tgz", + "integrity": "sha512-stdy09EpBTmsxGiXe1vB5qtXNww9wact36/uWLlSV0/vWbCOUAY2JjhPXoDVLk8n+E6r0M5HeZseLk+iTtifxg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/nested-clients": "^3.996.1", + "@aws-sdk/types": "^3.973.2", + "@smithy/property-provider": "^4.2.9", + "@smithy/protocol-http": "^5.3.9", + "@smithy/shared-ini-file-loader": "^4.4.4", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.972.12", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.12.tgz", + "integrity": "sha512-gMWGnHbNSKWRj+PAiuSg0EDpEwpyIgk0v9U6EuZ1C/5/BUv25Way+E+UFB7r+YYkscuBJMJ+ai8E2K0Q8dx50g==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "^3.972.11", + "@aws-sdk/credential-provider-http": "^3.972.13", + "@aws-sdk/credential-provider-ini": "^3.972.11", + "@aws-sdk/credential-provider-process": "^3.972.11", + "@aws-sdk/credential-provider-sso": "^3.972.11", + "@aws-sdk/credential-provider-web-identity": "^3.972.11", + "@aws-sdk/types": "^3.973.2", + "@smithy/credential-provider-imds": "^4.2.9", + "@smithy/property-provider": "^4.2.9", + "@smithy/shared-ini-file-loader": "^4.4.4", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.11.tgz", + "integrity": "sha512-B049fvbv41vf0Fs5bCtbzHpruBDp61sPiFDxUmkAJ/zvgSAturpj2rqzV1rj2clg4mb44Uxp9rgpcODexNFlFA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/types": "^3.973.2", + "@smithy/property-provider": "^4.2.9", + "@smithy/shared-ini-file-loader": "^4.4.4", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.11.tgz", + "integrity": "sha512-vX9z8skN8vPtamVWmSCm4KQohub+1uMuRzIo4urZ2ZUMBAl1bqHatVD/roCb3qRfAyIGvZXCA/AWS03BQRMyCQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/nested-clients": "^3.996.1", + "@aws-sdk/token-providers": "3.997.0", + "@aws-sdk/types": "^3.973.2", + "@smithy/property-provider": "^4.2.9", + "@smithy/shared-ini-file-loader": "^4.4.4", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.11.tgz", + "integrity": "sha512-VR2Ju/QBdOjnWNIYuxRml63eFDLGc6Zl8aDwLi1rzgWo3rLBgtaWhWVBAijhVXzyPdQIOqdL8hvll5ybqumjeQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/nested-clients": "^3.996.1", + "@aws-sdk/types": "^3.973.2", + "@smithy/property-provider": "^4.2.9", + "@smithy/shared-ini-file-loader": "^4.4.4", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.972.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.4.tgz", + "integrity": "sha512-4q2Vg7/zOB10huDBLjzzTwVjBpG22X3J3ief2XrJEgTaANZrNfA3/cGbCVNAibSbu/nIYA7tDk8WCdsIzDDc4Q==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.2", + "@smithy/protocol-http": "^5.3.9", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.972.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.4.tgz", + "integrity": "sha512-xFqPvTysuZAHSkdygT+ken/5rzkR7fhOoDPejAJQslZpp0XBepmCJnDOqA57ERtCTBpu8wpjTFI1ETd4S0AXEw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.2", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.972.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.4.tgz", + "integrity": "sha512-tVbRaayUZ7y2bOb02hC3oEPTqQf2A0HpPDwdMl1qTmye/q8Mq1F1WiIoFkQwG/YQFvbyErYIDMbYzIlxzzLtjQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.2", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.9", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.972.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.13.tgz", + "integrity": "sha512-p1kVYbzBxRmhuOHoL/ANJPCedqUxnVgkEjxPoxt5pQv/yzppHM7aBWciYEE9TZY59M421D3GjLfZIZBoEFboVQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/types": "^3.973.2", + "@aws-sdk/util-endpoints": "^3.996.1", + "@smithy/core": "^3.23.4", + "@smithy/protocol-http": "^5.3.9", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.996.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.1.tgz", + "integrity": "sha512-XHVLFRGkuV2gh2uwBahCt65ALMb5wMpqplXEZIvFnWOCPlk60B7h7M5J9Em243K8iICDiWY6KhBEqVGfjTqlLA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/middleware-host-header": "^3.972.4", + "@aws-sdk/middleware-logger": "^3.972.4", + "@aws-sdk/middleware-recursion-detection": "^3.972.4", + "@aws-sdk/middleware-user-agent": "^3.972.13", + "@aws-sdk/region-config-resolver": "^3.972.4", + "@aws-sdk/types": "^3.973.2", + "@aws-sdk/util-endpoints": "^3.996.1", + "@aws-sdk/util-user-agent-browser": "^3.972.4", + "@aws-sdk/util-user-agent-node": "^3.972.12", + "@smithy/config-resolver": "^4.4.7", + "@smithy/core": "^3.23.4", + "@smithy/fetch-http-handler": "^5.3.10", + "@smithy/hash-node": "^4.2.9", + "@smithy/invalid-dependency": "^4.2.9", + "@smithy/middleware-content-length": "^4.2.9", + "@smithy/middleware-endpoint": "^4.4.18", + "@smithy/middleware-retry": "^4.4.35", + "@smithy/middleware-serde": "^4.2.10", + "@smithy/middleware-stack": "^4.2.9", + "@smithy/node-config-provider": "^4.3.9", + "@smithy/node-http-handler": "^4.4.11", + "@smithy/protocol-http": "^5.3.9", + "@smithy/smithy-client": "^4.11.7", + "@smithy/types": "^4.12.1", + "@smithy/url-parser": "^4.2.9", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.34", + "@smithy/util-defaults-mode-node": "^4.2.37", + "@smithy/util-endpoints": "^3.2.9", + "@smithy/util-middleware": "^4.2.9", + "@smithy/util-retry": "^4.2.9", + "@smithy/util-utf8": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.972.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.4.tgz", + "integrity": "sha512-3GrJYv5eI65oCKveBZP7Q246dVP+tqeys9aKMB0dfX1glUWfppWlxIu52derqdNb9BX9lxYmeiaBcBIqOAYSgQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.2", + "@smithy/config-resolver": "^4.4.7", + "@smithy/node-config-provider": "^4.3.9", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.997.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.997.0.tgz", + "integrity": "sha512-UdG36F7lU9aTqGFRieEyuRUJlgEJBqKeKKekC0esH21DbUSKhPR1kZBah214kYasIaWe1hLJLaqUigoTa5hZAQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.13", + "@aws-sdk/nested-clients": "^3.996.1", + "@aws-sdk/types": "^3.973.2", + "@smithy/property-provider": "^4.2.9", + "@smithy/shared-ini-file-loader": "^4.4.4", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.973.2", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.2.tgz", + "integrity": "sha512-maTZwGsALtnAw4TJr/S6yERAosTwPduu0XhUV+SdbvRZtCOgSgk1ttL2R0XYzvkYSpvbtJocn77tBXq2AKglBw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.996.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.1.tgz", + "integrity": "sha512-7cJyd+M5i0IoqWkJa1KFx8KNCGIx+Ywu+lT53KpqX7ReVwz03DCKUqvZ/y65vdKwo9w9/HptSAeLDluO5MpGIg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.2", + "@smithy/types": "^4.12.1", + "@smithy/url-parser": "^4.2.9", + "@smithy/util-endpoints": "^3.2.9", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.4.tgz", + "integrity": "sha512-H1onv5SkgPBK2P6JR2MjGgbOnttoNzSPIRoeZTNPZYyaplwGg50zS3amXvXqF0/qfXpWEC9rLWU564QTB9bSog==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.972.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.4.tgz", + "integrity": "sha512-GHb+8XHv6hfLWKQKAKaSOm+vRvogg07s+FWtbR3+eCXXPSFn9XVmiYF4oypAxH7dGIvoxkVG/buHEnzYukyJiA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.2", + "@smithy/types": "^4.12.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.972.12", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.12.tgz", + "integrity": "sha512-c1n3wBK6te+Vd9qU86nF8AsYuiBsxLn0AADGWyFX7vEADr3btaAg5iPQT6GYj6rvzSOEVVisvaAatOWInlJUbQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "^3.972.13", + "@aws-sdk/types": "^3.973.2", + "@smithy/node-config-provider": "^4.3.9", + "@smithy/types": "^4.12.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.6.tgz", + "integrity": "sha512-YrXu+UnfC8IdARa4ZkrpcyuRmA/TVgYW6Lcdtvi34NQgRjM1hTirNirN+rGb+s/kNomby8oJiIAu0KNbiZC7PA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.1", + "fast-xml-parser": "5.3.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.3.tgz", + "integrity": "sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", @@ -462,54 +1243,1067 @@ "node": ">=18" } }, - "node_modules/@types/node": { - "version": "20.17.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.22.tgz", - "integrity": "sha512-9RV2zST+0s3EhfrMZIhrz2bhuhBwxgkbHEwP2gtGWPjBzVQjifMzJ9exw7aDZhR1wbpj8zBrfp3bo8oJcGiUUw==", - "dev": true, + "node_modules/@inquirer/ansi": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.3.tgz", + "integrity": "sha512-g44zhR3NIKVs0zUesa4iMzExmZpLUdTLRMCStqX3GE5NT6VkPcxQGJ+uC8tDgBUC/vB1rUhUd55cOf++4NZcmw==", "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" } }, - "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "node_modules/@inquirer/checkbox": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.1.0.tgz", + "integrity": "sha512-/HjF1LN0a1h4/OFsbGKHNDtWICFU/dqXCdym719HFTyJo9IG7Otr+ziGWc9S0iQuohRZllh+WprSgd5UW5Fw0g==", "license": "MIT", "dependencies": { - "run-applescript": "^7.0.0" + "@inquirer/ansi": "^2.0.3", + "@inquirer/core": "^11.1.5", + "@inquirer/figures": "^2.0.3", + "@inquirer/type": "^4.0.3" }, "engines": { - "node": ">=18" + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "node_modules/@inquirer/confirm": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.0.8.tgz", + "integrity": "sha512-Di6dgmiZ9xCSUxWUReWTqDtbhXCuG2MQm2xmgSAIruzQzBqNf49b8E07/vbCYY506kDe8BiwJbegXweG8M1klw==", "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.5", + "@inquirer/type": "^4.0.3" + }, "engines": { - "node": ">=18" + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/default-browser": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", - "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "node_modules/@inquirer/core": { + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.1.5.tgz", + "integrity": "sha512-QQPAX+lka8GyLcZ7u7Nb1h6q72iZ/oy0blilC3IB2nSt1Qqxp7akt94Jqhi/DzARuN3Eo9QwJRvtl4tmVe4T5A==", "license": "MIT", "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" + "@inquirer/ansi": "^2.0.3", + "@inquirer/figures": "^2.0.3", + "@inquirer/type": "^4.0.3", + "cli-width": "^4.1.0", + "fast-wrap-ansi": "^0.2.0", + "mute-stream": "^3.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": ">=18" + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.0.8.tgz", + "integrity": "sha512-sLcpbb9B3XqUEGrj1N66KwhDhEckzZ4nI/W6SvLXyBX8Wic3LDLENlWRvkOGpCPoserabe+MxQkpiMoI8irvyA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.5", + "@inquirer/external-editor": "^2.0.3", + "@inquirer/type": "^4.0.3" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-5.0.8.tgz", + "integrity": "sha512-QieW3F1prNw3j+hxO7/NKkG1pk3oz7pOB6+5Upwu3OIwADfPX0oZVppsqlL+Vl/uBHHDSOBY0BirLctLnXwGGg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.5", + "@inquirer/type": "^4.0.3" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-2.0.3.tgz", + "integrity": "sha512-LgyI7Agbda74/cL5MvA88iDpvdXI2KuMBCGRkbCl2Dg1vzHeOgs+s0SDcXV7b+WZJrv2+ERpWSM65Fpi9VfY3w==", + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.3.tgz", + "integrity": "sha512-y09iGt3JKoOCBQ3w4YrSJdokcD8ciSlMIWsD+auPu+OZpfxLuyz+gICAQ6GCBOmJJt4KEQGHuZSVff2jiNOy7g==", + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + } + }, + "node_modules/@inquirer/input": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.0.8.tgz", + "integrity": "sha512-p0IJslw0AmedLEkOU+yrEX3Aj2RTpQq7ZOf8nc1DIhjzaxRWrrgeuE5Kyh39fVRgtcACaMXx/9WNo8+GjgBOfw==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.5", + "@inquirer/type": "^4.0.3" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-4.0.8.tgz", + "integrity": "sha512-uGLiQah9A0F9UIvJBX52m0CnqtLaym0WpT9V4YZrjZ+YRDKZdwwoEPz06N6w8ChE2lrnsdyhY9sL+Y690Kh9gQ==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.5", + "@inquirer/type": "^4.0.3" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-5.0.8.tgz", + "integrity": "sha512-zt1sF4lYLdvPqvmvHdmjOzuUUjuCQ897pdUCO8RbXMUDKXJTTyOQgtn23le+jwcb+MpHl3VAFvzIdxRAf6aPlA==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.3", + "@inquirer/core": "^11.1.5", + "@inquirer/type": "^4.0.3" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-8.3.0.tgz", + "integrity": "sha512-JAj66kjdH/F1+B7LCigjARbwstt3SNUOSzMdjpsvwJmzunK88gJeXmcm95L9nw1KynvFVuY4SzXh/3Y0lvtgSg==", + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^5.1.0", + "@inquirer/confirm": "^6.0.8", + "@inquirer/editor": "^5.0.8", + "@inquirer/expand": "^5.0.8", + "@inquirer/input": "^5.0.8", + "@inquirer/number": "^4.0.8", + "@inquirer/password": "^5.0.8", + "@inquirer/rawlist": "^5.2.4", + "@inquirer/search": "^4.1.4", + "@inquirer/select": "^5.1.0" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-5.2.4.tgz", + "integrity": "sha512-fTuJ5Cq9W286isLxwj6GGyfTjx1Zdk4qppVEPexFuA6yioCCXS4V1zfKroQqw7QdbDPN73xs2DiIAlo55+kBqg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.5", + "@inquirer/type": "^4.0.3" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.1.4.tgz", + "integrity": "sha512-9yPTxq7LPmYjrGn3DRuaPuPbmC6u3fiWcsE9ggfLcdgO/ICHYgxq7mEy1yJ39brVvgXhtOtvDVjDh9slJxE4LQ==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.1.5", + "@inquirer/figures": "^2.0.3", + "@inquirer/type": "^4.0.3" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.1.0.tgz", + "integrity": "sha512-OyYbKnchS1u+zRe14LpYrN8S0wH1vD0p2yKISvSsJdH2TpI87fh4eZdWnpdbrGauCRWDph3NwxRmM4Pcm/hx1Q==", + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.3", + "@inquirer/core": "^11.1.5", + "@inquirer/figures": "^2.0.3", + "@inquirer/type": "^4.0.3" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.3.tgz", + "integrity": "sha512-cKZN7qcXOpj1h+1eTTcGDVLaBIHNMT1Rz9JqJP5MnEJ0JhgVWllx7H/tahUp5YEK1qaByH2Itb8wLG/iScD5kw==", + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@smithy/abort-controller": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.10.tgz", + "integrity": "sha512-qocxM/X4XGATqQtUkbE9SPUB6wekBi+FyJOMbPj0AhvyvFGYEmOlz6VB22iMePCQsFmMIvFSeViDvA7mZJG47g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.9.tgz", + "integrity": "sha512-ejQvXqlcU30h7liR9fXtj7PIAau1t/sFbJpgWPfiYDs7zd16jpH0IsSXKcba2jF6ChTXvIjACs27kNMc5xxE2Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.10", + "@smithy/types": "^4.13.0", + "@smithy/util-config-provider": "^4.2.1", + "@smithy/util-endpoints": "^3.3.1", + "@smithy/util-middleware": "^4.2.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.23.6", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.6.tgz", + "integrity": "sha512-4xE+0L2NrsFKpEVFlFELkIHQddBvMbQ41LRIP74dGCXnY1zQ9DgksrBcRBDJT+iOzGy4VEJIeU3hkUK5mn06kg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-serde": "^4.2.11", + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-stream": "^4.5.15", + "@smithy/util-utf8": "^4.2.1", + "@smithy/uuid": "^1.1.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.10.tgz", + "integrity": "sha512-3bsMLJJLTZGZqVGGeBVFfLzuRulVsGTj12BzRKODTHqUABpIr0jMN1vN3+u6r2OfyhAQ2pXaMZWX/swBK5I6PQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.10", + "@smithy/property-provider": "^4.2.10", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.10.tgz", + "integrity": "sha512-A4ynrsFFfSXUHicfTcRehytppFBcY3HQxEGYiyGktPIOye3Ot7fxpiy4VR42WmtGI4Wfo6OXt/c1Ky1nUFxYYQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.10.tgz", + "integrity": "sha512-0xupsu9yj9oDVuQ50YCTS9nuSYhGlrwqdaKQel9y2Fz7LU9fNErVlw9N0o4pm4qqvWEGbSTI4HKc6XJfB30MVw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.10", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.10.tgz", + "integrity": "sha512-8kn6sinrduk0yaYHMJDsNuiFpXwQwibR7n/4CDUqn4UgaG+SeBHu5jHGFdU9BLFAM7Q4/gvr9RYxBHz9/jKrhA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.10.tgz", + "integrity": "sha512-uUrxPGgIffnYfvIOUmBM5i+USdEBRTdh7mLPttjphgtooxQ8CtdO1p6K5+Q4BBAZvKlvtJ9jWyrWpBJYzBKsyQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.10", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.10.tgz", + "integrity": "sha512-aArqzOEvcs2dK+xQVCgLbpJQGfZihw8SD4ymhkwNTtwKbnrzdhJsFDKuMQnam2kF69WzgJYOU5eJlCx+CA32bw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^4.2.10", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.11.tgz", + "integrity": "sha512-wbTRjOxdFuyEg0CpumjZO0hkUl+fetJFqxNROepuLIoijQh51aMBmzFLfoQdwRjxsuuS2jizzIUTjPWgd8pd7g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.10", + "@smithy/querystring-builder": "^4.2.10", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.10.tgz", + "integrity": "sha512-1VzIOI5CcsvMDvP3iv1vG/RfLJVVVc67dCRyLSB2Hn9SWCZrDO3zvcIzj3BfEtqRW5kcMg5KAeVf1K3dR6nD3w==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "@smithy/util-buffer-from": "^4.2.1", + "@smithy/util-utf8": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.10.tgz", + "integrity": "sha512-vy9KPNSFUU0ajFYk0sDZIYiUlAWGEAhRfehIr5ZkdFrRFTAuXEPUd41USuqHU6vvLX4r6Q9X7MKBco5+Il0Org==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.1.tgz", + "integrity": "sha512-Yfu664Qbf1B4IYIsYgKoABt010daZjkaCRvdU/sPnZG6TtHOB0md0RjNdLGzxe5UIdn9js4ftPICzmkRa9RJ4Q==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.10.tgz", + "integrity": "sha512-TQZ9kX5c6XbjhaEBpvhSvMEZ0klBs1CFtOdPFwATZSbC9UeQfKHPLPN9Y+I6wZGMOavlYTOlHEPDrt42PMSH9w==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.4.20", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.20.tgz", + "integrity": "sha512-9W6Np4ceBP3XCYAGLoMCmn8t2RRVzuD1ndWPLBbv7H9CrwM9Bprf6Up6BM9ZA/3alodg0b7Kf6ftBK9R1N04vw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.6", + "@smithy/middleware-serde": "^4.2.11", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/shared-ini-file-loader": "^4.4.5", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.10", + "@smithy/util-middleware": "^4.2.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.4.37", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.37.tgz", + "integrity": "sha512-/1psZZllBBSQ7+qo5+hhLz7AEPGLx3Z0+e3ramMBEuPK2PfvLK4SrncDB9VegX5mBn+oP/UTDrM6IHrFjvX1ZA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.10", + "@smithy/protocol-http": "^5.3.10", + "@smithy/service-error-classification": "^4.2.10", + "@smithy/smithy-client": "^4.12.0", + "@smithy/types": "^4.13.0", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-retry": "^4.2.10", + "@smithy/uuid": "^1.1.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.11.tgz", + "integrity": "sha512-STQdONGPwbbC7cusL60s7vOa6He6A9w2jWhoapL0mgVjmR19pr26slV+yoSP76SIssMTX/95e5nOZ6UQv6jolg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.10.tgz", + "integrity": "sha512-pmts/WovNcE/tlyHa8z/groPeOtqtEpp61q3W0nW1nDJuMq/x+hWa/OVQBtgU0tBqupeXq0VBOLA4UZwE8I0YA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.10.tgz", + "integrity": "sha512-UALRbJtVX34AdP2VECKVlnNgidLHA2A7YgcJzwSBg1hzmnO/bZBHl/LDQQyYifzUwp1UOODnl9JJ3KNawpUJ9w==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.10", + "@smithy/shared-ini-file-loader": "^4.4.5", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.12.tgz", + "integrity": "sha512-zo1+WKJkR9x7ZtMeMDAAsq2PufwiLDmkhcjpWPRRkmeIuOm6nq1qjFICSZbnjBvD09ei8KMo26BWxsu2BUU+5w==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.2.10", + "@smithy/protocol-http": "^5.3.10", + "@smithy/querystring-builder": "^4.2.10", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.10.tgz", + "integrity": "sha512-5jm60P0CU7tom0eNrZ7YrkgBaoLFXzmqB0wVS+4uK8PPGmosSrLNf6rRd50UBvukztawZ7zyA8TxlrKpF5z9jw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", + "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.10.tgz", + "integrity": "sha512-HeN7kEvuzO2DmAzLukE9UryiUvejD3tMp9a1D1NJETerIfKobBUCLfviP6QEk500166eD2IATaXM59qgUI+YDA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "@smithy/util-uri-escape": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.10.tgz", + "integrity": "sha512-4Mh18J26+ao1oX5wXJfWlTT+Q1OpDR8ssiC9PDOuEgVBGloqg18Fw7h5Ct8DyT9NBYwJgtJ2nLjKKFU6RP1G1Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.10.tgz", + "integrity": "sha512-0R/+/Il5y8nB/By90o8hy/bWVYptbIfvoTYad0igYQO5RefhNCDmNzqxaMx7K1t/QWo0d6UynqpqN5cCQt1MCg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.5.tgz", + "integrity": "sha512-pHgASxl50rrtOztgQCPmOXFjRW+mCd7ALr/3uXNzRrRoGV5G2+78GOsQ3HlQuBVHCh9o6xqMNvlIKZjWn4Euug==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.10.tgz", + "integrity": "sha512-Wab3wW8468WqTKIxI+aZe3JYO52/RYT/8sDOdzkUhjnLakLe9qoQqIcfih/qxcF4qWEFoWBszY0mj5uxffaVXA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.1", + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-uri-escape": "^4.2.1", + "@smithy/util-utf8": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.0.tgz", + "integrity": "sha512-R8bQ9K3lCcXyZmBnQqUZJF4ChZmtWT5NLi6x5kgWx5D+/j0KorXcA0YcFg/X5TOgnTCy1tbKc6z2g2y4amFupQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.6", + "@smithy/middleware-endpoint": "^4.4.20", + "@smithy/middleware-stack": "^4.2.10", + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", + "@smithy/util-stream": "^4.5.15", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", + "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.10.tgz", + "integrity": "sha512-uypjF7fCDsRk26u3qHmFI/ePL7bxxB9vKkE+2WKEciHhz+4QtbzWiHRVNRJwU3cKhrYDYQE3b0MRFtqfLYdA4A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^4.2.10", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.1.tgz", + "integrity": "sha512-BKGuawX4Doq/bI/uEmg+Zyc36rJKWuin3py89PquXBIBqmbnJwBBsmKhdHfNEp0+A4TDgLmT/3MSKZ1SxHcR6w==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.1", + "@smithy/util-utf8": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.1.tgz", + "integrity": "sha512-SiJeLiozrAoCrgDBUgsVbmqHmMgg/2bA15AzcbcW+zan7SuyAVHN4xTSbq0GlebAIwlcaX32xacnrG488/J/6g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.2.tgz", + "integrity": "sha512-4rHqBvxtJEBvsZcFQSPQqXP2b/yy/YlB66KlcEgcH2WNoOKCKB03DSLzXmOsXjbl8dJ4OEYTn31knhdznwk7zw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.1.tgz", + "integrity": "sha512-/swhmt1qTiVkaejlmMPPDgZhEaWb/HWMGRBheaxwuVkusp/z+ErJyQxO6kaXumOciZSWlmq6Z5mNylCd33X7Ig==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.1.tgz", + "integrity": "sha512-462id/00U8JWFw6qBuTSWfN5TxOHvDu4WliI97qOIOnuC/g+NDAknTU8eoGXEPlLkRVgWEr03jJBLV4o2FL8+A==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.3.36", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.36.tgz", + "integrity": "sha512-R0smq7EHQXRVMxkAxtH5akJ/FvgAmNF6bUy/GwY/N20T4GrwjT633NFm0VuRpC+8Bbv8R9A0DoJ9OiZL/M3xew==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.10", + "@smithy/smithy-client": "^4.12.0", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.2.39", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.39.tgz", + "integrity": "sha512-otWuoDm35btJV1L8MyHrPl462B07QCdMTktKc7/yM+Psv6KbED/ziXiHnmr7yPHUjfIwE9S8Max0LO24Mo3ZVg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^4.4.9", + "@smithy/credential-provider-imds": "^4.2.10", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/property-provider": "^4.2.10", + "@smithy/smithy-client": "^4.12.0", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.3.1.tgz", + "integrity": "sha512-xyctc4klmjmieQiF9I1wssBWleRV0RhJ2DpO8+8yzi2LO1Z+4IWOZNGZGNj4+hq9kdo+nyfrRLmQTzc16Op2Vg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.10", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.1.tgz", + "integrity": "sha512-c1hHtkgAWmE35/50gmdKajgGAKV3ePJ7t6UtEmpfCWJmQE9BQAQPz0URUVI89eSkcDqCtzqllxzG28IQoZPvwA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.10.tgz", + "integrity": "sha512-LxaQIWLp4y0r72eA8mwPNQ9va4h5KeLM0I3M/HV9klmFaY2kN766wf5vsTzmaOpNNb7GgXAd9a25P3h8T49PSA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.10.tgz", + "integrity": "sha512-HrBzistfpyE5uqTwiyLsFHscgnwB0kgv8vySp7q5kZ0Eltn/tjosaSGGDj/jJ9ys7pWzIP/icE2d+7vMKXLv7A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^4.2.10", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.15.tgz", + "integrity": "sha512-OlOKnaqnkU9X+6wEkd7mN+WB7orPbCVDauXOj22Q7VtiTkvy7ZdSsOg4QiNAZMgI4OkvNf+/VLUC3VXkxuWJZw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^5.3.11", + "@smithy/node-http-handler": "^4.4.12", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-buffer-from": "^4.2.1", + "@smithy/util-hex-encoding": "^4.2.1", + "@smithy/util-utf8": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.1.tgz", + "integrity": "sha512-YmiUDn2eo2IOiWYYvGQkgX5ZkBSiTQu4FlDo5jNPpAxng2t6Sjb6WutnZV9l6VR4eJul1ABmCrnWBC9hKHQa6Q==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.1.tgz", + "integrity": "sha512-DSIwNaWtmzrNQHv8g7DBGR9mulSit65KSj5ymGEIAknmIN8IpbZefEep10LaMG/P/xquwbmJ1h9ectz8z6mV6g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.10.tgz", + "integrity": "sha512-4eTWph/Lkg1wZEDAyObwme0kmhEb7J/JjibY2znJdrYRgKbKqB7YoEhhJVJ4R1g/SYih4zuwX7LpJaM8RsnTVg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.2.10", + "@smithy/types": "^4.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.1.tgz", + "integrity": "sha512-dSfDCeihDmZlV2oyr0yWPTUfh07suS+R5OB+FZGiv/hHyK3hrFBW5rR1UYjfa57vBsrP9lciFkRPzebaV1Qujw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@types/node": { + "version": "20.17.22", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.22.tgz", + "integrity": "sha512-9RV2zST+0s3EhfrMZIhrz2bhuhBwxgkbHEwP2gtGWPjBzVQjifMzJ9exw7aDZhR1wbpj8zBrfp3bo8oJcGiUUw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "license": "MIT" + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/default-browser-id": { @@ -578,6 +2372,48 @@ "@esbuild/win32-x64": "0.25.12" } }, + "node_modules/fast-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "license": "MIT" + }, + "node_modules/fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "license": "MIT", + "dependencies": { + "fast-string-truncated-width": "^3.0.2" + } + }, + "node_modules/fast-wrap-ansi": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.0.tgz", + "integrity": "sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==", + "license": "MIT", + "dependencies": { + "fast-string-width": "^3.0.2" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.6.tgz", + "integrity": "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^2.1.2" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -606,6 +2442,22 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/is-docker": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", @@ -654,6 +2506,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mute-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", + "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/open": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", @@ -694,6 +2555,42 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/strnum": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", + "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/tsx": { "version": "4.20.5", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.5.tgz", @@ -732,7 +2629,7 @@ "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, + "devOptional": true, "license": "MIT" } } diff --git a/package.json b/package.json index 8ecfe47..9fd6d16 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,11 @@ "typescript": "5.8.3" }, "dependencies": { + "@aws-sdk/client-cloudwatch-logs": "3.997.0", + "@aws-sdk/client-iam": "3.997.0", + "@aws-sdk/client-lambda": "3.997.0", + "@aws-sdk/client-sts": "3.997.0", + "@inquirer/prompts": "8.3.0", "commander": "12.1.0", "open": "10.1.0" } diff --git a/src/api.ts b/src/api.ts index be72ef4..5c8a7e8 100644 --- a/src/api.ts +++ b/src/api.ts @@ -14,7 +14,7 @@ async function apiCall(method: string, body?: unknown): Promise }; +export type Collector = 'cli' | 'cloudwatch-logs' | 'sdk' | 'vercel' | 'fluentbit'; + export async function ingestLogs(teamId: string, appId: string, env: string, logs: LogEntry[]): Promise> { + + const config = getConfig(); + + try { + + const response = await fetch(`${config.apiUrl}/v1/ingest`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${apiKey}`, + }, + body: JSON.stringify({appId, env, collector, logs}), + }); + + if (!response.ok) { + + const text = await response.text(); + return {ok: false, error: `API error: ${response.status} ${text}`}; + + } + + const data = await response.json() as {success: boolean; logsIngested: number; error?: string}; + + if ('error' in data && data.error) { + + return {ok: false, error: data.error}; + + } + + return {ok: true, data}; + + } catch (err) { + + return {ok: false, error: `Request failed: ${err}`}; + + } + +} diff --git a/src/commands/cloudwatch-remove.ts b/src/commands/cloudwatch-remove.ts new file mode 100644 index 0000000..df043eb --- /dev/null +++ b/src/commands/cloudwatch-remove.ts @@ -0,0 +1,218 @@ +import {STSClient, GetCallerIdentityCommand} from '@aws-sdk/client-sts'; +import { + CloudWatchLogsClient, + DescribeLogGroupsCommand, + DescribeSubscriptionFiltersCommand, + DeleteSubscriptionFilterCommand, + SubscriptionFilter, +} from '@aws-sdk/client-cloudwatch-logs'; +import {LambdaClient, GetFunctionCommand} from '@aws-sdk/client-lambda'; +import {checkbox, confirm} from '@inquirer/prompts'; + +const FORWARDER_LAMBDA_NAME = 'LogfoxForwarder'; + +interface LogfoxFilter { + logGroupName: string; + filterName: string; +} + +export async function cloudwatchRemove(): Promise { + + console.log('Logfox CloudWatch Remove'); + console.log('========================'); + console.log(); + + // 1. Check AWS credentials + console.log('Checking AWS credentials...'); + + const sts = new STSClient({}); + let region: string; + + try { + + const identity = await sts.send(new GetCallerIdentityCommand({})); + region = await sts.config.region() as string; + console.log(`✓ Using AWS account ${identity.Account} (${region})`); + + } catch { + + console.error('✗ Failed to get AWS credentials.'); + console.error(' Make sure you have AWS credentials configured.'); + console.error(' Run: aws configure'); + process.exit(1); + + } + + console.log(); + + // 2. Get Lambda ARN + console.log('Looking for Logfox Forwarder Lambda...'); + + const lambdaClient = new LambdaClient({}); + let lambdaArn: string | undefined; + + try { + + const lambda = await lambdaClient.send(new GetFunctionCommand({ + FunctionName: FORWARDER_LAMBDA_NAME, + })); + + lambdaArn = lambda.Configuration?.FunctionArn; + console.log(`✓ Found Lambda: ${FORWARDER_LAMBDA_NAME}`); + + } catch { + + console.log('⚠ Lambda not found. Will search for subscription filters by name.'); + + } + + console.log(); + + // 3. Find all subscription filters pointing to Logfox + console.log('Scanning for Logfox subscription filters...'); + + const logsClient = new CloudWatchLogsClient({}); + const logfoxFilters: LogfoxFilter[] = []; + + // Get all log groups + let nextToken: string | undefined; + + do { + + const logGroupsResponse = await logsClient.send(new DescribeLogGroupsCommand({nextToken})); + + for (const logGroup of logGroupsResponse.logGroups || []) { + + if (!logGroup.logGroupName) continue; + + try { + + const filtersResponse = await logsClient.send(new DescribeSubscriptionFiltersCommand({ + logGroupName: logGroup.logGroupName, + })); + + for (const filter of filtersResponse.subscriptionFilters || []) { + + if (isLogfoxFilter(filter, lambdaArn)) { + + logfoxFilters.push({ + logGroupName: logGroup.logGroupName, + filterName: filter.filterName!, + }); + + } + + } + + } catch { + // Ignore errors for individual log groups + } + + } + + nextToken = logGroupsResponse.nextToken; + + } while (nextToken); + + if (logfoxFilters.length === 0) { + + console.log('No Logfox subscription filters found.'); + console.log('Nothing to remove.'); + process.exit(0); + + } + + console.log(`Found ${logfoxFilters.length} Logfox subscription filter(s)`); + console.log(); + + // 4. Let user select which to remove + const toRemove = await checkbox({ + message: 'Select subscription filters to remove:', + choices: logfoxFilters.map((f) => ({ + name: f.logGroupName, + value: f, + checked: true, + })), + pageSize: 15, + }); + + if (toRemove.length === 0) { + + console.log('No filters selected. Exiting.'); + process.exit(0); + + } + + console.log(); + + // 5. Confirm + const proceed = await confirm({ + message: `Remove ${toRemove.length} subscription filter(s)?`, + default: true, + }); + + if (!proceed) { + + console.log('Cancelled.'); + process.exit(0); + + } + + console.log(); + + // 6. Delete selected filters + console.log('Removing subscription filters...'); + + for (const filter of toRemove) { + + try { + + await logsClient.send(new DeleteSubscriptionFilterCommand({ + logGroupName: filter.logGroupName, + filterName: filter.filterName, + })); + + console.log(`✓ Removed subscription filter for ${filter.logGroupName}`); + + } catch (error) { + + console.error(`✗ Failed to remove filter for ${filter.logGroupName}:`, error); + + } + + } + + console.log(); + console.log('Done! The selected log groups will no longer send logs to Logfox.'); + console.log(); + console.log('Note: The Logfox Forwarder Lambda is still deployed.'); + console.log('To completely remove it, delete the Lambda manually in the AWS Console.'); + +} + +function isLogfoxFilter(filter: SubscriptionFilter, lambdaArn?: string): boolean { + + // Check if filter name is 'logfox' + if (filter.filterName === 'logfox') { + + return true; + + } + + // Check if destination is the Logfox Lambda + if (lambdaArn && filter.destinationArn === lambdaArn) { + + return true; + + } + + // Check if destination contains 'LogfoxForwarder' + if (filter.destinationArn?.includes('LogfoxForwarder')) { + + return true; + + } + + return false; + +} diff --git a/src/commands/config.ts b/src/commands/config.ts index fec2507..0da50a8 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -8,11 +8,11 @@ export function showConfig(): void { console.log(JSON.stringify(config, null, 2)); console.log(); console.log('Commands:'); - console.log(' logspace config:get Get a config value'); - console.log(' logspace config:set Set a config value'); - console.log(' logspace config:reset Reset to defaults'); + console.log(' logfox config:get Get a config value'); + console.log(' logfox config:set Set a config value'); + console.log(' logfox config:reset Reset to defaults'); console.log(); - console.log('Valid keys: apiUrl, appUrl, teamId'); + console.log('Valid keys: apiUrl, appUrl, teamId, apiKey'); } @@ -34,14 +34,23 @@ export function getConfigValue(key: string): void { export async function setConfig(key: string, value: string): Promise { - if (key !== 'apiUrl' && key !== 'appUrl' && key !== 'teamId') { + if (key !== 'apiUrl' && key !== 'appUrl' && key !== 'teamId' && key !== 'apiKey') { console.error(`Invalid config key: ${key}`); - console.log('Valid keys: apiUrl, appUrl, teamId'); + console.log('Valid keys: apiUrl, appUrl, teamId, apiKey'); process.exit(1); } + // If setting apiKey, just save it directly + if (key === 'apiKey') { + + saveConfig({apiKey: value}); + console.log('API key saved.'); + return; + + } + // If setting teamId, also fetch and save the team name if (key === 'teamId') { diff --git a/src/commands/login.ts b/src/commands/login.ts index fb230f3..d9192e7 100644 --- a/src/commands/login.ts +++ b/src/commands/login.ts @@ -17,7 +17,7 @@ export async function login(): Promise { if (result.ok) { console.log(`Already logged in as ${result.data.email}`); - console.log('Run "logspace logout" to sign out first.'); + console.log('Run "logfox logout" to sign out first.'); return; } @@ -76,7 +76,7 @@ export async function login(): Promise { if (teamsResult.data.length > 1) { - console.log(`(You have ${teamsResult.data.length} teams. Run "logspace teams" to see all.)`); + console.log(`(You have ${teamsResult.data.length} teams. Run "logfox teams" to see all.)`); } @@ -110,7 +110,7 @@ function waitForAuthCallback(): Promise { res.writeHead(200, {'Content-Type': 'text/html'}); res.end(` - Logspace CLI + Logfox CLI

Login Successful!

You can close this window and return to the terminal.

diff --git a/src/commands/run.ts b/src/commands/run.ts index 60cde86..4f87b3a 100644 --- a/src/commands/run.ts +++ b/src/commands/run.ts @@ -10,6 +10,7 @@ const FLUSH_INTERVAL_MS = 3000; // 3s type RunOptions = { name: string + env: string }; function generateUserHash(userId: string): string { @@ -21,25 +22,43 @@ function generateUserHash(userId: string): string { export async function run(command: string[], options: RunOptions): Promise { const config = getConfig(); + const env = options.env || 'local'; + const isLocal = env === 'local'; - if (!config.authToken) { + // For non-local environments, we require API key auth + if (!isLocal) { - console.error('Not logged in. Run "logspace login" first.'); - process.exit(1); + if (!config.apiKey) { - } + console.error('API key not configured. Run "logfox config:set apiKey " first.'); + console.error('You can find your API key in the Logfox dashboard under Settings.'); + process.exit(1); - if (!config.teamId) { + } - console.error('No team configured. Run "logspace login" first.'); - process.exit(1); + } else { - } + // For local, we still support the old auth token flow + if (!config.authToken) { - if (!config.userId) { + console.error('Not logged in. Run "logfox login" first.'); + process.exit(1); - console.error('User ID not found. Run "logspace logout" then "logspace login" again.'); - process.exit(1); + } + + if (!config.teamId) { + + console.error('No team configured. Run "logfox login" first.'); + process.exit(1); + + } + + if (!config.userId) { + + console.error('User ID not found. Run "logfox logout" then "logfox login" again.'); + process.exit(1); + + } } @@ -53,46 +72,61 @@ export async function run(command: string[], options: RunOptions): Promise if (command.length === 0) { console.error('Please provide a command to run'); - console.error('Example: logspace run --name my-app -- npm start'); + console.error('Example: logfox run --name my-app -- npm start'); process.exit(1); } - // Build deterministic app name: local-{hash}-{label} - const userHash = generateUserHash(config.userId); + // Build app name - for local, use deterministic name with user hash const label = options.name.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, ''); - const appName = `local-${userHash}-${label}`; + let appName: string; - console.log(`Setting up local app "${appName}"...`); + if (isLocal && config.userId) { - // Search for existing app - const searchResult = await api.searchApps({teamId: config.teamId, name: appName}); + const userHash = generateUserHash(config.userId); + appName = `local-${userHash}-${label}`; - let app: App; + } else { - if (searchResult.ok && searchResult.data.length > 0) { + appName = label; - app = searchResult.data[0]; - console.log(`Found existing app: ${app.name}`); + } - } else { + console.log(`Setting up app "${appName}" for env "${env}"...`); - // Create new app - const createResult = await api.createApp({teamId: config.teamId, name: appName}); + // For local env with auth token, create/find app via API + let app: App | undefined; - if (!createResult.ok) { + if (isLocal && config.teamId) { - console.error('Failed to create local app:', createResult.error); - process.exit(1); + // Search for existing app + const searchResult = await api.searchApps({teamId: config.teamId, name: appName}); - } + if (searchResult.ok && searchResult.data.length > 0) { + + app = searchResult.data[0]; + console.log(`Found existing app: ${app.name}`); + + } else { + + // Create new app + const createResult = await api.createApp({teamId: config.teamId, name: appName}); + + if (!createResult.ok) { + + console.error('Failed to create local app:', createResult.error); + process.exit(1); - app = createResult.data; - console.log(`Created new app: ${app.name}`); + } + + app = createResult.data; + console.log(`Created new app: ${app.name}`); + + } } - console.log(`Logs will appear in Logspace under env "local", app "${app.name}"`); + console.log(`Logs will appear in Logfox under env "${env}", app "${appName}"`); console.log(); // Start the child process @@ -102,8 +136,9 @@ export async function run(command: string[], options: RunOptions): Promise shell: true, env: { ...process.env, - LOGSPACE_APP_ID: app.id, - LOGSPACE_APP_NAME: app.name, + LOGFOX_APP_ID: app?.id || appName, + LOGFOX_APP_NAME: appName, + LOGFOX_ENV: env, }, }); @@ -118,11 +153,27 @@ export async function run(command: string[], options: RunOptions): Promise const logsToSend = logBuffer; logBuffer = []; - const result = await api.ingestLogs(config.teamId!, app.id, 'local', logsToSend); + // Use API key auth for non-local, or if API key is available + if (config.apiKey) { + + const result = await api.ingestLogsV1(config.apiKey, appName, env, 'cli', logsToSend); + + if (!result.ok) { + + console.error(`[logfox] Failed to send logs: ${result.error}`); + + } + + } else if (isLocal && config.teamId && app) { + + // Fall back to old auth token method for local + const result = await api.ingestLogs(config.teamId, app.id, 'local', logsToSend); + + if (!result.ok) { - if (!result.ok) { + console.error(`[logfox] Failed to send logs: ${result.error}`); - console.error(`[logspace] Failed to send logs: ${result.error}`); + } } @@ -161,7 +212,7 @@ export async function run(command: string[], options: RunOptions): Promise // Flush if buffer is full if (logBuffer.length >= BATCH_SIZE) { - flushLogs(); + void flushLogs(); } else { diff --git a/src/commands/sessions.ts b/src/commands/sessions.ts index b0f7d6a..aab5cfa 100644 --- a/src/commands/sessions.ts +++ b/src/commands/sessions.ts @@ -7,14 +7,14 @@ export async function listSessions(): Promise { if (!config.teamId) { - console.error('No team configured. Run "logspace login" first.'); + console.error('No team configured. Run "logfox login" first.'); process.exit(1); } if (!config.userId) { - console.error('User ID not found. Run "logspace logout" then "logspace login" again.'); + console.error('User ID not found. Run "logfox logout" then "logfox login" again.'); process.exit(1); } @@ -35,7 +35,7 @@ export async function listSessions(): Promise { if (localApps.length === 0) { console.log('No local dev apps found.'); - console.log('Create one with: logspace run --name -- '); + console.log('Create one with: logfox run --name -- '); return; } @@ -80,7 +80,7 @@ export async function deleteSession(appId: string): Promise { if (!config.teamId) { - console.error('No team configured. Run "logspace login" first.'); + console.error('No team configured. Run "logfox login" first.'); process.exit(1); } diff --git a/src/commands/setup-cloudwatch.ts b/src/commands/setup-cloudwatch.ts new file mode 100644 index 0000000..64d649e --- /dev/null +++ b/src/commands/setup-cloudwatch.ts @@ -0,0 +1,426 @@ +/* eslint-disable max-lines-per-function */ +import {STSClient, GetCallerIdentityCommand} from '@aws-sdk/client-sts'; +import { + CloudWatchLogsClient, + DescribeLogGroupsCommand, + PutSubscriptionFilterCommand, + LogGroup, +} from '@aws-sdk/client-cloudwatch-logs'; +import { + LambdaClient, + CreateFunctionCommand, + GetFunctionCommand, + UpdateFunctionConfigurationCommand, + AddPermissionCommand, + ResourceConflictException, +} from '@aws-sdk/client-lambda'; +import { + IAMClient, + CreateRoleCommand, + AttachRolePolicyCommand, + GetRoleCommand, + EntityAlreadyExistsException, +} from '@aws-sdk/client-iam'; +import {input, checkbox, confirm} from '@inquirer/prompts'; +import {getConfig, saveConfig} from '../config'; + +const FORWARDER_LAMBDA_NAME = 'LogfoxForwarder'; +const FORWARDER_ROLE_NAME = 'LogfoxForwarderRole'; +const FORWARDER_S3_BUCKET = 'logfox-public-assets'; +const FORWARDER_S3_KEY = 'forwarder/v1/forwarder.zip'; + +interface LogGroupMapping { + logGroup: string; + appName: string; + env: string; +} + +export async function setupCloudwatch(): Promise { + + const config = getConfig(); + + console.log('Logfox CloudWatch Setup'); + console.log('======================='); + console.log(); + + // 1. Check AWS credentials + console.log('Checking AWS credentials...'); + + const sts = new STSClient({}); + let accountId: string; + let region: string; + + try { + + const identity = await sts.send(new GetCallerIdentityCommand({})); + accountId = identity.Account!; + region = await sts.config.region() as string; + console.log(`✓ Using AWS account ${accountId} (${region})`); + + } catch (error) { + + console.error('✗ Failed to get AWS credentials.'); + console.error(' Make sure you have AWS credentials configured.'); + console.error(' Run: aws configure'); + process.exit(1); + + } + + console.log(); + + // 2. Get or prompt for API key + let apiKey = config.apiKey; + + if (!apiKey) { + + apiKey = await input({ + message: 'Enter your Logfox API key:', + validate: (value) => value.length > 0 || 'API key is required', + }); + + saveConfig({apiKey}); + console.log('✓ API key saved'); + + } else { + + console.log(`✓ Using saved API key`); + + } + + console.log(); + + // 3. List log groups + console.log('Scanning for log groups...'); + + const logsClient = new CloudWatchLogsClient({}); + const logGroups: LogGroup[] = []; + let nextToken: string | undefined; + + do { + + const response = await logsClient.send(new DescribeLogGroupsCommand({nextToken})); + logGroups.push(...(response.logGroups || [])); + nextToken = response.nextToken; + + } while (nextToken); + + if (logGroups.length === 0) { + + console.log('No log groups found in this region.'); + console.log('Make sure you have CloudWatch log groups to monitor.'); + process.exit(1); + + } + + console.log(`Found ${logGroups.length} log groups in ${region}`); + console.log(); + + // 4. Let user select log groups + const selectedLogGroups = await checkbox({ + message: 'Select log groups to monitor:', + choices: logGroups.map((lg) => ({ + name: lg.logGroupName!, + value: lg.logGroupName!, + })), + pageSize: 15, + }); + + if (selectedLogGroups.length === 0) { + + console.log('No log groups selected. Exiting.'); + process.exit(0); + + } + + console.log(); + + // 5. Configure app/env mapping for each log group + console.log('Configure log routing:'); + console.log('(For each log group, specify the app name and environment)'); + console.log(); + + const mappings: LogGroupMapping[] = []; + + for (const logGroup of selectedLogGroups) { + + // Try to suggest app name from log group name + const suggestedApp = suggestAppName(logGroup); + + const appName = await input({ + message: `${logGroup} → App name:`, + default: suggestedApp, + validate: (value) => value.length > 0 || 'App name is required', + }); + + const env = await input({ + message: `${logGroup} → Environment:`, + default: suggestEnv(logGroup), + validate: (value) => value.length > 0 || 'Environment is required', + }); + + mappings.push({logGroup, appName, env}); + + } + + console.log(); + + // 6. Confirm + console.log('Summary:'); + + for (const m of mappings) { + + console.log(` ${m.logGroup} → ${m.appName} (${m.env})`); + + } + + console.log(); + + const proceed = await confirm({ + message: 'Deploy Logfox Forwarder Lambda?', + default: true, + }); + + if (!proceed) { + + console.log('Setup cancelled.'); + process.exit(0); + + } + + console.log(); + + // 7. Create IAM role + console.log('Setting up IAM role...'); + + const iamClient = new IAMClient({}); + let roleArn: string; + + try { + + const existingRole = await iamClient.send(new GetRoleCommand({RoleName: FORWARDER_ROLE_NAME})); + roleArn = existingRole.Role!.Arn!; + console.log(`✓ Using existing IAM role: ${FORWARDER_ROLE_NAME}`); + + } catch { + + try { + + const createRoleResult = await iamClient.send(new CreateRoleCommand({ + RoleName: FORWARDER_ROLE_NAME, + AssumeRolePolicyDocument: JSON.stringify({ + Version: '2012-10-17', + Statement: [{ + Effect: 'Allow', + Principal: {Service: 'lambda.amazonaws.com'}, + Action: 'sts:AssumeRole', + }], + }), + Description: 'IAM role for Logfox Forwarder Lambda', + })); + + roleArn = createRoleResult.Role!.Arn!; + + // Attach basic execution policy + await iamClient.send(new AttachRolePolicyCommand({ + RoleName: FORWARDER_ROLE_NAME, + PolicyArn: 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', + })); + + console.log(`✓ Created IAM role: ${FORWARDER_ROLE_NAME}`); + + // Wait for role to propagate + console.log(' Waiting for role to propagate...'); + await sleep(10000); + + } catch (error) { + + if (error instanceof EntityAlreadyExistsException) { + + const existingRole = await iamClient.send(new GetRoleCommand({RoleName: FORWARDER_ROLE_NAME})); + roleArn = existingRole.Role!.Arn!; + console.log(`✓ Using existing IAM role: ${FORWARDER_ROLE_NAME}`); + + } else { + + throw error; + + } + + } + + } + + // 8. Create or update Lambda function + console.log('Setting up Lambda function...'); + + const lambdaClient = new LambdaClient({}); + const logGroupMappings: Record = {}; + + for (const m of mappings) { + + logGroupMappings[m.logGroup] = {appId: m.appName, env: m.env}; + + } + + const lambdaEnv = { + LOGFOX_ENDPOINT: `${config.apiUrl}/v1/ingest`, + LOGFOX_API_KEY: apiKey, + LOG_GROUP_MAPPINGS: JSON.stringify(logGroupMappings), + }; + + let lambdaArn: string; + + try { + + // Check if Lambda exists + const existingLambda = await lambdaClient.send(new GetFunctionCommand({ + FunctionName: FORWARDER_LAMBDA_NAME, + })); + + lambdaArn = existingLambda.Configuration!.FunctionArn!; + + // Update environment variables + await lambdaClient.send(new UpdateFunctionConfigurationCommand({ + FunctionName: FORWARDER_LAMBDA_NAME, + Environment: {Variables: lambdaEnv}, + })); + + console.log(`✓ Updated existing Lambda: ${FORWARDER_LAMBDA_NAME}`); + + } catch { + + // Create new Lambda + try { + + const createResult = await lambdaClient.send(new CreateFunctionCommand({ + FunctionName: FORWARDER_LAMBDA_NAME, + Runtime: 'nodejs20.x', + Role: roleArn, + Handler: 'index.handler', + Code: { + S3Bucket: FORWARDER_S3_BUCKET, + S3Key: FORWARDER_S3_KEY, + }, + Environment: {Variables: lambdaEnv}, + Timeout: 30, + MemorySize: 128, + Description: 'Forwards CloudWatch logs to Logfox', + })); + + lambdaArn = createResult.FunctionArn!; + console.log(`✓ Created Lambda: ${FORWARDER_LAMBDA_NAME}`); + + } catch (error) { + + if (error instanceof ResourceConflictException) { + + // Lambda is being created, wait and retry + console.log(' Lambda is being created, waiting...'); + await sleep(5000); + const existingLambda = await lambdaClient.send(new GetFunctionCommand({ + FunctionName: FORWARDER_LAMBDA_NAME, + })); + lambdaArn = existingLambda.Configuration!.FunctionArn!; + + } else { + + throw error; + + } + + } + + } + + // 9. Create subscription filters + console.log('Creating subscription filters...'); + + for (const m of mappings) { + + try { + + // Add permission for CloudWatch Logs to invoke Lambda + try { + + await lambdaClient.send(new AddPermissionCommand({ + FunctionName: FORWARDER_LAMBDA_NAME, + StatementId: `logfox-${m.logGroup.replace(/\//g, '-').replace(/^-/, '')}`, + Action: 'lambda:InvokeFunction', + Principal: 'logs.amazonaws.com', + SourceArn: `arn:aws:logs:${region}:${accountId}:log-group:${m.logGroup}:*`, + })); + + } catch { + // Permission may already exist + } + + await logsClient.send(new PutSubscriptionFilterCommand({ + logGroupName: m.logGroup, + filterName: 'logfox', + destinationArn: lambdaArn, + filterPattern: '', + })); + + console.log(`✓ Created subscription filter for ${m.logGroup}`); + + } catch (error) { + + console.error(`✗ Failed to create subscription filter for ${m.logGroup}:`, error); + + } + + } + + console.log(); + console.log('Done! Logs will appear in Logfox within ~30 seconds.'); + console.log(); + console.log('To add more log groups later, run: logfox setup cloudwatch'); + console.log('To remove log groups, run: logfox cloudwatch remove'); + +} + +function suggestAppName(logGroup: string): string { + + // Extract app name from common log group patterns + // /aws/lambda/my-app-prod → my-app + // /ecs/my-service → my-service + + const parts = logGroup.split('/').filter(Boolean); + + if (parts.length >= 3 && parts[0] === 'aws' && parts[1] === 'lambda') { + + // Remove common suffixes like -prod, -staging, -dev + return parts[2].replace(/-(prod|production|staging|dev|development|test)$/i, ''); + + } + + if (parts.length >= 2 && parts[0] === 'ecs') { + + return parts[1].replace(/-(prod|production|staging|dev|development|test)$/i, ''); + + } + + // Default: use last part + const last = parts[parts.length - 1] || 'app'; + return last.replace(/-(prod|production|staging|dev|development|test)$/i, ''); + +} + +function suggestEnv(logGroup: string): string { + + const lower = logGroup.toLowerCase(); + + if (lower.includes('prod')) return 'production'; + if (lower.includes('staging')) return 'staging'; + if (lower.includes('dev')) return 'development'; + if (lower.includes('test')) return 'test'; + + return 'production'; + +} + +function sleep(ms: number): Promise { + + return new Promise((resolve) => setTimeout(resolve, ms)); + +} diff --git a/src/commands/status.ts b/src/commands/status.ts index 81aa5be..3af358f 100644 --- a/src/commands/status.ts +++ b/src/commands/status.ts @@ -7,7 +7,7 @@ export function showStatus(): void { if (!config.authToken) { console.log('Not logged in.'); - console.log('Run "logspace login" to authenticate.'); + console.log('Run "logfox login" to authenticate.'); return; } diff --git a/src/commands/teams.ts b/src/commands/teams.ts index f152b37..a521363 100644 --- a/src/commands/teams.ts +++ b/src/commands/teams.ts @@ -7,7 +7,7 @@ export async function listTeams(): Promise { if (!config.authToken) { - console.error('Not logged in. Run "logspace login" first.'); + console.error('Not logged in. Run "logfox login" first.'); process.exit(1); } @@ -40,6 +40,6 @@ export async function listTeams(): Promise { } - console.log('To switch teams: logspace config:set teamId '); + console.log('To switch teams: logfox config:set teamId '); } diff --git a/src/commands/update-cloudwatch.ts b/src/commands/update-cloudwatch.ts new file mode 100644 index 0000000..94411e1 --- /dev/null +++ b/src/commands/update-cloudwatch.ts @@ -0,0 +1,82 @@ +import {LambdaClient, UpdateFunctionCodeCommand, GetFunctionCommand} from '@aws-sdk/client-lambda'; +import {STSClient, GetCallerIdentityCommand} from '@aws-sdk/client-sts'; + +const FORWARDER_LAMBDA_NAME = 'LogfoxForwarder'; +const FORWARDER_S3_BUCKET = 'logfox-public-assets'; +const FORWARDER_S3_KEY = 'forwarder/v1/forwarder.zip'; + +export async function updateCloudwatch(): Promise { + + console.log('Logfox CloudWatch Update'); + console.log('========================'); + console.log(); + + // 1. Check AWS credentials + console.log('Checking AWS credentials...'); + + const sts = new STSClient({}); + + try { + + const identity = await sts.send(new GetCallerIdentityCommand({})); + const region = await sts.config.region() as string; + console.log(`✓ Using AWS account ${identity.Account} (${region})`); + + } catch { + + console.error('✗ Failed to get AWS credentials.'); + console.error(' Make sure you have AWS credentials configured.'); + console.error(' Run: aws configure'); + process.exit(1); + + } + + console.log(); + + // 2. Check if Lambda exists + console.log('Checking for existing Logfox Forwarder Lambda...'); + + const lambdaClient = new LambdaClient({}); + + try { + + await lambdaClient.send(new GetFunctionCommand({ + FunctionName: FORWARDER_LAMBDA_NAME, + })); + + console.log(`✓ Found Lambda: ${FORWARDER_LAMBDA_NAME}`); + + } catch { + + console.error(`✗ Lambda "${FORWARDER_LAMBDA_NAME}" not found.`); + console.error(' Run "logfox setup cloudwatch" first to deploy the Lambda.'); + process.exit(1); + + } + + console.log(); + + // 3. Update Lambda code + console.log('Updating Lambda code from S3...'); + + try { + + await lambdaClient.send(new UpdateFunctionCodeCommand({ + FunctionName: FORWARDER_LAMBDA_NAME, + S3Bucket: FORWARDER_S3_BUCKET, + S3Key: FORWARDER_S3_KEY, + })); + + console.log(`✓ Updated ${FORWARDER_LAMBDA_NAME} to latest version`); + + } catch (error) { + + console.error('✗ Failed to update Lambda:', error); + process.exit(1); + + } + + console.log(); + console.log('Done! The Logfox Forwarder Lambda has been updated.'); + +} diff --git a/src/config.ts b/src/config.ts index e256ced..965d989 100644 --- a/src/config.ts +++ b/src/config.ts @@ -2,7 +2,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; -const CONFIG_DIR = path.join(os.homedir(), '.logspace'); +const CONFIG_DIR = path.join(os.homedir(), '.logfox'); const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json'); export type Config = { @@ -13,11 +13,12 @@ export type Config = { teamName?: string userId?: string userEmail?: string + apiKey?: string }; const DEFAULT_CONFIG: Config = { - apiUrl: 'https://api.logspace.sh', - appUrl: 'https://app.logspace.sh', + apiUrl: 'https://api.logfox.ai', + appUrl: 'https://app.logfox.ai', }; export function getConfig(): Config { diff --git a/src/index.ts b/src/index.ts index 2372990..5c2d4e3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,22 +8,25 @@ import {listSessions, deleteSession} from './commands/sessions'; import {listTeams} from './commands/teams'; import {showConfig, getConfigValue, setConfig, resetConfig} from './commands/config'; import {showStatus} from './commands/status'; +import {setupCloudwatch} from './commands/setup-cloudwatch'; +import {updateCloudwatch} from './commands/update-cloudwatch'; +import {cloudwatchRemove} from './commands/cloudwatch-remove'; const program = new Command(); program - .name('logspace') - .description('Logspace CLI for local development logging') + .name('logfox') + .description('Logfox CLI for log collection and local development') .version('0.0.1'); program .command('login') - .description('Log in to Logspace') + .description('Log in to Logfox') .action(login); program .command('logout') - .description('Log out of Logspace') + .description('Log out of Logfox') .action(logout); program @@ -33,13 +36,14 @@ program program .command('run') - .description('Run a command and send logs to Logspace') - .requiredOption('-n, --name ', 'Name for this local app (e.g., "backend", "frontend")') + .description('Run a command and send logs to Logfox') + .requiredOption('-n, --name ', 'Name for this app (e.g., "backend", "api")') + .option('-e, --env ', 'Environment (default: local)', 'local') .argument('', 'Command to run') .allowExcessArguments(true) - .action((command: string[], options: {name: string}) => { + .action((command: string[], options: {name: string; env: string}) => { - run(command, options); + void run(command, options); }); @@ -79,4 +83,30 @@ program .description('Reset configuration to defaults (production)') .action(() => resetConfig()); +// CloudWatch commands +const setupCmd = program + .command('setup') + .description('Setup integrations'); + +setupCmd + .command('cloudwatch') + .description('Setup CloudWatch log forwarding to Logfox') + .action(() => void setupCloudwatch()); + +const updateCmd = program + .command('update') + .description('Update integrations'); + +updateCmd + .command('cloudwatch') + .description('Update the Logfox Forwarder Lambda to the latest version') + .action(() => void updateCloudwatch()); + +program + .command('cloudwatch') + .description('CloudWatch management commands') + .command('remove') + .description('Remove CloudWatch subscription filters') + .action(() => void cloudwatchRemove()); + program.parse();