diff --git a/package.json b/package.json index 93e12044f..a4c835bea 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,9 @@ "engines": { "node": ">=20" }, + "imports": { + "#i18n/*.js": "./src/i18n/*.ts" + }, "dependencies": { "@apify/actor-memory-expression": "^0.1.12", "@apify/actor-templates": "^0.1.5", @@ -101,6 +104,7 @@ "handlebars": "~4.7.9", "ignore": "^7.0.5", "indent-string": "^5.0.0", + "intl-messageformat": "^11.2.1", "is-ci": "~4.1.0", "istextorbinary": "~9.5.0", "jju": "~1.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 93e9f2938..a0ca33014 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -116,6 +116,9 @@ importers: indent-string: specifier: ^5.0.0 version: 5.0.0 + intl-messageformat: + specifier: ^11.2.1 + version: 11.2.3 is-ci: specifier: ~4.1.0 version: 4.1.0 @@ -167,7 +170,7 @@ importers: devDependencies: '@apify/oxlint-config': specifier: ^0.2.5 - version: 0.2.5(oxlint@1.62.0(oxlint-tsgolint@0.22.0)) + version: 0.2.9(oxlint@1.62.0(oxlint-tsgolint@0.22.0)) '@apify/tsconfig': specifier: ^0.1.2 version: 0.1.2 @@ -254,22 +257,22 @@ importers: dependencies: '@apify/docs-theme': specifier: ^1.0.244 - version: 1.0.245(@algolia/client-search@5.52.0)(@babel/core@7.29.0)(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(clsx@2.1.1)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5)(search-insights@2.17.3)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + version: 1.0.246(@algolia/client-search@5.52.1)(@babel/core@7.29.0)(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(clsx@2.1.1)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6)(search-insights@2.17.3)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) '@docusaurus/core': specifier: ^3.10.0 - version: 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + version: 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) '@docusaurus/faster': specifier: ^3.10.0 - version: 3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4) + version: 3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8) '@docusaurus/plugin-client-redirects': specifier: ^3.10.0 - version: 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + version: 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) '@docusaurus/preset-classic': specifier: ^3.10.0 - version: 3.10.1(@algolia/client-search@5.52.0)(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.2) + version: 3.10.1(@algolia/client-search@5.52.1)(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3)(typescript@6.0.2) '@signalwire/docusaurus-plugin-llms-txt': specifier: ^1.2.2 - version: 1.2.2(@docusaurus/core@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)) + version: 1.2.2(@docusaurus/core@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -281,13 +284,13 @@ importers: version: 15.8.1 raw-loader: specifier: ^4.0.2 - version: 4.0.2(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + version: 4.0.2(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) react: specifier: ^19.2.5 - version: 19.2.5 + version: 19.2.6 react-dom: specifier: ^19.2.5 - version: 19.2.5(react@19.2.5) + version: 19.2.6(react@19.2.6) unist-util-visit: specifier: ^5.1.0 version: 5.1.0 @@ -310,8 +313,8 @@ importers: packages: - '@algolia/abtesting@1.18.0': - resolution: {integrity: sha512-8siuLG+FIns1AjZ/g2SDVwHz9S+ObacDQISEJvS8XsNei1zl3FXqfqQrBpmrG7ACWCyesXHbicMJtvRbg00FEw==} + '@algolia/abtesting@1.18.1': + resolution: {integrity: sha512-aehCadlWOGvrT91KUIZpC0MbB8KBW9yUuvTJFd2xesR7le/IsT4nJUnjCCZ4ZqZCeTcPHPV5mo//fZ5oxcSVYw==} engines: {node: '>= 14.0.0'} '@algolia/autocomplete-core@1.19.2': @@ -366,8 +369,8 @@ packages: '@algolia/cache-in-memory@4.27.0': resolution: {integrity: sha512-abgMRTcVD0IllNvMM9JFhxtyLn1v6Ey7mQ7+BGS3JCzvkCX7KZqlS0BIuVUDgx9sPIfOeNsG/awGzMmP50TwZw==} - '@algolia/client-abtesting@5.52.0': - resolution: {integrity: sha512-wtwPgyPmO7b7sQPVgoK29c1VpfS08DnnJCmxX/oU1pV2DlMRJCzQcLN7JSloYpodyKHwM8+9wOzlAM0co3TDmA==} + '@algolia/client-abtesting@5.52.1': + resolution: {integrity: sha512-HmXOGBOAOJPounpBzBpuY0zDYeiCpxgHnQmuA7JO6ScukcBdGp3/XM9zJk5pJx/xNGD68mbPGXWpDxGtl6BwDQ==} engines: {node: '>= 14.0.0'} '@algolia/client-account@4.27.0': @@ -376,44 +379,44 @@ packages: '@algolia/client-analytics@4.27.0': resolution: {integrity: sha512-MqIDyxODljn9ZC4oqjQD0kez2a4zjIJ9ywA/b7cIiUiK/tDjZNTVjYd9WXMKQlXnWUwfrfXJZClVVqN1iCXS+Q==} - '@algolia/client-analytics@5.52.0': - resolution: {integrity: sha512-9KY36bRl4AH7RjqSeDDOKnjsz4IxQFBEOB8/fWmEbdQe+Isbs5jGzVJu9NEPQ1Tgwxlf8Uf07Swj3jZyMNUZ2g==} + '@algolia/client-analytics@5.52.1': + resolution: {integrity: sha512-5oo4+I8iixie9vXhCyNFCzeIr8pqA3FQ//VsLHTDvZAV4ttYOPGvYHGQq5NSalrLx5Jc3dRro/5uDOlnUMcBJg==} engines: {node: '>= 14.0.0'} '@algolia/client-common@4.27.0': resolution: {integrity: sha512-ZrT6l/YPQgyIUuBCxcYPeXol2VBLUMuNb1rKXrm6z1f/iTiwqtnEEb16/6CC11+Re0ZGXrdcMVrgDRrzveQ1aQ==} - '@algolia/client-common@5.52.0': - resolution: {integrity: sha512-3a/qM3dzJqqfTx7Yrw7uGQ98I3Q0rDfb4Vkv0wEzko96l7YQMxfBVz/VbLq2N+c59GweYv6Vhp8mPeqnWJSITw==} + '@algolia/client-common@5.52.1': + resolution: {integrity: sha512-qCDoZfx5MpX7XQzvQ3bC4tSEMkQWQMaF/ABtLuoze03Y/flR563CCSws02qIJ23oX7lxl92LsilZjINVyTdtLw==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.52.0': - resolution: {integrity: sha512-Rki7ACbMcvbQW0BuM84x9dkGHY47ABmv4jU6tYssat2k02p3mIUms2YOLUAMeknhmnFsj6lb6ZzOXdMWMyc1sA==} + '@algolia/client-insights@5.52.1': + resolution: {integrity: sha512-hnGs0/lsFJ2PWDxNBz7pxreXo/Xz7gxYRcfePBUjsH26ad0kU/sgnVZd9LwWBpsQv65z2jlb5dkyaB9WE9M9FQ==} engines: {node: '>= 14.0.0'} '@algolia/client-personalization@4.27.0': resolution: {integrity: sha512-OZqaFFVm+10hAlmxpiTWi/o2n+YKBESbSqSy2yXAumPH/kaK4moJHFblbh8IkV3KZR0lLm4hzPtn8Q2nWNiDUA==} - '@algolia/client-personalization@5.52.0': - resolution: {integrity: sha512-96s4Uzc3kk+/f4jJXIVVGWP5XlngOGNQ1x6hW9AT59pOixHlOs5tqJg+ZUS/GQ6h/iYP0ceQcmxDQeLyCLTaDQ==} + '@algolia/client-personalization@5.52.1': + resolution: {integrity: sha512-2VxxNc/uBysyKvGeBdSM5n9eIDKH8kWD7wd9/yqbJAiVwU4Yv6tU1LSJusHKrXV/aCu1KW7t9Gug9QyeEmtn/Q==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.52.0': - resolution: {integrity: sha512-lqeycNpSPe5Qa0OUWpejVvYQjQWV5nQuLT0a4aq7XzRAvCxprV/6Lf841EygdD2nrFnuS58ok7Au1uOtXzpnkg==} + '@algolia/client-query-suggestions@5.52.1': + resolution: {integrity: sha512-O6mPtsw3xEfNOe6gWFpYLeAZAIljNa4Hgna3bq15PwyN7nbjTY0wXJFRbzs/0YVf75Br+SbOQUmjKxXYjDiSiQ==} engines: {node: '>= 14.0.0'} '@algolia/client-search@4.27.0': resolution: {integrity: sha512-qmX/f67ay0eZ4V5Io8fWWOcUVo/gqre2yei1PnmEhQU2Gul6ushg25QnNrfu4BODiRrw1rwYveZaLCiHvcUxrQ==} - '@algolia/client-search@5.52.0': - resolution: {integrity: sha512-ly1wETVGRo30cx61O7fetESN+ElL9c9K+bD/AVgnT1ar4c6v+/Yqjrhdtu6Fm4D0s4NZP081Isf6tunH1wUXHg==} + '@algolia/client-search@5.52.1': + resolution: {integrity: sha512-gA8oJOV1LnQQkDf91iebNnFInHuW0gRPEgLSOQ7EfipCEjYTHm5swm1DlH9H5RaRw4RrHuzHBegnlzc0MAstcg==} engines: {node: '>= 14.0.0'} '@algolia/events@4.0.1': resolution: {integrity: sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==} - '@algolia/ingestion@1.52.0': - resolution: {integrity: sha512-U4EeTvgmluRjj39ykZSAd5X+a6LD5m7/mcOWDmB7hqm1R6QY0yT8jLxpNVEjYhzgEN5hcDGW6X67EWQY8KiYGQ==} + '@algolia/ingestion@1.52.1': + resolution: {integrity: sha512-U9zZfc5xIu9wRxZkt+HceJUAD4VKHKbAyLSloJdEyMRmphXeibfrY9cxqIXBcmPeZzGhn3Imb35Dq8l19PkJhw==} engines: {node: '>= 14.0.0'} '@algolia/logger-common@4.27.0': @@ -422,36 +425,36 @@ packages: '@algolia/logger-console@4.27.0': resolution: {integrity: sha512-UWvta8BxsR/u5z9eI088mOSLQaGtmoCtXeN3DYJurlxAdJwPuKtEb5+433kxA6/E9f2/JgoW89KZ1vNP9pcHBQ==} - '@algolia/monitoring@1.52.0': - resolution: {integrity: sha512-FCPnDcILfpTE94u7BVlV4DmnSV5wE3+j25EEF+3dYPrVzkVCSoAHs318oWDGxnxsAgiL4HpL12Jc4XHmw9shpA==} + '@algolia/monitoring@1.52.1': + resolution: {integrity: sha512-a3SGNceHmkQfq77iG8Ka+w1pvwfZa/0lzEIgse30fL0kD+yKnd/dg0dQvSfFPAEt2f21DMcGkDSSeJlO3KdQjQ==} engines: {node: '>= 14.0.0'} '@algolia/recommend@4.27.0': resolution: {integrity: sha512-CFy54xDjrsazPi3KN04yPmLRDT72AKokc3RLOdWQvG0/uEUjj7dhWqe9qenxpL4ydsjO7S1eY5YqmX+uMGonlg==} - '@algolia/recommend@5.52.0': - resolution: {integrity: sha512-br3DO7n4N8CXwTRbZS0MnB4WQ9YHfNjCwkCEzVR/wek/qNTDQKDb0nROmkFaNZ8ucUqUVKZi074dbwMwRDlK8Q==} + '@algolia/recommend@5.52.1': + resolution: {integrity: sha512-z98QEguCFDpxb4S/PyrUK1igqF8tPsdbqOUUO6ON91vJ58w+Gwa6ncrI0oNXSFcrkxA5EqPKPQ2A1PBCn08TYQ==} engines: {node: '>= 14.0.0'} '@algolia/requester-browser-xhr@4.27.0': resolution: {integrity: sha512-dTenMBIIpyp5o3C2ZnfbsuSlD/lL9jPkk6T+2+qm38fyw2nf49ANbcHFE79NgiGrnmw7QrYveCs9NIP3Wk4v6g==} - '@algolia/requester-browser-xhr@5.52.0': - resolution: {integrity: sha512-b0T/Ca2c9KyEslKsVrGZvbe1UrrKKSdfXhBZ2pbpKahFUzJfziRZ0urbOm7V65O0tO/jwU+Lo/+bIiiyhzGt8w==} + '@algolia/requester-browser-xhr@5.52.1': + resolution: {integrity: sha512-CI7+/0I11QeZM59Uc8whd2or0kqzFVjpaPn9Qpwll/krHcBAxk24WkAQ6WX+IwDVMfpont4YGbKwAmCre3vE8Q==} engines: {node: '>= 14.0.0'} '@algolia/requester-common@4.27.0': resolution: {integrity: sha512-VC3prAQVgWTubMStb3mJz6i61Hqbtagi2LeIbgNtoFJFff3XZDcAaO1D5r0GYl2+DrB2VzUHnQXbkiuI+HHYyg==} - '@algolia/requester-fetch@5.52.0': - resolution: {integrity: sha512-ozBT8J/mtD4H4IAojw8QPirlcL2gHrI1BGuZ4/ZXXO/rTE1yQ4VIPJj4mTTbwo4FbkS1MoJsD/DsrqLzhnc4/g==} + '@algolia/requester-fetch@5.52.1': + resolution: {integrity: sha512-S6bDuw9byfOvm3T71cgdoZgrgnZq6hpdMLkx52Louh57nUAmvGQESz2aojOynQHjbTiV55smvAFbgn0qT4tJrg==} engines: {node: '>= 14.0.0'} '@algolia/requester-node-http@4.27.0': resolution: {integrity: sha512-y8nUqaUQeSOQ5oaNo0b2QPznyBFW9LoIwljyUphJ+gUZpU6O/j2/C8ovoqDpIe6J0etqHg5RCcBizrCFZuLpyw==} - '@algolia/requester-node-http@5.52.0': - resolution: {integrity: sha512-gyyWcLD22tnabmoit4iukCXuoRc5HYJuUjPSEa8a0D/f/NlRafpWi52AlAaa4Uu/rsl7saHsJFTNjTptWbu2+A==} + '@algolia/requester-node-http@5.52.1': + resolution: {integrity: sha512-tqZXM+54rWo4mk5jL5Z/flE11nPmNEdXwFBM5py9DkOmbjeCNemfVd45FyM97XdzfZ0dl9uOJC6PYn1FpkeyQg==} engines: {node: '>= 14.0.0'} '@algolia/transporter@4.27.0': @@ -479,8 +482,8 @@ packages: react: '> 18.0.0' react-dom: '> 18.0.0' - '@apify/docs-theme@1.0.245': - resolution: {integrity: sha512-Jq871+ydTTMZAtEAJ8iz/WmWzw6Y22fl6gQyzMKYMgMh4z4A9zbH/PeCmLQxc9NJMHx4SVvOFqrdBH+Efv/yeg==} + '@apify/docs-theme@1.0.246': + resolution: {integrity: sha512-Z+T4aqrYkUwRNUNqJBX6pOFSKw8Sa6pTSMvJ/pb0EEC5TZxg4wkIcdS6y394wtQcH3im9r3G5RrKuB8/Kgx+5A==} peerDependencies: clsx: '*' react: '*' @@ -506,8 +509,8 @@ packages: '@apify/log@2.5.38': resolution: {integrity: sha512-Lzmrra3Vvb9Fi4JzWFWPOeSGxItAk50ZHpB070TsSPxuYf9mgJqQ1VlLWn3HNalcdbIf0OoPAFOW31BEs5Khsw==} - '@apify/oxlint-config@0.2.5': - resolution: {integrity: sha512-WTv3t49YBsAw/iIO3LauT7Gy/f9AEqMAqRwUtLBx1+gcBZSB0t2IHa4AqJA9DIo5115dnY6CWyqbqaf1IP0m0A==} + '@apify/oxlint-config@0.2.9': + resolution: {integrity: sha512-uGheX/IEIQBSptzdeT9GQlyYuSC01jq/MrNY+s+ka5pMSU/9b1nSLvroOv6FVVF11ia7pgfR41FopeIOznZ6OQ==} peerDependencies: oxlint: ^1.61.0 @@ -525,14 +528,14 @@ packages: '@apify/tsconfig@0.1.2': resolution: {integrity: sha512-9dzEI1ZQ5+iM0k0fmPJrpdSSPUolVdeI1nDGFZMjD9UabTmIvjQrzui+1a25uy913AUEBrKTojEPj87pU9/Ekg==} - '@apify/ui-icons@1.38.0': - resolution: {integrity: sha512-kx2a2K16qY3l6FvpfqKR2uxwkXG+V4CkjbF8XfhfxBykljtDLqNYuShv+10ZOprya3azYuHOHWKGOIkfExB98Q==} + '@apify/ui-icons@1.38.1': + resolution: {integrity: sha512-ExNz6LwzL5R0TG+KpY2ZmpFIQvKxDRuxXAGecR4q5JhU9+zeUUZtfkm5YtZ9o90ji466W7aAsKV09urrklqixA==} peerDependencies: react: 17.x || 18.x || 19.x react-dom: 17.x || 18.x || 19.x - '@apify/ui-library@1.137.2': - resolution: {integrity: sha512-mve+6r633IUWOYfAtQ7FQXqX3DTnb8o5OGjFAeoQTXg6dcxHcdbywpofMDL4uUdUPzf9BKA/pb08XHD63OMqhw==} + '@apify/ui-library@1.138.1': + resolution: {integrity: sha512-gbYlgbLo8KjoChx13XbuqDsGzH+vB2QWp/ZYSn+qbxIpmFjEImwym5qNxgyegbPg8iCxR83FNoUfjgCCTKnFmg==} peerDependencies: react: 17.x || 18.x || 19.x react-dom: 17.x || 18.x || 19.x @@ -545,6 +548,10 @@ packages: resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.29.3': resolution: {integrity: sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==} engines: {node: '>=6.9.0'} @@ -656,8 +663,8 @@ packages: resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.29.3': - resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} engines: {node: '>=6.0.0'} hasBin: true @@ -893,8 +900,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-modules-systemjs@7.29.0': - resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==} + '@babel/plugin-transform-modules-systemjs@7.29.4': + resolution: {integrity: sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1091,8 +1098,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/preset-env@7.29.3': - resolution: {integrity: sha512-ySZypNLAIH1ClygLDQzVMoGQRViATnkHkYYV6TcNDz+8+jwZCdsguGvsb3EY5d9wyWyhmF1iSuFM0Yh5XPnqSA==} + '@babel/preset-env@7.29.5': + resolution: {integrity: sha512-/69t2aEzGKHD76DyLbHysF/QH2LJOB8iFnYO37unDTKBTubzcMRv0f3H5EiN1Q6ajOd/eB7dAInF0qdFVS06kA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -2287,6 +2294,15 @@ packages: '@floating-ui/utils@0.2.11': resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + '@formatjs/fast-memoize@3.1.3': + resolution: {integrity: sha512-Ocd1vPuD68rW6BJDuAOtnnc1GPeVepY5kZXML1psGVFQ+1Q8CfkftT3Tnam+Mxx97Pz08jIEDCotl/GV+Naccg==} + + '@formatjs/icu-messageformat-parser@3.5.6': + resolution: {integrity: sha512-04ZjRIeQCnR/h32wBP9/S7rkyy1hLAs2fXJcNwc7hseJd//K9TMBqK0ukb4dXqnALKQ9m5ruZeOD2qqEkK9ixg==} + + '@formatjs/icu-skeleton-parser@2.1.6': + resolution: {integrity: sha512-9f1VQ2kaaLHK0WPU1OrAmiNKCKJwyoDmwNzQXbUa6XtFBOgHZ4YZURE8sSedHmMr0kvpB75OtplB0hMYkfdwfg==} + '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} @@ -3764,8 +3780,8 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@ungap/structured-clone@1.3.1': + resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} '@vitest/expect@4.1.2': resolution: {integrity: sha512-gbu+7B0YgUJ2nkdsRJrFFW6X7NTP44WlhiclHniUhxADQJH5Szt9mZ9hWnJPJ8YwOK5zUOSSlSvyzRf0u1DSBQ==} @@ -3925,22 +3941,22 @@ packages: peerDependencies: ajv: ^8.8.2 - ajv@6.15.0: - resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} - algoliasearch-helper@3.28.2: - resolution: {integrity: sha512-sexVcXLHrJN54+S0wXD52xV3ySeGZA5T6HMDkb84wT+3UcXCd8af/k2vU5qJTbHv7DoBb4mISJHdyQ2JOo3Aig==} + algoliasearch-helper@3.29.1: + resolution: {integrity: sha512-6ck2YFudF2Pje7szQoPBiRFTGfd+1I+0I/WfLPGn0bj1kvrFoOQmNyedNiDxTk3/r4IfSLDYk+RA4G7u8H6+yA==} peerDependencies: algoliasearch: '>= 3.1 < 6' algoliasearch@4.27.0: resolution: {integrity: sha512-C88C5grLa5VOCp9eYZJt+q99ik7yNdm92l7Q9+4XK0Md8kL05Lg8l2v9ZVX0uMW3mH9pAFxMMXlLOvqNumA4lw==} - algoliasearch@5.52.0: - resolution: {integrity: sha512-0ZzY9mjqV7gop/AH8pIBiAS8giXP7WcSiUfoFYIzYAK9QC5c37E4SIVtJVBMwlURc0/uNt2o4RcNRvdHa4CJ5w==} + algoliasearch@5.52.1: + resolution: {integrity: sha512-fHA8+kXTbjagw3jkLiaS7KKrH8qe2DyOsiUhGlN4cdT77PEsfqXZl7ewDk1hsg+pJnPlnE50XtLxjR91iJOpmg==} engines: {node: '>= 14.0.0'} ansi-align@3.0.1: @@ -4179,7 +4195,6 @@ packages: basic-ftp@5.2.0: resolution: {integrity: sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==} engines: {node: '>=10.0.0'} - deprecated: Security vulnerability fixed in 5.2.1, please upgrade batch@0.6.1: resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} @@ -4295,8 +4310,8 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.9: - resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} engines: {node: '>= 0.4'} call-bound@1.0.4: @@ -4331,8 +4346,8 @@ packages: caniuse-lite@1.0.30001784: resolution: {integrity: sha512-WU346nBTklUV9YfUl60fqRbU5ZqyXlqvo1SgigE1OAXK5bFL8LL9q1K7aap3N739l4BvNqnkm3YrGHiY9sfUQw==} - caniuse-lite@1.0.30001791: - resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==} + caniuse-lite@1.0.30001792: + resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -4724,8 +4739,8 @@ packages: resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} - cssdb@8.8.0: - resolution: {integrity: sha512-QbLeyz2Bgso1iRlh7IpWk6OKa3lLNGXsujVjDMPl9rOZpxKeiG69icLpbLCFxeURwmcdIfZqQyhlooKJYM4f8Q==} + cssdb@8.8.1: + resolution: {integrity: sha512-PdLTDamqN1muXEmfQggrogLmD+ZjfOhlZsFFs28tYSTqnlk6gEwg5wQCt6wLl2HstegUYgof6GrYyXXODFDC5g==} cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} @@ -5004,8 +5019,8 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - enhanced-resolve@5.21.0: - resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} + enhanced-resolve@5.21.2: + resolution: {integrity: sha512-xe9vQb5kReirPUxgQrXA3ihgbCqssmTiM7cOZ+Gzu+VeGWgpV98lLZvp0dl4yriyAePcewxGUs9UpKD8PET9KQ==} engines: {node: '>=10.13.0'} enquirer@2.3.6: @@ -5798,6 +5813,9 @@ packages: inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + intl-messageformat@11.2.3: + resolution: {integrity: sha512-kZthTU+3WLcoWoRg5j6LOkN1TeUBtmkX0OIwSAbcHVIfQAEbGVdmANM8u6GL3eUDOqLwheYoXMUshAh1UdeXlQ==} + invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} @@ -5887,8 +5905,8 @@ packages: resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} engines: {node: '>=10'} - is-network-error@1.3.1: - resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} + is-network-error@1.3.2: + resolution: {integrity: sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==} engines: {node: '>=16'} is-npm@6.1.0: @@ -7571,10 +7589,10 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-dom@19.2.5: - resolution: {integrity: sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==} + react-dom@19.2.6: + resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} peerDependencies: - react: ^19.2.5 + react: ^19.2.6 react-fast-compare@3.2.2: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} @@ -7585,8 +7603,8 @@ packages: react: '>=16.8.1' react-dom: '>=16.8.1' - react-hotkeys-hook@5.3.0: - resolution: {integrity: sha512-/pKgBHnUJM2V8VQtGGNG89s4aX371CBt5KV8mg4Gv6JpS+m6HocnD2T+k6ymtfZ21rvCCxWqWUGpw/w5papgIQ==} + react-hotkeys-hook@5.3.2: + resolution: {integrity: sha512-DDDy9xK6mbTQ6aPlQvIl0dA/a90T/AWml4Rm21JXFDLlRHalIg4/Rv3equUQYs5xPTWq+oEl6RD7mi/nBpU3Uw==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' @@ -7646,8 +7664,8 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' - react@19.2.5: - resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} + react@19.2.6: + resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} engines: {node: '>=0.10.0'} readable-stream@2.3.8: @@ -7787,8 +7805,8 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} hasBin: true @@ -8278,19 +8296,46 @@ packages: teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} - terser-webpack-plugin@5.5.0: - resolution: {integrity: sha512-UYhptBwhWvfIjKd/UuFo6D8uq9xpGLDK+z8EDsj/zWhrTaH34cKEbrkMKfV5YWqGBvAYA3tlzZbs2R+qYrbQJA==} + terser-webpack-plugin@5.6.0: + resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==} engines: {node: '>= 10.13.0'} peerDependencies: + '@minify-html/node': '*' '@swc/core': '*' + '@swc/css': '*' + '@swc/html': '*' + clean-css: '*' + cssnano: '*' + csso: '*' esbuild: '*' + html-minifier-terser: '*' + lightningcss: '*' + postcss: '*' uglify-js: '*' webpack: ^5.1.0 peerDependenciesMeta: + '@minify-html/node': + optional: true '@swc/core': optional: true + '@swc/css': + optional: true + '@swc/html': + optional: true + clean-css: + optional: true + cssnano: + optional: true + csso: + optional: true esbuild: optional: true + html-minifier-terser: + optional: true + lightningcss: + optional: true + postcss: + optional: true uglify-js: optional: true @@ -8932,96 +8977,96 @@ packages: snapshots: - '@algolia/abtesting@1.18.0': + '@algolia/abtesting@1.18.1': dependencies: - '@algolia/client-common': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 - '@algolia/autocomplete-core@1.19.2(@algolia/client-search@5.52.0)(algoliasearch@5.52.0)(search-insights@2.17.3)': + '@algolia/autocomplete-core@1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.19.2(@algolia/client-search@5.52.0)(algoliasearch@5.52.0)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.52.0)(algoliasearch@5.52.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-core@1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0)(search-insights@2.17.3)': + '@algolia/autocomplete-core@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-core@1.19.8(@algolia/client-search@5.52.0)(algoliasearch@5.52.0)(search-insights@2.17.3)': + '@algolia/autocomplete-core@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@5.52.0)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@5.52.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-js@1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0)(search-insights@2.17.3)': + '@algolia/autocomplete-js@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-core': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0)(search-insights@2.17.3) - '@algolia/autocomplete-preset-algolia': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0) - '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0) - '@algolia/client-search': 5.52.0 + '@algolia/autocomplete-core': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0)(search-insights@2.17.3) + '@algolia/autocomplete-preset-algolia': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0) + '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0) + '@algolia/client-search': 5.52.1 algoliasearch: 4.27.0 htm: 3.1.1 preact: 10.29.1 transitivePeerDependencies: - search-insights - '@algolia/autocomplete-plugin-algolia-insights@1.19.2(@algolia/client-search@5.52.0)(algoliasearch@5.52.0)(search-insights@2.17.3)': + '@algolia/autocomplete-plugin-algolia-insights@1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.52.0)(algoliasearch@5.52.0) + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-plugin-algolia-insights@1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0)(search-insights@2.17.3)': + '@algolia/autocomplete-plugin-algolia-insights@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0) + '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-plugin-algolia-insights@1.19.8(@algolia/client-search@5.52.0)(algoliasearch@5.52.0)(search-insights@2.17.3)': + '@algolia/autocomplete-plugin-algolia-insights@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@5.52.0) + '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-preset-algolia@1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0)': + '@algolia/autocomplete-preset-algolia@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0)': dependencies: - '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0) - '@algolia/client-search': 5.52.0 + '@algolia/autocomplete-shared': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0) + '@algolia/client-search': 5.52.1 algoliasearch: 4.27.0 - '@algolia/autocomplete-shared@1.19.2(@algolia/client-search@5.52.0)(algoliasearch@5.52.0)': + '@algolia/autocomplete-shared@1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)': dependencies: - '@algolia/client-search': 5.52.0 - algoliasearch: 5.52.0 + '@algolia/client-search': 5.52.1 + algoliasearch: 5.52.1 - '@algolia/autocomplete-shared@1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0)': + '@algolia/autocomplete-shared@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0)': dependencies: - '@algolia/client-search': 5.52.0 + '@algolia/client-search': 5.52.1 algoliasearch: 4.27.0 - '@algolia/autocomplete-shared@1.19.8(@algolia/client-search@5.52.0)(algoliasearch@5.52.0)': + '@algolia/autocomplete-shared@1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)': dependencies: - '@algolia/client-search': 5.52.0 - algoliasearch: 5.52.0 + '@algolia/client-search': 5.52.1 + algoliasearch: 5.52.1 '@algolia/autocomplete-theme-classic@1.19.8': {} @@ -9035,12 +9080,12 @@ snapshots: dependencies: '@algolia/cache-common': 4.27.0 - '@algolia/client-abtesting@5.52.0': + '@algolia/client-abtesting@5.52.1': dependencies: - '@algolia/client-common': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 '@algolia/client-account@4.27.0': dependencies: @@ -9055,26 +9100,26 @@ snapshots: '@algolia/requester-common': 4.27.0 '@algolia/transporter': 4.27.0 - '@algolia/client-analytics@5.52.0': + '@algolia/client-analytics@5.52.1': dependencies: - '@algolia/client-common': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 '@algolia/client-common@4.27.0': dependencies: '@algolia/requester-common': 4.27.0 '@algolia/transporter': 4.27.0 - '@algolia/client-common@5.52.0': {} + '@algolia/client-common@5.52.1': {} - '@algolia/client-insights@5.52.0': + '@algolia/client-insights@5.52.1': dependencies: - '@algolia/client-common': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 '@algolia/client-personalization@4.27.0': dependencies: @@ -9082,19 +9127,19 @@ snapshots: '@algolia/requester-common': 4.27.0 '@algolia/transporter': 4.27.0 - '@algolia/client-personalization@5.52.0': + '@algolia/client-personalization@5.52.1': dependencies: - '@algolia/client-common': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 - '@algolia/client-query-suggestions@5.52.0': + '@algolia/client-query-suggestions@5.52.1': dependencies: - '@algolia/client-common': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 '@algolia/client-search@4.27.0': dependencies: @@ -9102,21 +9147,21 @@ snapshots: '@algolia/requester-common': 4.27.0 '@algolia/transporter': 4.27.0 - '@algolia/client-search@5.52.0': + '@algolia/client-search@5.52.1': dependencies: - '@algolia/client-common': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 '@algolia/events@4.0.1': {} - '@algolia/ingestion@1.52.0': + '@algolia/ingestion@1.52.1': dependencies: - '@algolia/client-common': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 '@algolia/logger-common@4.27.0': {} @@ -9124,12 +9169,12 @@ snapshots: dependencies: '@algolia/logger-common': 4.27.0 - '@algolia/monitoring@1.52.0': + '@algolia/monitoring@1.52.1': dependencies: - '@algolia/client-common': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 '@algolia/recommend@4.27.0': dependencies: @@ -9145,34 +9190,34 @@ snapshots: '@algolia/requester-node-http': 4.27.0 '@algolia/transporter': 4.27.0 - '@algolia/recommend@5.52.0': + '@algolia/recommend@5.52.1': dependencies: - '@algolia/client-common': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + '@algolia/client-common': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 '@algolia/requester-browser-xhr@4.27.0': dependencies: '@algolia/requester-common': 4.27.0 - '@algolia/requester-browser-xhr@5.52.0': + '@algolia/requester-browser-xhr@5.52.1': dependencies: - '@algolia/client-common': 5.52.0 + '@algolia/client-common': 5.52.1 '@algolia/requester-common@4.27.0': {} - '@algolia/requester-fetch@5.52.0': + '@algolia/requester-fetch@5.52.1': dependencies: - '@algolia/client-common': 5.52.0 + '@algolia/client-common': 5.52.1 '@algolia/requester-node-http@4.27.0': dependencies: '@algolia/requester-common': 4.27.0 - '@algolia/requester-node-http@5.52.0': + '@algolia/requester-node-http@5.52.1': dependencies: - '@algolia/client-common': 5.52.0 + '@algolia/client-common': 5.52.1 '@algolia/transporter@4.27.0': dependencies: @@ -9198,18 +9243,18 @@ snapshots: '@apify/datastructures@2.0.3': {} - '@apify/docs-search-modal@1.3.6(@algolia/client-search@5.52.0)(@babel/core@7.29.0)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5)(search-insights@2.17.3)': + '@apify/docs-search-modal@1.3.6(@algolia/client-search@5.52.1)(@babel/core@7.29.0)(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-js': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@4.27.0)(search-insights@2.17.3) + '@algolia/autocomplete-js': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@4.27.0)(search-insights@2.17.3) '@algolia/autocomplete-theme-classic': 1.19.8 - '@apify/ui-library': 1.137.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5)) + '@apify/ui-library': 1.138.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6)) algoliasearch: 4.27.0 html-entities: 2.6.0 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-hotkeys-hook: 4.6.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - react-icons: 4.12.0(react@19.2.5) - styled-components: 5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-hotkeys-hook: 4.6.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-icons: 4.12.0(react@19.2.6) + styled-components: 5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6) transitivePeerDependencies: - '@algolia/client-search' - '@babel/core' @@ -9219,24 +9264,24 @@ snapshots: - search-insights - supports-color - '@apify/docs-theme@1.0.245(@algolia/client-search@5.52.0)(@babel/core@7.29.0)(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(clsx@2.1.1)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5)(search-insights@2.17.3)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4))': + '@apify/docs-theme@1.0.246(@algolia/client-search@5.52.1)(@babel/core@7.29.0)(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(clsx@2.1.1)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6)(search-insights@2.17.3)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8))': dependencies: - '@apify/docs-search-modal': 1.3.6(@algolia/client-search@5.52.0)(@babel/core@7.29.0)(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5)(search-insights@2.17.3) - '@apify/ui-icons': 1.38.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@apify/ui-library': 1.137.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5)) - '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@apify/docs-search-modal': 1.3.6(@algolia/client-search@5.52.1)(@babel/core@7.29.0)(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6)(search-insights@2.17.3) + '@apify/ui-icons': 1.38.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@apify/ui-library': 1.138.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6)) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@stackql/docusaurus-plugin-hubspot': 1.1.0 - algoliasearch: 5.52.0 - algoliasearch-helper: 3.28.2(algoliasearch@5.52.0) + algoliasearch: 5.52.1 + algoliasearch-helper: 3.29.1(algoliasearch@5.52.1) axios: 1.16.0 - babel-loader: 10.1.1(@babel/core@7.29.0)(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + babel-loader: 10.1.1(@babel/core@7.29.0)(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) clsx: 2.1.1 docusaurus-gtm-plugin: 0.0.2 postcss-preset-env: 11.2.1(postcss@8.5.8) - prism-react-renderer: 2.4.1(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-hotkeys-hook: 5.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + prism-react-renderer: 2.4.1(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-hotkeys-hook: 5.3.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6) remark-parse: 11.0.0 remark-stringify: 11.0.0 unified: 11.0.5 @@ -9245,12 +9290,20 @@ snapshots: - '@algolia/client-search' - '@babel/core' - '@docusaurus/plugin-content-docs' + - '@minify-html/node' - '@rspack/core' - '@swc/core' + - '@swc/css' + - '@swc/html' - '@types/react' - '@types/react-dom' + - clean-css + - cssnano + - csso - debug - esbuild + - html-minifier-terser + - lightningcss - postcss - react-is - search-insights @@ -9295,7 +9348,7 @@ snapshots: '@apify/consts': 2.53.0 ansi-colors: 4.1.3 - '@apify/oxlint-config@0.2.5(oxlint@1.62.0(oxlint-tsgolint@0.22.0))': + '@apify/oxlint-config@0.2.9(oxlint@1.62.0(oxlint-tsgolint@0.22.0))': dependencies: oxlint: 1.62.0(oxlint-tsgolint@0.22.0) @@ -9311,39 +9364,40 @@ snapshots: '@apify/tsconfig@0.1.2': {} - '@apify/ui-icons@1.38.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@apify/ui-icons@1.38.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: clsx: 2.1.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - - '@apify/ui-library@1.137.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5))': - dependencies: - '@apify/ui-icons': 1.38.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@floating-ui/react': 0.27.19(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@radix-ui/react-checkbox': 1.3.3(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@radix-ui/react-collapsible': 1.1.12(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@radix-ui/react-switch': 1.2.6(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@react-hook/resize-observer': 2.0.2(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@apify/ui-library@1.138.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6))': + dependencies: + '@apify/ui-icons': 1.38.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@floating-ui/react': 0.27.19(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-checkbox': 1.3.3(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-collapsible': 1.1.12(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-switch': 1.2.6(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-hook/resize-observer': 2.0.2(react@19.2.6) clsx: 2.1.1 dayjs: 1.11.9 emoji-regex: 9.2.2 fast-average-color: 9.5.2 history: 5.3.0 lodash: 4.18.1 - prism-react-renderer: 2.4.1(react@19.2.5) + prism-react-renderer: 2.4.1(react@19.2.6) prismjs: 1.30.0 query-string: 8.2.0 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-markdown: 10.1.0(@types/react@19.2.14)(react@19.2.5) - react-select: 5.10.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-markdown: 10.1.0(@types/react@19.2.14)(react@19.2.6) + react-select: 5.10.2(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) rehype-raw: 7.0.0 rehype-sanitize: 6.0.0 remark-gfm: 4.0.1 remark-toc: 9.0.0 slugify: 1.6.9 - styled-components: 5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5) + styled-components: 5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6) unist-util-visit: 5.1.0 transitivePeerDependencies: - '@types/react' @@ -9361,6 +9415,8 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/compat-data@7.29.0': {} + '@babel/compat-data@7.29.3': {} '@babel/core@7.29.0': @@ -9370,7 +9426,7 @@ snapshots: '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) '@babel/helpers': 7.29.2 - '@babel/parser': 7.29.3 + '@babel/parser': 7.29.2 '@babel/template': 7.28.6 '@babel/traverse': 7.29.0(supports-color@5.5.0) '@babel/types': 7.29.0 @@ -9385,7 +9441,7 @@ snapshots: '@babel/generator@7.29.1': dependencies: - '@babel/parser': 7.29.3 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 @@ -9406,7 +9462,7 @@ snapshots: '@babel/helper-compilation-targets@7.28.6': dependencies: - '@babel/compat-data': 7.29.3 + '@babel/compat-data': 7.29.0 '@babel/helper-validator-option': 7.27.1 browserslist: 4.28.2 lru-cache: 5.1.1 @@ -9439,7 +9495,7 @@ snapshots: '@babel/helper-plugin-utils': 7.28.6 debug: 4.4.3(supports-color@5.5.0) lodash.debounce: 4.0.8 - resolve: 1.22.12 + resolve: 1.22.11 transitivePeerDependencies: - supports-color @@ -9522,7 +9578,7 @@ snapshots: '@babel/template': 7.28.6 '@babel/types': 7.29.0 - '@babel/parser@7.29.3': + '@babel/parser@7.29.2': dependencies: '@babel/types': 7.29.0 @@ -9776,7 +9832,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': + '@babel/plugin-transform-modules-systemjs@7.29.4(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) @@ -9998,7 +10054,7 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/preset-env@7.29.3(@babel/core@7.29.0)': + '@babel/preset-env@7.29.5(@babel/core@7.29.0)': dependencies: '@babel/compat-data': 7.29.3 '@babel/core': 7.29.0 @@ -10040,7 +10096,7 @@ snapshots: '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.4(@babel/core@7.29.0) '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) @@ -10110,7 +10166,7 @@ snapshots: '@babel/template@7.28.6': dependencies: '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.3 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@babel/traverse@7.29.0(supports-color@5.5.0)': @@ -10118,7 +10174,7 @@ snapshots: '@babel/code-frame': 7.29.0 '@babel/generator': 7.29.1 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.3 + '@babel/parser': 7.29.2 '@babel/template': 7.28.6 '@babel/types': 7.29.0 debug: 4.4.3(supports-color@5.5.0) @@ -10867,86 +10923,97 @@ snapshots: '@discoveryjs/json-ext@0.5.7': {} - '@docsearch/core@4.6.3(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docsearch/core@4.6.3(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': optionalDependencies: '@types/react': 19.2.14 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) '@docsearch/css@4.6.3': {} - '@docsearch/react@4.6.3(@algolia/client-search@5.52.0)(@types/react@19.2.14)(algoliasearch@5.52.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)': + '@docsearch/react@4.6.3(@algolia/client-search@5.52.1)(@types/react@19.2.14)(algoliasearch@5.52.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.52.0)(algoliasearch@5.52.0)(search-insights@2.17.3) - '@docsearch/core': 4.6.3(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3) + '@docsearch/core': 4.6.3(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@docsearch/css': 4.6.3 optionalDependencies: '@types/react': 19.2.14 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@docusaurus/babel@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/babel@3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@babel/core': 7.29.0 '@babel/generator': 7.29.1 '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) - '@babel/preset-env': 7.29.3(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) '@babel/preset-react': 7.28.5(@babel/core@7.29.0) '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) '@babel/runtime': 7.29.2 '@babel/traverse': 7.29.0(supports-color@5.5.0) '@docusaurus/logger': 3.10.1 - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) babel-plugin-dynamic-import-node: 2.3.3 fs-extra: 11.3.4 tslib: 2.8.1 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - react - react-dom - supports-color - uglify-js - webpack-cli - '@docusaurus/bundler@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/bundler@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: '@babel/core': 7.29.0 - '@docusaurus/babel': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/babel': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@docusaurus/cssnano-preset': 3.10.1 '@docusaurus/logger': 3.10.1 - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - babel-loader: 9.2.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + babel-loader: 9.2.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) clean-css: 5.3.3 - copy-webpack-plugin: 11.0.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) - css-loader: 6.11.0(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(esbuild@0.27.4)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + copy-webpack-plugin: 11.0.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) + css-loader: 6.11.0(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(esbuild@0.27.4)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) cssnano: 6.1.2(postcss@8.5.8) - file-loader: 6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + file-loader: 6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) html-minifier-terser: 7.2.0 - mini-css-extract-plugin: 2.10.2(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) - null-loader: 4.0.1(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + mini-css-extract-plugin: 2.10.2(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) + null-loader: 4.0.1(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) postcss: 8.5.8 - postcss-loader: 7.3.4(postcss@8.5.8)(typescript@6.0.2)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + postcss-loader: 7.3.4(postcss@8.5.8)(typescript@6.0.2)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) postcss-preset-env: 10.6.1(postcss@8.5.8) - terser-webpack-plugin: 5.5.0(@swc/core@1.15.33)(esbuild@0.27.4)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + terser-webpack-plugin: 5.6.0(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) tslib: 2.8.1 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) - webpackbar: 7.0.0(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) + webpackbar: 7.0.0(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) optionalDependencies: - '@docusaurus/faster': 3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4) + '@docusaurus/faster': 3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8) transitivePeerDependencies: + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - csso - esbuild - lightningcss @@ -10957,16 +11024,16 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/core@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/core@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/babel': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/bundler': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/babel': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/bundler': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) '@docusaurus/logger': 3.10.1 - '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.5) + '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.6) boxen: 6.2.1 chalk: 4.1.2 chokidar: 3.6.0 @@ -10981,41 +11048,47 @@ snapshots: execa: 5.1.1 fs-extra: 11.3.4 html-tags: 3.3.1 - html-webpack-plugin: 5.6.7(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + html-webpack-plugin: 5.6.7(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) leven: 3.1.0 lodash: 4.18.1 open: 8.4.2 p-map: 4.0.0 prompts: 2.4.2 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.5)' - react-loadable-ssr-addon-v5-slorber: 1.0.3(@docusaurus/react-loadable@6.0.0(react@19.2.5))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) - react-router: 5.3.4(react@19.2.5) - react-router-config: 5.1.1(react-router@5.3.4(react@19.2.5))(react@19.2.5) - react-router-dom: 5.3.4(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.6)' + react-loadable-ssr-addon-v5-slorber: 1.0.3(@docusaurus/react-loadable@6.0.0(react@19.2.6))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) + react-router: 5.3.4(react@19.2.6) + react-router-config: 5.1.1(react-router@5.3.4(react@19.2.6))(react@19.2.6) + react-router-dom: 5.3.4(react@19.2.6) semver: 7.7.4 serve-handler: 6.1.7 tinypool: 1.1.1 tslib: 2.8.1 update-notifier: 6.0.2 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) webpack-merge: 6.0.1 optionalDependencies: - '@docusaurus/faster': 3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4) + '@docusaurus/faster': 3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8) transitivePeerDependencies: + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js @@ -11029,21 +11102,28 @@ snapshots: postcss-sort-media-queries: 5.2.0(postcss@8.5.8) tslib: 2.8.1 - '@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4)': + '@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8)': dependencies: - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@rspack/core': 1.7.11 '@swc/core': 1.15.33 '@swc/html': 1.15.33 browserslist: 4.28.2 lightningcss: 1.32.0 semver: 7.7.4 - swc-loader: 0.2.7(@swc/core@1.15.33)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + swc-loader: 0.2.7(@swc/core@1.15.33)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) tslib: 2.8.1 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(@swc/html@1.15.33)(esbuild@0.27.4)(lightningcss@1.32.0)(postcss@8.5.8) transitivePeerDependencies: + - '@minify-html/node' + - '@swc/css' - '@swc/helpers' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - postcss - uglify-js - webpack-cli @@ -11052,22 +11132,22 @@ snapshots: chalk: 4.1.2 tslib: 2.8.1 - '@docusaurus/mdx-loader@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/mdx-loader@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@docusaurus/logger': 3.10.1 - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mdx-js/mdx': 3.1.1 '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 estree-util-value-to-estree: 3.5.0 - file-loader: 6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + file-loader: 6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) fs-extra: 11.3.4 image-size: 2.0.2 mdast-util-mdx: 3.0.0 mdast-util-to-string: 4.0.0 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) rehype-raw: 7.0.0 remark-directive: 3.0.1 remark-emoji: 4.0.1 @@ -11077,196 +11157,244 @@ snapshots: tslib: 2.8.1 unified: 11.0.5 unist-util-visit: 5.1.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) vfile: 6.0.3 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - supports-color - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/module-type-aliases@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/history': 4.7.11 '@types/react': 19.2.14 '@types/react-router-config': 5.0.11 '@types/react-router-dom': 5.3.3 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.5)' + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.6)' transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - supports-color - uglify-js - webpack-cli - '@docusaurus/plugin-client-redirects@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-client-redirects@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) '@docusaurus/logger': 3.10.1 - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) eta: 2.2.0 fs-extra: 11.3.4 lodash: 4.18.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-blog@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-content-blog@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) '@docusaurus/logger': 3.10.1 - '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/plugin-content-docs': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/plugin-content-docs': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) cheerio: 1.0.0-rc.12 combine-promises: 1.2.0 feed: 4.2.2 fs-extra: 11.3.4 lodash: 4.18.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) schema-dts: 1.1.5 srcset: 4.0.0 tslib: 2.8.1 unist-util-visit: 5.1.0 utility-types: 3.11.0 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) '@docusaurus/logger': 3.10.1 - '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/module-type-aliases': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/module-type-aliases': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 fs-extra: 11.3.4 js-yaml: 4.1.1 lodash: 4.18.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) schema-dts: 1.1.5 tslib: 2.8.1 utility-types: 3.11.0 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-pages@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-content-pages@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) fs-extra: 11.3.4 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-css-cascade-layers@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-css-cascade-layers@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - react - react-dom - supports-color @@ -11275,207 +11403,249 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-debug@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-debug@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) fs-extra: 11.3.4 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-json-view-lite: 2.5.0(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-json-view-lite: 2.5.0(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-analytics@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-google-analytics@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-gtag@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-google-gtag@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/gtag.js': 0.0.20 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-google-tag-manager@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-sitemap@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-sitemap@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) '@docusaurus/logger': 3.10.1 - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) fs-extra: 11.3.4 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) sitemap: 7.1.3 tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/plugin-svgr@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/plugin-svgr@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@svgr/core': 8.1.0(typescript@6.0.2) '@svgr/webpack': 8.1.0(typescript@6.0.2) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) transitivePeerDependencies: - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - supports-color - typescript - uglify-js - utf-8-validate - webpack-cli - '@docusaurus/preset-classic@3.10.1(@algolia/client-search@5.52.0)(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.2)': - dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-content-blog': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-content-docs': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-content-pages': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-css-cascade-layers': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-debug': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-google-analytics': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-google-gtag': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-google-tag-manager': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-sitemap': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-svgr': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/theme-classic': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/theme-search-algolia': 3.10.1(@algolia/client-search@5.52.0)(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.2) - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@docusaurus/preset-classic@3.10.1(@algolia/client-search@5.52.1)(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3)(typescript@6.0.2)': + dependencies: + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-content-blog': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-content-docs': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-content-pages': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-css-cascade-layers': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-debug': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-google-analytics': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-google-gtag': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-google-tag-manager': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-sitemap': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-svgr': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/theme-classic': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/theme-search-algolia': 3.10.1(@algolia/client-search@5.52.1)(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3)(typescript@6.0.2) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - '@types/react' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - search-insights - supports-color - typescript @@ -11483,52 +11653,57 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/react-loadable@6.0.0(react@19.2.5)': + '@docusaurus/react-loadable@6.0.0(react@19.2.6)': dependencies: '@types/react': 19.2.14 - react: 19.2.5 + react: 19.2.6 - '@docusaurus/theme-classic@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2)': + '@docusaurus/theme-classic@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) '@docusaurus/logger': 3.10.1 - '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/module-type-aliases': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/plugin-content-blog': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-content-docs': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/plugin-content-pages': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/module-type-aliases': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/plugin-content-blog': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-content-docs': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/plugin-content-pages': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@docusaurus/theme-translations': 3.10.1 - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.5) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.6) clsx: 2.1.1 copy-text-to-clipboard: 3.2.2 infima: 0.2.0-alpha.45 lodash: 4.18.1 nprogress: 0.2.0 postcss: 8.5.8 - prism-react-renderer: 2.4.1(react@19.2.5) + prism-react-renderer: 2.4.1(react@19.2.6) prismjs: 1.30.0 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-router-dom: 5.3.4(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-router-dom: 5.3.4(react@19.2.6) rtlcss: 4.3.0 tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: - '@docusaurus/faster' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - '@types/react' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss - supports-color - typescript @@ -11536,65 +11711,80 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-common@3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/theme-common@3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/module-type-aliases': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/plugin-content-docs': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/mdx-loader': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/module-type-aliases': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/plugin-content-docs': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/history': 4.7.11 '@types/react': 19.2.14 '@types/react-router-config': 5.0.11 clsx: 2.1.1 parse-numeric-range: 1.3.0 - prism-react-renderer: 2.4.1(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + prism-react-renderer: 2.4.1(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - supports-color - uglify-js - webpack-cli - '@docusaurus/theme-search-algolia@3.10.1(@algolia/client-search@5.52.0)(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3)(typescript@6.0.2)': + '@docusaurus/theme-search-algolia@3.10.1(@algolia/client-search@5.52.1)(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(@types/react@19.2.14)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3)(typescript@6.0.2)': dependencies: - '@algolia/autocomplete-core': 1.19.8(@algolia/client-search@5.52.0)(algoliasearch@5.52.0)(search-insights@2.17.3) - '@docsearch/react': 4.6.3(@algolia/client-search@5.52.0)(@types/react@19.2.14)(algoliasearch@5.52.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(search-insights@2.17.3) - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@algolia/autocomplete-core': 1.19.8(@algolia/client-search@5.52.1)(algoliasearch@5.52.1)(search-insights@2.17.3) + '@docsearch/react': 4.6.3(@algolia/client-search@5.52.1)(@types/react@19.2.14)(algoliasearch@5.52.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(search-insights@2.17.3) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) '@docusaurus/logger': 3.10.1 - '@docusaurus/plugin-content-docs': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) - '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/plugin-content-docs': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) + '@docusaurus/theme-common': 3.10.1(@docusaurus/plugin-content-docs@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@docusaurus/theme-translations': 3.10.1 - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - algoliasearch: 5.52.0 - algoliasearch-helper: 3.28.2(algoliasearch@5.52.0) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-validation': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + algoliasearch: 5.52.1 + algoliasearch-helper: 3.29.1(algoliasearch@5.52.1) clsx: 2.1.1 eta: 2.2.0 fs-extra: 11.3.4 lodash: 4.18.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/faster' - '@mdx-js/react' + - '@minify-html/node' - '@parcel/css' - '@rspack/core' - '@swc/core' - '@swc/css' + - '@swc/html' - '@types/react' - bufferutil + - clean-css + - cssnano - csso - debug - esbuild + - html-minifier-terser - lightningcss + - postcss - search-insights - supports-color - typescript @@ -11607,7 +11797,7 @@ snapshots: fs-extra: 11.3.4 tslib: 2.8.1 - '@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/types@3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@mdx-js/mdx': 3.1.1 '@types/history': 4.7.11 @@ -11615,59 +11805,86 @@ snapshots: '@types/react': 19.2.14 commander: 5.1.0 joi: 17.13.3 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)' + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)' utility-types: 3.11.0 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) webpack-merge: 5.10.0 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - supports-color - uglify-js - webpack-cli - '@docusaurus/utils-common@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/utils-common@3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) tslib: 2.8.1 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - react - react-dom - supports-color - uglify-js - webpack-cli - '@docusaurus/utils-validation@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/utils-validation@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@docusaurus/logger': 3.10.1 - '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/utils': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) fs-extra: 11.3.4 joi: 17.13.3 js-yaml: 4.1.1 lodash: 4.18.1 tslib: 2.8.1 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - react - react-dom - supports-color - uglify-js - webpack-cli - '@docusaurus/utils@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@docusaurus/utils@3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@docusaurus/logger': 3.10.1 - '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@docusaurus/types': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@docusaurus/utils-common': 3.10.1(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) escape-string-regexp: 4.0.0 execa: 5.1.1 - file-loader: 6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + file-loader: 6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) fs-extra: 11.3.4 github-slugger: 1.5.0 globby: 11.1.0 @@ -11680,12 +11897,21 @@ snapshots: prompts: 2.4.2 resolve-pathname: 3.0.0 tslib: 2.8.1 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) utility-types: 3.11.0 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - react - react-dom - supports-color @@ -11740,17 +11966,17 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.5)': + '@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6)': dependencies: '@babel/runtime': 7.29.2 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.5) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.6) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 19.2.5 + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 transitivePeerDependencies: @@ -11772,9 +11998,9 @@ snapshots: '@emotion/unitless@0.7.5': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.5)': + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 '@emotion/utils@1.4.2': {} @@ -11869,22 +12095,30 @@ snapshots: '@floating-ui/core': 1.7.5 '@floating-ui/utils': 0.2.11 - '@floating-ui/react-dom@2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@floating-ui/react-dom@2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@floating-ui/dom': 1.7.6 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) - '@floating-ui/react@0.27.19(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@floating-ui/react@0.27.19(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@floating-ui/react-dom': 2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@floating-ui/utils': 0.2.11 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) tabbable: 6.4.0 '@floating-ui/utils@0.2.11': {} + '@formatjs/fast-memoize@3.1.3': {} + + '@formatjs/icu-messageformat-parser@3.5.6': + dependencies: + '@formatjs/icu-skeleton-parser': 2.1.6 + + '@formatjs/icu-skeleton-parser@2.1.6': {} + '@hapi/hoek@9.3.0': {} '@hapi/topo@5.1.0': @@ -12148,11 +12382,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5)': + '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6)': dependencies: '@types/mdx': 2.0.13 '@types/react': 19.2.14 - react: 19.2.5 + react: 19.2.6 '@module-federation/error-codes@0.22.0': {} @@ -12403,140 +12637,140 @@ snapshots: '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-checkbox@1.3.3(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@radix-ui/react-checkbox@1.3.3(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-presence': 1.1.5(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@radix-ui/react-primitive': 2.1.3(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-presence': 1.1.5(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-collapsible@1.1.12(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@radix-ui/react-collapsible@1.1.12(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-presence': 1.1.5(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@radix-ui/react-primitive': 2.1.3(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-presence': 1.1.5(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.5)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.5)': + '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.5)': + '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.6)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) - react: 19.2.5 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-presence@1.1.5(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@radix-ui/react-presence@1.1.5(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-primitive@2.1.3(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@radix-ui/react-primitive@2.1.3(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.5)': + '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.6)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) - react: 19.2.5 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-switch@1.2.6(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@radix-ui/react-switch@1.2.6(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-primitive': 2.1.3(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.5) - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.5)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.6)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.5) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) - react: 19.2.5 + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.14)(react@19.2.5)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.14)(react@19.2.6)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) - react: 19.2.5 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.14)(react@19.2.5)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.14)(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.14)(react@19.2.5)': + '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.14)(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 - '@radix-ui/react-use-size@1.1.1(@types/react@19.2.14)(react@19.2.5)': + '@radix-ui/react-use-size@1.1.1(@types/react@19.2.14)(react@19.2.6)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) - react: 19.2.5 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 - '@react-hook/latest@1.0.3(react@19.2.5)': + '@react-hook/latest@1.0.3(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-hook/passive-layout-effect@1.2.1(react@19.2.5)': + '@react-hook/passive-layout-effect@1.2.1(react@19.2.6)': dependencies: - react: 19.2.5 + react: 19.2.6 - '@react-hook/resize-observer@2.0.2(react@19.2.5)': + '@react-hook/resize-observer@2.0.2(react@19.2.6)': dependencies: - '@react-hook/latest': 1.0.3(react@19.2.5) - '@react-hook/passive-layout-effect': 1.2.1(react@19.2.5) - react: 19.2.5 + '@react-hook/latest': 1.0.3(react@19.2.6) + '@react-hook/passive-layout-effect': 1.2.1(react@19.2.6) + react: 19.2.6 '@rolldown/binding-android-arm64@1.0.0-rc.12': optional: true @@ -12719,9 +12953,9 @@ snapshots: '@sideway/pinpoint@2.0.0': {} - '@signalwire/docusaurus-plugin-llms-txt@1.2.2(@docusaurus/core@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2))': + '@signalwire/docusaurus-plugin-llms-txt@1.2.2(@docusaurus/core@3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2))': dependencies: - '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(esbuild@0.27.4))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.2) + '@docusaurus/core': 3.10.1(@docusaurus/faster@3.10.1(@docusaurus/types@3.10.1(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.27.4)(postcss@8.5.8))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.6))(@rspack/core@1.7.11)(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2) fs-extra: 11.3.4 hast-util-select: 6.0.4 hast-util-to-html: 9.0.5 @@ -12749,13 +12983,13 @@ snapshots: '@skyra/jaro-winkler@1.1.1': {} - '@slorber/react-helmet-async@1.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@slorber/react-helmet-async@1.3.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@babel/runtime': 7.29.2 invariant: 2.2.4 prop-types: 15.8.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) react-fast-compare: 3.2.2 shallowequal: 1.1.0 @@ -12852,7 +13086,7 @@ snapshots: dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.29.0) - '@babel/preset-env': 7.29.3(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) '@babel/preset-react': 7.28.5(@babel/core@7.29.0) '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) '@svgr/core': 8.1.0(typescript@6.0.2) @@ -13237,7 +13471,7 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@ungap/structured-clone@1.3.0': {} + '@ungap/structured-clone@1.3.1': {} '@vitest/expect@4.1.2': dependencies: @@ -13415,16 +13649,16 @@ snapshots: optionalDependencies: ajv: 8.18.0 - ajv-keywords@3.5.2(ajv@6.15.0): + ajv-keywords@3.5.2(ajv@6.14.0): dependencies: - ajv: 6.15.0 + ajv: 6.14.0 ajv-keywords@5.1.0(ajv@8.18.0): dependencies: ajv: 8.18.0 fast-deep-equal: 3.1.3 - ajv@6.15.0: + ajv@6.14.0: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 @@ -13438,10 +13672,10 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - algoliasearch-helper@3.28.2(algoliasearch@5.52.0): + algoliasearch-helper@3.29.1(algoliasearch@5.52.1): dependencies: '@algolia/events': 4.0.1 - algoliasearch: 5.52.0 + algoliasearch: 5.52.1 algoliasearch@4.27.0: dependencies: @@ -13461,22 +13695,22 @@ snapshots: '@algolia/requester-node-http': 4.27.0 '@algolia/transporter': 4.27.0 - algoliasearch@5.52.0: - dependencies: - '@algolia/abtesting': 1.18.0 - '@algolia/client-abtesting': 5.52.0 - '@algolia/client-analytics': 5.52.0 - '@algolia/client-common': 5.52.0 - '@algolia/client-insights': 5.52.0 - '@algolia/client-personalization': 5.52.0 - '@algolia/client-query-suggestions': 5.52.0 - '@algolia/client-search': 5.52.0 - '@algolia/ingestion': 1.52.0 - '@algolia/monitoring': 1.52.0 - '@algolia/recommend': 5.52.0 - '@algolia/requester-browser-xhr': 5.52.0 - '@algolia/requester-fetch': 5.52.0 - '@algolia/requester-node-http': 5.52.0 + algoliasearch@5.52.1: + dependencies: + '@algolia/abtesting': 1.18.1 + '@algolia/client-abtesting': 5.52.1 + '@algolia/client-analytics': 5.52.1 + '@algolia/client-common': 5.52.1 + '@algolia/client-insights': 5.52.1 + '@algolia/client-personalization': 5.52.1 + '@algolia/client-query-suggestions': 5.52.1 + '@algolia/client-search': 5.52.1 + '@algolia/ingestion': 1.52.1 + '@algolia/monitoring': 1.52.1 + '@algolia/recommend': 5.52.1 + '@algolia/requester-browser-xhr': 5.52.1 + '@algolia/requester-fetch': 5.52.1 + '@algolia/requester-node-http': 5.52.1 ansi-align@3.0.1: dependencies: @@ -13616,7 +13850,7 @@ snapshots: autoprefixer@10.5.0(postcss@8.5.8): dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001791 + caniuse-lite: 1.0.30001792 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.8 @@ -13632,20 +13866,20 @@ snapshots: b4a@1.8.0: {} - babel-loader@10.1.1(@babel/core@7.29.0)(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + babel-loader@10.1.1(@babel/core@7.29.0)(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: '@babel/core': 7.29.0 find-up: 5.0.0 optionalDependencies: '@rspack/core': 1.7.11 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) - babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: '@babel/core': 7.29.0 find-cache-dir: 4.0.0 schema-utils: 4.3.3 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) babel-plugin-dynamic-import-node@2.3.3: dependencies: @@ -13655,7 +13889,7 @@ snapshots: dependencies: '@babel/runtime': 7.29.2 cosmiconfig: 7.1.0 - resolve: 1.22.12 + resolve: 1.22.11 babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): dependencies: @@ -13689,14 +13923,14 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-styled-components@2.1.4(@babel/core@7.29.0)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5))(supports-color@5.5.0): + babel-plugin-styled-components@2.1.4(@babel/core@7.29.0)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6))(supports-color@5.5.0): dependencies: '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) lodash: 4.18.1 picomatch: 2.3.2 - styled-components: 5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5) + styled-components: 5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6) transitivePeerDependencies: - '@babel/core' - supports-color @@ -13898,7 +14132,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - call-bind@1.0.9: + call-bind@1.0.8: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 @@ -13934,7 +14168,7 @@ snapshots: caniuse-lite@1.0.30001784: {} - caniuse-lite@1.0.30001791: {} + caniuse-lite@1.0.30001792: {} ccount@2.0.1: {} @@ -14138,7 +14372,7 @@ snapshots: copy-text-to-clipboard@3.2.2: {} - copy-webpack-plugin@11.0.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + copy-webpack-plugin@11.0.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: fast-glob: 3.3.3 glob-parent: 6.0.2 @@ -14146,7 +14380,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.3.3 serialize-javascript: 6.0.2 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) core-js-compat@3.49.0: dependencies: @@ -14232,7 +14466,7 @@ snapshots: postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 - css-loader@6.11.0(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + css-loader@6.11.0(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: icss-utils: 5.1.0(postcss@8.5.8) postcss: 8.5.8 @@ -14244,9 +14478,9 @@ snapshots: semver: 7.7.4 optionalDependencies: '@rspack/core': 1.7.11 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) - css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(esbuild@0.27.4)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(esbuild@0.27.4)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: '@jridgewell/trace-mapping': 0.3.31 cssnano: 6.1.2(postcss@8.5.8) @@ -14254,7 +14488,7 @@ snapshots: postcss: 8.5.8 schema-utils: 4.3.3 serialize-javascript: 6.0.2 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) optionalDependencies: clean-css: 5.3.3 esbuild: 0.27.4 @@ -14303,7 +14537,7 @@ snapshots: css-what@6.2.2: {} - cssdb@8.8.0: {} + cssdb@8.8.1: {} cssesc@3.0.0: {} @@ -14570,7 +14804,7 @@ snapshots: encodeurl@2.0.0: {} - enhanced-resolve@5.21.0: + enhanced-resolve@5.21.2: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -14918,11 +15152,11 @@ snapshots: dependencies: is-unicode-supported: 2.1.0 - file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) file-type@20.5.0: dependencies: @@ -15296,7 +15530,7 @@ snapshots: dependencies: '@types/hast': 3.0.4 '@types/unist': 3.0.3 - '@ungap/structured-clone': 1.3.0 + '@ungap/structured-clone': 1.3.1 hast-util-from-parse5: 8.0.3 hast-util-to-parse5: 8.0.1 html-void-elements: 3.0.0 @@ -15311,7 +15545,7 @@ snapshots: hast-util-sanitize@5.0.2: dependencies: '@types/hast': 3.0.4 - '@ungap/structured-clone': 1.3.0 + '@ungap/structured-clone': 1.3.1 unist-util-position: 5.0.0 hast-util-select@6.0.4: @@ -15391,7 +15625,7 @@ snapshots: dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.0 + '@ungap/structured-clone': 1.3.1 hast-util-phrasing: 3.0.1 hast-util-to-html: 9.0.5 hast-util-to-text: 4.0.2 @@ -15504,7 +15738,7 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.6.7(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + html-webpack-plugin@5.6.7(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -15513,7 +15747,7 @@ snapshots: tapable: 2.3.3 optionalDependencies: '@rspack/core': 1.7.11 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) htmlparser2@6.1.0: dependencies: @@ -15655,6 +15889,11 @@ snapshots: inline-style-parser@0.2.7: {} + intl-messageformat@11.2.3: + dependencies: + '@formatjs/fast-memoize': 3.1.3 + '@formatjs/icu-messageformat-parser': 3.5.6 + invariant@2.2.4: dependencies: loose-envify: 1.4.0 @@ -15723,7 +15962,7 @@ snapshots: global-dirs: 3.0.1 is-path-inside: 3.0.3 - is-network-error@1.3.1: {} + is-network-error@1.3.2: {} is-npm@6.1.0: {} @@ -16208,7 +16447,7 @@ snapshots: dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.0 + '@ungap/structured-clone': 1.3.1 devlop: 1.1.0 micromark-util-sanitize-uri: 2.0.1 trim-lines: 3.0.1 @@ -16236,7 +16475,7 @@ snapshots: dependencies: '@types/mdast': 4.0.4 '@types/ungap__structured-clone': 1.2.0 - '@ungap/structured-clone': 1.3.0 + '@ungap/structured-clone': 1.3.1 github-slugger: 2.0.0 mdast-util-to-string: 4.0.0 unist-util-is: 6.0.1 @@ -16609,11 +16848,11 @@ snapshots: mimic-response@4.0.0: {} - mini-css-extract-plugin@2.10.2(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + mini-css-extract-plugin@2.10.2(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: schema-utils: 4.3.3 tapable: 2.3.3 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) minimalistic-assert@1.0.1: {} @@ -16707,11 +16946,11 @@ snapshots: dependencies: boolbase: 1.0.0 - null-loader@4.0.1(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + null-loader@4.0.1(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) object-assign@4.1.1: {} @@ -16721,7 +16960,7 @@ snapshots: object.assign@4.1.7: dependencies: - call-bind: 1.0.9 + call-bind: 1.0.8 call-bound: 1.0.4 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -16858,7 +17097,7 @@ snapshots: p-retry@6.2.1: dependencies: '@types/retry': 0.12.2 - is-network-error: 1.3.1 + is-network-error: 1.3.2 retry: 0.13.1 p-timeout@3.2.0: @@ -17235,13 +17474,13 @@ snapshots: '@csstools/utilities': 3.0.0(postcss@8.5.8) postcss: 8.5.8 - postcss-loader@7.3.4(postcss@8.5.8)(typescript@6.0.2)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + postcss-loader@7.3.4(postcss@8.5.8)(typescript@6.0.2)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: cosmiconfig: 8.3.6(typescript@6.0.2) jiti: 1.21.7 postcss: 8.5.8 semver: 7.7.4 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) transitivePeerDependencies: - typescript @@ -17460,7 +17699,7 @@ snapshots: css-blank-pseudo: 7.0.1(postcss@8.5.8) css-has-pseudo: 7.0.3(postcss@8.5.8) css-prefers-color-scheme: 10.0.0(postcss@8.5.8) - cssdb: 8.8.0 + cssdb: 8.8.1 postcss: 8.5.8 postcss-attribute-case-insensitive: 7.0.1(postcss@8.5.8) postcss-clamp: 4.1.0(postcss@8.5.8) @@ -17537,7 +17776,7 @@ snapshots: css-blank-pseudo: 8.0.1(postcss@8.5.8) css-has-pseudo: 8.0.0(postcss@8.5.8) css-prefers-color-scheme: 11.0.0(postcss@8.5.8) - cssdb: 8.8.0 + cssdb: 8.8.1 postcss: 8.5.8 postcss-attribute-case-insensitive: 8.0.0(postcss@8.5.8) postcss-clamp: 4.1.0(postcss@8.5.8) @@ -17660,11 +17899,11 @@ snapshots: pretty-time@1.1.0: {} - prism-react-renderer@2.4.1(react@19.2.5): + prism-react-renderer@2.4.1(react@19.2.6): dependencies: '@types/prismjs': 1.26.6 clsx: 2.1.1 - react: 19.2.5 + react: 19.2.6 prismjs@1.30.0: {} @@ -17775,11 +18014,11 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 - raw-loader@4.0.2(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + raw-loader@4.0.2(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) rc@1.2.8: dependencies: @@ -17788,40 +18027,40 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-dom@19.2.5(react@19.2.5): + react-dom@19.2.6(react@19.2.6): dependencies: - react: 19.2.5 + react: 19.2.6 scheduler: 0.27.0 react-fast-compare@3.2.2: {} - react-hotkeys-hook@4.6.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + react-hotkeys-hook@4.6.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) - react-hotkeys-hook@5.3.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + react-hotkeys-hook@5.3.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) - react-icons@4.12.0(react@19.2.5): + react-icons@4.12.0(react@19.2.6): dependencies: - react: 19.2.5 + react: 19.2.6 react-is@16.13.1: {} - react-json-view-lite@2.5.0(react@19.2.5): + react-json-view-lite@2.5.0(react@19.2.6): dependencies: - react: 19.2.5 + react: 19.2.6 - react-loadable-ssr-addon-v5-slorber@1.0.3(@docusaurus/react-loadable@6.0.0(react@19.2.5))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + react-loadable-ssr-addon-v5-slorber@1.0.3(@docusaurus/react-loadable@6.0.0(react@19.2.6))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: '@babel/runtime': 7.29.2 - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.5)' - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.6)' + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) - react-markdown@10.1.0(@types/react@19.2.14)(react@19.2.5): + react-markdown@10.1.0(@types/react@19.2.14)(react@19.2.6): dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 @@ -17830,7 +18069,7 @@ snapshots: hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 mdast-util-to-hast: 13.2.1 - react: 19.2.5 + react: 19.2.6 remark-parse: 11.0.0 remark-rehype: 11.1.2 unified: 11.0.5 @@ -17839,24 +18078,24 @@ snapshots: transitivePeerDependencies: - supports-color - react-router-config@5.1.1(react-router@5.3.4(react@19.2.5))(react@19.2.5): + react-router-config@5.1.1(react-router@5.3.4(react@19.2.6))(react@19.2.6): dependencies: '@babel/runtime': 7.29.2 - react: 19.2.5 - react-router: 5.3.4(react@19.2.5) + react: 19.2.6 + react-router: 5.3.4(react@19.2.6) - react-router-dom@5.3.4(react@19.2.5): + react-router-dom@5.3.4(react@19.2.6): dependencies: '@babel/runtime': 7.29.2 history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.2.5 - react-router: 5.3.4(react@19.2.5) + react: 19.2.6 + react-router: 5.3.4(react@19.2.6) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - react-router@5.3.4(react@19.2.5): + react-router@5.3.4(react@19.2.6): dependencies: '@babel/runtime': 7.29.2 history: 4.10.1 @@ -17864,38 +18103,38 @@ snapshots: loose-envify: 1.4.0 path-to-regexp: 1.9.0 prop-types: 15.8.1 - react: 19.2.5 + react: 19.2.6 react-is: 16.13.1 tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - react-select@5.10.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + react-select@5.10.2(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: '@babel/runtime': 7.29.2 '@emotion/cache': 11.14.0 - '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.5) + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) '@floating-ui/dom': 1.7.6 '@types/react-transition-group': 4.4.12(@types/react@19.2.14) memoize-one: 6.0.0 prop-types: 15.8.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) - react-transition-group: 4.4.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - use-isomorphic-layout-effect: 1.2.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-transition-group: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + use-isomorphic-layout-effect: 1.2.1(@types/react@19.2.14)(react@19.2.6) transitivePeerDependencies: - '@types/react' - supports-color - react-transition-group@4.4.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + react-transition-group@4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: '@babel/runtime': 7.29.2 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) - react@19.2.5: {} + react@19.2.6: {} readable-stream@2.3.8: dependencies: @@ -18123,9 +18362,8 @@ snapshots: resolve-pkg-maps@1.0.0: {} - resolve@1.22.12: + resolve@1.22.11: dependencies: - es-errors: 1.3.0 is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -18263,8 +18501,8 @@ snapshots: schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 - ajv: 6.15.0 - ajv-keywords: 3.5.2(ajv@6.15.0) + ajv: 6.14.0 + ajv-keywords: 3.5.2(ajv@6.14.0) schema-utils@4.3.3: dependencies: @@ -18646,18 +18884,18 @@ snapshots: dependencies: inline-style-parser: 0.2.7 - styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5): + styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6): dependencies: '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) '@babel/traverse': 7.29.0(supports-color@5.5.0) '@emotion/is-prop-valid': 1.4.0 '@emotion/stylis': 0.8.5 '@emotion/unitless': 0.7.5 - babel-plugin-styled-components: 2.1.4(@babel/core@7.29.0)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.5(react@19.2.5))(react-is@16.13.1)(react@19.2.5))(supports-color@5.5.0) + babel-plugin-styled-components: 2.1.4(@babel/core@7.29.0)(styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.6(react@19.2.6))(react-is@16.13.1)(react@19.2.6))(supports-color@5.5.0) css-to-react-native: 3.2.0 hoist-non-react-statics: 3.3.2 - react: 19.2.5 - react-dom: 19.2.5(react@19.2.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) react-is: 16.13.1 shallowequal: 1.1.0 supports-color: 5.5.0 @@ -18698,11 +18936,11 @@ snapshots: picocolors: 1.1.1 sax: 1.6.0 - swc-loader@0.2.7(@swc/core@1.15.33)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + swc-loader@0.2.7(@swc/core@1.15.33)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: '@swc/core': 1.15.33 '@swc/counter': 0.1.3 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) tabbable@6.4.0: {} @@ -18734,16 +18972,34 @@ snapshots: - bare-abort-controller - react-native-b4a - terser-webpack-plugin@5.5.0(@swc/core@1.15.33)(esbuild@0.27.4)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + terser-webpack-plugin@5.6.0(@swc/core@1.15.33)(@swc/html@1.15.33)(esbuild@0.27.4)(lightningcss@1.32.0)(postcss@8.5.8)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 terser: 5.46.1 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) optionalDependencies: '@swc/core': 1.15.33 + '@swc/html': 1.15.33 esbuild: 0.27.4 + lightningcss: 1.32.0 + postcss: 8.5.8 + + terser-webpack-plugin@5.6.0(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.46.1 + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) + optionalDependencies: + '@swc/core': 1.15.33 + clean-css: 5.3.3 + cssnano: 6.1.2(postcss@8.5.8) + esbuild: 0.27.4 + html-minifier-terser: 7.2.0 + postcss: 8.5.8 terser@5.46.1: dependencies: @@ -19026,18 +19282,18 @@ snapshots: dependencies: punycode: 2.3.1 - url-loader@4.1.1(file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + url-loader@4.1.1(file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)))(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) optionalDependencies: - file-loader: 6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + file-loader: 6.2.0(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) - use-isomorphic-layout-effect@1.2.1(@types/react@19.2.14)(react@19.2.5): + use-isomorphic-layout-effect@1.2.1(@types/react@19.2.14)(react@19.2.6): dependencies: - react: 19.2.5 + react: 19.2.6 optionalDependencies: '@types/react': 19.2.14 @@ -19149,7 +19405,7 @@ snapshots: - bufferutil - utf-8-validate - webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: colorette: 2.0.20 memfs: 4.57.2(tslib@2.8.1) @@ -19158,11 +19414,11 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) transitivePeerDependencies: - tslib - webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -19190,10 +19446,10 @@ snapshots: serve-index: 1.9.2 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) ws: 8.20.0 optionalDependencies: - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) transitivePeerDependencies: - bufferutil - debug @@ -19215,7 +19471,7 @@ snapshots: webpack-sources@3.4.1: {} - webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4): + webpack@5.106.2(@swc/core@1.15.33)(@swc/html@1.15.33)(esbuild@0.27.4)(lightningcss@1.32.0)(postcss@8.5.8): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -19227,7 +19483,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.21.0 + enhanced-resolve: 5.21.2 es-module-lexer: 2.0.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -19238,15 +19494,64 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.5.0(@swc/core@1.15.33)(esbuild@0.27.4)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)) + terser-webpack-plugin: 5.6.0(@swc/core@1.15.33)(@swc/html@1.15.33)(esbuild@0.27.4)(lightningcss@1.32.0)(postcss@8.5.8)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) watchpack: 2.5.1 webpack-sources: 3.4.1 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + webpack@5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.21.2 + es-module-lexer: 2.0.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + loader-runner: 4.3.2 + mime-db: 1.54.0 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)) + watchpack: 2.5.1 + webpack-sources: 3.4.1 + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss - uglify-js - webpackbar@7.0.0(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)): + webpackbar@7.0.0(@rspack/core@1.7.11)(webpack@5.106.2(@swc/core@1.15.33)(esbuild@0.27.4)(postcss@8.5.8)): dependencies: ansis: 3.17.0 consola: 3.4.2 @@ -19254,7 +19559,7 @@ snapshots: std-env: 3.10.0 optionalDependencies: '@rspack/core': 1.7.11 - webpack: 5.106.2(@swc/core@1.15.33)(esbuild@0.27.4) + webpack: 5.106.2(@swc/core@1.15.33)(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.8))(esbuild@0.27.4)(html-minifier-terser@7.2.0)(postcss@8.5.8) websocket-driver@0.7.4: dependencies: diff --git a/src/commands/actor/calculate-memory.ts b/src/commands/actor/calculate-memory.ts index e2fc2c62f..142b3b6d4 100644 --- a/src/commands/actor/calculate-memory.ts +++ b/src/commands/actor/calculate-memory.ts @@ -1,13 +1,14 @@ import { join, resolve } from 'node:path'; import process from 'node:process'; +import { ActorCalculateMemoryCommandMessages } from '#i18n/commands/actor/calculate-memory.js'; + import { calculateRunDynamicMemory } from '@apify/actor-memory-expression'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Flags } from '../../lib/command-framework/flags.js'; import { CommandExitCodes } from '../../lib/consts.js'; import { useActorConfig } from '../../lib/hooks/useActorConfig.js'; -import { error, info, success } from '../../lib/outputs.js'; import { getJsonFileContent, getLocalKeyValueStorePath } from '../../lib/utils.js'; const DEFAULT_INPUT_PATH = join(getLocalKeyValueStorePath('default'), 'INPUT.json'); @@ -84,15 +85,13 @@ export class ActorCalculateMemoryCommand extends ApifyCommand async run() { const { eventName } = this.args; const { count, testPayPerEvent, idempotencyKey } = this.flags; + const idempotencyKeyDisplay = idempotencyKey ?? 'not-provided'; const isAtHome = Boolean(process.env.APIFY_IS_AT_HOME); if (!isAtHome) { - info({ - message: `No platform detected: would charge ${count} events of type "${eventName}" with idempotency key "${idempotencyKey ?? 'not-provided'}".`, - stdout: true, - }); + this.logger.stdout.info( + this.t(ActorChargeCommandMessages.noPlatformDetected, { + count, + eventName, + idempotencyKey: idempotencyKeyDisplay, + jsonParams: [{ count, eventName, idempotencyKey: idempotencyKeyDisplay }], + }), + ); return; } if (testPayPerEvent) { - info({ - message: `PPE test mode: would charge ${count} events of type "${eventName}" with idempotency key "${idempotencyKey ?? 'not-provided'}".`, - stdout: true, - }); + this.logger.stdout.info( + this.t(ActorChargeCommandMessages.ppeTestMode, { + count, + eventName, + idempotencyKey: idempotencyKeyDisplay, + jsonParams: [{ count, eventName, idempotencyKey: idempotencyKeyDisplay }], + }), + ); return; } const apifyToken = await getApifyTokenFromEnvOrAuthFile(); const apifyClient = await getLoggedClient(apifyToken); if (!apifyClient) { - throw new Error('Apify token is not set. Please set it using the environment variable APIFY_TOKEN.'); + throw new Error(this.t(ActorChargeCommandMessages.missingApifyToken)); } + const runId = process.env[APIFY_ENV_VARS.ACTOR_RUN_ID]; if (!runId) { - throw new Error('Charge command must be executed in a running Actor. Run ID not found.'); + throw new Error(this.t(ActorChargeCommandMessages.notInRunningActor)); } const run = await apifyClient.run(runId).get(); + if (run?.pricingInfo?.pricingModel !== 'PAY_PER_EVENT') { - throw new Error('Charge command can only be used with pay-per-event pricing model.'); + throw new Error( + this.t(ActorChargeCommandMessages.invalidPricingModel, { + jsonParams: [run?.pricingInfo?.pricingModel ?? 'N/A'], + }), + ); } - info({ - message: `Charging ${count} events of type "${eventName}" with idempotency key "${idempotencyKey ?? 'not-provided'}" (runId: ${runId}).`, - stdout: true, - }); + this.logger.stdout.info( + this.t(ActorChargeCommandMessages.charging, { + count, + eventName, + idempotencyKey: idempotencyKeyDisplay, + runId, + jsonParams: [{ count, eventName, idempotencyKey: idempotencyKeyDisplay, runId }], + }), + ); await apifyClient.run(runId).charge({ eventName, count, diff --git a/src/commands/actor/generate-schema-types.ts b/src/commands/actor/generate-schema-types.ts index c4f127a7b..93e1c9063 100644 --- a/src/commands/actor/generate-schema-types.ts +++ b/src/commands/actor/generate-schema-types.ts @@ -2,6 +2,7 @@ import { mkdir, stat, writeFile } from 'node:fs/promises'; import path from 'node:path'; import process from 'node:process'; +import { ActorGenerateSchemaTypesCommandMessages } from '#i18n/commands/actor/generate-schema-types.js'; import type { JSONSchema4 } from 'json-schema'; import { compile, type Options } from 'json-schema-to-typescript'; @@ -15,7 +16,6 @@ import { readOutputSchema, readStorageSchema, } from '../../lib/input_schema.js'; -import { error, info, success, warning } from '../../lib/outputs.js'; import { clearAllRequired, makePropertiesRequired, @@ -130,8 +130,10 @@ just as if the command were run from that directory with no argument.`; cwd: effectiveCwd, getMessage: (schemaPath) => schemaPath - ? `Generating types from input schema at ${schemaPath}` - : `Generating types from input schema embedded in '${LOCAL_CONFIG_PATH}'`, + ? this.t(ActorGenerateSchemaTypesCommandMessages.generatingFromInputSchemaAt, { schemaPath }) + : this.t(ActorGenerateSchemaTypesCommandMessages.generatingFromInputSchemaEmbedded, { + configPath: LOCAL_CONFIG_PATH, + }), }); const name = 'input'; @@ -157,7 +159,9 @@ just as if the command were run from that directory with no argument.`; const outputFile = path.join(outputDir, `${name}.ts`); await writeFile(outputFile, result, 'utf-8'); - success({ message: `Generated types written to ${outputFile}` }); + this.logger.stderr.success( + this.t(ActorGenerateSchemaTypesCommandMessages.generatedTypesWritten, { outputFile }), + ); // When no specific file path is provided, also generate types from additional schemas // (this includes both "no argument" and "directory argument" modes) @@ -174,9 +178,15 @@ just as if the command were run from that directory with no argument.`; for (const [i, schemaResult] of schemaResults.entries()) { if (schemaResult.status === 'rejected') { anyFailed = true; - error({ - message: `Failed to generate types for ${schemaLabels[i]} schema: ${schemaResult.reason instanceof Error ? schemaResult.reason.message : String(schemaResult.reason)}`, - }); + this.logger.stderr.error( + this.t(ActorGenerateSchemaTypesCommandMessages.schemaGenerationFailed, { + label: schemaLabels[i], + message: + schemaResult.reason instanceof Error + ? schemaResult.reason.message + : String(schemaResult.reason), + }), + ); } } @@ -204,15 +214,23 @@ just as if the command were run from that directory with no argument.`; const { datasetSchema, datasetSchemaPath } = datasetResult; if (datasetSchemaPath) { - info({ message: `[experimental] Generating types from Dataset schema at ${datasetSchemaPath}` }); + this.logger.stderr.info( + this.t(ActorGenerateSchemaTypesCommandMessages.experimentalDatasetAt, { + schemaPath: datasetSchemaPath, + }), + ); } else { - info({ message: `[experimental] Generating types from Dataset schema embedded in '${LOCAL_CONFIG_PATH}'` }); + this.logger.stderr.info( + this.t(ActorGenerateSchemaTypesCommandMessages.experimentalDatasetEmbedded, { + configPath: LOCAL_CONFIG_PATH, + }), + ); } const prepared = prepareFieldsSchemaForCompilation(datasetSchema); if (!prepared) { - warning({ message: 'Dataset schema has no fields defined, skipping type generation.' }); + this.logger.stderr.warning(this.t(ActorGenerateSchemaTypesCommandMessages.datasetHasNoFields)); return; } @@ -225,7 +243,9 @@ just as if the command were run from that directory with no argument.`; const outputFile = path.join(outputDir, `${datasetName}.ts`); await writeFile(outputFile, result, 'utf-8'); - success({ message: `Generated types written to ${outputFile}` }); + this.logger.stderr.success( + this.t(ActorGenerateSchemaTypesCommandMessages.generatedTypesWritten, { outputFile }), + ); } private async generateOutputTypes({ @@ -246,15 +266,21 @@ just as if the command were run from that directory with no argument.`; const { outputSchema, outputSchemaPath } = outputResult; if (outputSchemaPath) { - info({ message: `[experimental] Generating types from Output schema at ${outputSchemaPath}` }); + this.logger.stderr.info( + this.t(ActorGenerateSchemaTypesCommandMessages.experimentalOutputAt, { schemaPath: outputSchemaPath }), + ); } else { - info({ message: `[experimental] Generating types from Output schema embedded in '${LOCAL_CONFIG_PATH}'` }); + this.logger.stderr.info( + this.t(ActorGenerateSchemaTypesCommandMessages.experimentalOutputEmbedded, { + configPath: LOCAL_CONFIG_PATH, + }), + ); } const prepared = prepareOutputSchemaForCompilation(outputSchema); if (!prepared) { - warning({ message: 'Output schema has no properties defined, skipping type generation.' }); + this.logger.stderr.warning(this.t(ActorGenerateSchemaTypesCommandMessages.outputHasNoProperties)); return; } @@ -267,7 +293,9 @@ just as if the command were run from that directory with no argument.`; const outputFile = path.join(outputDir, `${outputName}.ts`); await writeFile(outputFile, result, 'utf-8'); - success({ message: `Generated types written to ${outputFile}` }); + this.logger.stderr.success( + this.t(ActorGenerateSchemaTypesCommandMessages.generatedTypesWritten, { outputFile }), + ); } private async generateKvsTypes({ @@ -288,19 +316,21 @@ just as if the command were run from that directory with no argument.`; const { schema: kvsSchema, schemaPath: kvsSchemaPath } = kvsResult; if (kvsSchemaPath) { - info({ message: `[experimental] Generating types from Key-Value Store schema at ${kvsSchemaPath}` }); + this.logger.stderr.info( + this.t(ActorGenerateSchemaTypesCommandMessages.experimentalKvsAt, { schemaPath: kvsSchemaPath }), + ); } else { - info({ - message: `[experimental] Generating types from Key-Value Store schema embedded in '${LOCAL_CONFIG_PATH}'`, - }); + this.logger.stderr.info( + this.t(ActorGenerateSchemaTypesCommandMessages.experimentalKvsEmbedded, { + configPath: LOCAL_CONFIG_PATH, + }), + ); } const collections = prepareKvsCollectionsForCompilation(kvsSchema); if (collections.length === 0) { - warning({ - message: 'Key-Value Store schema has no collections with JSON schemas, skipping type generation.', - }); + this.logger.stderr.warning(this.t(ActorGenerateSchemaTypesCommandMessages.kvsHasNoCollections)); return; } @@ -321,6 +351,8 @@ just as if the command were run from that directory with no argument.`; const outputFile = path.join(outputDir, 'key-value-store.ts'); await writeFile(outputFile, parts.join('\n'), 'utf-8'); - success({ message: `Generated types written to ${outputFile}` }); + this.logger.stderr.success( + this.t(ActorGenerateSchemaTypesCommandMessages.generatedTypesWritten, { outputFile }), + ); } } diff --git a/src/commands/actor/get-public-url.ts b/src/commands/actor/get-public-url.ts index 6b5cb8001..5dd0f81a3 100644 --- a/src/commands/actor/get-public-url.ts +++ b/src/commands/actor/get-public-url.ts @@ -1,3 +1,4 @@ +import { ActorGetPublicUrlCommandMessages } from '#i18n/commands/actor/get-public-url.js'; import type { ApifyClient } from 'apify-client'; import { ACTOR_ENV_VARS, APIFY_ENV_VARS } from '@apify/consts'; @@ -6,7 +7,6 @@ import { getApifyStorageClient } from '../../lib/actor.js'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { CommandExitCodes } from '../../lib/consts.js'; -import { error } from '../../lib/outputs.js'; export class ActorGetPublicUrlCommand extends ApifyCommand { static override name = 'get-public-url' as const; @@ -35,17 +35,21 @@ export class ActorGetPublicUrlCommand extends ApifyCommand { static override name = 'push-data' as const; @@ -28,6 +29,7 @@ export class ActorPushDataCommand extends ApifyCommand { static override name = 'call' as const; @@ -84,8 +78,6 @@ export class ActorsCallCommand extends ApifyCommand { // TODO: do we want to do the --stream-x flags? Can we even do them? }; - static override enableJsonFlag = true; - static override args = { actorId: Args.string({ required: false, @@ -103,7 +95,7 @@ export class ActorsCallCommand extends ApifyCommand { const usernameOrId = userInfo.username || (userInfo.id as string); if (this.flags.json && this.flags.outputDataset) { - error({ message: 'You cannot use both the --json and --output-dataset flags when running this command.' }); + this.logger.stderr.error(this.t(ActorsCallCommandMessages.conflictingJsonAndOutputDataset)); process.exitCode = CommandExitCodes.InvalidInput; return; @@ -174,12 +166,18 @@ export class ActorsCallCommand extends ApifyCommand { datasetUrl = `https://console.apify.com/storage/datasets/${yieldedRun.defaultDatasetId}`; const message: string[] = [ - `${chalk.yellow('Started')}: ${TimestampFormatter.display(yieldedRun.startedAt)}`, + this.t(ActorsCallCommandMessages.runStartedHeader, { + startedAt: TimestampFormatter.display(yieldedRun.startedAt), + }), ]; // container url if (yieldedRun.containerUrl) { - message.push(`${chalk.yellow('Container URL')}: ${chalk.blue(yieldedRun.containerUrl)}`); + message.push( + this.t(ActorsCallCommandMessages.containerUrlLine, { + containerUrl: yieldedRun.containerUrl, + }), + ); } // basic version info @@ -192,52 +190,54 @@ export class ActorsCallCommand extends ApifyCommand { (actorData.taggedBuilds ?? {}) as Record, ).find(([, data]) => data.buildNumber === yieldedRun.buildNumber)?.[0]; - const messageParts = [`${chalk.yellow('Build')}:`, chalk.cyan(run.buildNumber)]; + const buildTagText = runVersionTaggedAs + ? this.t(ActorsCallCommandMessages.buildTagValue, { tag: runVersionTaggedAs }) + : this.t(ActorsCallCommandMessages.buildTagNa); - if (runVersionTaggedAs) { - messageParts.push(`(${chalk.yellow(runVersionTaggedAs)})`); - } else { - messageParts.push(`(${chalk.gray('N/A')})`); - } - - if (actorVersion) { - messageParts.push( - `| ${chalk.gray('Actor version:')} ${chalk.cyan(actorVersion.versionNumber)} (${chalk.yellow(actorVersion.buildTag)})`, - ); - } + const actorVersionInfo = actorVersion + ? this.t(ActorsCallCommandMessages.actorVersionInfo, { + versionNumber: actorVersion.versionNumber ?? '', + buildTag: actorVersion.buildTag ?? '', + }) + : ''; - message.push(messageParts.join(' ')); + message.push( + this.t(ActorsCallCommandMessages.buildLine, { + buildNumber: run.buildNumber, + buildTag: buildTagText, + actorVersionInfo, + }), + ); // timeout message.push( - `${chalk.yellow('Timeout')}: ${run.options.timeoutSecs.toLocaleString('en-US')} seconds`, + this.t(ActorsCallCommandMessages.timeoutLine, { + timeoutSecs: run.options.timeoutSecs.toLocaleString('en-US'), + }), ); // memory limit - message.push(`${chalk.yellow('Memory')}: ${run.options.memoryMbytes} MB`); + message.push( + this.t(ActorsCallCommandMessages.memoryLine, { memoryMbytes: run.options.memoryMbytes }), + ); // url - message.push(`${chalk.blue('View on Apify Console')}: ${url}`, ''); + message.push(this.t(ActorsCallCommandMessages.viewOnConsoleLine, { url }), ''); - simpleLog({ message: message.join('\n'), stdout: !this.flags.json }); + (!this.flags.json ? this.logger.stdout : this.logger.stderr).log(message.join('\n')); } } } if (this.flags.json) { - printJsonToStdout(run!); + this.logger.stdout.json(run!); return; } if (!this.flags.silent) { - simpleLog({ - message: [ - '', - `${chalk.blue('Export results')}: ${datasetUrl!}`, - `${chalk.blue('View on Apify Console')}: ${url!}`, - ].join('\n'), - stdout: true, - }); + this.logger.stdout.log( + this.t(ActorsCallCommandMessages.resultLinks, { datasetUrl: datasetUrl!, url: url! }), + ); } if (this.flags.outputDataset) { @@ -283,7 +283,7 @@ export class ActorsCallCommand extends ApifyCommand { if (providedActorNameOrId?.includes('/')) { const actor = await client.actor(providedActorNameOrId).get(); if (!actor) { - throw new Error(`Cannot find Actor with ID '${providedActorNameOrId}' in your account.`); + throw new Error(t(ActorsCallCommandMessages.actorNotFoundByFullId, { actorId: providedActorNameOrId })); } return { @@ -315,7 +315,7 @@ export class ActorsCallCommand extends ApifyCommand { }; } - throw new Error(`Cannot find Actor with name or ID '${providedActorNameOrId}' in your account.`); + throw new Error(t(ActorsCallCommandMessages.actorNotFoundByNameOrId, { actorId: providedActorNameOrId })); } if (localActorName) { @@ -323,8 +323,9 @@ export class ActorsCallCommand extends ApifyCommand { if (!actor) { throw new Error( - `Cannot find Actor with ID '${usernameOrId}/${localActorName}' ` + - 'in your account. Call "apify push" to push this Actor to Apify platform.', + t(ActorsCallCommandMessages.actorNotFoundFromLocalConfig, { + actorId: `${usernameOrId}/${localActorName}`, + }), ); } @@ -335,8 +336,6 @@ export class ActorsCallCommand extends ApifyCommand { }; } - throw new Error( - 'Please provide an Actor ID or name, or run this command from a directory with a valid Apify Actor.', - ); + throw new Error(t(ActorsCallCommandMessages.missingActorIdentifier)); } } diff --git a/src/commands/actors/info.ts b/src/commands/actors/info.ts index 8f4e36701..2abdd1743 100644 --- a/src/commands/actors/info.ts +++ b/src/commands/actors/info.ts @@ -1,3 +1,4 @@ +import { ActorsInfoCommandMessages } from '#i18n/commands/actors/info.js'; import type { Actor, ActorTaggedBuild, Build, User } from 'apify-client'; import chalk from 'chalk'; @@ -6,8 +7,7 @@ import { Args } from '../../lib/command-framework/args.js'; import { Flags } from '../../lib/command-framework/flags.js'; import { resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; -import { error, simpleLog } from '../../lib/outputs.js'; -import { DurationFormatter, getLoggedClientOrThrow, printJsonToStdout, TimestampFormatter } from '../../lib/utils.js'; +import { DurationFormatter, getLoggedClientOrThrow, TimestampFormatter } from '../../lib/utils.js'; interface HydratedActorInfo extends Omit { taggedBuilds?: Record; @@ -81,8 +81,6 @@ export class ActorsInfoCommand extends ApifyCommand { }), }; - static override enableJsonFlag = true; - async run() { const { actorId } = this.args; const { readme, input, json } = this.flags; @@ -91,10 +89,7 @@ export class ActorsInfoCommand extends ApifyCommand { const ctx = await resolveActorContext({ providedActorNameOrId: actorId, client }); if (!ctx.valid) { - error({ - message: `${ctx.reason}. Please specify the Actor ID.`, - stdout: true, - }); + this.logger.stdout.error(this.t(ActorsInfoCommandMessages.invalidActorContext, { reason: ctx.reason })); return; } @@ -116,7 +111,7 @@ export class ActorsInfoCommand extends ApifyCommand { } if (json) { - printJsonToStdout(actorInfo); + this.logger.stdout.json(actorInfo); return; } @@ -124,89 +119,82 @@ export class ActorsInfoCommand extends ApifyCommand { if (readme) { if (!latest) { - error({ - message: 'No README found for this Actor.', - stdout: true, - }); + this.logger.stdout.error(this.t(ActorsInfoCommandMessages.noReadme)); return; } if (!latest.build?.readme) { - error({ - message: 'No README found for this Actor.', - stdout: true, - }); + this.logger.stdout.error(this.t(ActorsInfoCommandMessages.noReadme)); return; } - simpleLog({ message: latest.build.readme, stdout: true }); + this.logger.stdout.log(latest.build.readme); return; } if (input) { if (!latest) { - error({ - message: 'No input schema found for this Actor.', - stdout: true, - }); + this.logger.stdout.error(this.t(ActorsInfoCommandMessages.noInputSchema)); return; } if (!latest.build?.inputSchema) { - error({ - message: 'No input schema found for this Actor.', - stdout: true, - }); + this.logger.stdout.error(this.t(ActorsInfoCommandMessages.noInputSchema)); return; } - simpleLog({ message: latest.build.inputSchema, stdout: true }); + this.logger.stdout.log(latest.build.inputSchema); return; } const message = [ - `Information about Actor ${chalk.yellow(`${actorInfo.username}/${actorInfo.name}`)} (${chalk.gray(actorInfo.id)})`, - '', + this.t(ActorsInfoCommandMessages.header, { + fullName: `${actorInfo.username}/${actorInfo.name}`, + id: actorInfo.id, + }), ]; if (actorInfo.title) { - message.push(`${chalk.yellow('Title:')} ${chalk.bold(actorInfo.title)}`); + message.push(this.t(ActorsInfoCommandMessages.titleLine, { title: actorInfo.title })); } if (actorInfo.description) { - message.push(`${chalk.yellow('Description:')} ${actorInfo.description}`); + message.push(this.t(ActorsInfoCommandMessages.descriptionLine, { description: actorInfo.description })); } message.push( - `${chalk.yellow('Created at:')} ${chalk.cyan(TimestampFormatter.display(actorInfo.createdAt))} ${chalk.gray('|')} ${chalk.yellow('Updated at:')} ${chalk.cyan( - TimestampFormatter.display(actorInfo.modifiedAt), - )}`, + this.t(ActorsInfoCommandMessages.createdUpdatedLine, { + createdAt: TimestampFormatter.display(actorInfo.createdAt), + modifiedAt: TimestampFormatter.display(actorInfo.modifiedAt), + }), ); if (actorInfo.actorMaker) { message.push( '', - `${chalk.yellow('Made by:')} ${chalk.cyan(actorInfo.actorMaker.profile.name ?? actorInfo.actorMaker.username)}`, + this.t(ActorsInfoCommandMessages.madeByLine, { + name: actorInfo.actorMaker.profile.name ?? actorInfo.actorMaker.username, + }), ); // Missing types who? if (Reflect.get(actorInfo, 'isCritical')) { - message[message.length - 1] += ` ${chalk.bgGray('Maintained by Apify')}`; + message[message.length - 1] += ` ${this.t(ActorsInfoCommandMessages.maintainedByApifyBadge)}`; } } if (actorInfo.isPublic) { - message.push('', `${chalk.yellow('Actor is')} ${chalk.green('PUBLIC')}`); + message.push('', this.t(ActorsInfoCommandMessages.actorIsPublic)); } else { - message.push('', `${chalk.yellow('Actor is')} ${chalk.cyan('PRIVATE')}`); + message.push('', this.t(ActorsInfoCommandMessages.actorIsPrivate)); } if (actorInfo.isDeprecated) { - message.push('', `${chalk.yellow('Actor is')} ${chalk.red('DEPRECATED')}`); + message.push('', this.t(ActorsInfoCommandMessages.actorIsDeprecated)); } // Pricing info @@ -219,14 +207,16 @@ export class ActorsInfoCommand extends ApifyCommand { switch (latestPricingInfo.pricingModel) { case 'FLAT_PRICE_PER_MONTH': { message.push( - `${chalk.yellow('Pricing information:')} ${chalk.bgGray(`$${latestPricingInfo.pricePerUnitUsd}/month + usage`)}`, + this.t(ActorsInfoCommandMessages.pricingFlatPerMonth, { + priceLabel: `$${latestPricingInfo.pricePerUnitUsd}/month + usage`, + }), ); if (latestPricingInfo.trialMinutes) { const minutesToMs = latestPricingInfo.trialMinutes * 60 * 1000; const duration = DurationFormatter.format(minutesToMs); - message.push(` ${chalk.yellow('Trial duration:')} ${chalk.bold(duration)}`); + message.push(this.t(ActorsInfoCommandMessages.pricingTrialDuration, { duration })); } break; @@ -235,13 +225,15 @@ export class ActorsInfoCommand extends ApifyCommand { const pricePerOneKItems = latestPricingInfo.pricePerUnitUsd * 1000; message.push( - `${chalk.yellow('Pricing information:')} ${chalk.bgGray(`$${pricePerOneKItems.toFixed(2)} / 1,000 results`)}`, + this.t(ActorsInfoCommandMessages.pricingPerDatasetItem, { + priceLabel: `$${pricePerOneKItems.toFixed(2)} / 1,000 results`, + }), ); break; } case 'PAY_PER_EVENT': { - message.push(`${chalk.yellow('Pricing information:')} ${chalk.bgGray('Pay per event')}`); + message.push(this.t(ActorsInfoCommandMessages.pricingPayPerEvent)); const events = Object.values(latestPricingInfo.pricingPerEvent?.actorChargeEvents ?? {}); @@ -264,42 +256,49 @@ export class ActorsInfoCommand extends ApifyCommand { } case 'FREE': { - message.push(`${chalk.yellow('Pricing information:')} ${chalk.bgGray('Pay for usage')}`); + message.push(this.t(ActorsInfoCommandMessages.pricingFree)); break; } default: { message.push( - `${chalk.yellow('Pricing information:')} ${chalk.bgGray(`Unknown pricing model (${chalk.yellow(latestPricingInfo.pricingModel)})`)}`, + this.t(ActorsInfoCommandMessages.pricingUnknown, { + pricingModel: latestPricingInfo.pricingModel, + }), ); } } } else { - message.push(`${chalk.yellow('Pricing information:')} ${chalk.bgGray('Pay for usage')}`); + message.push(this.t(ActorsInfoCommandMessages.pricingFree)); } // TODO: do we care about this information? if (actorInfo.seoTitle || actorInfo.seoDescription) { - message.push('', chalk.yellow('SEO information:')); + message.push('', this.t(ActorsInfoCommandMessages.seoHeader)); if (actorInfo.seoTitle) { - message.push(` ${chalk.yellow('Title:')} ${actorInfo.seoTitle}`); + message.push(this.t(ActorsInfoCommandMessages.seoTitleLine, { seoTitle: actorInfo.seoTitle })); } if (actorInfo.seoDescription) { - message.push(` ${chalk.yellow('Description:')} ${actorInfo.seoDescription}`); + message.push( + this.t(ActorsInfoCommandMessages.seoDescriptionLine, { seoDescription: actorInfo.seoDescription }), + ); } } if (actorInfo.taggedBuilds) { - message.push('', chalk.yellow('Builds:')); + message.push('', this.t(ActorsInfoCommandMessages.buildsHeader)); // Handle latest first const latestBuild = actorInfo.taggedBuilds.latest; if (latestBuild) { message.push( - ` ${chalk.yellow('-')} ${chalk.cyan(latestBuild.buildNumber)} ${chalk.gray('/')} ${chalk.yellow('latest')}`, + this.t(ActorsInfoCommandMessages.buildEntry, { + buildNumber: latestBuild.buildNumber ?? '', + tag: 'latest', + }), ); } @@ -309,11 +308,14 @@ export class ActorsInfoCommand extends ApifyCommand { } message.push( - ` ${chalk.yellow('-')} ${chalk.cyan(build.buildNumber)} ${chalk.gray('/')} ${chalk.yellow(buildTag)}`, + this.t(ActorsInfoCommandMessages.buildEntry, { + buildNumber: build.buildNumber ?? '', + tag: buildTag, + }), ); } } - simpleLog({ message: message.join('\n'), stdout: true }); + this.logger.stdout.log(message.join('\n')); } } diff --git a/src/commands/actors/ls.ts b/src/commands/actors/ls.ts index 54cb0e493..747788e82 100644 --- a/src/commands/actors/ls.ts +++ b/src/commands/actors/ls.ts @@ -1,4 +1,5 @@ import { Time } from '@sapphire/duration'; +import { ActorsLsCommandMessages } from '#i18n/commands/actors/ls.js'; import type { Actor, ActorRunListItem, ActorTaggedBuild, PaginatedList } from 'apify-client'; import chalk from 'chalk'; @@ -8,12 +9,10 @@ import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Flags } from '../../lib/command-framework/flags.js'; import { prettyPrintStatus } from '../../lib/commands/pretty-print-status.js'; import { CompactMode, kSkipColumn, ResponsiveTable } from '../../lib/commands/responsive-table.js'; -import { info, simpleLog } from '../../lib/outputs.js'; import { DateOnlyTimestampFormatter, getLoggedClientOrThrow, MultilineTimestampFormatter, - printJsonToStdout, ShortDurationFormatter, } from '../../lib/utils.js'; @@ -135,8 +134,6 @@ export class ActorsLsCommand extends ApifyCommand { }), }; - static override enableJsonFlag = true; - async run() { const { desc, limit, offset, my, json } = this.flags; @@ -146,14 +143,13 @@ export class ActorsLsCommand extends ApifyCommand { if (rawActorList.count === 0) { if (json) { - printJsonToStdout(rawActorList); + this.logger.stdout.json(rawActorList); return; } - info({ - message: my ? "You don't have any Actors yet!" : 'There are no recent Actors used by you.', - stdout: true, - }); + this.logger.stdout.info( + my ? this.t(ActorsLsCommandMessages.noActorsOwned) : this.t(ActorsLsCommandMessages.noRecentActors), + ); return; } @@ -193,7 +189,7 @@ export class ActorsLsCommand extends ApifyCommand { actorList.items = my ? this.sortByModifiedAt(actorList.items) : this.sortByLastRun(actorList.items); if (json) { - printJsonToStdout(actorList); + this.logger.stdout.json(actorList); return; } @@ -298,10 +294,7 @@ export class ActorsLsCommand extends ApifyCommand { }); } - simpleLog({ - message: table.render(CompactMode.WebLikeCompact), - stdout: true, - }); + this.logger.stdout.log(table.render(CompactMode.WebLikeCompact)); } private sortByModifiedAt(items: HydratedListData[]) { diff --git a/src/commands/actors/pull.ts b/src/commands/actors/pull.ts index c09cf1057..a203ca9ec 100644 --- a/src/commands/actors/pull.ts +++ b/src/commands/actors/pull.ts @@ -2,6 +2,7 @@ import { mkdirSync, readdirSync, writeFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import process from 'node:process'; +import { ActorsPullCommandMessages } from '#i18n/commands/actors/pull.js'; import AdmZip from 'adm-zip'; import axios from 'axios'; import jju from 'jju'; @@ -13,7 +14,6 @@ import { Args } from '../../lib/command-framework/args.js'; import { Flags } from '../../lib/command-framework/flags.js'; import { CommandExitCodes, LOCAL_CONFIG_PATH } from '../../lib/consts.js'; import { useActorConfig } from '../../lib/hooks/useActorConfig.js'; -import { error, success } from '../../lib/outputs.js'; import { getLocalUserInfo, getLoggedClientOrThrow } from '../../lib/utils.js'; const extractGitHubZip = async (url: string, directoryPath: string) => { @@ -77,7 +77,9 @@ export class ActorsPullCommand extends ApifyCommand { const actorConfigResult = await useActorConfig({ cwd }); if (actorConfigResult.isErr()) { - error({ message: actorConfigResult.unwrapErr().message }); + this.logger.stderr.error( + this.t(ActorsPullCommandMessages.actorConfigError, { message: actorConfigResult.unwrapErr().message }), + ); process.exitCode = CommandExitCodes.InvalidActorJson; return; } @@ -95,34 +97,36 @@ export class ActorsPullCommand extends ApifyCommand { (actorConfig?.id as string | undefined) || (actorConfig?.name ? `${usernameOrId}/${actorConfig.name}` : undefined); - if (!actorId) throw new Error('Cannot find Actor in this directory.'); + if (!actorId) throw new Error(this.t(ActorsPullCommandMessages.cannotFindActorInDirectory)); let actor; try { actor = await apifyClient.actor(actorId).get(); } catch { - throw new Error(`Cannot find Actor with ID/name '${actorId}' in your account.`); + throw new Error(this.t(ActorsPullCommandMessages.cannotFindActorByIdOrName, { actorId })); } if (!actor) { - throw new Error(`Cannot find Actor with ID/name '${actorId}' in your account.`); + throw new Error(this.t(ActorsPullCommandMessages.cannotFindActorByIdOrName, { actorId })); } const { name, versions } = actor; const throwMissingSourceCodeAccessError = () => { - throw new Error(`You cannot pull source code of this Actor because you do not have permission to do so.`); + throw new Error(this.t(ActorsPullCommandMessages.missingSourceCodeAccess)); }; if (!actor.versions.length) { - throw new Error(`Actor ${actorId} has no versions.`); + throw new Error(this.t(ActorsPullCommandMessages.actorHasNoVersions, { actorId })); } let correctVersion = null; if (this.flags.version) { correctVersion = versions.find((version) => version.versionNumber === this.flags.version); if (!correctVersion) { - throw new Error(`Cannot find version ${this.flags.version} of Actor ${actorId}.`); + throw new Error( + this.t(ActorsPullCommandMessages.versionNotFound, { version: this.flags.version, actorId }), + ); } } @@ -137,7 +141,7 @@ export class ActorsPullCommand extends ApifyCommand { mkdirSync(dirpath, { recursive: true }); if (!isActorAutomaticallyDetected && !(readdirSync(dirpath).length === 0)) { - error({ message: `Directory ${dirpath} is not empty. Please empty it or choose another directory.` }); + this.logger.stderr.error(this.t(ActorsPullCommandMessages.directoryNotEmpty, { dirpath })); return; } @@ -199,7 +203,12 @@ export class ActorsPullCommand extends ApifyCommand { try { await emitter.clone(dirpath); } catch (err) { - throw new Error(`Failed to pull Actor from ${gitRepoUrl}. ${(err as Error).message}`); + throw new Error( + this.t(ActorsPullCommandMessages.gitPullFailed, { + gitRepoUrl, + message: (err as Error).message, + }), + ); } break; @@ -214,11 +223,13 @@ export class ActorsPullCommand extends ApifyCommand { break; } default: - throw new Error(`Unknown source type: ${sourceType}`); + throw new Error(this.t(ActorsPullCommandMessages.unknownSourceType, { sourceType })); } - success({ - message: isActorAutomaticallyDetected ? `Actor ${name} updated at ${dirpath}/` : `Pulled to ${dirpath}/`, - }); + this.logger.stderr.success( + isActorAutomaticallyDetected + ? this.t(ActorsPullCommandMessages.actorUpdatedAt, { name, dirpath }) + : this.t(ActorsPullCommandMessages.pulledTo, { dirpath }), + ); } } diff --git a/src/commands/actors/push.ts b/src/commands/actors/push.ts index f8905ac09..942b0e829 100644 --- a/src/commands/actors/push.ts +++ b/src/commands/actors/push.ts @@ -2,6 +2,7 @@ import { readFileSync, statSync, unlinkSync } from 'node:fs'; import { join, resolve } from 'node:path'; import process from 'node:process'; +import { ActorsPushCommandMessages } from '#i18n/commands/actors/push.js'; import type { Actor, ActorCollectionCreateOptions, ActorDefaultRunOptions } from 'apify-client'; import open from 'open'; @@ -16,7 +17,6 @@ import { CommandExitCodes, DEPRECATED_LOCAL_CONFIG_NAME, LOCAL_CONFIG_PATH } fro import { sumFilesSizeInBytes } from '../../lib/files.js'; import { useAbortJobOnSignal } from '../../lib/hooks/useAbortJobOnSignal.js'; import { useActorConfig } from '../../lib/hooks/useActorConfig.js'; -import { error, info, link, run, success, warning } from '../../lib/outputs.js'; import { transformEnvToEnvVars } from '../../lib/secrets.js'; import { createActZip, @@ -25,7 +25,6 @@ import { getLocalUserInfo, getLoggedClientOrThrow, outputJobLog, - printJsonToStdout, } from '../../lib/utils.js'; const TEMP_ZIP_FILE_NAME = 'temp_file.zip'; @@ -72,8 +71,6 @@ export class ActorsPushCommand extends ApifyCommand { static override docsUrl = 'https://docs.apify.com/cli/docs/reference#apify-push'; - static override enableJsonFlag = true; - static override flags = { version: Flags.string({ char: 'v', @@ -130,7 +127,7 @@ export class ActorsPushCommand extends ApifyCommand { const filePathsToPush = await getActorLocalFilePaths(cwd); if (!filePathsToPush.length) { - error({ message: 'You need to call this command from a folder that has an Actor in it!' }); + this.logger.stderr.error(this.t(ActorsPushCommandMessages.noActorInDirectory)); process.exitCode = CommandExitCodes.NoFilesToPush; return; } @@ -147,12 +144,7 @@ export class ActorsPushCommand extends ApifyCommand { '.actor', ].some((filePath) => filePathsToPush.some((fp) => fp === filePath || fp.startsWith(filePath))) ) { - error({ - message: [ - 'A valid Actor could not be found in the current directory. Please make sure you are in the correct directory.', - 'You can also turn this directory into an Actor by running `apify init`.', - ].join('\n'), - }); + this.logger.stderr.error(this.t(ActorsPushCommandMessages.noValidActorFound)); process.exitCode = CommandExitCodes.NoFilesToPush; return; @@ -163,7 +155,9 @@ export class ActorsPushCommand extends ApifyCommand { const actorConfigResult = await useActorConfig({ cwd }); if (actorConfigResult.isErr()) { - error({ message: actorConfigResult.unwrapErr().message }); + this.logger.stderr.error( + this.t(ActorsPushCommandMessages.actorConfigError, { message: actorConfigResult.unwrapErr().message }), + ); process.exitCode = CommandExitCodes.InvalidActorJson; return; } @@ -202,7 +196,9 @@ export class ActorsPushCommand extends ApifyCommand { if (forceActorId) { actor = (await apifyClient.actor(forceActorId).get())!; - if (!actor) throw new Error(`Cannot find Actor with ID '${forceActorId}' in your account.`); + if (!actor) { + throw new Error(this.t(ActorsPushCommandMessages.cannotFindActorById, { actorId: forceActorId })); + } actorId = actor.id; } else { const usernameOrId = userInfo.username || userInfo.id; @@ -238,13 +234,17 @@ export class ActorsPushCommand extends ApifyCommand { actor = await apifyClient.actors().create(newActor); actorId = actor.id; isActorCreatedNow = true; - info({ message: `Created Actor with name ${actorConfig!.name} on Apify.` }); + this.logger.stderr.info( + this.t(ActorsPushCommandMessages.createdActor, { name: actorConfig!.name as string }), + ); } } const actorClient = apifyClient.actor(actorId); - info({ message: `Deploying Actor '${actorConfig!.name}' to Apify.` }); + this.logger.stderr.info( + this.t(ActorsPushCommandMessages.deployingActor, { name: actorConfig!.name as string }), + ); const filesSize = await sumFilesSizeInBytes(filePathsToPush, cwd); @@ -273,8 +273,9 @@ export class ActorsPushCommand extends ApifyCommand { (actorConfig?.name || forceActorId) ) { throw new Error( - `Actor with identifier "${actorConfig?.name || forceActorId}" is already on the platform and was modified there since modified locally. -Skipping push. Use --force to override.`, + this.t(ActorsPushCommandMessages.remoteModifiedNewer, { + identifier: (actorConfig?.name || forceActorId) as string, + }), ); } } @@ -283,7 +284,7 @@ Skipping push. Use --force to override.`, sourceType = ACTOR_SOURCE_TYPES.SOURCE_FILES; } else { // Create zip - run({ message: 'Zipping Actor files' }); + this.logger.stderr.run(this.t(ActorsPushCommandMessages.zippingActorFiles)); await createActZip(TEMP_ZIP_FILE_NAME, filePathsToPush, cwd); // Upload it to Apify.keyValueStores @@ -330,7 +331,7 @@ Skipping push. Use --force to override.`, const actorVersionModifier = { tarballUrl, sourceFiles, buildTag, sourceType, envVars }; // TODO: fix this type too -.- await actorClient.version(version).update(actorVersionModifier as never); - run({ message: `Updated version ${version} for Actor ${actor.name}.` }); + this.logger.stderr.run(this.t(ActorsPushCommandMessages.updatedVersion, { version, name: actor.name })); } else { const actorNewVersion = { versionNumber: version, @@ -345,18 +346,23 @@ Skipping push. Use --force to override.`, ...actorNewVersion, } as never); - run({ message: `Created version ${version} for Actor ${actor.name}.` }); + this.logger.stderr.run(this.t(ActorsPushCommandMessages.createdVersion, { version, name: actor.name })); } // Sync standby mode on existing actors with actor.json if (!isActorCreatedNow && !!actorConfig!.usesStandbyMode !== !!actor.actorStandby?.isEnabled) { const isEnabled = !!actorConfig!.usesStandbyMode; await actorClient.update({ actorStandby: { isEnabled } }); - info({ message: `${isEnabled ? 'Enabled' : 'Disabled'} standby mode for Actor ${actor.name}.` }); + this.logger.stderr.info( + this.t(ActorsPushCommandMessages.standbyToggled, { + action: isEnabled ? 'Enabled' : 'Disabled', + name: actor.name, + }), + ); } // Build Actor on Apify and wait for build to finish - run({ message: `Building Actor ${actor.name}` }); + this.logger.stderr.run(this.t(ActorsPushCommandMessages.buildingActor, { name: actor.name })); let build = await actorClient.build(version, { useCache: true, waitForFinish: 2, // NOTE: We need to wait some time to Apify open stream and we can create connection @@ -376,49 +382,49 @@ Skipping push. Use --force to override.`, await outputJobLog({ job: build, timeoutMillis: waitForFinishMillis, apifyClient }); } catch (err) { - warning({ message: 'Can not get log:' }); + this.logger.stderr.warning(this.t(ActorsPushCommandMessages.cannotGetLog)); console.error(err); } build = (await apifyClient.build(build.id).get())!; if (this.flags.json) { - printJsonToStdout(build); + this.logger.stdout.json(build); return; } - link({ - message: 'Actor build detail', - url: `https://console.apify.com${redirectUrlPart}/actors/${build.actId}#/builds/${build.buildNumber}`, - }); + this.logger.stderr.link( + this.t(ActorsPushCommandMessages.actorBuildDetailLabel), + `https://console.apify.com${redirectUrlPart}/actors/${build.actId}#/builds/${build.buildNumber}`, + ); - link({ - message: 'Actor detail', - url: `https://console.apify.com${redirectUrlPart}/actors/${build.actId}`, - }); + this.logger.stderr.link( + this.t(ActorsPushCommandMessages.actorDetailLabel), + `https://console.apify.com${redirectUrlPart}/actors/${build.actId}`, + ); if (this.flags.open) { await open(`https://console.apify.com${redirectUrlPart}/actors/${build.actId}`); } if (build.status === ACTOR_JOB_STATUSES.SUCCEEDED) { - success({ message: 'Actor was deployed to Apify cloud and built there.' }); + this.logger.stderr.success(this.t(ActorsPushCommandMessages.deployedSuccess)); // @ts-expect-error FIX THESE TYPES 😢 } else if (build.status === ACTOR_JOB_STATUSES.READY) { - warning({ message: 'Build is waiting for allocation.' }); + this.logger.stderr.warning(this.t(ActorsPushCommandMessages.buildWaitingForAllocation)); // @ts-expect-error FIX THESE TYPES 😢 } else if (build.status === ACTOR_JOB_STATUSES.RUNNING) { - warning({ message: 'Build is still running.' }); + this.logger.stderr.warning(this.t(ActorsPushCommandMessages.buildStillRunning)); // @ts-expect-error FIX THESE TYPES 😢 } else if (build.status === ACTOR_JOB_STATUSES.ABORTED || build.status === ACTOR_JOB_STATUSES.ABORTING) { - warning({ message: 'Build was aborted!' }); + this.logger.stderr.warning(this.t(ActorsPushCommandMessages.buildAborted)); process.exitCode = CommandExitCodes.BuildAborted; // @ts-expect-error FIX THESE TYPES 😢 } else if (build.status === ACTOR_JOB_STATUSES.TIMED_OUT || build.status === ACTOR_JOB_STATUSES.TIMING_OUT) { - warning({ message: 'Build timed out!' }); + this.logger.stderr.warning(this.t(ActorsPushCommandMessages.buildTimedOut)); process.exitCode = CommandExitCodes.BuildTimedOut; } else { - error({ message: 'Build failed!' }); + this.logger.stderr.error(this.t(ActorsPushCommandMessages.buildFailed)); process.exitCode = CommandExitCodes.BuildFailed; } } diff --git a/src/commands/actors/rm.ts b/src/commands/actors/rm.ts index 88f75c135..e9dab2ee2 100644 --- a/src/commands/actors/rm.ts +++ b/src/commands/actors/rm.ts @@ -1,10 +1,10 @@ +import { ActorsRmCommandMessages } from '#i18n/commands/actors/rm.js'; import type { ApifyApiError } from 'apify-client'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { YesFlag } from '../../lib/command-framework/flags.js'; import { useYesNoConfirm } from '../../lib/hooks/user-confirmations/useYesNoConfirm.js'; -import { error, info, success } from '../../lib/outputs.js'; import { getLoggedClientOrThrow } from '../../lib/utils.js'; export class ActorsRmCommand extends ApifyCommand { @@ -46,7 +46,7 @@ export class ActorsRmCommand extends ApifyCommand { const actor = await apifyClient.actor(actorId).get(); if (!actor) { - error({ message: `Actor with ID "${actorId}" was not found on your account.` }); + this.logger.stderr.error(this.t(ActorsRmCommandMessages.actorNotFound, { actorId })); return; } @@ -56,19 +56,22 @@ export class ActorsRmCommand extends ApifyCommand { }); if (!confirmedDelete) { - info({ - message: `Deletion of Actor "${actorId}" was canceled.`, - }); + this.logger.stderr.info(this.t(ActorsRmCommandMessages.deletionCanceled, { actorId })); return; } try { await apifyClient.actor(actorId).delete(); - success({ message: `Actor with ID "${actorId}" was deleted.` }); + this.logger.stderr.success(this.t(ActorsRmCommandMessages.actorDeleted, { actorId })); } catch (err) { const casted = err as ApifyApiError; - error({ message: `Failed to delete Actor "${actorId}".\n ${casted.message || casted}` }); + this.logger.stderr.error( + this.t(ActorsRmCommandMessages.deleteFailed, { + actorId, + message: casted.message || String(casted), + }), + ); } } } diff --git a/src/commands/actors/search.ts b/src/commands/actors/search.ts index d1a576e18..4a931be6a 100644 --- a/src/commands/actors/search.ts +++ b/src/commands/actors/search.ts @@ -1,3 +1,4 @@ +import { ActorsSearchCommandMessages } from '#i18n/commands/actors/search.js'; import { ApifyClient } from 'apify-client'; import chalk from 'chalk'; @@ -6,8 +7,7 @@ import { Args } from '../../lib/command-framework/args.js'; import { Flags } from '../../lib/command-framework/flags.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; import { CommandExitCodes } from '../../lib/consts.js'; -import { error, info, simpleLog } from '../../lib/outputs.js'; -import { getApifyClientOptions, printJsonToStdout } from '../../lib/utils.js'; +import { getApifyClientOptions } from '../../lib/utils.js'; const pricingModelLabels: Record = { FREE: 'Free', @@ -90,8 +90,6 @@ export class ActorsSearchCommand extends ApifyCommand { @@ -60,8 +53,6 @@ export class ActorsStartCommand extends ApifyCommand }), }; - static override enableJsonFlag = true; - static override args = { actorId: Args.string({ required: false, @@ -130,7 +121,7 @@ export class ActorsStartCommand extends ApifyCommand } if (this.flags.json) { - printJsonToStdout(run); + this.logger.stdout.json(run); return; } @@ -138,14 +129,16 @@ export class ActorsStartCommand extends ApifyCommand const datasetUrl = `https://console.apify.com/storage/datasets/${run.defaultDatasetId}`; const message: string[] = [ - `${chalk.gray('Run:')} Calling Actor ${userFriendlyId} (${chalk.gray(actorId)})`, + this.t(ActorsStartCommandMessages.callingActor, { userFriendlyId, actorId }), '', - `${chalk.yellow('Started')}: ${TimestampFormatter.display(run.startedAt)}`, + this.t(ActorsStartCommandMessages.runStartedHeader, { + startedAt: TimestampFormatter.display(run.startedAt), + }), ]; if (run.containerUrl) { // container url - message.push(`${chalk.yellow('Container URL')}: ${chalk.blue(run.containerUrl)}`); + message.push(this.t(ActorsStartCommandMessages.containerUrlLine, { containerUrl: run.containerUrl })); } // basic version info @@ -158,38 +151,38 @@ export class ActorsStartCommand extends ApifyCommand (actorData.taggedBuilds ?? {}) as Record, ).find(([, data]) => data.buildNumber === run.buildNumber)?.[0]; - const messageParts = [`${chalk.yellow('Build')}:`, chalk.cyan(run.buildNumber)]; - - if (runVersionTaggedAs) { - messageParts.push(`(${chalk.yellow(runVersionTaggedAs)})`); - } else { - messageParts.push(`(${chalk.gray('N/A')})`); - } + const buildTagText = runVersionTaggedAs + ? this.t(ActorsStartCommandMessages.buildTagValue, { tag: runVersionTaggedAs }) + : this.t(ActorsStartCommandMessages.buildTagNa); - if (actorVersion) { - messageParts.push( - `| ${chalk.gray('Actor version:')} ${chalk.cyan(actorVersion.versionNumber)} (${chalk.yellow(actorVersion.buildTag)})`, - ); - } + const actorVersionInfo = actorVersion + ? this.t(ActorsStartCommandMessages.actorVersionInfo, { + versionNumber: actorVersion.versionNumber ?? '', + buildTag: actorVersion.buildTag ?? '', + }) + : ''; - message.push(messageParts.join(' ')); + message.push( + this.t(ActorsStartCommandMessages.buildLine, { + buildNumber: run.buildNumber, + buildTag: buildTagText, + actorVersionInfo, + }), + ); // timeout - message.push(`${chalk.yellow('Timeout')}: ${run.options.timeoutSecs.toLocaleString('en-US')} seconds`); + message.push( + this.t(ActorsStartCommandMessages.timeoutLine, { + timeoutSecs: run.options.timeoutSecs.toLocaleString('en-US'), + }), + ); // memory limit - message.push(`${chalk.yellow('Memory')}: ${run.options.memoryMbytes} MB`); + message.push(this.t(ActorsStartCommandMessages.memoryLine, { memoryMbytes: run.options.memoryMbytes })); // url - message.push( - '', - `${chalk.blue('Export results')}: ${datasetUrl!}`, - `${chalk.blue('View on Apify Console')}: ${url}`, - ); + message.push(this.t(ActorsStartCommandMessages.resultLinks, { datasetUrl: datasetUrl!, url })); - simpleLog({ - message: message.join('\n'), - stdout: true, - }); + this.logger.stdout.log(message.join('\n')); } } diff --git a/src/commands/api.ts b/src/commands/api.ts index d4825c9f8..a976861df 100644 --- a/src/commands/api.ts +++ b/src/commands/api.ts @@ -1,12 +1,13 @@ import process from 'node:process'; +import { ApiCommandMessages } from '#i18n/commands/api.js'; import chalk from 'chalk'; import { ApifyCommand, StdinMode } from '../lib/command-framework/apify-command.js'; import { Args } from '../lib/command-framework/args.js'; import { Flags } from '../lib/command-framework/flags.js'; import { APIFY_CLIENT_DEFAULT_HEADERS, CommandExitCodes } from '../lib/consts.js'; -import { error, simpleLog } from '../lib/outputs.js'; +import { t } from '../lib/i18n/index.js'; import { getLoggedClientOrThrow } from '../lib/utils.js'; const HTTP_METHODS: string[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']; @@ -33,11 +34,11 @@ function parseParams(raw: string | undefined): string { try { parsed = JSON.parse(raw); } catch { - throw new Error('Invalid JSON in --params flag. Please provide a valid JSON object, e.g. \'{"limit": 1}\'.'); + throw new Error(t(ApiCommandMessages.paramsInvalidJson, { example: '{"limit": 1}' })); } if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) { - throw new Error('--params must be a JSON object (e.g. \'{"limit": 1}\').'); + throw new Error(t(ApiCommandMessages.paramsNotObject, { example: '{"limit": 1}' })); } const searchParams = new URLSearchParams(); @@ -49,8 +50,10 @@ function parseParams(raw: string | undefined): string { if (typeof value === 'object') { throw new Error( - `--params value for "${key}" must be a scalar (string, number, or boolean), got ${Array.isArray(value) ? 'array' : 'object'}. ` + - 'Query parameters cannot contain nested objects or arrays.', + t(ApiCommandMessages.paramsNotScalar, { + key, + kind: Array.isArray(value) ? 'array' : 'object', + }), ); } @@ -74,18 +77,18 @@ function parseHeaders(raw: string | undefined): Record { try { parsed = JSON.parse(trimmed); } catch { - throw new Error('Invalid JSON in --header flag. Provide a JSON object like \'{"X-Foo": "bar"}\'.'); + throw new Error(t(ApiCommandMessages.headerInvalidJson, { example: '{"X-Foo": "bar"}' })); } if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) { - throw new Error('--header JSON must be an object mapping header names to string values.'); + throw new Error(t(ApiCommandMessages.headerJsonNotObject)); } const result: Record = {}; for (const [key, value] of Object.entries(parsed as Record)) { if (typeof value !== 'string') { - throw new Error(`--header value for "${key}" must be a string, got ${typeof value}.`); + throw new Error(t(ApiCommandMessages.headerValueNotString, { key, kind: typeof value })); } result[key.trim()] = value.trim(); @@ -98,7 +101,7 @@ function parseHeaders(raw: string | undefined): Record { const colonIndex = trimmed.indexOf(':'); if (colonIndex === -1) { - throw new Error('Header must be in "key:value" format, or a JSON object for multiple headers.'); + throw new Error(t(ApiCommandMessages.headerInvalidFormat)); } return { @@ -206,8 +209,7 @@ export class ApiCommand extends ApifyCommand { if (explicitMethodFlag && explicitMethodFlag !== positionalMethod) { throw new Error( - `Conflicting HTTP methods: positional "${positionalMethod}" vs --method "${explicitMethodFlag}". ` + - 'Please specify the method only once.', + this.t(ApiCommandMessages.conflictingMethods, { positionalMethod, explicitMethodFlag }), ); } @@ -233,15 +235,13 @@ export class ApiCommand extends ApifyCommand { // Validate body is valid JSON before sending if (this.flags.body) { if (METHODS_WITHOUT_BODY.has(method)) { - throw new Error( - `HTTP ${method} requests cannot have a request body. Use a different method (e.g. POST, PUT, PATCH) or omit --body.`, - ); + throw new Error(this.t(ApiCommandMessages.methodCannotHaveBody, { method })); } try { JSON.parse(this.flags.body); } catch { - throw new Error('Invalid JSON in --body flag. Please provide a valid JSON string.'); + throw new Error(this.t(ApiCommandMessages.bodyInvalidJson)); } } @@ -299,22 +299,21 @@ export class ApiCommand extends ApifyCommand { // Print status to stderr but JSON response bodies to stdout so that // pipelines like `apify api ... | jq` still receive the payload on failure. - error({ message: `${response.status} ${response.statusText}` }); + this.logger.stderr.error( + this.t(ApiCommandMessages.responseStatus, { status: response.status, statusText: response.statusText }), + ); if (responseText) { try { const parsed = JSON.parse(responseText); - simpleLog({ message: JSON.stringify(parsed, null, 2), stdout: true }); + this.logger.stdout.log(JSON.stringify(parsed, null, 2)); } catch { - simpleLog({ message: responseText, stdout: true }); + this.logger.stdout.log(responseText); } } if (response.status === 404) { - simpleLog({ - message: `\nRun ${chalk.cyan('apify api --list-endpoints')} to see all available Apify API endpoints.`, - stdout: false, - }); + this.logger.stderr.log(this.t(ApiCommandMessages.listEndpointsHint)); } return; @@ -323,9 +322,9 @@ export class ApiCommand extends ApifyCommand { if (responseText) { try { const parsed = JSON.parse(responseText); - simpleLog({ message: JSON.stringify(parsed, null, 2), stdout: true }); + this.logger.stdout.log(JSON.stringify(parsed, null, 2)); } catch { - simpleLog({ message: responseText, stdout: true }); + this.logger.stdout.log(responseText); } } } @@ -358,13 +357,20 @@ async function fetchEndpoints(): Promise { response = await fetch(OPENAPI_SPEC_URL); } catch (err) { throw new Error( - `Failed to download the Apify OpenAPI spec from ${OPENAPI_SPEC_URL}: ${(err as Error).message}`, + t(ApiCommandMessages.specDownloadFailedFetch, { + url: OPENAPI_SPEC_URL, + message: (err as Error).message, + }), ); } if (!response.ok) { throw new Error( - `Failed to download the Apify OpenAPI spec from ${OPENAPI_SPEC_URL}: ${response.status} ${response.statusText}`, + t(ApiCommandMessages.specDownloadFailedStatus, { + url: OPENAPI_SPEC_URL, + status: response.status, + statusText: response.statusText, + }), ); } diff --git a/src/commands/auth/login.ts b/src/commands/auth/login.ts index b5fa80a8b..dc4252fa6 100644 --- a/src/commands/auth/login.ts +++ b/src/commands/auth/login.ts @@ -1,7 +1,7 @@ import type { Server } from 'node:http'; import type { AddressInfo } from 'node:net'; -import chalk from 'chalk'; +import { AuthLoginCommandMessages } from '#i18n/commands/auth/login.js'; import computerName from 'computer-name'; import cors from 'cors'; import express from 'express'; @@ -15,7 +15,8 @@ import { AUTH_FILE_PATH } from '../../lib/consts.js'; import { updateUserId } from '../../lib/hooks/telemetry/useTelemetryState.js'; import { useMaskedInput } from '../../lib/hooks/user-confirmations/useMaskedInput.js'; import { useSelectFromList } from '../../lib/hooks/user-confirmations/useSelectFromList.js'; -import { error, info, success } from '../../lib/outputs.js'; +import { t } from '../../lib/i18n/index.js'; +import { logger } from '../../lib/logger.js'; import { getLocalUserInfo, getLoggedClient, tildify } from '../../lib/utils.js'; const CONSOLE_BASE_URL = 'https://console.apify.com/settings/integrations'; @@ -34,13 +35,14 @@ const tryToLogin = async (token: string) => { if (isUserLogged) { await updateUserId(userInfo.id!); - success({ - message: `You are logged in to Apify as ${userInfo.username || userInfo.id}. ${chalk.gray(`Your token is stored at ${AUTH_FILE_PATH()}.`)}`, - }); + logger.stderr.success( + t(AuthLoginCommandMessages.loggedInSuccess, { + userName: userInfo.username || userInfo.id!, + authFilePath: AUTH_FILE_PATH(), + }), + ); } else { - error({ - message: 'Login to Apify failed, the provided API token is not valid.', - }); + logger.stderr.error(t(AuthLoginCommandMessages.invalidTokenLogin)); } return isUserLogged; }; @@ -169,12 +171,14 @@ export class AuthLoginCommand extends ApifyCommand { if (req.body.apiToken) { await tryToLogin(req.body.apiToken); } else { - throw new Error('Request did not contain API token'); + throw new Error(this.t(AuthLoginCommandMessages.requestMissingApiToken)); } res.end(); } catch (err) { - const errorMessage = `Login to Apify failed with error: ${(err as Error).message}`; - error({ message: errorMessage }); + const errorMessage = this.t(AuthLoginCommandMessages.loginFailedWithError, { + message: (err as Error).message, + }); + this.logger.stderr.error(errorMessage); res.status(500); res.send(errorMessage); } @@ -183,15 +187,11 @@ export class AuthLoginCommand extends ApifyCommand { apiRouter.post('/exit', (req, res) => { if (req.body.isWindowClosed) { - error({ - message: 'Login to Apify failed, the console window was closed.', - }); + this.logger.stderr.error(this.t(AuthLoginCommandMessages.loginFailedWindowClosed)); } else if (req.body.actionCanceled) { - error({ - message: 'Login to Apify failed, the action was canceled in the Apify Console.', - }); + this.logger.stderr.error(this.t(AuthLoginCommandMessages.loginFailedActionCanceled)); } else { - error({ message: 'Login to Apify failed.' }); + this.logger.stderr.error(this.t(AuthLoginCommandMessages.loginFailed)); } res.end(); @@ -213,7 +213,7 @@ export class AuthLoginCommand extends ApifyCommand { // Ignore errors from fetching computer name as it's not critical } - info({ message: `Opening Apify Console at "${consoleUrl.href}"...` }); + this.logger.stderr.info(this.t(AuthLoginCommandMessages.openingConsole, { consoleHref: consoleUrl.href })); await open(consoleUrl.href); } else { console.log( diff --git a/src/commands/auth/logout.ts b/src/commands/auth/logout.ts index a324e9878..fd981510d 100644 --- a/src/commands/auth/logout.ts +++ b/src/commands/auth/logout.ts @@ -1,8 +1,9 @@ +import { AuthLogoutCommandMessages } from '#i18n/commands/auth/logout.js'; + import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { AUTH_FILE_PATH } from '../../lib/consts.js'; import { rimrafPromised } from '../../lib/files.js'; import { updateUserId } from '../../lib/hooks/telemetry/useTelemetryState.js'; -import { success } from '../../lib/outputs.js'; import { tildify } from '../../lib/utils.js'; export class AuthLogoutCommand extends ApifyCommand { @@ -28,6 +29,6 @@ export class AuthLogoutCommand extends ApifyCommand { await updateUserId(null); - success({ message: 'You are logged out from your Apify account.' }); + this.logger.stderr.success(this.t(AuthLogoutCommandMessages.loggedOut)); } } diff --git a/src/commands/auth/token.ts b/src/commands/auth/token.ts index c2a307e88..150959814 100644 --- a/src/commands/auth/token.ts +++ b/src/commands/auth/token.ts @@ -1,5 +1,4 @@ import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; -import { simpleLog } from '../../lib/outputs.js'; import { getLocalUserInfo, getLoggedClientOrThrow } from '../../lib/utils.js'; export class AuthTokenCommand extends ApifyCommand { @@ -21,7 +20,7 @@ export class AuthTokenCommand extends ApifyCommand { const userInfo = await getLocalUserInfo(); if (userInfo.token) { - simpleLog({ message: userInfo.token, stdout: true }); + this.logger.stdout.log(userInfo.token); } } } diff --git a/src/commands/builds/add-tag.ts b/src/commands/builds/add-tag.ts index a450be39f..f693b7f73 100644 --- a/src/commands/builds/add-tag.ts +++ b/src/commands/builds/add-tag.ts @@ -1,9 +1,8 @@ +import { BuildsAddTagCommandMessages } from '#i18n/commands/builds/add-tag.js'; import type { ActorTaggedBuild, ApifyApiError } from 'apify-client'; -import chalk from 'chalk'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Flags } from '../../lib/command-framework/flags.js'; -import { error, success, warning } from '../../lib/outputs.js'; import { getLoggedClientOrThrow } from '../../lib/utils.js'; export class BuildsAddTagCommand extends ApifyCommand { @@ -45,22 +44,21 @@ export class BuildsAddTagCommand extends ApifyCommand { static override name = 'create' as const; @@ -53,8 +47,6 @@ export class BuildsCreateCommand extends ApifyCommand v.versionNumber === version))) { - error({ - message: `The Actor Version "${version}" does not have the tag "${tag}".`, - stdout: true, - }); + this.logger.stdout.error( + this.t(BuildsCreateCommandMessages.versionDoesNotHaveTag, { version: version!, tag }), + ); return; } @@ -112,10 +100,12 @@ export class BuildsCreateCommand extends ApifyCommand 1) { if (!version) { - error({ - message: `Multiple Actor versions with the tag "${tag}" found. Please specify the version number using the "--version" flag.\n Available versions for this tag: ${taggedVersions.map((v) => chalk.yellow(v.versionNumber)).join(', ')}`, - stdout: true, - }); + this.logger.stdout.error( + this.t(BuildsCreateCommandMessages.multipleVersionsForTag, { + tag: tag!, + availableVersions: taggedVersions.map((v) => chalk.yellow(v.versionNumber)).join(', '), + }), + ); return; } @@ -125,10 +115,7 @@ export class BuildsCreateCommand extends ApifyCommand { static override name = 'info' as const; @@ -28,8 +27,6 @@ export class BuildsInfoCommand extends ApifyCommand { }), }; - static override enableJsonFlag = true; - async run() { const { buildId } = this.args; @@ -38,13 +35,13 @@ export class BuildsInfoCommand extends ApifyCommand { const build = await apifyClient.build(buildId).get(); if (!build) { - error({ message: `Build with ID "${buildId}" was not found on your account.`, stdout: true }); + this.logger.stdout.error(this.t(BuildsInfoCommandMessages.buildNotFound, { buildId })); return; } // JSON output -> return the object (which is handled by oclif) if (this.flags.json) { - printJsonToStdout(build); + this.logger.stdout.json(build); return; } @@ -65,50 +62,69 @@ export class BuildsInfoCommand extends ApifyCommand { const exitCode = Reflect.get(build, 'exitCode') as number | undefined; const fullActorName = actor?.username ? `${actor.username}/${actor.name}` : (actor?.name ?? 'unknown-actor'); - const versionTaggedAs = buildTag ? ` (tagged as ${chalk.yellow(buildTag)})` : ''; - const exitCodeStatus = typeof exitCode !== 'undefined' ? ` (exit code: ${chalk.gray(exitCode)})` : ''; + const versionTaggedAs = buildTag ? this.t(BuildsInfoCommandMessages.versionTaggedAs, { buildTag }) : ''; + const exitCodeStatus = + typeof exitCode !== 'undefined' + ? this.t(BuildsInfoCommandMessages.exitCodeStatus, { exitCode: String(exitCode) }) + : ''; const message: string[] = [ - // - `${chalk.yellow('Actor')}: ${fullActorName} (${chalk.gray(build.actId)})`, - '', - `${chalk.yellow('Build Information')} (ID: ${chalk.gray(build.id)})`, - ` ${chalk.yellow('Build Number')}: ${build.buildNumber}${versionTaggedAs}`, - ` ${chalk.yellow('Status')}: ${prettyPrintStatus(build.status)}${exitCodeStatus}`, - ` ${chalk.yellow('Started')}: ${TimestampFormatter.display(build.startedAt)}`, + this.t(BuildsInfoCommandMessages.header, { + fullActorName, + actId: build.actId, + buildId: build.id, + buildNumber: build.buildNumber!, + versionTaggedAs, + status: prettyPrintStatus(build.status), + exitCodeStatus, + startedAt: TimestampFormatter.display(build.startedAt), + }), ]; if (build.finishedAt) { message.push( - ` ${chalk.yellow('Finished')}: ${TimestampFormatter.display(build.finishedAt)} (took ${chalk.gray(DurationFormatter.format(build.stats?.durationMillis ?? 0))})`, + this.t(BuildsInfoCommandMessages.finishedAtLine, { + finishedAt: TimestampFormatter.display(build.finishedAt), + duration: DurationFormatter.format(build.stats?.durationMillis ?? 0), + }), ); } else { const diff = Date.now() - build.startedAt.getTime(); message.push( - ` ${chalk.yellow('Finished')}: ${chalk.gray(`Running for ${DurationFormatter.format(diff)}`)}`, + this.t(BuildsInfoCommandMessages.runningForLine, { + duration: DurationFormatter.format(diff), + }), ); } if (build.stats?.computeUnits) { // Platform shows 3 decimal places, so shall we - message.push(` ${chalk.yellow('Compute Units')}: ${build.stats.computeUnits.toFixed(3)}`); + message.push( + this.t(BuildsInfoCommandMessages.computeUnitsLine, { + computeUnits: build.stats.computeUnits.toFixed(3), + }), + ); } // TODO: untyped field, https://github.com/apify/apify-client-js/issues/526 const dockerImageSize = Reflect.get(build.stats ?? {}, 'imageSizeBytes') as number | undefined; if (dockerImageSize) { - message.push(` ${chalk.yellow('Docker Image Size')}: ${prettyPrintBytes({ bytes: dockerImageSize })}`); + message.push( + this.t(BuildsInfoCommandMessages.dockerImageSizeLine, { + size: prettyPrintBytes({ bytes: dockerImageSize }), + }), + ); } - message.push(` ${chalk.yellow('Origin')}: ${build.meta.origin ?? 'UNKNOWN'}`); + message.push(this.t(BuildsInfoCommandMessages.originLine, { origin: build.meta.origin ?? 'UNKNOWN' })); message.push(''); const url = `https://console.apify.com/actors/${build.actId}/builds/${build.buildNumber}`; - message.push(`${chalk.blue('View in Apify Console')}: ${url}`); + message.push(this.t(BuildsInfoCommandMessages.viewInConsole, { url })); - simpleLog({ message: message.join('\n'), stdout: true }); + this.logger.stdout.log(message.join('\n')); } } diff --git a/src/commands/builds/log.ts b/src/commands/builds/log.ts index 5375234e7..b241421e2 100644 --- a/src/commands/builds/log.ts +++ b/src/commands/builds/log.ts @@ -1,6 +1,7 @@ +import { BuildsLogCommandMessages } from '#i18n/commands/builds/log.js'; + import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; -import { info } from '../../lib/outputs.js'; import { getLoggedClientOrThrow, outputJobLog } from '../../lib/utils.js'; export class BuildsLogCommand extends ApifyCommand { @@ -32,11 +33,18 @@ export class BuildsLogCommand extends ApifyCommand { const build = await apifyClient.build(buildId).get(); if (!build) { - throw new Error(`Build with ID "${buildId}" was not found on your account.`); + throw new Error(this.t(BuildsLogCommandMessages.buildNotFound, { buildId })); } - info({ message: `Log for build with ID "${buildId}":\n` }); + this.logger.stderr.info(this.t(BuildsLogCommandMessages.logHeader, { buildId })); - await outputJobLog({ job: build, apifyClient }); + try { + await outputJobLog({ job: build, apifyClient }); + } catch (err) { + // This should never happen... + this.logger.stdout.error( + this.t(BuildsLogCommandMessages.logFailed, { buildId, message: (err as Error).message }), + ); + } } } diff --git a/src/commands/builds/ls.ts b/src/commands/builds/ls.ts index db7f9c1cc..81e637817 100644 --- a/src/commands/builds/ls.ts +++ b/src/commands/builds/ls.ts @@ -1,3 +1,4 @@ +import { BuildsLsCommandMessages } from '#i18n/commands/builds/ls.js'; import type { BuildCollectionClientListItem } from 'apify-client'; import chalk from 'chalk'; @@ -7,8 +8,7 @@ import { Flags } from '../../lib/command-framework/flags.js'; import { prettyPrintStatus } from '../../lib/commands/pretty-print-status.js'; import { resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; -import { error, simpleLog } from '../../lib/outputs.js'; -import { getLoggedClientOrThrow, objectGroupBy, printJsonToStdout, ShortDurationFormatter } from '../../lib/utils.js'; +import { getLoggedClientOrThrow, objectGroupBy, ShortDurationFormatter } from '../../lib/utils.js'; const tableFactory = () => new ResponsiveTable({ @@ -64,8 +64,6 @@ export class BuildsLsCommand extends ApifyCommand { }), }; - static override enableJsonFlag = true; - async run() { const { desc, limit, offset, compact, json } = this.flags; const { actorId } = this.args; @@ -76,10 +74,7 @@ export class BuildsLsCommand extends ApifyCommand { const ctx = await resolveActorContext({ providedActorNameOrId: actorId, client }); if (!ctx.valid) { - error({ - message: `${ctx.reason}. Please run this command in an Actor directory, or specify the Actor ID.`, - stdout: true, - }); + this.logger.stdout.error(this.t(BuildsLsCommandMessages.invalidActorContext, { reason: ctx.reason })); return; } @@ -117,23 +112,24 @@ export class BuildsLsCommand extends ApifyCommand { } } - printJsonToStdout(allBuilds); + this.logger.stdout.json(allBuilds); return; } - simpleLog({ - message: `${chalk.reset('Showing')} ${chalk.yellow(allBuilds.items.length)} out of ${chalk.yellow(allBuilds.total)} builds for Actor ${chalk.yellow(ctx.userFriendlyId)} (${chalk.gray(ctx.id)})\n`, - stdout: true, - }); + this.logger.stdout.log( + this.t(BuildsLsCommandMessages.showingBuildsHeader, { + shown: allBuilds.items.length, + total: allBuilds.total, + userFriendlyId: ctx.userFriendlyId, + actorId: ctx.id, + }), + ); const sortedActorVersions = Object.entries(buildsByActorVersion).sort((a, b) => a[0].localeCompare(b[0])); for (const [actorVersion, buildsForVersion] of sortedActorVersions) { if (!buildsForVersion?.length) { - simpleLog({ - message: `No builds for version ${actorVersion}`, - stdout: true, - }); + this.logger.stdout.log(this.t(BuildsLsCommandMessages.noBuildsForVersion, { actorVersion })); continue; } @@ -145,19 +141,16 @@ export class BuildsLsCommand extends ApifyCommand { }); const latestBuildTagMessage = latestBuildTag - ? ` (latest build gets tagged with ${chalk.yellow(latestBuildTag)})` + ? this.t(BuildsLsCommandMessages.latestBuildTagSuffix, { latestBuildTag }) : ''; const message = [ - chalk.reset(`Builds for Actor Version ${chalk.yellow(actorVersion)}${latestBuildTagMessage}`), + this.t(BuildsLsCommandMessages.buildsForVersionHeader, { actorVersion, latestBuildTagMessage }), table.render(compact ? CompactMode.VeryCompact : CompactMode.None), '', ]; - simpleLog({ - message: message.join('\n'), - stdout: true, - }); + this.logger.stdout.log(message.join('\n')); } } diff --git a/src/commands/builds/remove-tag.ts b/src/commands/builds/remove-tag.ts index b474b8f07..9a54a6c81 100644 --- a/src/commands/builds/remove-tag.ts +++ b/src/commands/builds/remove-tag.ts @@ -1,10 +1,10 @@ +import { BuildsRemoveTagCommandMessages } from '#i18n/commands/builds/remove-tag.js'; import type { ActorTaggedBuild, ApifyApiError } from 'apify-client'; import chalk from 'chalk'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Flags, YesFlag } from '../../lib/command-framework/flags.js'; import { useYesNoConfirm } from '../../lib/hooks/user-confirmations/useYesNoConfirm.js'; -import { error, info, success } from '../../lib/outputs.js'; import { getLoggedClientOrThrow } from '../../lib/utils.js'; export class BuildsRemoveTagCommand extends ApifyCommand { @@ -47,14 +47,14 @@ export class BuildsRemoveTagCommand extends ApifyCommand { @@ -47,7 +47,7 @@ export class BuildsRmCommand extends ApifyCommand { const build = await apifyClient.build(buildId).get(); if (!build) { - throw new Error(`Build with ID "${buildId}" was not found on your account.`); + throw new Error(this.t(BuildsRmCommandMessages.buildNotFound, { buildId })); } const actor = await apifyClient.actor(build.actId).get(); @@ -82,19 +82,13 @@ export class BuildsRmCommand extends ApifyCommand { } if (!confirmed) { - info({ - message: `Deletion of build "${buildId}" was canceled.`, - stdout: true, - }); + this.logger.stdout.info(this.t(BuildsRmCommandMessages.deletionCanceled, { buildId })); return; } await apifyClient.build(buildId).delete(); - success({ - message: `Build with ID "${buildId}" was deleted.`, - stdout: true, - }); + this.logger.stdout.success(this.t(BuildsRmCommandMessages.buildDeleted, { buildId })); } } diff --git a/src/commands/cli-management/install.ts b/src/commands/cli-management/install.ts index 7069b967c..c1b6ca8e0 100644 --- a/src/commands/cli-management/install.ts +++ b/src/commands/cli-management/install.ts @@ -5,15 +5,15 @@ import { homedir } from 'node:os'; import { dirname, join } from 'node:path'; import { ReadStream } from 'node:tty'; +import { InstallCommandMessages } from '#i18n/commands/cli-management/install.js'; import chalk from 'chalk'; import which from 'which'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { useCLIMetadata } from '../../lib/hooks/useCLIMetadata.js'; import { useYesNoConfirm } from '../../lib/hooks/user-confirmations/useYesNoConfirm.js'; -import { error, info, simpleLog, success, warning } from '../../lib/outputs.js'; +import { logger } from '../../lib/logger.js'; import { detectShell, shellConfigFile, tildify } from '../../lib/utils.js'; -import { cliDebugPrint } from '../../lib/utils/cliDebugPrint.js'; const pathToInstallMarker = (installPath: string) => join(installPath, '.install-marker'); const HOMEDIR = () => process.env.HOME ?? homedir(); @@ -29,7 +29,7 @@ export class InstallCommand extends ApifyCommand { const { installMethod, installPath, version } = useCLIMetadata(); if (installMethod !== 'bundle') { - info({ message: `Apify and Actor CLI are already fully configured! 👍` }); + this.logger.stderr.info(this.t(InstallCommandMessages.alreadyConfigured)); return; } @@ -38,7 +38,7 @@ export class InstallCommand extends ApifyCommand { const installMarkerPath = pathToInstallMarker(installPath); if (existsSync(installMarkerPath)) { - info({ message: `Apify and Actor CLI are already fully configured! 👍` }); + this.logger.stderr.info(this.t(InstallCommandMessages.alreadyConfigured)); return; } @@ -49,42 +49,42 @@ export class InstallCommand extends ApifyCommand { try { await this.promptAddToShell(); } catch (err: any) { - error({ message: err.message || 'Failed to automatically handle shell integration' }); + this.logger.stderr.error( + err.message + ? this.t(InstallCommandMessages.shellIntegrationFailed, { message: err.message }) + : this.t(InstallCommandMessages.shellIntegrationFailedFallback), + ); } - simpleLog({ message: '' }); + this.logger.stderr.log(''); } await writeFile(installMarkerPath, version); - cliDebugPrint('[install] install marker written to', installMarkerPath); - - simpleLog({ - message: [ - '', - chalk.green('Apify and Actor CLI were installed successfully!'), - '', - chalk.gray(` Version: ${chalk.green(version)}`), - chalk.gray( - ` Location: ${chalk.bold.white(tildify(join(installPath, 'apify')))} and ${chalk.bold.white(tildify(join(installPath, 'actor')))}`, - ), - ].join('\n'), - }); - - simpleLog({ message: '' }); - success({ message: 'To get started, run:' }); - simpleLog({ message: chalk.white.bold(' apify --help\n actor --help') }); + logger.debug('[install] install marker written to', installMarkerPath); + + this.logger.stderr.log( + this.t(InstallCommandMessages.installSuccessMessage, { + version, + apifyLocation: tildify(join(installPath, 'apify')), + actorLocation: tildify(join(installPath, 'actor')), + }), + ); + + this.logger.stderr.log(''); + this.logger.stderr.success(this.t(InstallCommandMessages.toGetStarted)); + this.logger.stderr.log(this.t(InstallCommandMessages.helpCommands)); } private async symlinkToLocalBin(installPath: string) { const userHomeDirectory = HOMEDIR(); - cliDebugPrint('[install -> symlinkToLocalBin] user home directory', userHomeDirectory); + logger.debug('[install -> symlinkToLocalBin] user home directory', userHomeDirectory); if (!userHomeDirectory) { - cliDebugPrint('[install -> symlinkToLocalBin] user home directory not found'); + logger.debug('[install -> symlinkToLocalBin] user home directory not found'); - warning({ message: chalk.gray(`User home directory not found, cannot symlink to ~/.local/bin`) }); + this.logger.stderr.warning(this.t(InstallCommandMessages.homeDirNotFound)); return; } @@ -100,9 +100,9 @@ export class InstallCommand extends ApifyCommand { const originalPath = join(installPath, file); if (!existsSync(originalPath)) { - cliDebugPrint('[install] file not found for symlinking', file, originalPath); + logger.debug('[install] file not found for symlinking', file, originalPath); - warning({ message: chalk.gray(`Bundle not found for symlinking: ${file}`) }); + this.logger.stderr.warning(this.t(InstallCommandMessages.bundleNotFoundForSymlinking, { file })); continue; } @@ -114,10 +114,12 @@ export class InstallCommand extends ApifyCommand { await symlink(originalPath, symlinkPath); - cliDebugPrint('[install] symlink created for item', file, symlinkPath); + logger.debug('[install] symlink created for item', file, symlinkPath); } - info({ message: chalk.gray(`Symlinked apify, actor, and apify-cli to ${tildify(localBinDirectory)}`) }); + this.logger.stderr.info( + this.t(InstallCommandMessages.symlinkedToLocalBin, { localBinDirectory: tildify(localBinDirectory) }), + ); } /** @@ -136,7 +138,7 @@ export class InstallCommand extends ApifyCommand { }; try { - cliDebugPrint('[install] opening /dev/tty for raw mode'); + logger.debug('[install] opening /dev/tty for raw mode'); fd = openSync('/dev/tty', 'r'); ttyStream = new ReadStream(fd); @@ -170,7 +172,7 @@ export class InstallCommand extends ApifyCommand { return result; } catch (err) { - cliDebugPrint('[install] failed to open /dev/tty for raw mode', err); + logger.debug('[install] failed to open /dev/tty for raw mode', err); return false; } finally { if (ttyStream) { @@ -205,28 +207,28 @@ export class InstallCommand extends ApifyCommand { apifyCliPath.value && actorCliPath.value ) { - cliDebugPrint('[install -> promptAddToShell] already in PATH', { apifyCliPath, actorCliPath }); + logger.debug('[install -> promptAddToShell] already in PATH', { apifyCliPath, actorCliPath }); - info({ message: chalk.gray(`Apify and Actor CLIs are already in PATH, skipping shell integration`) }); + this.logger.stderr.info(this.t(InstallCommandMessages.alreadyInPath)); return; } const userHomeDirectory = HOMEDIR(); - cliDebugPrint('[install -> promptAddToShell] user home directory', userHomeDirectory); + logger.debug('[install -> promptAddToShell] user home directory', userHomeDirectory); const defaultInstallDir = process.env.APIFY_CLI_INSTALL ?? join(userHomeDirectory, '.apify'); const defaultBinDir = process.env.FINAL_BIN_DIR ?? join(defaultInstallDir, 'bin'); const installDir = process.env.PROVIDED_INSTALL_DIR ?? defaultInstallDir; if (!installDir) { - warning({ message: chalk.gray(`Install directory not found, cannot add to shell`) }); + this.logger.stderr.warning(this.t(InstallCommandMessages.installDirNotFound)); return; } const binDir = process.env.FINAL_BIN_DIR ?? defaultBinDir; - simpleLog({ message: '' }); + this.logger.stderr.log(''); const confirmMessage = 'Should the CLI handle adding itself to your shell automatically?'; @@ -238,7 +240,7 @@ export class InstallCommand extends ApifyCommand { // Instead, we open /dev/tty directly and read a single keypress ourselves. allowedToAutomaticallyDo = await this.confirmFromTty(confirmMessage); } else { - cliDebugPrint('[install] opening /dev/tty for raw mode not requested, falling back to normal flow'); + logger.debug('[install] opening /dev/tty for raw mode not requested, falling back to normal flow'); allowedToAutomaticallyDo = await useYesNoConfirm({ message: confirmMessage, // For now, no stdin -> always false @@ -281,7 +283,7 @@ export class InstallCommand extends ApifyCommand { } } - simpleLog({ message: '' }); + this.logger.stderr.log(''); if (allowedToAutomaticallyDo && configFile) { const oldContent = await readFile(configFile, 'utf-8').catch((err) => { @@ -291,7 +293,11 @@ export class InstallCommand extends ApifyCommand { } throw new Error( - `Failed to read config file "${tildify(configFile)}". Received error code: ${err.code}; ${err.message}`, + this.t(InstallCommandMessages.readConfigFailed, { + configFile: tildify(configFile), + code: err.code, + message: err.message, + }), ); }); @@ -303,23 +309,25 @@ export class InstallCommand extends ApifyCommand { } catch (err: any) { if (err.code === 'EACCES') { throw new Error( - `Failed to write to config file "${tildify(configFile)}", as the CLI does not have permission to write to it.`, + this.t(InstallCommandMessages.writeConfigPermissionDenied, { configFile: tildify(configFile) }), ); } throw new Error( - `Failed to write to config file "${tildify(configFile)}". Received error code: ${err.code}; ${err.message}`, + this.t(InstallCommandMessages.writeConfigFailed, { + configFile: tildify(configFile), + code: err.code, + message: err.message, + }), ); } - info({ - message: [ - chalk.gray(`Added "${tildify(binDir)}" to your PATH in ${tildify(configFile)}.`), - chalk.gray( - ` You may need to run ${chalk.white.bold(`source ${tildify(configFile)}`)} to reload your shell.`, - ), - ].join('\n'), - }); + this.logger.stderr.info( + this.t(InstallCommandMessages.pathAddedSuccess, { + binDir: tildify(binDir), + configFile: tildify(configFile), + }), + ); return; } @@ -329,23 +337,16 @@ export class InstallCommand extends ApifyCommand { if (showOneLiner) { const oneLiner = `echo -e '${linesToAdd.join('\\n')}' >> "${resolvedConfigFile}" && source "${resolvedConfigFile}"`; - info({ - message: [ - // - chalk.gray(`The Apify & Actor CLIs are not in your PATH. Run:`), - '', - chalk.white.bold(` ${oneLiner}`), - ].join('\n'), - }); + this.logger.stderr.info(this.t(InstallCommandMessages.notInPathOneLiner, { oneLiner })); return; } - info({ - message: [ - chalk.gray(`Manually add the following lines to ${resolvedConfigFile} or similar:`), - ...linesToAdd.map((line) => chalk.white.bold(` ${line}`)), - ].join('\n'), - }); + this.logger.stderr.info( + this.t(InstallCommandMessages.manuallyAdd, { + configFile: resolvedConfigFile, + linesToAdd: linesToAdd.map((line) => chalk.white.bold(` ${line}`)).join('\n'), + }), + ); } } diff --git a/src/commands/cli-management/upgrade.ts b/src/commands/cli-management/upgrade.ts index 7ade40737..f9dec4dd7 100644 --- a/src/commands/cli-management/upgrade.ts +++ b/src/commands/cli-management/upgrade.ts @@ -3,7 +3,7 @@ import { existsSync } from 'node:fs'; import { lstat, readdir, writeFile } from 'node:fs/promises'; import { dirname, join } from 'node:path'; -import chalk from 'chalk'; +import { UpgradeCommandMessages } from '#i18n/commands/cli-management/upgrade.js'; import { gte } from 'semver'; import { USER_AGENT } from '../../entrypoints/_shared.js'; @@ -14,8 +14,7 @@ import { DEVELOPMENT_VERSION_MARKER, type InstallMethod, useCLIMetadata } from ' import type { Asset } from '../../lib/hooks/useCLIVersionAssets.js'; import { useCLIVersionAssets } from '../../lib/hooks/useCLIVersionAssets.js'; import { useCLIVersionCheck } from '../../lib/hooks/useCLIVersionCheck.js'; -import { error, info, simpleLog, success, warning } from '../../lib/outputs.js'; -import { cliDebugPrint } from '../../lib/utils/cliDebugPrint.js'; +import { logger } from '../../lib/logger.js'; const UPDATE_COMMANDS: Record string[]> = { bundle: (_, entrypoint) => [`${entrypoint}`, 'upgrade'], @@ -88,14 +87,14 @@ export class UpgradeCommand extends ApifyCommand { const { installMethod } = useCLIMetadata(); if (!result.shouldUpdate || result.currentVersion === DEVELOPMENT_VERSION_MARKER) { - cliDebugPrint('[upgrade] no update needed', { + logger.debug('[upgrade] no update needed', { shouldUpdate: result.shouldUpdate, currentVersion: result.currentVersion, }); // Always print, unless the command was called automatically by the CLI for a version check if (!this.flags.internalAutomaticCall) { - info({ message: `${this.cliName} is up to date 👍 \n` }); + this.logger.stderr.info(this.t(UpgradeCommandMessages.upToDate, { cliName: this.cliName })); } return; @@ -109,22 +108,22 @@ export class UpgradeCommand extends ApifyCommand { const updateCommand = UPDATE_COMMANDS[installMethod]('latest', this.entrypoint).join(' '); - simpleLog({ message: '' }); + this.logger.stderr.log(''); - const message = [ - `You are using an old version of ${this.cliName}. We strongly recommend you always use the latest available version.`, - ` ↪ Run ${chalk.bgWhite(chalk.black(updateCommand))} to update! 👍 \n`, - ].join('\n'); - - warning({ message }); + this.logger.stderr.warning( + this.t(UpgradeCommandMessages.oldVersionWarning, { + cliName: this.cliName, + updateCommand, + }), + ); } async handleInstallSpecificVersion(version: string) { // Technically, we could allow downgrades to older versions, but then users would lose the upgrade command 🤷 if (version !== 'latest' && !gte(version, MINIMUM_VERSION_FOR_UPGRADE_COMMAND)) { - error({ - message: `The minimum version of the CLI you can manually downgrade/upgrade to is ${MINIMUM_VERSION_FOR_UPGRADE_COMMAND}.`, - }); + this.logger.stderr.error( + this.t(UpgradeCommandMessages.minimumVersion, { minVersion: MINIMUM_VERSION_FOR_UPGRADE_COMMAND }), + ); return; } @@ -132,7 +131,7 @@ export class UpgradeCommand extends ApifyCommand { const versionData = await useCLIVersionAssets(version); if (!versionData) { - error({ message: `The provided version does not exist. Please check the version number and try again.` }); + this.logger.stderr.error(this.t(UpgradeCommandMessages.versionNotFound)); return; } @@ -140,9 +139,9 @@ export class UpgradeCommand extends ApifyCommand { // Check again, in case `latest` returns an older version for whatever reason if (!gte(versionWithoutV, MINIMUM_VERSION_FOR_UPGRADE_COMMAND)) { - error({ - message: `The minimum version of the CLI you can manually downgrade/upgrade to is ${MINIMUM_VERSION_FOR_UPGRADE_COMMAND}.`, - }); + this.logger.stderr.error( + this.t(UpgradeCommandMessages.minimumVersion, { minVersion: MINIMUM_VERSION_FOR_UPGRADE_COMMAND }), + ); return; } @@ -150,33 +149,34 @@ export class UpgradeCommand extends ApifyCommand { if (metadata.installMethod === 'bundle') { if (!assets.length) { - error({ - message: [ - 'Failed to find the assets for your system and the provided version. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:', - `- The version you are trying to upgrade to: ${versionWithoutV}`, - `- The system you are running on: ${metadata.platform} ${metadata.arch}`, - ].join('\n'), - }); + this.logger.stderr.error( + this.t(UpgradeCommandMessages.assetsNotFound, { + version: versionWithoutV, + platform: metadata.platform, + arch: metadata.arch, + }), + ); return; } const bundleDirectory = dirname(process.execPath); - cliDebugPrint('[upgrade] bundleDirectory', bundleDirectory); + logger.debug('[upgrade] bundleDirectory', bundleDirectory); const directoryEntries = await readdir(bundleDirectory); if (!directoryEntries.some((entry) => entry.startsWith('apify') || entry.startsWith('actor'))) { - cliDebugPrint('[upgrade] directoryEntries', directoryEntries); - - error({ - message: [ - `Failed to find the currently installed ${this.cliName} bundle. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:`, - `- The version you are trying to upgrade to: ${versionWithoutV}`, - `- The system you are running on: ${metadata.platform} ${metadata.arch}`, - `- The directory where the ${this.cliName} bundle is installed: ${bundleDirectory}`, - ].join('\n'), - }); + logger.debug('[upgrade] directoryEntries', directoryEntries); + + this.logger.stderr.error( + this.t(UpgradeCommandMessages.bundleNotFound, { + cliName: this.cliName, + version: versionWithoutV, + platform: metadata.platform, + arch: metadata.arch, + bundleDirectory, + }), + ); return; } @@ -194,7 +194,9 @@ export class UpgradeCommand extends ApifyCommand { const updateCommand = UPDATE_COMMANDS[metadata.installMethod](version, this.entrypoint); if (process.env.APIFY_CLI_DEBUG) { - info({ message: `Would run command: ${updateCommand.join(' ')}` }); + this.logger.stderr.info( + this.t(UpgradeCommandMessages.wouldRunCommand, { updateCommand: updateCommand.join(' ') }), + ); return; } @@ -203,14 +205,14 @@ export class UpgradeCommand extends ApifyCommand { this.successMessage(versionWithoutV); } catch { - error({ - message: `Failed to upgrade the CLI. Please run the following command manually: ${updateCommand.join(' ')}`, - }); + this.logger.stderr.error( + this.t(UpgradeCommandMessages.upgradeFailed, { updateCommand: updateCommand.join(' ') }), + ); } } private successMessage(version: string) { - success({ message: `Successfully upgraded to ${version} 👍` }); + this.logger.stderr.success(this.t(UpgradeCommandMessages.successfullyUpgraded, { version })); } private async startUpgradeProcess(bundleDirectory: string, version: string, assets: Asset[]) { @@ -235,9 +237,9 @@ export class UpgradeCommand extends ApifyCommand { args.push('-AllUrls', `"${urls}"`); - cliDebugPrint('[upgrade] starting upgrade process with args', args); + logger.debug('[upgrade] starting upgrade process with args', args); - info({ message: `Starting upgrade process...` }); + this.logger.stderr.info(this.t(UpgradeCommandMessages.startingUpgradeProcess)); const upgradeProcess = spawn('powershell.exe', args, { detached: true, @@ -248,7 +250,7 @@ export class UpgradeCommand extends ApifyCommand { }); upgradeProcess.on('spawn', () => { - cliDebugPrint('[upgrade] upgrade process spawned'); + logger.debug('[upgrade] upgrade process spawned'); upgradeProcess.unref(); // CLI exits, but the upgrade process continues in the background @@ -256,7 +258,7 @@ export class UpgradeCommand extends ApifyCommand { }); upgradeProcess.on('error', (err) => { - error({ message: `Failed to start the upgrade process: ${err.message}` }); + this.logger.stderr.error(this.t(UpgradeCommandMessages.failedToStartUpgrade, { message: err.message })); }); } @@ -272,14 +274,14 @@ export class UpgradeCommand extends ApifyCommand { const res = await fetch(WINDOWS_UPGRADE_SCRIPT_URL, { headers: { 'User-Agent': USER_AGENT } }); if (!res.ok) { - error({ - message: [ - `Failed to fetch the upgrade script. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:`, - `- The system you are running on: ${metadata.platform} ${metadata.arch}`, - `- The URL of the asset that failed to fetch: ${WINDOWS_UPGRADE_SCRIPT_URL}`, - `- The status code of the response: ${res.status}`, - ].join('\n'), - }); + this.logger.stderr.error( + this.t(UpgradeCommandMessages.fetchScriptFailed, { + platform: metadata.platform, + arch: metadata.arch, + url: WINDOWS_UPGRADE_SCRIPT_URL, + status: res.status, + }), + ); process.exit(1); } @@ -288,7 +290,7 @@ export class UpgradeCommand extends ApifyCommand { await writeFile(filePath, Buffer.from(buffer)); - cliDebugPrint('[upgrade] downloaded upgrade script to', filePath); + logger.debug('[upgrade] downloaded upgrade script to', filePath); } private async handleUnixUpgrade(bundleDirectory: string, version: string, assets: Asset[]) { @@ -298,36 +300,37 @@ export class UpgradeCommand extends ApifyCommand { const cliName = asset.name.split('-')[0]; const filePath = join(bundleDirectory, cliName); - info({ message: `Downloading \`${cliName}\` binary of the Apify CLI...` }); + this.logger.stderr.info(this.t(UpgradeCommandMessages.downloadingBinary, { cliName })); const res = await fetch(asset.browser_download_url, { headers: { 'User-Agent': USER_AGENT } }); if (!res.ok) { const body = await res.text(); - cliDebugPrint('[upgrade] failed to fetch asset', { asset, status: res.status, body }); - - error({ - message: [ - `Failed to fetch the ${cliName} bundle. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:`, - `- The version you are trying to upgrade to: ${version}`, - `- The system you are running on: ${metadata.platform} ${metadata.arch}`, - `- The URL of the asset that failed to fetch: ${asset.browser_download_url}`, - `- The status code of the response: ${res.status}`, - `- The body of the response: ${body}`, - ].join('\n'), - }); + logger.debug('[upgrade] failed to fetch asset', { asset, status: res.status, body }); + + this.logger.stderr.error( + this.t(UpgradeCommandMessages.fetchAssetFailed, { + cliName, + version, + platform: metadata.platform, + arch: metadata.arch, + url: asset.browser_download_url, + status: res.status, + body, + }), + ); return; } if (process.env.APIFY_CLI_DEBUG && !process.env.APIFY_CLI_FORCE) { - info({ message: `Would write asset ${cliName} to ${filePath}` }); + this.logger.stderr.info(this.t(UpgradeCommandMessages.wouldWriteAsset, { cliName, filePath })); continue; } - info({ message: chalk.gray(`Writing ${cliName} to ${filePath}...`) }); + this.logger.stderr.info(this.t(UpgradeCommandMessages.writingAsset, { cliName, filePath })); const buffer = await res.arrayBuffer(); @@ -343,19 +346,20 @@ export class UpgradeCommand extends ApifyCommand { mode: originalFilePerms | 0o700, }); - cliDebugPrint(`[upgrade ${cliName}] wrote asset to`, filePath); + logger.debug(`[upgrade ${cliName}] wrote asset to`, filePath); } catch (err: any) { - cliDebugPrint('[upgrade] failed to write asset', { error: err }); - - error({ - message: [ - `Failed to write the ${cliName} bundle. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:`, - `- The version you are trying to upgrade to: ${version}`, - `- The system you are running on: ${metadata.platform} ${metadata.arch}`, - `- The URL of the asset that failed to fetch: ${asset.browser_download_url}`, - `- The error: ${err.message}`, - ].join('\n'), - }); + logger.debug('[upgrade] failed to write asset', { error: err }); + + this.logger.stderr.error( + this.t(UpgradeCommandMessages.writeAssetFailed, { + cliName, + version, + platform: metadata.platform, + arch: metadata.arch, + url: asset.browser_download_url, + message: err.message, + }), + ); } } } diff --git a/src/commands/create.ts b/src/commands/create.ts index 41f8e2e2b..c1aa7cdd1 100644 --- a/src/commands/create.ts +++ b/src/commands/create.ts @@ -2,6 +2,7 @@ import { mkdir, readdir, stat } from 'node:fs/promises'; import { join } from 'node:path'; import process from 'node:process'; +import { CreateCommandMessages } from '#i18n/commands/create.js'; import { gte, minVersion } from 'semver'; import { fetchManifest, manifestUrl } from '@apify/actor-templates'; @@ -28,7 +29,6 @@ import { usePythonRuntime } from '../lib/hooks/runtimes/python.js'; import { getInstallCommandSuggestion } from '../lib/hooks/runtimes/utils.js'; import { ProjectLanguage, useCwdProject } from '../lib/hooks/useCwdProject.js'; import { createPrefilledInputFileFromInputSchema } from '../lib/input_schema.js'; -import { error, info, simpleLog, success, warning } from '../lib/outputs.js'; import { downloadAndUnzip, getJsonFileContent, @@ -113,7 +113,7 @@ export class CreateCommand extends ApifyCommand { // Start fetching manifest immediately to prevent // annoying delays that sometimes happen on CLI startup. const manifestPromise = fetchManifest().catch((err) => { - return new Error(`Could not fetch template list from server. Cause: ${err?.message}`); + return new Error(this.t(CreateCommandMessages.manifestFetchFailed, { cause: err?.message })); }); actorName = await ensureValidActorName(actorName); @@ -130,11 +130,7 @@ export class CreateCommand extends ApifyCommand { .catch(() => false)); if (folderExists?.isDirectory() && folderHasFiles) { - error({ - message: - `Cannot create new Actor, directory '${actorName}' already exists. Please provide a different name.` + - ' You can use "apify init" to create a local Actor environment inside an existing directory.', - }); + this.logger.stderr.error(this.t(CreateCommandMessages.directoryExists, { actorName })); actorName = await ensureValidActorName(); actFolderDir = join(cwd, actorName); @@ -198,18 +194,20 @@ export class CreateCommand extends ApifyCommand { if (!project.runtime) { switch (project.type) { case ProjectLanguage.JavaScript: { - warning({ - message: - `No Node.js detected! Please install Node.js ${minimumSupportedNodeVersion} or higher` + - ' to be able to run Node.js Actors locally.', - }); + this.logger.stderr.warning( + this.t(CreateCommandMessages.noNodeDetected, { + minimumVersion: String(minimumSupportedNodeVersion), + }), + ); break; } case ProjectLanguage.Scrapy: case ProjectLanguage.Python: { - warning({ - message: `No Python detected! Please install Python ${MINIMUM_SUPPORTED_PYTHON_VERSION} or higher to be able to run Python Actors locally.`, - }); + this.logger.stderr.warning( + this.t(CreateCommandMessages.noPythonDetected, { + minimumVersion: MINIMUM_SUPPORTED_PYTHON_VERSION, + }), + ); break; } default: @@ -223,11 +221,12 @@ export class CreateCommand extends ApifyCommand { switch (project.type) { case ProjectLanguage.JavaScript: { if (!isNodeVersionSupported(runtime.version)) { - warning({ - message: - `You are running Node.js version ${runtime.version}, which is no longer supported. ` + - `Please upgrade to Node.js version ${minimumSupportedNodeVersion} or later.`, - }); + this.logger.stderr.warning( + this.t(CreateCommandMessages.nodeUnsupported, { + version: runtime.version, + minimumVersion: String(minimumSupportedNodeVersion), + }), + ); } // If the Actor is a Node.js Actor (has package.json), run `npm install` @@ -275,20 +274,18 @@ export class CreateCommand extends ApifyCommand { case ProjectLanguage.Python: case ProjectLanguage.Scrapy: { if (!isPythonVersionSupported(runtime.version)) { - warning({ - message: `Python Actors require Python 3.9 or higher, but you have Python ${runtime.version}!`, - }); - warning({ - message: 'Please install Python 3.9 or higher to be able to run Python Actors locally.', - }); + this.logger.stderr.warning( + this.t(CreateCommandMessages.pythonUnsupported, { version: runtime.version }), + ); + this.logger.stderr.warning(this.t(CreateCommandMessages.pythonUnsupportedHint)); return; } const venvPath = join(actFolderDir, '.venv'); - info({ message: `Python version ${runtime.version} detected.` }); - info({ - message: `Creating a virtual environment in "${venvPath}" and installing dependencies from "requirements.txt"...`, - }); + this.logger.stderr.info( + this.t(CreateCommandMessages.pythonDetected, { version: runtime.version }), + ); + this.logger.stderr.info(this.t(CreateCommandMessages.creatingVenv, { venvPath })); if (!process.env.VIRTUAL_ENV) { // If Python is not running in a virtual environment, create a new one @@ -365,22 +362,26 @@ export class CreateCommand extends ApifyCommand { : null; // Success message with extra empty line - simpleLog({ message: '' }); - success({ - message: formatCreateSuccessMessage({ - actorName, - dependenciesInstalled, - postCreate: messages?.postCreate ?? null, - gitRepositoryInitialized: !skipGitInit && !cwdHasGit && gitInitResult.success, - installCommandSuggestion, + this.logger.stderr.log(this.t(CreateCommandMessages.blankLine)); + this.logger.stderr.success( + this.t(CreateCommandMessages.successMessage, { + message: formatCreateSuccessMessage({ + actorName, + dependenciesInstalled, + postCreate: messages?.postCreate ?? null, + gitRepositoryInitialized: !skipGitInit && !cwdHasGit && gitInitResult.success, + installCommandSuggestion, + }), }), - }); + ); // Report git initialization result only if it failed (success already included in success message) if (!skipGitInit && !cwdHasGit && !gitInitResult.success) { // Git init is not critical, so we just warn if it fails - warning({ message: `Failed to initialize git repository: ${gitInitResult.error!.message}` }); - warning({ message: 'You can manually run "git init" in the Actor directory if needed.' }); + this.logger.stderr.warning( + this.t(CreateCommandMessages.gitInitFailed, { message: gitInitResult.error!.message }), + ); + this.logger.stderr.warning(this.t(CreateCommandMessages.gitInitManualHint)); } } } diff --git a/src/commands/datasets/create.ts b/src/commands/datasets/create.ts index 33efd6cbd..e132d154a 100644 --- a/src/commands/datasets/create.ts +++ b/src/commands/datasets/create.ts @@ -1,10 +1,9 @@ -import chalk from 'chalk'; +import { DatasetsCreateCommandMessages } from '#i18n/commands/datasets/create.js'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { tryToGetDataset } from '../../lib/commands/storages.js'; -import { error, success } from '../../lib/outputs.js'; -import { getLoggedClientOrThrow, printJsonToStdout } from '../../lib/utils.js'; +import { getLoggedClientOrThrow } from '../../lib/utils.js'; export class DatasetsCreateCommand extends ApifyCommand { static override name = 'create' as const; @@ -31,8 +30,6 @@ export class DatasetsCreateCommand extends ApifyCommand = { @@ -68,7 +68,7 @@ export class DatasetsGetItems extends ApifyCommand { const maybeDataset = await this.tryToGetDataset(apifyClient, datasetId); if (!maybeDataset) { - error({ message: `Dataset with ID "${datasetId}" not found.` }); + this.logger.stderr.error(this.t(DatasetsGetItemsMessages.datasetNotFound, { datasetId })); return; } @@ -85,7 +85,7 @@ export class DatasetsGetItems extends ApifyCommand { const contentType = downloadFormatToContentType[format] ?? 'application/octet-stream'; - simpleLog({ message: contentType }); + this.logger.stderr.log(this.t(DatasetsGetItemsMessages.contentType, { contentType })); process.stdout.write(result); process.stdout.write('\n'); diff --git a/src/commands/datasets/info.ts b/src/commands/datasets/info.ts index 846141f54..8a0d34441 100644 --- a/src/commands/datasets/info.ts +++ b/src/commands/datasets/info.ts @@ -1,3 +1,4 @@ +import { DatasetsInfoCommandMessages } from '#i18n/commands/datasets/info.js'; import type { Task } from 'apify-client'; import chalk from 'chalk'; @@ -7,8 +8,7 @@ import { prettyPrintBytes } from '../../lib/commands/pretty-print-bytes.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; import { getUserPlanPricing } from '../../lib/commands/storage-size.js'; import { tryToGetDataset } from '../../lib/commands/storages.js'; -import { error, simpleLog } from '../../lib/outputs.js'; -import { getLoggedClientOrThrow, printJsonToStdout, TimestampFormatter } from '../../lib/utils.js'; +import { getLoggedClientOrThrow, TimestampFormatter } from '../../lib/utils.js'; const consoleLikeTable = new ResponsiveTable({ allColumns: ['Row1', 'Row2'], @@ -36,8 +36,6 @@ export class DatasetsInfoCommand extends ApifyCommand { }), }; - static override enableJsonFlag = true; - async run() { const { desc, offset, limit, json, unnamed } = this.flags; @@ -63,15 +61,12 @@ export class DatasetsLsCommand extends ApifyCommand { const rawDatasetList = await client.datasets().list({ desc, offset, limit, unnamed }); if (json) { - printJsonToStdout(rawDatasetList); + this.logger.stdout.json(rawDatasetList); return; } if (rawDatasetList.count === 0) { - info({ - message: "You don't have any Datasets on your account", - stdout: true, - }); + this.logger.stdout.info(this.t(DatasetsLsCommandMessages.noDatasets)); return; } @@ -93,9 +88,8 @@ export class DatasetsLsCommand extends ApifyCommand { }); } - simpleLog({ - message: table.render(CompactMode.WebLikeCompact), - stdout: true, - }); + this.logger.stdout.log( + this.t(DatasetsLsCommandMessages.table, { table: table.render(CompactMode.WebLikeCompact) }), + ); } } diff --git a/src/commands/datasets/push-items.ts b/src/commands/datasets/push-items.ts index dff4d30c8..db0d460fb 100644 --- a/src/commands/datasets/push-items.ts +++ b/src/commands/datasets/push-items.ts @@ -1,11 +1,10 @@ +import { DatasetsPushDataCommandMessages } from '#i18n/commands/datasets/push-items.js'; import type { ApifyApiError } from 'apify-client'; -import chalk from 'chalk'; import { cachedStdinInput } from '../../entrypoints/_shared.js'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { tryToGetDataset } from '../../lib/commands/storages.js'; -import { error, success } from '../../lib/outputs.js'; import { getLoggedClientOrThrow } from '../../lib/utils.js'; export class DatasetsPushDataCommand extends ApifyCommand { @@ -44,9 +43,7 @@ export class DatasetsPushDataCommand extends ApifyCommand { @@ -47,14 +46,12 @@ export class DatasetsRenameCommand extends ApifyCommand { if (!name) { - return `The name of the dataset with ID ${chalk.yellow(id)} has been set to: ${chalk.yellow(newName)}`; + return this.t(DatasetsRenameCommandMessages.nameSet, { id, newName: newName! }); } if (unname) { - return `The name of the dataset with ID ${chalk.yellow(id)} has been removed (was ${chalk.yellow(name)} previously).`; + return this.t(DatasetsRenameCommandMessages.nameRemoved, { id, previousName: name }); } - return `The name of the dataset with ID ${chalk.yellow(id)} was changed from ${chalk.yellow(name)} to ${chalk.yellow(newName)}.`; + return this.t(DatasetsRenameCommandMessages.nameChanged, { id, previousName: name, newName: newName! }); })(); try { await existingDataset.datasetClient.update({ name: unname ? (null as never) : newName! }); - success({ - message: successMessage, - stdout: true, - }); + this.logger.stdout.success(successMessage); } catch (err) { const casted = err as ApifyApiError; - error({ - message: `Failed to rename dataset with ID ${chalk.yellow(id)}\n ${casted.message || casted}`, - }); + this.logger.stderr.error( + this.t(DatasetsRenameCommandMessages.renameFailed, { id, message: casted.message || String(casted) }), + ); } } } diff --git a/src/commands/datasets/rm.ts b/src/commands/datasets/rm.ts index b81b66f0d..5a9219370 100644 --- a/src/commands/datasets/rm.ts +++ b/src/commands/datasets/rm.ts @@ -1,12 +1,11 @@ +import { DatasetsRmCommandMessages } from '#i18n/commands/datasets/rm.js'; import type { ApifyApiError } from 'apify-client'; -import chalk from 'chalk'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { YesFlag } from '../../lib/command-framework/flags.js'; import { tryToGetDataset } from '../../lib/commands/storages.js'; import { useYesNoConfirm } from '../../lib/hooks/user-confirmations/useYesNoConfirm.js'; -import { error, info, success } from '../../lib/outputs.js'; import { getLoggedClientOrThrow } from '../../lib/utils.js'; export class DatasetsRmCommand extends ApifyCommand { @@ -48,9 +47,7 @@ export class DatasetsRmCommand extends ApifyCommand { const existingDataset = await tryToGetDataset(client, datasetNameOrId); if (!existingDataset) { - error({ - message: `Dataset with ID or name "${datasetNameOrId}" not found.`, - }); + this.logger.stderr.error(this.t(DatasetsRmCommandMessages.datasetNotFound, { datasetNameOrId })); return; } @@ -61,7 +58,7 @@ export class DatasetsRmCommand extends ApifyCommand { }); if (!confirmed) { - info({ message: 'Dataset deletion has been aborted.' }); + this.logger.stderr.info(this.t(DatasetsRmCommandMessages.deletionAborted)); return; } @@ -70,16 +67,17 @@ export class DatasetsRmCommand extends ApifyCommand { try { await existingDataset.datasetClient.delete(); - success({ - message: `Dataset with ID ${chalk.yellow(id)}${name ? ` (called ${chalk.yellow(name)})` : ''} has been deleted.`, - stdout: true, - }); + this.logger.stdout.success( + name + ? this.t(DatasetsRmCommandMessages.deletedWithName, { id, name }) + : this.t(DatasetsRmCommandMessages.deletedUnnamed, { id }), + ); } catch (err) { const casted = err as ApifyApiError; - error({ - message: `Failed to delete dataset with ID ${chalk.yellow(id)}\n ${casted.message || casted}`, - }); + this.logger.stderr.error( + this.t(DatasetsRmCommandMessages.deleteFailed, { id, message: casted.message || String(casted) }), + ); } } } diff --git a/src/commands/edit-input-schema.ts b/src/commands/edit-input-schema.ts index 06e8a63f4..0186a3881 100644 --- a/src/commands/edit-input-schema.ts +++ b/src/commands/edit-input-schema.ts @@ -3,6 +3,7 @@ import type { Server } from 'node:http'; import type { AddressInfo } from 'node:net'; import { dirname } from 'node:path'; +import { EditInputSchemaCommandMessages } from '#i18n/commands/edit-input-schema.js'; import cors from 'cors'; import detectIndent from 'detect-indent'; import express from 'express'; @@ -14,7 +15,6 @@ import { ApifyCommand } from '../lib/command-framework/apify-command.js'; import { Args } from '../lib/command-framework/args.js'; import { LOCAL_CONFIG_PATH } from '../lib/consts.js'; import { readInputSchema } from '../lib/input_schema.js'; -import { error, info, success, warning } from '../lib/outputs.js'; const INPUT_SCHEMA_EDITOR_BASE_URL = 'https://apify.github.io/input-schema-editor-react/'; const INPUT_SCHEMA_EDITOR_ORIGIN = new URL(INPUT_SCHEMA_EDITOR_BASE_URL).origin; @@ -71,12 +71,12 @@ export class EditInputSchemaCommand extends ApifyCommand { try { - info({ message: 'Got input schema from editor...' }); + this.logger.stderr.info(this.t(EditInputSchemaCommandMessages.gotSchema)); const inputSchemaObj = req.body; let inputSchemaStr = JSON.stringify(inputSchemaObj, null, jsonIndentation); if (appendFinalNewline) inputSchemaStr += '\n'; @@ -181,10 +187,12 @@ export class EditInputSchemaCommand extends ApifyCommand { if (req.body.isWindowClosed) { - info({ message: 'Editor closed, finishing...' }); + this.logger.stderr.info(this.t(EditInputSchemaCommandMessages.editorClosed)); } else { - info({ message: 'Editing finished, you can close the editor.' }); + this.logger.stderr.info(this.t(EditInputSchemaCommandMessages.editingFinished)); } res.end(); - server.close(() => success({ message: 'Done.' })); + server.close(() => this.logger.stderr.success(this.t(EditInputSchemaCommandMessages.done))); }); // Listening on port 0 will assign a random available port server = app.listen(0); const { port } = server.address() as AddressInfo; - info({ message: `Listening for messages from input schema editor on port ${port}...` }); + this.logger.stderr.info(this.t(EditInputSchemaCommandMessages.listening, { port })); const editorUrl = `${INPUT_SCHEMA_EDITOR_BASE_URL}?localCliPort=${port}&localCliToken=${authToken}&localCliApiVersion=${API_VERSION}`; - info({ message: `Opening input schema editor at "${editorUrl}"...` }); + this.logger.stderr.info(this.t(EditInputSchemaCommandMessages.openingEditor, { url: editorUrl })); await open(editorUrl); } } diff --git a/src/commands/help.ts b/src/commands/help.ts index c0b7588b3..2e25c8c5c 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -1,10 +1,10 @@ +import { HelpCommandMessages } from '#i18n/commands/help.js'; import chalk from 'chalk'; import { ApifyCommand, commandRegistry } from '../lib/command-framework/apify-command.js'; import { Args } from '../lib/command-framework/args.js'; import { renderHelpForCommand, renderMainHelpMenu } from '../lib/command-framework/help.js'; import { useCommandSuggestions } from '../lib/hooks/useCommandSuggestions.js'; -import { error } from '../lib/outputs.js'; export class HelpCommand extends ApifyCommand { static override name = 'help' as const; @@ -39,18 +39,14 @@ export class HelpCommand extends ApifyCommand { if (!command) { const closestMatches = useCommandSuggestions(lowercasedCommandString); - let message = chalk.gray(`Command ${chalk.whiteBright(commandString)} not found`); + const message = closestMatches.length + ? this.t(HelpCommandMessages.commandNotFoundWithSuggestions, { + commandString, + suggestions: closestMatches.map((cmd) => chalk.whiteBright(cmd)).join(', '), + }) + : this.t(HelpCommandMessages.commandNotFound, { commandString }); - if (closestMatches.length) { - message += '\n '; - message += chalk.gray( - `Did you mean: ${closestMatches.map((cmd) => chalk.whiteBright(cmd)).join(', ')}?`, - ); - } - - error({ - message, - }); + this.logger.stderr.error(message); return; } diff --git a/src/commands/init-wrap-scrapy.ts b/src/commands/init-wrap-scrapy.ts index b390ed493..4c66d0b46 100644 --- a/src/commands/init-wrap-scrapy.ts +++ b/src/commands/init-wrap-scrapy.ts @@ -1,6 +1,7 @@ +import { WrapScrapyCommandMessages } from '#i18n/commands/init-wrap-scrapy.js'; + import { ApifyCommand } from '../lib/command-framework/apify-command.js'; import { Args } from '../lib/command-framework/args.js'; -import { info } from '../lib/outputs.js'; import { wrapScrapyProject } from '../lib/projects/scrapy/wrapScrapyProject.js'; export class WrapScrapyCommand extends ApifyCommand { @@ -27,6 +28,6 @@ It adds the following features: async run() { await wrapScrapyProject({ projectPath: this.args.path }); - info({ message: 'Scrapy project wrapped successfully.' }); + this.logger.stderr.info(this.t(WrapScrapyCommandMessages.wrapped)); } } diff --git a/src/commands/init.ts b/src/commands/init.ts index 315bbce6c..7e217b489 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -1,6 +1,8 @@ import { basename } from 'node:path'; import process from 'node:process'; +import { InitCommandMessages } from '#i18n/commands/init.js'; + import { ApifyCommand } from '../lib/command-framework/apify-command.js'; import { Args } from '../lib/command-framework/args.js'; import { Flags, YesFlag } from '../lib/command-framework/flags.js'; @@ -10,7 +12,6 @@ import { ProjectLanguage, useCwdProject } from '../lib/hooks/useCwdProject.js'; import { useUserInput } from '../lib/hooks/user-confirmations/useUserInput.js'; import { useYesNoConfirm } from '../lib/hooks/user-confirmations/useYesNoConfirm.js'; import { createPrefilledInputFileFromInputSchema } from '../lib/input_schema.js'; -import { error, info, success, warning } from '../lib/outputs.js'; import { wrapScrapyProject } from '../lib/projects/scrapy/wrapScrapyProject.js'; import { sanitizeActorName, setLocalConfig, setLocalEnv, validateActorName } from '../lib/utils.js'; @@ -70,7 +71,9 @@ export class InitCommand extends ApifyCommand { // TODO: use direct .unwrap() once we migrate to yargs if (projectResult.isErr()) { - error({ message: projectResult.unwrapErr().message }); + this.logger.stderr.error( + this.t(InitCommandMessages.projectError, { message: projectResult.unwrapErr().message }), + ); process.exit(1); } @@ -78,7 +81,7 @@ export class InitCommand extends ApifyCommand { if (project.warnings?.length) { for (const w of project.warnings) { - warning({ message: w }); + this.logger.stderr.warning(this.t(InitCommandMessages.warning, { warning: w })); } } @@ -91,14 +94,14 @@ export class InitCommand extends ApifyCommand { } if (project.type === ProjectLanguage.Scrapy) { - info({ message: 'The current directory looks like a Scrapy project. Using automatic project wrapping.' }); + this.logger.stderr.info(this.t(InitCommandMessages.scrapyDetected)); this.telemetryData.actorWrapper = 'scrapy'; return wrapScrapyProject({ projectPath: cwd }); } if (!this.flags.yes && project.type === ProjectLanguage.Unknown) { - warning({ message: 'The current directory does not look like a Node.js or Python project.' }); + this.logger.stderr.warning(this.t(InitCommandMessages.notJsOrPython)); const confirmed = await useYesNoConfirm({ message: 'Do you want to continue?', @@ -113,12 +116,12 @@ export class InitCommand extends ApifyCommand { const actorConfig = await useActorConfig({ cwd }); if (actorConfig.isOkAnd((cfg) => cfg.exists && !cfg.migrated)) { - warning({ - message: `Skipping creation of '${LOCAL_CONFIG_PATH}', the file already exists in the current directory.`, - }); + this.logger.stderr.warning(this.t(InitCommandMessages.configExists, { configPath: LOCAL_CONFIG_PATH })); } else { if (actorConfig.isErr()) { - error({ message: actorConfig.unwrapErr().message }); + this.logger.stderr.error( + this.t(InitCommandMessages.actorConfigError, { message: actorConfig.unwrapErr().message }), + ); process.exitCode = CommandExitCodes.InvalidActorJson; return; } @@ -140,7 +143,9 @@ export class InitCommand extends ApifyCommand { response = answer; } catch (err) { - error({ message: (err as Error).message }); + this.logger.stderr.error( + this.t(InitCommandMessages.invalidActorName, { message: (err as Error).message }), + ); } } @@ -170,6 +175,6 @@ export class InitCommand extends ApifyCommand { // Create prefilled INPUT.json file from the input schema prefills await createPrefilledInputFileFromInputSchema(cwd); - success({ message: 'The Actor has been initialized in the current directory.' }); + this.logger.stderr.success(this.t(InitCommandMessages.initialized)); } } diff --git a/src/commands/key-value-stores/create.ts b/src/commands/key-value-stores/create.ts index 3dbe7cb65..2fe6cb6c3 100644 --- a/src/commands/key-value-stores/create.ts +++ b/src/commands/key-value-stores/create.ts @@ -1,10 +1,9 @@ -import chalk from 'chalk'; +import { KeyValueStoresCreateCommandMessages } from '#i18n/commands/key-value-stores/create.js'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { tryToGetKeyValueStore } from '../../lib/commands/storages.js'; -import { error, success } from '../../lib/outputs.js'; -import { getLoggedClientOrThrow, printJsonToStdout } from '../../lib/utils.js'; +import { getLoggedClientOrThrow } from '../../lib/utils.js'; export class KeyValueStoresCreateCommand extends ApifyCommand { static override name = 'create' as const; @@ -31,8 +30,6 @@ export class KeyValueStoresCreateCommand extends ApifyCommand { @@ -51,9 +50,7 @@ export class KeyValueStoresDeleteValueCommand extends ApifyCommand { @@ -50,7 +51,9 @@ export class KeyValueStoresGetValueCommand extends ApifyCommand { @@ -47,14 +46,12 @@ export class KeyValueStoresRenameCommand extends ApifyCommand { if (!name) { - return `The name of the key-value store with ID ${chalk.yellow(id)} has been set to: ${chalk.yellow(newName)}`; + return this.t(KeyValueStoresRenameCommandMessages.nameSet, { id, newName: newName! }); } if (unname) { - return `The name of the key-value store with ID ${chalk.yellow(id)} has been removed (was ${chalk.yellow(name)} previously).`; + return this.t(KeyValueStoresRenameCommandMessages.nameRemoved, { id, name }); } - return `The name of the key-value store with ID ${chalk.yellow(id)} was changed from ${chalk.yellow(name)} to ${chalk.yellow(newName)}.`; + return this.t(KeyValueStoresRenameCommandMessages.nameChanged, { id, name, newName: newName! }); })(); try { await existingDataset.keyValueStoreClient.update({ name: unname ? (null as never) : newName! }); - success({ - message: successMessage, - stdout: true, - }); + this.logger.stdout.success(successMessage); } catch (err) { const casted = err as ApifyApiError; - error({ - message: `Failed to rename key-value store with ID ${chalk.yellow(id)}\n ${casted.message || casted}`, - }); + this.logger.stderr.error( + this.t(KeyValueStoresRenameCommandMessages.renameFailed, { + id, + message: String(casted.message || casted), + }), + ); } } } diff --git a/src/commands/key-value-stores/rm.ts b/src/commands/key-value-stores/rm.ts index 4c390ed06..f9faba190 100644 --- a/src/commands/key-value-stores/rm.ts +++ b/src/commands/key-value-stores/rm.ts @@ -1,12 +1,11 @@ +import { KeyValueStoresRmCommandMessages } from '#i18n/commands/key-value-stores/rm.js'; import type { ApifyApiError } from 'apify-client'; -import chalk from 'chalk'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { YesFlag } from '../../lib/command-framework/flags.js'; import { tryToGetKeyValueStore } from '../../lib/commands/storages.js'; import { useYesNoConfirm } from '../../lib/hooks/user-confirmations/useYesNoConfirm.js'; -import { error, info, success } from '../../lib/outputs.js'; import { getLoggedClientOrThrow } from '../../lib/utils.js'; export class KeyValueStoresRmCommand extends ApifyCommand { @@ -48,9 +47,9 @@ export class KeyValueStoresRmCommand extends ApifyCommand { @@ -54,9 +54,7 @@ export class KeyValueStoresSetValueCommand extends ApifyCommand { if (localConfigResult.isErr()) { const { message, cause } = localConfigResult.unwrapErr(); - error({ message: `${message}${cause ? `\n ${cause.message}` : ''}` }); + this.logger.stderr.error( + cause + ? this.t(RunCommandMessages.actorConfigErrorWithCause, { message, cause: cause.message }) + : message, + ); process.exitCode = CommandExitCodes.InvalidActorJson; return; } @@ -167,7 +171,7 @@ export class RunCommand extends ApifyCommand { const projectRuntimeResult = await useCwdProject({ cwd }); if (projectRuntimeResult.isErr()) { - error({ message: projectRuntimeResult.unwrapErr().message }); + this.logger.stderr.error(projectRuntimeResult.unwrapErr().message); process.exitCode = CommandExitCodes.InvalidActorJson; return; } @@ -177,34 +181,36 @@ export class RunCommand extends ApifyCommand { if (project.warnings?.length) { for (const w of project.warnings) { - warning({ message: w }); + this.logger.stderr.warning(w); } } if (type === ProjectLanguage.Unknown) { - throw new Error( - 'Actor is of an unknown format.' + - ` Make sure your project is supported by Apify CLI (either a package.json file is present, or a Python entrypoint could be found) or you are in a migrated Scrapy project.`, - ); + throw new Error(this.t(RunCommandMessages.unknownProjectFormat)); } if (!runtime) { switch (type) { case ProjectLanguage.JavaScript: - error({ - message: `No Node.js detected! Please install Node.js ${SUPPORTED_NODEJS_VERSION} (or higher) to be able to run Node.js Actors locally.`, - }); + this.logger.stderr.error( + this.t(RunCommandMessages.noNodeRuntime, { supportedVersion: SUPPORTED_NODEJS_VERSION }), + ); break; case ProjectLanguage.Scrapy: case ProjectLanguage.Python: - error({ - message: `No Python detected! Please install Python ${MINIMUM_SUPPORTED_PYTHON_VERSION} (or higher) to be able to run Python Actors locally.`, - }); + this.logger.stderr.error( + this.t(RunCommandMessages.noPythonRuntime, { + supportedVersion: MINIMUM_SUPPORTED_PYTHON_VERSION, + }), + ); break; default: - error({ - message: `No runtime detected! Make sure you have Python ${MINIMUM_SUPPORTED_PYTHON_VERSION} (or higher) or Node.js ${SUPPORTED_NODEJS_VERSION} (or higher) installed.`, - }); + this.logger.stderr.error( + this.t(RunCommandMessages.noRuntime, { + pythonVersion: MINIMUM_SUPPORTED_PYTHON_VERSION, + nodeVersion: SUPPORTED_NODEJS_VERSION, + }), + ); } return; @@ -239,20 +245,16 @@ export class RunCommand extends ApifyCommand { runType = type !== ProjectLanguage.JavaScript ? RunType.Module : RunType.DirectFile; entrypoint = cwdEntrypoint.path; } else { - error({ - message: `No entrypoint detected! Please provide an entrypoint using the --entrypoint flag, or make sure your project has an entrypoint.`, - }); + this.logger.stderr.error(this.t(RunCommandMessages.noEntrypoint)); return; } if (existsSync(LEGACY_LOCAL_STORAGE_DIR) && !existsSync(actualStoragePath)) { renameSync(LEGACY_LOCAL_STORAGE_DIR, actualStoragePath); - warning({ - message: - `The legacy 'apify_storage' directory was renamed to '${actualStoragePath}' to align it with Apify SDK v3.` + - ' Contents were left intact.', - }); + this.logger.stderr.warning( + this.t(RunCommandMessages.legacyStorageRenamed, { storagePath: actualStoragePath }), + ); } const crawleeVersion = await useModuleVersion({ @@ -277,7 +279,7 @@ export class RunCommand extends ApifyCommand { purgeDefaultKeyValueStore(resolvedInputKey), purgeDefaultDataset(), ]); - info({ message: 'All default local stores were purged.' }); + this.logger.stderr.info(this.t(RunCommandMessages.storesPurged)); } } @@ -285,11 +287,7 @@ export class RunCommand extends ApifyCommand { const isStorageEmpty = await checkIfStorageIsEmpty(resolvedInputKey); if (!isStorageEmpty && !this.flags.resurrect) { - warning({ - message: - 'The storage directory contains a previous state, the Actor will continue where it left off. ' + - 'To start from the initial state, use --purge parameter to clean the storage directory.', - }); + this.logger.stderr.warning(this.t(RunCommandMessages.storageNotEmpty)); } } @@ -348,10 +346,7 @@ export class RunCommand extends ApifyCommand { const env = { ...process.env, ...localEnvVars }; if (!userId) { - warning({ - message: - 'You are not logged in with your Apify Account. Some features like Apify Proxy will not work. Call "apify login" to fix that.', - }); + this.logger.stderr.warning(this.t(RunCommandMessages.notLoggedIn)); } try { @@ -368,11 +363,12 @@ export class RunCommand extends ApifyCommand { ? `${env.NODE_OPTIONS} --max-http-header-size=80000` : '--max-http-header-size=80000'; } else { - warning({ - message: - `You are running Node.js version ${runtime.version}, which is no longer supported. ` + - `Please upgrade to Node.js version ${minimumSupportedNodeVersion} or later.`, - }); + this.logger.stderr.warning( + this.t(RunCommandMessages.unsupportedNodeVersion, { + currentVersion: runtime.version, + minimumVersion: String(minimumSupportedNodeVersion), + }), + ); } if (runType === RunType.DirectFile || runType === RunType.Module) { @@ -388,23 +384,15 @@ export class RunCommand extends ApifyCommand { const packageJsonObj = JSON.parse(packageJson); if (!packageJsonObj.scripts) { - throw new Error( - 'No scripts were found in package.json. Please set it up for your project. ' + - 'For more information about that call "apify help run".', - ); + throw new Error(this.t(RunCommandMessages.noScriptsInPackageJson)); } if (!packageJsonObj.scripts[entrypoint]) { - throw new Error( - `The script "${entrypoint}" was not found in package.json. Please set it up for your project. ` + - 'For more information about that call "apify help run".', - ); + throw new Error(this.t(RunCommandMessages.scriptNotFound, { entrypoint })); } if (!runtime.pmPath) { - throw new Error( - 'No npm executable found! Please make sure your Node.js runtime has npm installed if you want to run package.json scripts locally.', - ); + throw new Error(this.t(RunCommandMessages.noNpmExecutable)); } await execWithLog({ @@ -421,12 +409,10 @@ export class RunCommand extends ApifyCommand { case ProjectLanguage.Python: case ProjectLanguage.Scrapy: { if (!isPythonVersionSupported(runtime.version)) { - error({ - message: `Python Actors require Python 3.9 or higher, but you have Python ${runtime.version}!`, - }); - error({ - message: 'Please install Python 3.9 or higher to be able to run Python Actors locally.', - }); + this.logger.stderr.error( + this.t(RunCommandMessages.pythonVersionTooLow, { currentVersion: runtime.version }), + ); + this.logger.stderr.error(this.t(RunCommandMessages.pleaseInstallPython)); return; } @@ -450,9 +436,7 @@ export class RunCommand extends ApifyCommand { break; } default: - error({ - message: `Failed to detect the language of your project. Please report this issue to the Apify team with your project structure over at https://github.com/apify/apify-cli/issues`, - }); + this.logger.stderr.error(this.t(RunCommandMessages.failedToDetectLanguage)); } } catch (err) { const { stderr } = err as ExecaError; @@ -473,9 +457,11 @@ export class RunCommand extends ApifyCommand { // If its in a 5ms range, we assume the file was modified (realistically impossible) if (mtime - storedInputResults.writtenAt >= 5) { - warning({ - message: `The "${storedInputResults.inputFilePath}" file was overwritten during the run. The CLI will not undo the setting of missing default fields from your input schema.`, - }); + this.logger.stderr.warning( + this.t(RunCommandMessages.inputFileOverwritten, { + filePath: storedInputResults.inputFilePath, + }), + ); // eslint-disable-next-line no-unsafe-finally -- we do not return anything in the commands anyways return; @@ -547,18 +533,16 @@ export class RunCommand extends ApifyCommand { switch (inputOverride?.source) { case 'stdin': - errorHeader = - 'The input provided through standard input is invalid. Please fix the following errors:\n'; + errorHeader = this.t(RunCommandMessages.stdinInputInvalid); break; case 'input': - errorHeader = - 'The input provided through the --input flag is invalid. Please fix the following errors:\n'; + errorHeader = this.t(RunCommandMessages.flagInputInvalid); break; default: if (inputOverride) { - errorHeader = `The input provided through the ${inputOverride.source} file is invalid. Please fix the following errors:\n`; + errorHeader = this.t(RunCommandMessages.fileInputInvalid, { source: inputOverride.source }); } else { - errorHeader = 'The input in your storage is invalid. Please fix the following errors:\n'; + errorHeader = this.t(RunCommandMessages.storedInputInvalid); } break; } @@ -574,9 +558,10 @@ export class RunCommand extends ApifyCommand { if (errors.length > 0) { throw new Error( - `${errorHeader}${errors - .map((e) => ` - ${e.message.replace('Field input.', 'Field ')}`) - .join('\n')}`, + this.t(RunCommandMessages.invalidInputErrors, { + header: errorHeader, + errors: errors.map((e) => ` - ${e.message.replace('Field input.', 'Field ')}`).join('\n'), + }), ); } @@ -610,7 +595,7 @@ export class RunCommand extends ApifyCommand { const inputJson = JSON.parse(existingInput.body.toString('utf-8')); if (Array.isArray(inputJson)) { - throw new Error('The input in your storage is invalid. It should be an object, not an array.'); + throw new Error(this.t(RunCommandMessages.storedInputNotObject)); } const fullInput = { @@ -622,9 +607,10 @@ export class RunCommand extends ApifyCommand { if (errors.length > 0) { throw new Error( - `${errorHeader}${errors - .map((e) => ` - ${e.message.replace('Field input.', 'Field ')}`) - .join('\n')}`, + this.t(RunCommandMessages.invalidInputErrors, { + header: errorHeader, + errors: errors.map((e) => ` - ${e.message.replace('Field input.', 'Field ')}`).join('\n'), + }), ); } diff --git a/src/commands/runs/abort.ts b/src/commands/runs/abort.ts index 669d0cc6d..02ab365c2 100644 --- a/src/commands/runs/abort.ts +++ b/src/commands/runs/abort.ts @@ -1,3 +1,4 @@ +import { RunsAbortCommandMessages } from '#i18n/commands/runs/abort.js'; import type { ApifyApiError } from 'apify-client'; import { ACTOR_JOB_STATUSES } from '@apify/consts'; @@ -5,8 +6,7 @@ import { ACTOR_JOB_STATUSES } from '@apify/consts'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { Flags } from '../../lib/command-framework/flags.js'; -import { error, success } from '../../lib/outputs.js'; -import { getLoggedClientOrThrow, printJsonToStdout } from '../../lib/utils.js'; +import { getLoggedClientOrThrow } from '../../lib/utils.js'; const runningStatuses = [ACTOR_JOB_STATUSES.READY, ACTOR_JOB_STATUSES.RUNNING]; @@ -45,8 +45,6 @@ export class RunsAbortCommand extends ApifyCommand { }), }; - static override enableJsonFlag = true; - async run() { const { runId } = this.args; @@ -55,15 +53,15 @@ export class RunsAbortCommand extends ApifyCommand { const run = await apifyClient.run(runId).get(); if (!run) { - error({ message: `Run with ID "${runId}" was not found on your account.`, stdout: true }); + this.logger.stdout.error(this.t(RunsAbortCommandMessages.runNotFound, { runId })); return; } if (!runningStatuses.includes(run.status as never)) { if (abortingStatuses.includes(run.status as never)) { - error({ message: `Run with ID "${runId}" is already aborting.`, stdout: true }); + this.logger.stdout.error(this.t(RunsAbortCommandMessages.alreadyAborting, { runId })); } else { - error({ message: `Run with ID "${runId}" is already aborted.`, stdout: true }); + this.logger.stdout.error(this.t(RunsAbortCommandMessages.alreadyAborted, { runId })); } return; @@ -73,25 +71,21 @@ export class RunsAbortCommand extends ApifyCommand { const result = await apifyClient.run(runId).abort({ gracefully: !this.flags.force }); if (this.flags.json) { - printJsonToStdout(result); + this.logger.stdout.json(result); return; } if (this.flags.force) { - success({ message: `Triggered the immediate abort of run "${runId}".`, stdout: true }); + this.logger.stdout.success(this.t(RunsAbortCommandMessages.triggeredForce, { runId })); } else { - success({ - message: `Triggered the abort of run "${runId}", it should finish aborting in up to 30 seconds.`, - stdout: true, - }); + this.logger.stdout.success(this.t(RunsAbortCommandMessages.triggeredGraceful, { runId })); } } catch (err) { const casted = err as ApifyApiError; - error({ - message: `Failed to abort run "${runId}".\n ${casted.message || casted}`, - stdout: true, - }); + this.logger.stdout.error( + this.t(RunsAbortCommandMessages.abortFailed, { runId, message: String(casted.message || casted) }), + ); } } } diff --git a/src/commands/runs/info.ts b/src/commands/runs/info.ts index 96000fb6a..65192bcbc 100644 --- a/src/commands/runs/info.ts +++ b/src/commands/runs/info.ts @@ -1,3 +1,4 @@ +import { RunsInfoCommandMessages } from '#i18n/commands/runs/info.js'; import type { ActorRun, ActorRunUsage, ActorTaggedBuild } from 'apify-client'; import chalk from 'chalk'; @@ -7,13 +8,7 @@ import { Flags } from '../../lib/command-framework/flags.js'; import { prettyPrintBytes } from '../../lib/commands/pretty-print-bytes.js'; import { prettyPrintStatus } from '../../lib/commands/pretty-print-status.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; -import { error, simpleLog } from '../../lib/outputs.js'; -import { - getLoggedClientOrThrow, - printJsonToStdout, - ShortDurationFormatter, - TimestampFormatter, -} from '../../lib/utils.js'; +import { getLoggedClientOrThrow, ShortDurationFormatter, TimestampFormatter } from '../../lib/utils.js'; const usageTable = new ResponsiveTable({ allColumns: ['', 'Unit', 'USD Amount'], @@ -76,8 +71,6 @@ export class RunsInfoCommand extends ApifyCommand { }), }; - static override enableJsonFlag = true; - async run() { const { runId } = this.args; @@ -86,7 +79,7 @@ export class RunsInfoCommand extends ApifyCommand { const run = await apifyClient.run(runId).get(); if (!run) { - error({ message: `Run with ID "${runId}" was not found on your account.` }); + this.logger.stderr.error(this.t(RunsInfoCommandMessages.runNotFound, { runId })); return; } @@ -100,7 +93,7 @@ export class RunsInfoCommand extends ApifyCommand { ]); if (this.flags.json) { - printJsonToStdout({ + this.logger.stdout.json({ ...run, actor, build, @@ -268,7 +261,7 @@ export class RunsInfoCommand extends ApifyCommand { message.push(`${chalk.blue('View saved items')}: ${keyValueStoreUrl}`); message.push(`${chalk.blue('View in Apify Console')}: ${url}`); - simpleLog({ message: message.join('\n'), stdout: true }); + this.logger.stdout.log(message.join('\n')); } private addDetailedUsage(run: ActorRun) { diff --git a/src/commands/runs/log.ts b/src/commands/runs/log.ts index cc8fcfe24..e51e9b554 100644 --- a/src/commands/runs/log.ts +++ b/src/commands/runs/log.ts @@ -1,6 +1,7 @@ +import { RunsLogCommandMessages } from '#i18n/commands/runs/log.js'; + import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; -import { error, info } from '../../lib/outputs.js'; import { getLoggedClientOrThrow, outputJobLog } from '../../lib/utils.js'; export class RunsLogCommand extends ApifyCommand { @@ -32,17 +33,19 @@ export class RunsLogCommand extends ApifyCommand { const run = await apifyClient.run(runId).get(); if (!run) { - error({ message: `Run with ID "${runId}" was not found on your account.`, stdout: true }); + this.logger.stdout.error(this.t(RunsLogCommandMessages.runNotFound, { runId })); return; } - info({ message: `Log for run with ID "${runId}":\n`, stdout: true }); + this.logger.stdout.info(this.t(RunsLogCommandMessages.logHeader, { runId })); try { await outputJobLog({ job: run, apifyClient }); } catch (err) { // This should never happen... - error({ message: `Failed to get log for run with ID "${runId}": ${(err as Error).message}` }); + this.logger.stderr.error( + this.t(RunsLogCommandMessages.logFetchFailed, { runId, message: (err as Error).message }), + ); } } } diff --git a/src/commands/runs/ls.ts b/src/commands/runs/ls.ts index e4808979d..b11a5a584 100644 --- a/src/commands/runs/ls.ts +++ b/src/commands/runs/ls.ts @@ -1,3 +1,4 @@ +import { RunsLsCommandMessages } from '#i18n/commands/runs/ls.js'; import chalk from 'chalk'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; @@ -6,13 +7,7 @@ import { Flags } from '../../lib/command-framework/flags.js'; import { prettyPrintStatus } from '../../lib/commands/pretty-print-status.js'; import { resolveActorContext } from '../../lib/commands/resolve-actor-context.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; -import { error, simpleLog } from '../../lib/outputs.js'; -import { - getLoggedClientOrThrow, - MultilineTimestampFormatter, - printJsonToStdout, - ShortDurationFormatter, -} from '../../lib/utils.js'; +import { getLoggedClientOrThrow, MultilineTimestampFormatter, ShortDurationFormatter } from '../../lib/utils.js'; const table = new ResponsiveTable({ allColumns: ['ID', 'Status', 'Results', 'Usage', 'Started At', 'Took', 'Build No.', 'Origin'], @@ -74,8 +69,6 @@ export class RunsLsCommand extends ApifyCommand { }), }; - static override enableJsonFlag = true; - async run() { const { desc, limit, offset, compact, json } = this.flags; const { actorId } = this.args; @@ -86,9 +79,7 @@ export class RunsLsCommand extends ApifyCommand { const ctx = await resolveActorContext({ providedActorNameOrId: actorId, client }); if (!ctx.valid) { - error({ - message: `${ctx.reason}. Please run this command in an Actor directory, or specify the Actor ID.`, - }); + this.logger.stderr.error(this.t(RunsLsCommandMessages.invalidActor, { reason: ctx.reason })); return; } @@ -96,14 +87,12 @@ export class RunsLsCommand extends ApifyCommand { const allRuns = await client.actor(ctx.id).runs().list({ desc, limit, offset }); if (json) { - printJsonToStdout(allRuns); + this.logger.stdout.json(allRuns); return; } if (!allRuns.items.length) { - simpleLog({ - message: 'There are no recent runs found for this Actor.', - }); + this.logger.stderr.log(this.t(RunsLsCommandMessages.noRuns)); return; } @@ -153,9 +142,6 @@ export class RunsLsCommand extends ApifyCommand { message.push(table.render(compact ? CompactMode.VeryCompact : CompactMode.WebLikeCompact)); - simpleLog({ - message: message.join('\n'), - stdout: true, - }); + this.logger.stdout.log(message.join('\n')); } } diff --git a/src/commands/runs/resurrect.ts b/src/commands/runs/resurrect.ts index a41c87300..527485e10 100644 --- a/src/commands/runs/resurrect.ts +++ b/src/commands/runs/resurrect.ts @@ -1,11 +1,11 @@ +import { RunsResurrectCommandMessages } from '#i18n/commands/runs/resurrect.js'; import type { ApifyApiError } from 'apify-client'; import { ACTOR_JOB_STATUSES } from '@apify/consts'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; -import { error, success } from '../../lib/outputs.js'; -import { getLoggedClientOrThrow, printJsonToStdout } from '../../lib/utils.js'; +import { getLoggedClientOrThrow } from '../../lib/utils.js'; const resurrectStatuses = [ ACTOR_JOB_STATUSES.SUCCEEDED, @@ -35,8 +35,6 @@ export class RunsResurrectCommand extends ApifyCommand { const run = await apifyClient.run(runId).get(); if (!run) { - error({ message: `Run with ID "${runId}" was not found on your account.` }); + this.logger.stderr.error(this.t(RunsRmCommandMessages.runNotFound, { runId })); return; } if (!deletableStatuses.includes(run.status as never)) { - error({ - message: `Run with ID "${runId}" cannot be deleted, as it is still running or in the process of aborting.`, - }); + this.logger.stderr.error(this.t(RunsRmCommandMessages.cannotDelete, { runId })); return; } @@ -73,9 +71,7 @@ export class RunsRmCommand extends ApifyCommand { }); if (!confirmedDelete) { - info({ - message: `Deletion of run "${runId}" was canceled.`, - }); + this.logger.stderr.info(this.t(RunsRmCommandMessages.deletionCanceled, { runId })); return; } @@ -83,12 +79,12 @@ export class RunsRmCommand extends ApifyCommand { try { await apifyClient.run(runId).delete(); - success({ - message: `Run with ID "${runId}" was deleted.`, - }); + this.logger.stderr.success(this.t(RunsRmCommandMessages.deleted, { runId })); } catch (err) { const casted = err as ApifyApiError; - error({ message: `Failed to delete run "${runId}".\n ${casted.message || casted}` }); + this.logger.stderr.error( + this.t(RunsRmCommandMessages.deleteFailed, { runId, message: String(casted.message || casted) }), + ); } } } diff --git a/src/commands/secrets/ls.ts b/src/commands/secrets/ls.ts index 76b5c1f97..c80399bb3 100644 --- a/src/commands/secrets/ls.ts +++ b/src/commands/secrets/ls.ts @@ -1,10 +1,9 @@ +import { SecretsLsCommandMessages } from '#i18n/commands/secrets/ls.js'; import chalk from 'chalk'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { CompactMode, ResponsiveTable } from '../../lib/commands/responsive-table.js'; -import { info, simpleLog } from '../../lib/outputs.js'; import { getSecretsFile } from '../../lib/secrets.js'; -import { printJsonToStdout } from '../../lib/utils.js'; const table = new ResponsiveTable({ allColumns: ['Secret Name'], @@ -28,8 +27,6 @@ export class SecretsLsCommand extends ApifyCommand { static override docsUrl = 'https://docs.apify.com/cli/docs/reference#apify-secrets-ls'; - static override enableJsonFlag = true; - async run() { const { json } = this.flags; @@ -37,15 +34,12 @@ export class SecretsLsCommand extends ApifyCommand { const secretKeys = Object.keys(secrets); if (json) { - printJsonToStdout({ keys: secretKeys }); + this.logger.stdout.json({ keys: secretKeys }); return; } if (secretKeys.length === 0) { - info({ - message: "You don't have any secrets stored locally. Use 'apify secrets add' to add a secret.", - stdout: true, - }); + this.logger.stdout.info(this.t(SecretsLsCommandMessages.noSecrets)); return; } @@ -56,9 +50,6 @@ export class SecretsLsCommand extends ApifyCommand { }); } - simpleLog({ - message: table.render(CompactMode.WebLikeCompact), - stdout: true, - }); + this.logger.stdout.log(table.render(CompactMode.WebLikeCompact)); } } diff --git a/src/commands/task/run.ts b/src/commands/task/run.ts index 5f3acdad4..3b78f416f 100644 --- a/src/commands/task/run.ts +++ b/src/commands/task/run.ts @@ -1,10 +1,9 @@ +import { TaskRunCommandMessages } from '#i18n/commands/task/run.js'; import type { ApifyClient, TaskStartOptions } from 'apify-client'; -import chalk from 'chalk'; import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { Args } from '../../lib/command-framework/args.js'; import { runActorOrTaskOnCloud, SharedRunOnCloudFlags } from '../../lib/commands/run-on-cloud.js'; -import { simpleLog } from '../../lib/outputs.js'; import { getLocalUserInfo, getLoggedClientOrThrow } from '../../lib/utils.js'; export class TaskRunCommand extends ApifyCommand { @@ -78,14 +77,12 @@ export class TaskRunCommand extends ApifyCommand { datasetUrl = `https://console.apify.com/storage/datasets/${yieldedRun.defaultDatasetId}`; } - simpleLog({ - message: [ - '', - `${chalk.blue('Export results')}: ${datasetUrl!}`, - `${chalk.blue('View on Apify Console')}: ${url!}`, - ].join('\n'), - stdout: true, - }); + this.logger.stdout.log( + this.t(TaskRunCommandMessages.resultLinks, { + datasetUrl: datasetUrl!, + url: url!, + }), + ); } private async resolveTaskId(client: ApifyClient, usernameOrId: string) { @@ -95,7 +92,7 @@ export class TaskRunCommand extends ApifyCommand { if (taskId?.includes('/')) { const task = await client.task(taskId).get(); if (!task) { - throw new Error(`Cannot find Task with ID '${taskId}' in your account.`); + throw new Error(this.t(TaskRunCommandMessages.taskNotFoundById, { taskId })); } return { @@ -111,7 +108,7 @@ export class TaskRunCommand extends ApifyCommand { const task = await client.task(`${usernameOrId}/${taskId.toLowerCase()}`).get(); if (!task) { - throw new Error(`Cannot find Task with name '${taskId}' in your account.`); + throw new Error(this.t(TaskRunCommandMessages.taskNotFoundByName, { taskId })); } return { @@ -122,6 +119,6 @@ export class TaskRunCommand extends ApifyCommand { }; } - throw new Error('Please provide a valid Task ID or name.'); + throw new Error(this.t(TaskRunCommandMessages.invalidTaskIdentifier)); } } diff --git a/src/commands/telemetry/disable.ts b/src/commands/telemetry/disable.ts index 0ebc7586a..bc2edcdc5 100644 --- a/src/commands/telemetry/disable.ts +++ b/src/commands/telemetry/disable.ts @@ -1,6 +1,7 @@ +import { TelemetryDisableCommandMessages } from '#i18n/commands/telemetry/disable.js'; + import { ApifyCommand } from '../../lib/command-framework/apify-command.js'; import { updateTelemetryEnabled, useTelemetryState } from '../../lib/hooks/telemetry/useTelemetryState.js'; -import { info, success } from '../../lib/outputs.js'; export class TelemetryDisableCommand extends ApifyCommand { static override name = 'disable' as const; @@ -22,9 +23,9 @@ export class TelemetryDisableCommand extends ApifyCommand { static override name = 'enable' as const; @@ -20,11 +21,11 @@ export class TelemetryEnableCommand extends ApifyCommand { @@ -66,10 +67,11 @@ When no path is provided, validates all schemas found in '${LOCAL_CONFIG_PATH}': await readAndValidateInputSchema({ forcePath, cwd: process.cwd(), - getMessage: (path) => `Validating input schema at ${path ?? forcePath}`, + getMessage: (path) => + this.t(ValidateSchemaCommandMessages.validatingInputSchemaAtPath, { path: path ?? forcePath }), }); - success({ message: 'Input schema is valid.' }); + this.logger.stderr.success(this.t(ValidateSchemaCommandMessages.inputSchemaValid)); } private async validateAllSchemas() { @@ -86,17 +88,28 @@ When no path is provided, validates all schemas found in '${LOCAL_CONFIG_PATH}': if (inputSchema) { foundAny = true; - const location = inputSchemaPath ? `at ${inputSchemaPath}` : `embedded in '${LOCAL_CONFIG_PATH}'`; - info({ message: `Validating input schema ${location}` }); + if (inputSchemaPath) { + this.logger.stderr.info( + this.t(ValidateSchemaCommandMessages.validatingInputSchemaAtLocation, { + location: inputSchemaPath, + }), + ); + } else { + this.logger.stderr.info( + this.t(ValidateSchemaCommandMessages.validatingInputSchemaEmbedded, { + configPath: LOCAL_CONFIG_PATH, + }), + ); + } const validator = new Ajv2019({ strict: false }); validateInputSchema(validator, inputSchema); - success({ message: 'Input schema is valid.' }); + this.logger.stderr.success(this.t(ValidateSchemaCommandMessages.inputSchemaValid)); } } catch (err) { foundAny = true; hasErrors = true; - error({ message: (err as Error).message }); + this.logger.stderr.error((err as Error).message); } // Storage schemas (Dataset, Output, Key-Value Store) @@ -133,25 +146,34 @@ When no path is provided, validates all schemas found in '${LOCAL_CONFIG_PATH}': if (result) { foundAny = true; - const location = result.schemaPath - ? `at ${result.schemaPath}` - : `embedded in '${LOCAL_CONFIG_PATH}'`; - info({ message: `Validating ${label} schema ${location}` }); + if (result.schemaPath) { + this.logger.stderr.info( + this.t(ValidateSchemaCommandMessages.validatingNamedSchemaAtLocation, { + label, + location: result.schemaPath, + }), + ); + } else { + this.logger.stderr.info( + this.t(ValidateSchemaCommandMessages.validatingNamedSchemaEmbedded, { + label, + configPath: LOCAL_CONFIG_PATH, + }), + ); + } validate(result.schema); - success({ message: `${label} schema is valid.` }); + this.logger.stderr.success(this.t(ValidateSchemaCommandMessages.namedSchemaValid, { label })); } } catch (err) { foundAny = true; hasErrors = true; - error({ message: (err as Error).message }); + this.logger.stderr.error((err as Error).message); } } if (!foundAny) { - throw new Error( - `No schemas found. Make sure '${LOCAL_CONFIG_PATH}' exists and defines at least one schema.`, - ); + throw new Error(this.t(ValidateSchemaCommandMessages.noSchemasFound, { configPath: LOCAL_CONFIG_PATH })); } if (hasErrors) { diff --git a/src/entrypoints/_shared.ts b/src/entrypoints/_shared.ts index 501469d7d..c7c0afd82 100644 --- a/src/entrypoints/_shared.ts +++ b/src/entrypoints/_shared.ts @@ -1,6 +1,7 @@ import process from 'node:process'; import { parseArgs } from 'node:util'; +import { sharedEntrypointMessages } from '#i18n/entrypoints/_shared.js'; import chalk from 'chalk'; import { satisfies } from 'semver'; @@ -14,8 +15,8 @@ import { SUPPORTED_NODEJS_VERSION } from '../lib/consts.js'; import { useCLIMetadata } from '../lib/hooks/useCLIMetadata.js'; import { shouldSkipVersionCheck } from '../lib/hooks/useCLIVersionCheck.js'; import { useCommandSuggestions } from '../lib/hooks/useCommandSuggestions.js'; -import { error } from '../lib/outputs.js'; -import { cliDebugPrint } from '../lib/utils/cliDebugPrint.js'; +import { t } from '../lib/i18n/index.js'; +import { logger } from '../lib/logger.js'; export const cachedStdinInput = await readStdin(); @@ -29,9 +30,13 @@ export function processVersionCheck(cliName: string) { } if (!satisfies(process.version, SUPPORTED_NODEJS_VERSION)) { - error({ - message: `${cliName} CLI requires Node.js version ${SUPPORTED_NODEJS_VERSION}. Your current version is ${process.version}.`, - }); + logger.stderr.error( + t(sharedEntrypointMessages.unsupportedNodeVersion, { + cliName, + supportedRange: SUPPORTED_NODEJS_VERSION, + currentVersion: process.version, + }), + ); process.exit(1); } @@ -73,14 +78,14 @@ type TopLevelValues = ReturnType< function handleCommandNotFound(commandName: string): never { const closestMatches = useCommandSuggestions(String(commandName)); - let message = chalk.gray(`Command ${chalk.whiteBright(commandName)} not found`); - - if (closestMatches.length) { - message += '\n '; - message += chalk.gray(`Did you mean: ${closestMatches.map((cmd) => chalk.whiteBright(cmd)).join(', ')}?`); - } + const message = closestMatches.length + ? t(sharedEntrypointMessages.commandNotFoundWithSuggestions, { + commandName, + suggestions: closestMatches.map((cmd) => chalk.whiteBright(cmd)).join(', '), + }) + : t(sharedEntrypointMessages.commandNotFound, { commandName }); - error({ message }); + logger.stderr.error(message); process.exit(1); } @@ -93,13 +98,13 @@ async function runVersionCheck(entrypoint: string, maybeCommandName?: string) { const checkVersionsCommandIds = [UpgradeCommand.name, ...(UpgradeCommand.aliases ?? [])]; if (checkVersionsCommandIds.some((id) => maybeCommandName === id)) { - cliDebugPrint('[VersionCheckMiddleware]', 'upgrade command detected, skipping version check'); + logger.debug('[VersionCheckMiddleware]', 'upgrade command detected, skipping version check'); // Skip running the middleware return; } if (shouldSkipVersionCheck()) { - cliDebugPrint('[VersionCheckMiddleware]', 'skipping version check because APIFY_CLI_SKIP_UPDATE_CHECK is set'); + logger.debug('[VersionCheckMiddleware]', 'skipping version check because APIFY_CLI_SKIP_UPDATE_CHECK is set'); // If the user has configured the `APIFY_CLI_SKIP_UPDATE_CHECK` env variable then skip the check. return; } @@ -109,7 +114,7 @@ async function runVersionCheck(entrypoint: string, maybeCommandName?: string) { } export async function runCLI(entrypoint: string) { - cliDebugPrint('CLIMetadata', { + logger.debug('CLIMetadata', { ...cliMetadata, fullVersionString: cliMetadata.fullVersionString, argv: process.argv, @@ -119,7 +124,7 @@ export async function runCLI(entrypoint: string) { const startingArgs = process.argv.slice(2); - cliDebugPrint('ProcessArgv', startingArgs); + logger.debug('ProcessArgv', startingArgs); const startingResult = parseArgs({ allowPositionals: true, @@ -146,7 +151,7 @@ export async function runCLI(entrypoint: string) { // MIDDLEWARE END // - cliDebugPrint('TopLevelOptions', startingResult); + logger.debug('TopLevelOptions', startingResult); const commandName = startingResult.positionals[0]; @@ -213,17 +218,17 @@ export async function runCLI(entrypoint: string) { const rebuiltArgs: string[] = [...startingArgs]; const commandNameIndex = rebuiltArgs.indexOf(commandName); - cliDebugPrint('CommandNameIndex', commandNameIndex); + logger.debug('CommandNameIndex', commandNameIndex); rebuiltArgs.splice(commandNameIndex, 1); if (hasSubcommand) { const subcommandNameIndex = rebuiltArgs.indexOf(maybeSubcommandName); - cliDebugPrint('SubcommandNameIndex', subcommandNameIndex); + logger.debug('SubcommandNameIndex', subcommandNameIndex); rebuiltArgs.splice(subcommandNameIndex, 1); } - cliDebugPrint('RebuiltArgs', rebuiltArgs); - cliDebugPrint('CommandToRun', FinalCommand); + logger.debug('RebuiltArgs', rebuiltArgs); + logger.debug('CommandToRun', FinalCommand); const instance = new FinalCommand( entrypoint, @@ -235,7 +240,7 @@ export async function runCLI(entrypoint: string) { // eslint-disable-next-line dot-notation const parserOptions = instance['_buildParseArgsOption'](); - cliDebugPrint('ParserOptionsForCommand', parserOptions); + logger.debug('ParserOptionsForCommand', parserOptions); try { const commandResult = parseArgs({ @@ -246,11 +251,11 @@ export async function runCLI(entrypoint: string) { // eslint-disable-next-line dot-notation await instance['_run'](commandResult); - cliDebugPrint('CommandArgsResult', commandResult); + logger.debug('CommandArgsResult', commandResult); } catch (err) { const commandError = CommandError.into(err, FinalCommand); - error({ message: commandError.getPrettyMessage() }); + logger.stderr.error(commandError.getPrettyMessage()); process.exit(1); } diff --git a/src/i18n/commands/actor/calculate-memory.ts b/src/i18n/commands/actor/calculate-memory.ts new file mode 100644 index 000000000..e4c38b329 --- /dev/null +++ b/src/i18n/commands/actor/calculate-memory.ts @@ -0,0 +1,35 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorCalculateMemoryCommandMessages = defineMessages({ + en: { + missingMemoryExpression: { + markdown: + 'No memory-calculation expression found. Provide it via the `--default-memory-mbytes` flag or define `defaultMemoryMbytes` in actor.json.', + json: () => ({ + code: 'MISSING_MEMORY_EXPRESSION', + hint: '--default-memory-mbytes OR define in actor.json', + }), + }, + evaluatingExpression: { + markdown: 'Evaluating memory expression: {memoryExpression}', + // Null won't print out anything in JSON mode + json: () => null, + }, + calculatedMemory: { + markdown: 'Calculated memory: {result} MB', + json: (props: { expression: string; resultMb: number }) => ({ ...props, code: 'CALCULATED_MEMORY' }), + }, + calculationFailed: { + markdown: 'Memory calculation failed: {message}', + json: (message: string) => ({ code: 'CALCULATION_FAILED', message }), + }, + configLoadError: { + markdown: '{message}', + json: (message: string) => ({ code: 'CONFIG_LOAD_ERROR', message }), + }, + configLoadErrorWithCause: { + markdown: '{message}\n {cause}', + json: (message: string, cause: string) => ({ code: 'CONFIG_LOAD_ERROR_WITH_CAUSE', message, cause }), + }, + }, +}); diff --git a/src/i18n/commands/actor/charge.ts b/src/i18n/commands/actor/charge.ts new file mode 100644 index 000000000..d74e7412b --- /dev/null +++ b/src/i18n/commands/actor/charge.ts @@ -0,0 +1,50 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export interface ActorChargeCommandMessagesCommonProps { + count: number; + eventName: string; + idempotencyKey: string; +} + +export const ActorChargeCommandMessages = defineMessages({ + en: { + noPlatformDetected: { + markdown: + 'No platform detected: would charge `{count,number}` events of type "{eventName}" with idempotency key "{idempotencyKey}".', + json: (props: ActorChargeCommandMessagesCommonProps) => ({ ...props, code: 'NO_PLATFORM_DETECTED' }), + }, + ppeTestMode: { + markdown: + 'PPE test mode: would charge `{count,number}` events of type "{eventName}" with idempotency key "{idempotencyKey}".', + json: (props: ActorChargeCommandMessagesCommonProps) => ({ ...props, code: 'PPE_TEST_MODE' }), + }, + missingApifyToken: { + markdown: 'Apify token is not set. Please set it using the environment variable APIFY_TOKEN.', + json: () => ({ + code: 'MISSING_APIFY_TOKEN', + hint: 'login with `apify auth login` or set APIFY_TOKEN environment variable', + }), + }, + notInRunningActor: { + markdown: 'Charge command must be executed in a running Actor. Run ID not found.', + json: () => ({ code: 'NO_RUN_ID_FOUND', hint: 'run the command in a running Actor' }), + }, + invalidPricingModel: { + markdown: 'Charge command can only be used with pay-per-event pricing model.', + json: (currentPricingModel: string) => ({ + code: 'INVALID_PRICING_MODEL', + currentPricingModel, + expectedPricingModel: 'PAY_PER_EVENT', + hint: 'can be used only within pay-per-event Actor', + }), + }, + charging: { + markdown: + 'Charging {count,number} events of type "{eventName}" with idempotency key "{idempotencyKey}" (runId: {runId}).', + json: (props: ActorChargeCommandMessagesCommonProps & { runId: string }) => ({ + ...props, + code: 'CHARGING', + }), + }, + }, +}); diff --git a/src/i18n/commands/actor/generate-schema-types.ts b/src/i18n/commands/actor/generate-schema-types.ts new file mode 100644 index 000000000..d80f58090 --- /dev/null +++ b/src/i18n/commands/actor/generate-schema-types.ts @@ -0,0 +1,58 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorGenerateSchemaTypesCommandMessages = defineMessages({ + en: { + generatingFromInputSchemaAt: { + markdown: "Generating types from input schema at ''{schemaPath}''", + json: () => null, + }, + generatingFromInputSchemaEmbedded: { + markdown: "Generating types from input schema embedded in ''{configPath}''", + json: () => null, + }, + generatedTypesWritten: { + markdown: 'Generated types written to {outputFile}', + json: () => null, + }, + experimentalDatasetAt: { + markdown: '[experimental] Generating types from Dataset schema at {schemaPath}', + json: () => null, + }, + experimentalDatasetEmbedded: { + markdown: "[experimental] Generating types from Dataset schema embedded in ''{configPath}''", + json: () => null, + }, + datasetHasNoFields: { + markdown: 'Dataset schema has no fields defined, skipping type generation.', + json: () => null, + }, + experimentalOutputAt: { + markdown: '[experimental] Generating types from Output schema at {schemaPath}', + json: () => null, + }, + experimentalOutputEmbedded: { + markdown: "[experimental] Generating types from Output schema embedded in ''{configPath}''", + json: () => null, + }, + outputHasNoProperties: { + markdown: 'Output schema has no properties defined, skipping type generation.', + json: () => null, + }, + experimentalKvsAt: { + markdown: '[experimental] Generating types from Key-Value Store schema at {schemaPath}', + json: () => null, + }, + experimentalKvsEmbedded: { + markdown: "[experimental] Generating types from Key-Value Store schema embedded in ''{configPath}''", + json: () => null, + }, + kvsHasNoCollections: { + markdown: 'Key-Value Store schema has no collections with JSON schemas, skipping type generation.', + json: () => null, + }, + schemaGenerationFailed: { + markdown: 'Failed to generate types for {label} schema: {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/actor/get-public-url.ts b/src/i18n/commands/actor/get-public-url.ts new file mode 100644 index 000000000..a6ff555e3 --- /dev/null +++ b/src/i18n/commands/actor/get-public-url.ts @@ -0,0 +1,23 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorGetPublicUrlCommandMessages = defineMessages({ + en: { + notImplementedLocally: { + markdown: 'get-public-url is not yet implemented for local development', + json: () => ({ code: 'NOT_SUPPORTED_LOCALLY' }), + }, + missingEnvVar: { + markdown: 'Missing environment variable: {envVar}. Please set it before running the command.', + json: (envVar: string) => ({ code: 'MISSING_ENV_VAR', environmentVariable: envVar }), + }, + storeNotFound: { + markdown: + "Key-Value store with ID ''{storeId}'' was not found. Ensure the store exists and that the correct ID is set in `{envVar}`.", + json: ({ storeId, envVar }: { storeId: string; envVar: string }) => ({ + code: 'KEY_VALUE_STORE_NOT_FOUND', + keyValueStoreId: storeId, + environmentVariable: envVar, + }), + }, + }, +}); diff --git a/src/i18n/commands/actor/push-data.ts b/src/i18n/commands/actor/push-data.ts new file mode 100644 index 000000000..a94d6ae0e --- /dev/null +++ b/src/i18n/commands/actor/push-data.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorPushDataCommandMessages = defineMessages({ + en: { + noItemProvided: { + markdown: 'No item was provided. Provide an object or an array of objects to this command', + json: () => ({ code: 'NO_ITEM_PROVIDED', hint: 'pass JSON object or array of objects' }), + }, + failedToParseJson: { + markdown: 'Failed to parse data as JSON string: {message}', + json: (message: string) => ({ code: 'FAILED_TO_PARSE_JSON', message }), + }, + }, +}); diff --git a/src/i18n/commands/actors/call.ts b/src/i18n/commands/actors/call.ts new file mode 100644 index 000000000..69619905f --- /dev/null +++ b/src/i18n/commands/actors/call.ts @@ -0,0 +1,73 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorsCallCommandMessages = defineMessages({ + en: { + conflictingJsonAndOutputDataset: { + markdown: 'You cannot use both the --json and --output-dataset flags when running this command.', + json: () => null, + }, + runStartedHeader: { + markdown: (md, colors) => md(`${colors.yellow('Started')}: {startedAt}`), + json: () => null, + }, + containerUrlLine: { + markdown: (md, colors) => md(`${colors.yellow('Container URL')}: ${colors.blue('{containerUrl}')}`), + json: () => null, + }, + buildLine: { + markdown: (md, colors) => + md(`${colors.yellow('Build')}: ${colors.cyan('{buildNumber}')} ({buildTag}){actorVersionInfo}`), + json: () => null, + }, + buildTagNa: { + markdown: (md, colors) => md(colors.gray('N/A')), + json: () => null, + }, + buildTagValue: { + markdown: (md, colors) => md(colors.yellow('{tag}')), + json: () => null, + }, + actorVersionInfo: { + markdown: (md, colors) => + md( + ` | ${colors.gray('Actor version:')} ${colors.cyan('{versionNumber}')} (${colors.yellow('{buildTag}')})`, + ), + json: () => null, + }, + timeoutLine: { + markdown: (md, colors) => md(`${colors.yellow('Timeout')}: {timeoutSecs} seconds`), + json: () => null, + }, + memoryLine: { + markdown: (md, colors) => md(`${colors.yellow('Memory')}: {memoryMbytes,number} MB`), + json: () => null, + }, + viewOnConsoleLine: { + markdown: (md, colors) => md(`${colors.blue('View on Apify Console')}: {url}`), + json: () => null, + }, + resultLinks: { + markdown: (md, colors) => + md(`\n${colors.blue('Export results')}: {datasetUrl}\n${colors.blue('View on Apify Console')}: {url}`), + json: () => null, + }, + actorNotFoundByFullId: { + markdown: 'Cannot find Actor with ID {actorId} in your account.', + json: () => null, + }, + actorNotFoundByNameOrId: { + markdown: 'Cannot find Actor with name or ID {actorId} in your account.', + json: () => null, + }, + actorNotFoundFromLocalConfig: { + markdown: + 'Cannot find Actor with ID {actorId} in your account. Call "apify push" to push this Actor to Apify platform.', + json: () => null, + }, + missingActorIdentifier: { + markdown: + 'Please provide an Actor ID or name, or run this command from a directory with a valid Apify Actor.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/actors/info.ts b/src/i18n/commands/actors/info.ts new file mode 100644 index 000000000..981dbf862 --- /dev/null +++ b/src/i18n/commands/actors/info.ts @@ -0,0 +1,108 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorsInfoCommandMessages = defineMessages({ + en: { + invalidActorContext: { + markdown: '{reason}. Please specify the Actor ID.', + json: () => null, + }, + noReadme: { + markdown: 'No README found for this Actor.', + json: () => null, + }, + noInputSchema: { + markdown: 'No input schema found for this Actor.', + json: () => null, + }, + header: { + markdown: (md, colors) => + md(`Information about Actor ${colors.yellow('{fullName}')} (${colors.gray('{id}')})\n`), + json: () => null, + }, + titleLine: { + markdown: (md, colors) => md(`${colors.yellow('Title:')} ${colors.bold('{title}')}`), + json: () => null, + }, + descriptionLine: { + markdown: (md, colors) => md(`${colors.yellow('Description:')} {description}`), + json: () => null, + }, + createdUpdatedLine: { + markdown: (md, colors) => + md( + `${colors.yellow('Created at:')} ${colors.cyan('{createdAt}')} ${colors.gray('|')} ${colors.yellow('Updated at:')} ${colors.cyan('{modifiedAt}')}`, + ), + json: () => null, + }, + madeByLine: { + markdown: (md, colors) => md(`${colors.yellow('Made by:')} ${colors.cyan('{name}')}`), + json: () => null, + }, + maintainedByApifyBadge: { + markdown: (md, colors) => md(colors.bgGray('Maintained by Apify')), + json: () => null, + }, + actorIsPublic: { + markdown: (md, colors) => md(`${colors.yellow('Actor is')} ${colors.green('PUBLIC')}`), + json: () => null, + }, + actorIsPrivate: { + markdown: (md, colors) => md(`${colors.yellow('Actor is')} ${colors.cyan('PRIVATE')}`), + json: () => null, + }, + actorIsDeprecated: { + markdown: (md, colors) => md(`${colors.yellow('Actor is')} ${colors.red('DEPRECATED')}`), + json: () => null, + }, + pricingFlatPerMonth: { + markdown: (md, colors) => md(`${colors.yellow('Pricing information:')} ${colors.bgGray(`{priceLabel}`)}`), + json: () => null, + }, + pricingTrialDuration: { + markdown: (md, colors) => md(` ${colors.yellow('Trial duration:')} ${colors.bold('{duration}')}`), + json: () => null, + }, + pricingPerDatasetItem: { + markdown: (md, colors) => md(`${colors.yellow('Pricing information:')} ${colors.bgGray(`{priceLabel}`)}`), + json: () => null, + }, + pricingPayPerEvent: { + markdown: (md, colors) => md(`${colors.yellow('Pricing information:')} ${colors.bgGray('Pay per event')}`), + json: () => null, + }, + pricingFree: { + markdown: (md, colors) => md(`${colors.yellow('Pricing information:')} ${colors.bgGray('Pay for usage')}`), + json: () => null, + }, + pricingUnknown: { + markdown: (md, colors) => + md( + `${colors.yellow('Pricing information:')} ${colors.bgGray(`Unknown pricing model (${colors.yellow('{pricingModel}')})`)}`, + ), + json: () => null, + }, + seoHeader: { + markdown: (md, colors) => md(colors.yellow('SEO information:')), + json: () => null, + }, + seoTitleLine: { + markdown: (md, colors) => md(` ${colors.yellow('Title:')} {seoTitle}`), + json: () => null, + }, + seoDescriptionLine: { + markdown: (md, colors) => md(` ${colors.yellow('Description:')} {seoDescription}`), + json: () => null, + }, + buildsHeader: { + markdown: (md, colors) => md(colors.yellow('Builds:')), + json: () => null, + }, + buildEntry: { + markdown: (md, colors) => + md( + ` ${colors.yellow('-')} ${colors.cyan('{buildNumber}')} ${colors.gray('/')} ${colors.yellow('{tag}')}`, + ), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/actors/ls.ts b/src/i18n/commands/actors/ls.ts new file mode 100644 index 000000000..1a02b0a80 --- /dev/null +++ b/src/i18n/commands/actors/ls.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorsLsCommandMessages = defineMessages({ + en: { + noActorsOwned: { + markdown: "You don't have any Actors yet!", + json: () => null, + }, + noRecentActors: { + markdown: 'There are no recent Actors used by you.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/actors/pull.ts b/src/i18n/commands/actors/pull.ts new file mode 100644 index 000000000..014d02352 --- /dev/null +++ b/src/i18n/commands/actors/pull.ts @@ -0,0 +1,50 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorsPullCommandMessages = defineMessages({ + en: { + actorConfigError: { + markdown: '{message}', + json: () => null, + }, + cannotFindActorInDirectory: { + markdown: 'Cannot find Actor in this directory.', + json: () => null, + }, + cannotFindActorByIdOrName: { + markdown: 'Cannot find Actor with ID/name {actorId} in your account.', + json: () => null, + }, + missingSourceCodeAccess: { + markdown: 'You cannot pull source code of this Actor because you do not have permission to do so.', + json: () => null, + }, + actorHasNoVersions: { + markdown: 'Actor {actorId} has no versions.', + json: () => null, + }, + versionNotFound: { + markdown: 'Cannot find version {version} of Actor {actorId}.', + json: () => null, + }, + directoryNotEmpty: { + markdown: 'Directory {dirpath} is not empty. Please empty it or choose another directory.', + json: () => null, + }, + gitPullFailed: { + markdown: 'Failed to pull Actor from {gitRepoUrl}. {message}', + json: () => null, + }, + unknownSourceType: { + markdown: 'Unknown source type: {sourceType}', + json: () => null, + }, + actorUpdatedAt: { + markdown: 'Actor {name} updated at {dirpath}/', + json: () => null, + }, + pulledTo: { + markdown: 'Pulled to {dirpath}/', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/actors/push.ts b/src/i18n/commands/actors/push.ts new file mode 100644 index 000000000..cf671f8ea --- /dev/null +++ b/src/i18n/commands/actors/push.ts @@ -0,0 +1,92 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorsPushCommandMessages = defineMessages({ + en: { + noActorInDirectory: { + markdown: 'You need to call this command from a folder that has an Actor in it!', + json: () => null, + }, + noValidActorFound: { + markdown: + 'A valid Actor could not be found in the current directory. Please make sure you are in the correct directory.\nYou can also turn this directory into an Actor by running `apify init`.', + json: () => null, + }, + actorConfigError: { + markdown: '{message}', + json: () => null, + }, + cannotFindActorById: { + markdown: 'Cannot find Actor with ID {actorId} in your account.', + json: () => null, + }, + createdActor: { + markdown: 'Created Actor with name {name} on Apify.', + json: () => null, + }, + deployingActor: { + markdown: 'Deploying Actor {name} to Apify.', + json: () => null, + }, + remoteModifiedNewer: { + markdown: + 'Actor with identifier "{identifier}" is already on the platform and was modified there since modified locally.\nSkipping push. Use --force to override.', + json: () => null, + }, + zippingActorFiles: { + markdown: 'Zipping Actor files', + json: () => null, + }, + updatedVersion: { + markdown: 'Updated version {version} for Actor {name}.', + json: () => null, + }, + createdVersion: { + markdown: 'Created version {version} for Actor {name}.', + json: () => null, + }, + standbyToggled: { + markdown: '{action} standby mode for Actor {name}.', + json: () => null, + }, + buildingActor: { + markdown: 'Building Actor {name}', + json: () => null, + }, + cannotGetLog: { + markdown: 'Can not get log:', + json: () => null, + }, + actorBuildDetailLabel: { + markdown: 'Actor build detail', + json: () => null, + }, + actorDetailLabel: { + markdown: 'Actor detail', + json: () => null, + }, + deployedSuccess: { + markdown: 'Actor was deployed to Apify cloud and built there.', + json: () => null, + }, + buildWaitingForAllocation: { + markdown: 'Build is waiting for allocation.', + json: () => null, + }, + buildStillRunning: { + markdown: 'Build is still running.', + json: () => null, + }, + buildAborted: { + markdown: 'Build was aborted!', + json: () => null, + }, + buildTimedOut: { + markdown: 'Build timed out!', + json: () => null, + }, + buildFailed: { + markdown: 'Build failed!', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/actors/rm.ts b/src/i18n/commands/actors/rm.ts new file mode 100644 index 000000000..443557ffd --- /dev/null +++ b/src/i18n/commands/actors/rm.ts @@ -0,0 +1,22 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorsRmCommandMessages = defineMessages({ + en: { + actorNotFound: { + markdown: 'Actor with ID "{actorId}" was not found on your account.', + json: () => null, + }, + deletionCanceled: { + markdown: 'Deletion of Actor "{actorId}" was canceled.', + json: () => null, + }, + actorDeleted: { + markdown: 'Actor with ID "{actorId}" was deleted.', + json: () => null, + }, + deleteFailed: { + markdown: 'Failed to delete Actor "{actorId}".\n {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/actors/search.ts b/src/i18n/commands/actors/search.ts new file mode 100644 index 000000000..80196433b --- /dev/null +++ b/src/i18n/commands/actors/search.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorsSearchCommandMessages = defineMessages({ + en: { + searchFailed: { + markdown: 'Failed to search Apify Store: {message}', + json: () => null, + }, + noResults: { + markdown: 'No Actors found matching your search.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/actors/start.ts b/src/i18n/commands/actors/start.ts new file mode 100644 index 000000000..dcffd5be4 --- /dev/null +++ b/src/i18n/commands/actors/start.ts @@ -0,0 +1,52 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const ActorsStartCommandMessages = defineMessages({ + en: { + callingActor: { + markdown: (md, colors) => + md(`${colors.gray('Run:')} Calling Actor {userFriendlyId} (${colors.gray('{actorId}')})`), + json: () => null, + }, + runStartedHeader: { + markdown: (md, colors) => md(`${colors.yellow('Started')}: {startedAt}`), + json: () => null, + }, + containerUrlLine: { + markdown: (md, colors) => md(`${colors.yellow('Container URL')}: ${colors.blue('{containerUrl}')}`), + json: () => null, + }, + buildLine: { + markdown: (md, colors) => + md(`${colors.yellow('Build')}: ${colors.cyan('{buildNumber}')} ({buildTag}){actorVersionInfo}`), + json: () => null, + }, + buildTagNa: { + markdown: (md, colors) => md(colors.gray('N/A')), + json: () => null, + }, + buildTagValue: { + markdown: (md, colors) => md(colors.yellow('{tag}')), + json: () => null, + }, + actorVersionInfo: { + markdown: (md, colors) => + md( + ` | ${colors.gray('Actor version:')} ${colors.cyan('{versionNumber}')} (${colors.yellow('{buildTag}')})`, + ), + json: () => null, + }, + timeoutLine: { + markdown: (md, colors) => md(`${colors.yellow('Timeout')}: {timeoutSecs} seconds`), + json: () => null, + }, + memoryLine: { + markdown: (md, colors) => md(`${colors.yellow('Memory')}: {memoryMbytes,number} MB`), + json: () => null, + }, + resultLinks: { + markdown: (md, colors) => + md(`\n${colors.blue('Export results')}: {datasetUrl}\n${colors.blue('View on Apify Console')}: {url}`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/api.ts b/src/i18n/commands/api.ts new file mode 100644 index 000000000..d596f0838 --- /dev/null +++ b/src/i18n/commands/api.ts @@ -0,0 +1,66 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const ApiCommandMessages = defineMessages({ + en: { + paramsInvalidJson: { + markdown: `Invalid JSON in --params flag. Please provide a valid JSON object, e.g. ''{example}''.`, + json: () => null, + }, + paramsNotObject: { + markdown: `--params must be a JSON object (e.g. ''{example}'').`, + json: () => null, + }, + paramsNotScalar: { + markdown: + '--params value for "{key}" must be a scalar (string, number, or boolean), got {kind}. Query parameters cannot contain nested objects or arrays.', + json: () => null, + }, + headerInvalidJson: { + markdown: `Invalid JSON in --header flag. Provide a JSON object like ''{example}''.`, + json: () => null, + }, + headerJsonNotObject: { + markdown: '--header JSON must be an object mapping header names to string values.', + json: () => null, + }, + headerValueNotString: { + markdown: '--header value for "{key}" must be a string, got {kind}.', + json: () => null, + }, + headerInvalidFormat: { + markdown: 'Header must be in "key:value" format, or a JSON object for multiple headers.', + json: () => null, + }, + conflictingMethods: { + markdown: + 'Conflicting HTTP methods: positional "{positionalMethod}" vs --method "{explicitMethodFlag}". Please specify the method only once.', + json: () => null, + }, + methodCannotHaveBody: { + markdown: + 'HTTP {method} requests cannot have a request body. Use a different method (e.g. POST, PUT, PATCH) or omit --body.', + json: () => null, + }, + bodyInvalidJson: { + markdown: 'Invalid JSON in --body flag. Please provide a valid JSON string.', + json: () => null, + }, + responseStatus: { + markdown: '{status,number} {statusText}', + json: () => null, + }, + listEndpointsHint: { + markdown: (md, colors) => + md(`\nRun ${colors.cyan('apify api --list-endpoints')} to see all available Apify API endpoints.`), + json: () => null, + }, + specDownloadFailedFetch: { + markdown: 'Failed to download the Apify OpenAPI spec from {url}: {message}', + json: () => null, + }, + specDownloadFailedStatus: { + markdown: 'Failed to download the Apify OpenAPI spec from {url}: {status,number} {statusText}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/auth/login.ts b/src/i18n/commands/auth/login.ts new file mode 100644 index 000000000..bc1aebdc0 --- /dev/null +++ b/src/i18n/commands/auth/login.ts @@ -0,0 +1,41 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const AuthLoginCommandMessages = defineMessages({ + en: { + loggedInSuccess: { + markdown: (md, colors) => + md( + `You are logged in to Apify as {userName}. ${colors.gray('Your token is stored at {authFilePath}.')}`, + ), + json: () => null, + }, + invalidTokenLogin: { + markdown: 'Login to Apify failed, the provided API token is not valid.', + json: () => null, + }, + requestMissingApiToken: { + markdown: 'Request did not contain API token', + json: () => null, + }, + loginFailedWithError: { + markdown: 'Login to Apify failed with error: {message}', + json: () => null, + }, + loginFailedWindowClosed: { + markdown: 'Login to Apify failed, the console window was closed.', + json: () => null, + }, + loginFailedActionCanceled: { + markdown: 'Login to Apify failed, the action was canceled in the Apify Console.', + json: () => null, + }, + loginFailed: { + markdown: 'Login to Apify failed.', + json: () => null, + }, + openingConsole: { + markdown: 'Opening Apify Console at "{consoleHref}"...', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/auth/logout.ts b/src/i18n/commands/auth/logout.ts new file mode 100644 index 000000000..07c0dac63 --- /dev/null +++ b/src/i18n/commands/auth/logout.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const AuthLogoutCommandMessages = defineMessages({ + en: { + loggedOut: { + markdown: 'You are logged out from your Apify account.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/builds/add-tag.ts b/src/i18n/commands/builds/add-tag.ts new file mode 100644 index 000000000..5bd2d4399 --- /dev/null +++ b/src/i18n/commands/builds/add-tag.ts @@ -0,0 +1,40 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const BuildsAddTagCommandMessages = defineMessages({ + en: { + buildNotFound: { + markdown: 'Build with ID "{buildId}" was not found on your account.', + json: () => null, + }, + buildNotSucceeded: { + markdown: 'Build with ID "{buildId}" has status "{status}". Only successful builds can be tagged.', + json: () => null, + }, + actorNotFound: { + markdown: 'Actor with ID "{actorId}" was not found.', + json: () => null, + }, + tagAlreadyPointsToBuild: { + markdown: 'Build "{buildId}" is already tagged as "{tag}".', + json: () => null, + }, + tagAddedWithPrevious: { + markdown: (md, colors) => + md( + `Tag "${colors.yellow('{tag}')}" added to build ${colors.gray('{buildNumber}')} (${colors.gray('{buildId}')}) (previously pointed to build ${colors.gray('{previousBuildNumber}')})`, + ), + json: () => null, + }, + tagAdded: { + markdown: (md, colors) => + md( + `Tag "${colors.yellow('{tag}')}" added to build ${colors.gray('{buildNumber}')} (${colors.gray('{buildId}')})`, + ), + json: () => null, + }, + tagAddFailed: { + markdown: 'Failed to add tag "{tag}" to build "{buildId}".\n {errorMessage}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/builds/create.ts b/src/i18n/commands/builds/create.ts new file mode 100644 index 000000000..8739a30b7 --- /dev/null +++ b/src/i18n/commands/builds/create.ts @@ -0,0 +1,39 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const BuildsCreateCommandMessages = defineMessages({ + en: { + invalidActorContext: { + markdown: '{reason}. Please run this command in an Actor directory, or specify the Actor ID.', + json: () => null, + }, + versionDoesNotHaveTag: { + markdown: 'The Actor Version "{version}" does not have the tag "{tag}".', + json: () => null, + }, + multipleVersionsForTag: { + markdown: + 'Multiple Actor versions with the tag "{tag}" found. Please specify the version number using the "--version" flag.\n Available versions for this tag: {availableVersions}', + json: () => null, + }, + noVersionsForTag: { + markdown: + 'No Actor versions with the tag "{tag}" found. You can push a new version with this tag by using "apify push --build-tag={tag}".', + json: () => null, + }, + buildStartedMessage: { + markdown: (md, colors) => + md( + `${colors.yellow('Actor')}: {fullActorName} (${colors.gray('{actId}')})\n ${colors.yellow('Version')}: {selectedVersion} (tagged with ${colors.yellow('{actualTag}')})\n\n${colors.greenBright('Build Started')} (ID: ${colors.gray('{buildId}')})\n ${colors.yellow('Build Number')}: {buildNumber} (will get tagged once finished)\n ${colors.yellow('Started')}: {startedAt}\n`, + ), + json: () => null, + }, + viewInConsole: { + markdown: (md, colors) => md(`${colors.blue('View in Apify Console')}: {url}`), + json: () => null, + }, + logFailed: { + markdown: 'Failed to print log for build with ID "{buildId}": {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/builds/info.ts b/src/i18n/commands/builds/info.ts new file mode 100644 index 000000000..046c0c3d1 --- /dev/null +++ b/src/i18n/commands/builds/info.ts @@ -0,0 +1,50 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const BuildsInfoCommandMessages = defineMessages({ + en: { + buildNotFound: { + markdown: 'Build with ID "{buildId}" was not found on your account.', + json: () => null, + }, + header: { + markdown: (md, colors) => + md( + `${colors.yellow('Actor')}: {fullActorName} (${colors.gray('{actId}')})\n\n${colors.yellow('Build Information')} (ID: ${colors.gray('{buildId}')})\n ${colors.yellow('Build Number')}: {buildNumber}{versionTaggedAs}\n ${colors.yellow('Status')}: {status}{exitCodeStatus}\n ${colors.yellow('Started')}: {startedAt}`, + ), + json: () => null, + }, + versionTaggedAs: { + markdown: (md, colors) => md(` (tagged as ${colors.yellow('{buildTag}')})`), + json: () => null, + }, + exitCodeStatus: { + markdown: (md, colors) => md(` (exit code: ${colors.gray('{exitCode}')})`), + json: () => null, + }, + finishedAtLine: { + markdown: (md, colors) => + md(` ${colors.yellow('Finished')}: {finishedAt} (took ${colors.gray('{duration}')})`), + json: () => null, + }, + runningForLine: { + markdown: (md, colors) => md(` ${colors.yellow('Finished')}: ${colors.gray('Running for {duration}')}`), + json: () => null, + }, + computeUnitsLine: { + markdown: (md, colors) => md(` ${colors.yellow('Compute Units')}: {computeUnits}`), + json: () => null, + }, + dockerImageSizeLine: { + markdown: (md, colors) => md(` ${colors.yellow('Docker Image Size')}: {size}`), + json: () => null, + }, + originLine: { + markdown: (md, colors) => md(` ${colors.yellow('Origin')}: {origin}`), + json: () => null, + }, + viewInConsole: { + markdown: (md, colors) => md(`${colors.blue('View in Apify Console')}: {url}`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/builds/log.ts b/src/i18n/commands/builds/log.ts new file mode 100644 index 000000000..5a094406a --- /dev/null +++ b/src/i18n/commands/builds/log.ts @@ -0,0 +1,18 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const BuildsLogCommandMessages = defineMessages({ + en: { + buildNotFound: { + markdown: 'Build with ID "{buildId}" was not found on your account.', + json: () => null, + }, + logHeader: { + markdown: 'Log for build with ID "{buildId}":\n', + json: () => null, + }, + logFailed: { + markdown: 'Failed to get log for build with ID "{buildId}": {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/builds/ls.ts b/src/i18n/commands/builds/ls.ts new file mode 100644 index 000000000..c99fb645c --- /dev/null +++ b/src/i18n/commands/builds/ls.ts @@ -0,0 +1,30 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const BuildsLsCommandMessages = defineMessages({ + en: { + invalidActorContext: { + markdown: '{reason}. Please run this command in an Actor directory, or specify the Actor ID.', + json: () => null, + }, + showingBuildsHeader: { + markdown: (md, colors) => + md( + `${colors.reset('Showing')} ${colors.yellow('{shown,number}')} out of ${colors.yellow('{total,number}')} builds for Actor ${colors.yellow('{userFriendlyId}')} (${colors.gray('{actorId}')})\n`, + ), + json: () => null, + }, + noBuildsForVersion: { + markdown: 'No builds for version {actorVersion}', + json: () => null, + }, + buildsForVersionHeader: { + markdown: (md, colors) => + md(colors.reset(`Builds for Actor Version ${colors.yellow('{actorVersion}')}{latestBuildTagMessage}`)), + json: () => null, + }, + latestBuildTagSuffix: { + markdown: (md, colors) => md(` (latest build gets tagged with ${colors.yellow('{latestBuildTag}')})`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/builds/remove-tag.ts b/src/i18n/commands/builds/remove-tag.ts new file mode 100644 index 000000000..35459c79e --- /dev/null +++ b/src/i18n/commands/builds/remove-tag.ts @@ -0,0 +1,38 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const BuildsRemoveTagCommandMessages = defineMessages({ + en: { + buildNotFound: { + markdown: 'Build with ID "{buildId}" was not found on your account.', + json: () => null, + }, + actorNotFound: { + markdown: 'Actor with ID "{actorId}" was not found.', + json: () => null, + }, + tagDoesNotExist: { + markdown: 'Tag "{tag}" does not exist on Actor "{actorName}".', + json: () => null, + }, + tagNotOnBuild: { + markdown: + 'Tag "{tag}" is not associated with build "{buildId}". It points to build "{otherBuildNumber}" ({otherBuildId}).', + json: () => null, + }, + canceled: { + markdown: 'Tag removal was canceled.', + json: () => null, + }, + tagRemoved: { + markdown: (md, colors) => + md( + `Tag "${colors.yellow('{tag}')}" removed from build ${colors.gray('{buildNumber}')} (${colors.gray('{buildId}')})`, + ), + json: () => null, + }, + tagRemoveFailed: { + markdown: 'Failed to remove tag "{tag}" from build "{buildId}".\n {errorMessage}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/builds/rm.ts b/src/i18n/commands/builds/rm.ts new file mode 100644 index 000000000..c4be15454 --- /dev/null +++ b/src/i18n/commands/builds/rm.ts @@ -0,0 +1,18 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const BuildsRmCommandMessages = defineMessages({ + en: { + buildNotFound: { + markdown: 'Build with ID "{buildId}" was not found on your account.', + json: () => null, + }, + deletionCanceled: { + markdown: 'Deletion of build "{buildId}" was canceled.', + json: () => null, + }, + buildDeleted: { + markdown: 'Build with ID "{buildId}" was deleted.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/cli-management/install.ts b/src/i18n/commands/cli-management/install.ts new file mode 100644 index 000000000..656448228 --- /dev/null +++ b/src/i18n/commands/cli-management/install.ts @@ -0,0 +1,86 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const InstallCommandMessages = defineMessages({ + en: { + alreadyConfigured: { + markdown: 'Apify and Actor CLI are already fully configured! 👍', + json: () => null, + }, + shellIntegrationFailedFallback: { + markdown: 'Failed to automatically handle shell integration', + json: () => null, + }, + shellIntegrationFailed: { + markdown: '{message}', + json: () => null, + }, + installSuccessMessage: { + markdown: (md, colors) => + md( + `\n${colors.green('Apify and Actor CLI were installed successfully!')}\n\n${colors.gray(` Version: ${colors.green('{version}')}`)}\n${colors.gray(` Location: ${colors.bold.white('{apifyLocation}')} and ${colors.bold.white('{actorLocation}')}`)}`, + ), + json: () => null, + }, + toGetStarted: { + markdown: 'To get started, run:', + json: () => null, + }, + helpCommands: { + markdown: (md, colors) => md(colors.white.bold(' apify --help\n actor --help')), + json: () => null, + }, + homeDirNotFound: { + markdown: (md, colors) => md(colors.gray('User home directory not found, cannot symlink to ~/.local/bin')), + json: () => null, + }, + bundleNotFoundForSymlinking: { + markdown: (md, colors) => md(colors.gray('Bundle not found for symlinking: {file}')), + json: () => null, + }, + symlinkedToLocalBin: { + markdown: (md, colors) => md(colors.gray('Symlinked apify, actor, and apify-cli to {localBinDirectory}')), + json: () => null, + }, + alreadyInPath: { + markdown: (md, colors) => + md(colors.gray('Apify and Actor CLIs are already in PATH, skipping shell integration')), + json: () => null, + }, + installDirNotFound: { + markdown: (md, colors) => md(colors.gray('Install directory not found, cannot add to shell')), + json: () => null, + }, + readConfigFailed: { + markdown: 'Failed to read config file "{configFile}". Received error code: {code}; {message}', + json: () => null, + }, + writeConfigPermissionDenied: { + markdown: + 'Failed to write to config file "{configFile}", as the CLI does not have permission to write to it.', + json: () => null, + }, + writeConfigFailed: { + markdown: 'Failed to write to config file "{configFile}". Received error code: {code}; {message}', + json: () => null, + }, + pathAddedSuccess: { + markdown: (md, colors) => + md( + `${colors.gray('Added "{binDir}" to your PATH in {configFile}.')}\n${colors.gray(` You may need to run ${colors.white.bold('source {configFile}')} to reload your shell.`)}`, + ), + json: () => null, + }, + notInPathOneLiner: { + markdown: (md, colors) => + md( + `${colors.gray('The Apify & Actor CLIs are not in your PATH. Run:')}\n\n${colors.white.bold(' {oneLiner}')}`, + ), + json: () => null, + }, + manuallyAdd: { + markdown: (md, colors) => + md(`${colors.gray('Manually add the following lines to {configFile} or similar:')}\n{linesToAdd}`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/cli-management/upgrade.ts b/src/i18n/commands/cli-management/upgrade.ts new file mode 100644 index 000000000..40eb1f965 --- /dev/null +++ b/src/i18n/commands/cli-management/upgrade.ts @@ -0,0 +1,82 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const UpgradeCommandMessages = defineMessages({ + en: { + upToDate: { + markdown: '{cliName} is up to date 👍 \n', + json: () => null, + }, + oldVersionWarning: { + markdown: (md, colors) => + md( + `You are using an old version of {cliName}. We strongly recommend you always use the latest available version.\n ↪ Run ${colors.bgWhite(colors.black('{updateCommand}'))} to update! 👍 \n`, + ), + json: () => null, + }, + minimumVersion: { + markdown: 'The minimum version of the CLI you can manually downgrade/upgrade to is {minVersion}.', + json: () => null, + }, + versionNotFound: { + markdown: 'The provided version does not exist. Please check the version number and try again.', + json: () => null, + }, + assetsNotFound: { + markdown: + 'Failed to find the assets for your system and the provided version. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:\n- The version you are trying to upgrade to: {version}\n- The system you are running on: {platform} {arch}', + json: () => null, + }, + bundleNotFound: { + markdown: + 'Failed to find the currently installed {cliName} bundle. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:\n- The version you are trying to upgrade to: {version}\n- The system you are running on: {platform} {arch}\n- The directory where the {cliName} bundle is installed: {bundleDirectory}', + json: () => null, + }, + wouldRunCommand: { + markdown: 'Would run command: {updateCommand}', + json: () => null, + }, + upgradeFailed: { + markdown: 'Failed to upgrade the CLI. Please run the following command manually: {updateCommand}', + json: () => null, + }, + successfullyUpgraded: { + markdown: 'Successfully upgraded to {version} 👍', + json: () => null, + }, + startingUpgradeProcess: { + markdown: 'Starting upgrade process...', + json: () => null, + }, + failedToStartUpgrade: { + markdown: 'Failed to start the upgrade process: {message}', + json: () => null, + }, + fetchScriptFailed: { + markdown: + 'Failed to fetch the upgrade script. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:\n- The system you are running on: {platform} {arch}\n- The URL of the asset that failed to fetch: {url}\n- The status code of the response: {status,number}', + json: () => null, + }, + downloadingBinary: { + markdown: 'Downloading `{cliName}` binary of the Apify CLI...', + json: () => null, + }, + fetchAssetFailed: { + markdown: + 'Failed to fetch the {cliName} bundle. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:\n- The version you are trying to upgrade to: {version}\n- The system you are running on: {platform} {arch}\n- The URL of the asset that failed to fetch: {url}\n- The status code of the response: {status,number}\n- The body of the response: {body}', + json: () => null, + }, + wouldWriteAsset: { + markdown: 'Would write asset {cliName} to {filePath}', + json: () => null, + }, + writingAsset: { + markdown: (md, colors) => md(colors.gray('Writing {cliName} to {filePath}...')), + json: () => null, + }, + writeAssetFailed: { + markdown: + 'Failed to write the {cliName} bundle. Please open an issue on https://github.com/apify/apify-cli/issues/new and provide the following information:\n- The version you are trying to upgrade to: {version}\n- The system you are running on: {platform} {arch}\n- The URL of the asset that failed to fetch: {url}\n- The error: {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/create.ts b/src/i18n/commands/create.ts new file mode 100644 index 000000000..995d6f431 --- /dev/null +++ b/src/i18n/commands/create.ts @@ -0,0 +1,63 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const CreateCommandMessages = defineMessages({ + en: { + manifestFetchFailed: { + markdown: 'Could not fetch template list from server. Cause: {cause}', + json: () => null, + }, + directoryExists: { + markdown: + 'Cannot create new Actor, directory `{actorName}` already exists. Please provide a different name. You can use "apify init" to create a local Actor environment inside an existing directory.', + json: () => null, + }, + noNodeDetected: { + markdown: + 'No Node.js detected! Please install Node.js {minimumVersion} or higher to be able to run Node.js Actors locally.', + json: () => null, + }, + noPythonDetected: { + markdown: + 'No Python detected! Please install Python {minimumVersion} or higher to be able to run Python Actors locally.', + json: () => null, + }, + nodeUnsupported: { + markdown: + 'You are running Node.js version {version}, which is no longer supported. Please upgrade to Node.js version {minimumVersion} or later.', + json: () => null, + }, + pythonUnsupported: { + markdown: 'Python Actors require Python 3.9 or higher, but you have Python {version}!', + json: () => null, + }, + pythonUnsupportedHint: { + markdown: 'Please install Python 3.9 or higher to be able to run Python Actors locally.', + json: () => null, + }, + pythonDetected: { + markdown: 'Python version {version} detected.', + json: () => null, + }, + creatingVenv: { + markdown: + 'Creating a virtual environment in "{venvPath}" and installing dependencies from "requirements.txt"...', + json: () => null, + }, + blankLine: { + markdown: '', + json: () => null, + }, + successMessage: { + markdown: '{message}', + json: () => null, + }, + gitInitFailed: { + markdown: 'Failed to initialize git repository: {message}', + json: () => null, + }, + gitInitManualHint: { + markdown: 'You can manually run "git init" in the Actor directory if needed.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/datasets/create.ts b/src/i18n/commands/datasets/create.ts new file mode 100644 index 000000000..109aae400 --- /dev/null +++ b/src/i18n/commands/datasets/create.ts @@ -0,0 +1,19 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const DatasetsCreateCommandMessages = defineMessages({ + en: { + alreadyExists: { + markdown: 'A Dataset with this name already exists!', + json: () => null, + }, + createdWithName: { + markdown: (md, colors) => + md(`Dataset with ID ${colors.yellow('{id}')} (called ${colors.yellow('{name}')}) was created.`), + json: () => null, + }, + created: { + markdown: (md, colors) => md(`Dataset with ID ${colors.yellow('{id}')} was created.`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/datasets/get-items.ts b/src/i18n/commands/datasets/get-items.ts new file mode 100644 index 000000000..4db894ef1 --- /dev/null +++ b/src/i18n/commands/datasets/get-items.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const DatasetsGetItemsMessages = defineMessages({ + en: { + datasetNotFound: { + markdown: 'Dataset with ID "{datasetId}" not found.', + json: () => null, + }, + contentType: { + markdown: '{contentType}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/datasets/info.ts b/src/i18n/commands/datasets/info.ts new file mode 100644 index 000000000..74728b777 --- /dev/null +++ b/src/i18n/commands/datasets/info.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const DatasetsInfoCommandMessages = defineMessages({ + en: { + storeNotFound: { + markdown: 'Key-value store with ID or name "{storeId}" not found.', + json: () => null, + }, + message: { + markdown: '{message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/datasets/ls.ts b/src/i18n/commands/datasets/ls.ts new file mode 100644 index 000000000..e710667c1 --- /dev/null +++ b/src/i18n/commands/datasets/ls.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const DatasetsLsCommandMessages = defineMessages({ + en: { + noDatasets: { + markdown: "You don't have any Datasets on your account", + json: () => null, + }, + table: { + markdown: '{table}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/datasets/push-items.ts b/src/i18n/commands/datasets/push-items.ts new file mode 100644 index 000000000..8d5059a39 --- /dev/null +++ b/src/i18n/commands/datasets/push-items.ts @@ -0,0 +1,42 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const DatasetsPushDataCommandMessages = defineMessages({ + en: { + datasetNotFound: { + markdown: 'Dataset with ID or name "{nameOrId}" not found.', + json: () => null, + }, + noItemsProvided: { + markdown: 'No items were provided.', + json: () => null, + }, + parseError: { + markdown: 'Failed to parse data as JSON string: {message}', + json: () => null, + }, + pushedNamed: { + markdown: (md, colors) => + md( + `{pluralLabel} pushed to Dataset named ${colors.yellow('{name}')} (${colors.gray('ID:')} ${colors.yellow('{id}')}) successfully.`, + ), + json: () => null, + }, + pushedUnnamed: { + markdown: (md, colors) => + md(`{pluralLabel} pushed to Dataset with ID ${colors.yellow('{id}')} successfully.`), + json: () => null, + }, + pushFailedNamed: { + markdown: (md, colors) => + md( + `Failed to push items into Dataset named ${colors.yellow('{name}')} (${colors.gray('ID:')} ${colors.yellow('{id}')})\n {message}`, + ), + json: () => null, + }, + pushFailedUnnamed: { + markdown: (md, colors) => + md(`Failed to push items into Dataset with ID ${colors.yellow('{id}')}\n {message}`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/datasets/rename.ts b/src/i18n/commands/datasets/rename.ts new file mode 100644 index 000000000..8ec016096 --- /dev/null +++ b/src/i18n/commands/datasets/rename.ts @@ -0,0 +1,43 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const DatasetsRenameCommandMessages = defineMessages({ + en: { + mustProvideNameOrUnname: { + markdown: 'You must provide either a new name or the --unname flag.', + json: () => null, + }, + cannotProvideBoth: { + markdown: 'You cannot provide a new name and the --unname flag.', + json: () => null, + }, + datasetNotFound: { + markdown: 'Dataset with ID or name "{nameOrId}" not found.', + json: () => null, + }, + nameSet: { + markdown: (md, colors) => + md( + `The name of the dataset with ID ${colors.yellow('{id}')} has been set to: ${colors.yellow('{newName}')}`, + ), + json: () => null, + }, + nameRemoved: { + markdown: (md, colors) => + md( + `The name of the dataset with ID ${colors.yellow('{id}')} has been removed (was ${colors.yellow('{previousName}')} previously).`, + ), + json: () => null, + }, + nameChanged: { + markdown: (md, colors) => + md( + `The name of the dataset with ID ${colors.yellow('{id}')} was changed from ${colors.yellow('{previousName}')} to ${colors.yellow('{newName}')}.`, + ), + json: () => null, + }, + renameFailed: { + markdown: (md, colors) => md(`Failed to rename dataset with ID ${colors.yellow('{id}')}\n {message}`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/datasets/rm.ts b/src/i18n/commands/datasets/rm.ts new file mode 100644 index 000000000..3554e3d19 --- /dev/null +++ b/src/i18n/commands/datasets/rm.ts @@ -0,0 +1,27 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const DatasetsRmCommandMessages = defineMessages({ + en: { + datasetNotFound: { + markdown: 'Dataset with ID or name "{datasetNameOrId}" not found.', + json: () => null, + }, + deletionAborted: { + markdown: 'Dataset deletion has been aborted.', + json: () => null, + }, + deletedWithName: { + markdown: (md, colors) => + md(`Dataset with ID ${colors.yellow('{id}')} (called ${colors.yellow('{name}')}) has been deleted.`), + json: () => null, + }, + deletedUnnamed: { + markdown: (md, colors) => md(`Dataset with ID ${colors.yellow('{id}')} has been deleted.`), + json: () => null, + }, + deleteFailed: { + markdown: (md, colors) => md(`Failed to delete dataset with ID ${colors.yellow('{id}')}\n {message}`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/edit-input-schema.ts b/src/i18n/commands/edit-input-schema.ts new file mode 100644 index 000000000..c9b911c4c --- /dev/null +++ b/src/i18n/commands/edit-input-schema.ts @@ -0,0 +1,70 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const EditInputSchemaCommandMessages = defineMessages({ + en: { + embeddedSchemaUnsupported: { + markdown: 'Editing an input schema directly embedded in `{configPath}` is not yet supported.', + json: () => null, + }, + experimentalWarning: { + markdown: 'This command is still experimental and might break at any time. Use at your own risk.\n', + json: () => null, + }, + editingSchema: { + markdown: 'Editing input schema at "{path}"...', + json: () => null, + }, + schemaLoaded: { + markdown: 'Input schema loaded from "{path}"', + json: () => null, + }, + emptySchemaInitialized: { + markdown: 'Empty input schema initialized.', + json: () => null, + }, + readError: { + markdown: 'Reading input schema from disk failed with: {message}', + json: () => null, + }, + parseError: { + markdown: 'Parsing input schema failed with error: {message}', + json: () => null, + }, + schemaSent: { + markdown: 'Input schema sent to editor.', + json: () => null, + }, + gotSchema: { + markdown: 'Got input schema from editor...', + json: () => null, + }, + schemaSaved: { + markdown: 'Input schema saved to disk.', + json: () => null, + }, + saveError: { + markdown: 'Saving input schema failed with error: {message}', + json: () => null, + }, + editorClosed: { + markdown: 'Editor closed, finishing...', + json: () => null, + }, + editingFinished: { + markdown: 'Editing finished, you can close the editor.', + json: () => null, + }, + done: { + markdown: 'Done.', + json: () => null, + }, + listening: { + markdown: 'Listening for messages from input schema editor on port {port,number}...', + json: () => null, + }, + openingEditor: { + markdown: 'Opening input schema editor at "{url}"...', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/help.ts b/src/i18n/commands/help.ts new file mode 100644 index 000000000..cbd2a3338 --- /dev/null +++ b/src/i18n/commands/help.ts @@ -0,0 +1,17 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const HelpCommandMessages = defineMessages({ + en: { + commandNotFound: { + markdown: (md, colors) => md(colors.gray(`Command ${colors.whiteBright('{commandString}')} not found`)), + json: () => null, + }, + commandNotFoundWithSuggestions: { + markdown: (md, colors) => + md( + `${colors.gray(`Command ${colors.whiteBright('{commandString}')} not found`)}\n ${colors.gray(`Did you mean: {suggestions}?`)}`, + ), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/init-wrap-scrapy.ts b/src/i18n/commands/init-wrap-scrapy.ts new file mode 100644 index 000000000..533ec5dea --- /dev/null +++ b/src/i18n/commands/init-wrap-scrapy.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const WrapScrapyCommandMessages = defineMessages({ + en: { + wrapped: { + markdown: 'Scrapy project wrapped successfully.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/init.ts b/src/i18n/commands/init.ts new file mode 100644 index 000000000..74411c95e --- /dev/null +++ b/src/i18n/commands/init.ts @@ -0,0 +1,38 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const InitCommandMessages = defineMessages({ + en: { + projectError: { + markdown: '{message}', + json: () => null, + }, + warning: { + markdown: '{warning}', + json: () => null, + }, + scrapyDetected: { + markdown: 'The current directory looks like a Scrapy project. Using automatic project wrapping.', + json: () => null, + }, + notJsOrPython: { + markdown: 'The current directory does not look like a Node.js or Python project.', + json: () => null, + }, + actorConfigError: { + markdown: '{message}', + json: () => null, + }, + configExists: { + markdown: 'Skipping creation of `{configPath}`, the file already exists in the current directory.', + json: () => null, + }, + invalidActorName: { + markdown: '{message}', + json: () => null, + }, + initialized: { + markdown: 'The Actor has been initialized in the current directory.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/key-value-stores/create.ts b/src/i18n/commands/key-value-stores/create.ts new file mode 100644 index 000000000..8110d2b01 --- /dev/null +++ b/src/i18n/commands/key-value-stores/create.ts @@ -0,0 +1,19 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const KeyValueStoresCreateCommandMessages = defineMessages({ + en: { + duplicateName: { + markdown: 'Cannot create a key-value store with the same name!', + json: () => null, + }, + createdNamed: { + markdown: (md, colors) => + md(`Key-value store with ID ${colors.yellow('{id}')} (called ${colors.yellow('{name}')}) was created.`), + json: () => null, + }, + createdUnnamed: { + markdown: (md, colors) => md(`Key-value store with ID ${colors.yellow('{id}')} was created.`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/key-value-stores/delete-value.ts b/src/i18n/commands/key-value-stores/delete-value.ts new file mode 100644 index 000000000..603ce4681 --- /dev/null +++ b/src/i18n/commands/key-value-stores/delete-value.ts @@ -0,0 +1,27 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const KeyValueStoresDeleteValueCommandMessages = defineMessages({ + en: { + storeNotFound: { + markdown: 'Key-value store with ID or name "{storeId}" not found.', + json: () => null, + }, + itemNotFound: { + markdown: 'Item with key "{itemKey}" not found in the key-value store.', + json: () => null, + }, + deletionAborted: { + markdown: 'Key-value store record deletion aborted.', + json: () => null, + }, + deleted: { + markdown: (md, colors) => + md(`Record with key "${colors.yellow('{itemKey}')}" deleted from the key-value store.`), + json: () => null, + }, + deleteFailed: { + markdown: 'Failed to delete record with key "{itemKey}" from the key-value store.\n {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/key-value-stores/get-value.ts b/src/i18n/commands/key-value-stores/get-value.ts new file mode 100644 index 000000000..9b3dbe5ed --- /dev/null +++ b/src/i18n/commands/key-value-stores/get-value.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const KeyValueStoresGetValueCommandMessages = defineMessages({ + en: { + storeNotFound: { + markdown: 'Key-value store with ID "{storeId}" not found.', + json: () => null, + }, + itemNotFound: { + markdown: 'Item with key "{itemKey}" not found in the key-value store.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/key-value-stores/info.ts b/src/i18n/commands/key-value-stores/info.ts new file mode 100644 index 000000000..6a93cb33d --- /dev/null +++ b/src/i18n/commands/key-value-stores/info.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const KeyValueStoresInfoCommandMessages = defineMessages({ + en: { + storeNotFound: { + markdown: 'Key-value store with ID or name "{storeId}" not found.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/key-value-stores/keys.ts b/src/i18n/commands/key-value-stores/keys.ts new file mode 100644 index 000000000..bc4902c24 --- /dev/null +++ b/src/i18n/commands/key-value-stores/keys.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const KeyValueStoresKeysCommandMessages = defineMessages({ + en: { + storeNotFound: { + markdown: 'Key-value store with ID or name "{storeId}" not found.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/key-value-stores/ls.ts b/src/i18n/commands/key-value-stores/ls.ts new file mode 100644 index 000000000..42da74c06 --- /dev/null +++ b/src/i18n/commands/key-value-stores/ls.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const KeyValueStoresLsCommandMessages = defineMessages({ + en: { + noStores: { + markdown: "You don't have any key-value stores on your account", + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/key-value-stores/rename.ts b/src/i18n/commands/key-value-stores/rename.ts new file mode 100644 index 000000000..357603650 --- /dev/null +++ b/src/i18n/commands/key-value-stores/rename.ts @@ -0,0 +1,44 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const KeyValueStoresRenameCommandMessages = defineMessages({ + en: { + missingNameOrUnname: { + markdown: 'You must provide either a new name or the --unname flag.', + json: () => null, + }, + conflictingNameAndUnname: { + markdown: 'You cannot provide a new name and the --unname flag.', + json: () => null, + }, + storeNotFound: { + markdown: 'Key-value store with ID or name "{nameOrId}" not found.', + json: () => null, + }, + nameSet: { + markdown: (md, colors) => + md( + `The name of the key-value store with ID ${colors.yellow('{id}')} has been set to: ${colors.yellow('{newName}')}`, + ), + json: () => null, + }, + nameRemoved: { + markdown: (md, colors) => + md( + `The name of the key-value store with ID ${colors.yellow('{id}')} has been removed (was ${colors.yellow('{name}')} previously).`, + ), + json: () => null, + }, + nameChanged: { + markdown: (md, colors) => + md( + `The name of the key-value store with ID ${colors.yellow('{id}')} was changed from ${colors.yellow('{name}')} to ${colors.yellow('{newName}')}.`, + ), + json: () => null, + }, + renameFailed: { + markdown: (md, colors) => + md(`Failed to rename key-value store with ID ${colors.yellow('{id}')}\n {message}`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/key-value-stores/rm.ts b/src/i18n/commands/key-value-stores/rm.ts new file mode 100644 index 000000000..579ebbed6 --- /dev/null +++ b/src/i18n/commands/key-value-stores/rm.ts @@ -0,0 +1,30 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const KeyValueStoresRmCommandMessages = defineMessages({ + en: { + storeNotFound: { + markdown: 'Key-value store with ID or name "{nameOrId}" not found.', + json: () => null, + }, + deletionAborted: { + markdown: 'Key-value store deletion has been aborted.', + json: () => null, + }, + deletedNamed: { + markdown: (md, colors) => + md( + `Key-value store with ID ${colors.yellow('{id}')} (called ${colors.yellow('{name}')}) has been deleted.`, + ), + json: () => null, + }, + deletedUnnamed: { + markdown: (md, colors) => md(`Key-value store with ID ${colors.yellow('{id}')} has been deleted.`), + json: () => null, + }, + deleteFailed: { + markdown: (md, colors) => + md(`Failed to delete key-value store with ID ${colors.yellow('{id}')}\n {message}`), + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/key-value-stores/set-value.ts b/src/i18n/commands/key-value-stores/set-value.ts new file mode 100644 index 000000000..f285f23db --- /dev/null +++ b/src/i18n/commands/key-value-stores/set-value.ts @@ -0,0 +1,18 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const KeyValueStoresSetValueCommandMessages = defineMessages({ + en: { + storeNotFound: { + markdown: 'Key-value store with ID or name "{storeId}" not found.', + json: () => null, + }, + valueSet: { + markdown: 'Value with key "{itemKey}" set in the key-value store.', + json: () => null, + }, + setFailed: { + markdown: 'Failed to set value with key "{itemKey}" in the key-value store.\n {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/run.ts b/src/i18n/commands/run.ts new file mode 100644 index 000000000..c9da10fa6 --- /dev/null +++ b/src/i18n/commands/run.ts @@ -0,0 +1,116 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const RunCommandMessages = defineMessages({ + en: { + actorConfigErrorWithCause: { + markdown: '{message}\n {cause}', + json: () => null, + }, + unknownProjectFormat: { + markdown: + 'Actor is of an unknown format. Make sure your project is supported by Apify CLI (either a package.json file is present, or a Python entrypoint could be found) or you are in a migrated Scrapy project.', + json: () => null, + }, + noNodeRuntime: { + markdown: + 'No Node.js detected! Please install Node.js {supportedVersion} (or higher) to be able to run Node.js Actors locally.', + json: () => null, + }, + noPythonRuntime: { + markdown: + 'No Python detected! Please install Python {supportedVersion} (or higher) to be able to run Python Actors locally.', + json: () => null, + }, + noRuntime: { + markdown: + 'No runtime detected! Make sure you have Python {pythonVersion} (or higher) or Node.js {nodeVersion} (or higher) installed.', + json: () => null, + }, + noEntrypoint: { + markdown: + 'No entrypoint detected! Please provide an entrypoint using the --entrypoint flag, or make sure your project has an entrypoint.', + json: () => null, + }, + legacyStorageRenamed: { + markdown: + 'The legacy `apify_storage` directory was renamed to `{storagePath}` to align it with Apify SDK v3. Contents were left intact.', + json: () => null, + }, + storesPurged: { + markdown: 'All default local stores were purged.', + json: () => null, + }, + storageNotEmpty: { + markdown: + 'The storage directory contains a previous state, the Actor will continue where it left off. To start from the initial state, use --purge parameter to clean the storage directory.', + json: () => null, + }, + notLoggedIn: { + markdown: + 'You are not logged in with your Apify Account. Some features like Apify Proxy will not work. Call "apify login" to fix that.', + json: () => null, + }, + unsupportedNodeVersion: { + markdown: + 'You are running Node.js version {currentVersion}, which is no longer supported. Please upgrade to Node.js version {minimumVersion} or later.', + json: () => null, + }, + noScriptsInPackageJson: { + markdown: + 'No scripts were found in package.json. Please set it up for your project. For more information about that call "apify help run".', + json: () => null, + }, + scriptNotFound: { + markdown: + 'The script "{entrypoint}" was not found in package.json. Please set it up for your project. For more information about that call "apify help run".', + json: () => null, + }, + noNpmExecutable: { + markdown: + 'No npm executable found! Please make sure your Node.js runtime has npm installed if you want to run package.json scripts locally.', + json: () => null, + }, + pythonVersionTooLow: { + markdown: 'Python Actors require Python 3.9 or higher, but you have Python {currentVersion}!', + json: () => null, + }, + pleaseInstallPython: { + markdown: 'Please install Python 3.9 or higher to be able to run Python Actors locally.', + json: () => null, + }, + failedToDetectLanguage: { + markdown: + 'Failed to detect the language of your project. Please report this issue to the Apify team with your project structure over at https://github.com/apify/apify-cli/issues', + json: () => null, + }, + inputFileOverwritten: { + markdown: + 'The "{filePath}" file was overwritten during the run. The CLI will not undo the setting of missing default fields from your input schema.', + json: () => null, + }, + stdinInputInvalid: { + markdown: 'The input provided through standard input is invalid. Please fix the following errors:\n', + json: () => null, + }, + flagInputInvalid: { + markdown: 'The input provided through the --input flag is invalid. Please fix the following errors:\n', + json: () => null, + }, + fileInputInvalid: { + markdown: 'The input provided through the {source} file is invalid. Please fix the following errors:\n', + json: () => null, + }, + storedInputInvalid: { + markdown: 'The input in your storage is invalid. Please fix the following errors:\n', + json: () => null, + }, + invalidInputErrors: { + markdown: '{header}{errors}', + json: () => null, + }, + storedInputNotObject: { + markdown: 'The input in your storage is invalid. It should be an object, not an array.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/runs/abort.ts b/src/i18n/commands/runs/abort.ts new file mode 100644 index 000000000..b161e115a --- /dev/null +++ b/src/i18n/commands/runs/abort.ts @@ -0,0 +1,30 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const RunsAbortCommandMessages = defineMessages({ + en: { + runNotFound: { + markdown: 'Run with ID "{runId}" was not found on your account.', + json: () => null, + }, + alreadyAborting: { + markdown: 'Run with ID "{runId}" is already aborting.', + json: () => null, + }, + alreadyAborted: { + markdown: 'Run with ID "{runId}" is already aborted.', + json: () => null, + }, + triggeredForce: { + markdown: 'Triggered the immediate abort of run "{runId}".', + json: () => null, + }, + triggeredGraceful: { + markdown: 'Triggered the abort of run "{runId}", it should finish aborting in up to 30 seconds.', + json: () => null, + }, + abortFailed: { + markdown: 'Failed to abort run "{runId}".\n {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/runs/info.ts b/src/i18n/commands/runs/info.ts new file mode 100644 index 000000000..a04fe6952 --- /dev/null +++ b/src/i18n/commands/runs/info.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const RunsInfoCommandMessages = defineMessages({ + en: { + runNotFound: { + markdown: 'Run with ID "{runId}" was not found on your account.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/runs/log.ts b/src/i18n/commands/runs/log.ts new file mode 100644 index 000000000..42ec007ed --- /dev/null +++ b/src/i18n/commands/runs/log.ts @@ -0,0 +1,18 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const RunsLogCommandMessages = defineMessages({ + en: { + runNotFound: { + markdown: 'Run with ID "{runId}" was not found on your account.', + json: () => null, + }, + logHeader: { + markdown: 'Log for run with ID "{runId}":\n', + json: () => null, + }, + logFetchFailed: { + markdown: 'Failed to get log for run with ID "{runId}": {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/runs/ls.ts b/src/i18n/commands/runs/ls.ts new file mode 100644 index 000000000..74c5acfac --- /dev/null +++ b/src/i18n/commands/runs/ls.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const RunsLsCommandMessages = defineMessages({ + en: { + invalidActor: { + markdown: '{reason}. Please run this command in an Actor directory, or specify the Actor ID.', + json: () => null, + }, + noRuns: { + markdown: 'There are no recent runs found for this Actor.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/runs/resurrect.ts b/src/i18n/commands/runs/resurrect.ts new file mode 100644 index 000000000..cf948837e --- /dev/null +++ b/src/i18n/commands/runs/resurrect.ts @@ -0,0 +1,23 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const RunsResurrectCommandMessages = defineMessages({ + en: { + runNotFound: { + markdown: 'Run with ID "{runId}" was not found on your account.', + json: () => null, + }, + cannotResurrect: { + markdown: + 'Run with ID "{runId}" cannot be resurrected, as it is still running or in the process of aborting.', + json: () => null, + }, + resurrected: { + markdown: 'Run with ID "{runId}" was resurrected successfully.', + json: () => null, + }, + resurrectFailed: { + markdown: 'Failed to resurrect run "{runId}".\n {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/runs/rm.ts b/src/i18n/commands/runs/rm.ts new file mode 100644 index 000000000..4db0efc20 --- /dev/null +++ b/src/i18n/commands/runs/rm.ts @@ -0,0 +1,26 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const RunsRmCommandMessages = defineMessages({ + en: { + runNotFound: { + markdown: 'Run with ID "{runId}" was not found on your account.', + json: () => null, + }, + cannotDelete: { + markdown: 'Run with ID "{runId}" cannot be deleted, as it is still running or in the process of aborting.', + json: () => null, + }, + deletionCanceled: { + markdown: 'Deletion of run "{runId}" was canceled.', + json: () => null, + }, + deleted: { + markdown: 'Run with ID "{runId}" was deleted.', + json: () => null, + }, + deleteFailed: { + markdown: 'Failed to delete run "{runId}".\n {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/secrets/ls.ts b/src/i18n/commands/secrets/ls.ts new file mode 100644 index 000000000..8dab6b110 --- /dev/null +++ b/src/i18n/commands/secrets/ls.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const SecretsLsCommandMessages = defineMessages({ + en: { + noSecrets: { + markdown: "You don't have any secrets stored locally. Use 'apify secrets add' to add a secret.", + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/task/run.ts b/src/i18n/commands/task/run.ts new file mode 100644 index 000000000..0bbfca7e4 --- /dev/null +++ b/src/i18n/commands/task/run.ts @@ -0,0 +1,23 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const TaskRunCommandMessages = defineMessages({ + en: { + resultLinks: { + markdown: (md, colors) => + md(`\n${colors.blue('Export results')}: {datasetUrl}\n${colors.blue('View on Apify Console')}: {url}`), + json: () => null, + }, + taskNotFoundById: { + markdown: "Cannot find Task with ID ''{taskId}'' in your account.", + json: () => null, + }, + taskNotFoundByName: { + markdown: "Cannot find Task with name ''{taskId}'' in your account.", + json: () => null, + }, + invalidTaskIdentifier: { + markdown: 'Please provide a valid Task ID or name.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/telemetry/disable.ts b/src/i18n/commands/telemetry/disable.ts new file mode 100644 index 000000000..c4a530521 --- /dev/null +++ b/src/i18n/commands/telemetry/disable.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const TelemetryDisableCommandMessages = defineMessages({ + en: { + disabled: { + markdown: 'Telemetry disabled.', + json: () => null, + }, + alreadyDisabled: { + markdown: 'Telemetry is already disabled.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/telemetry/enable.ts b/src/i18n/commands/telemetry/enable.ts new file mode 100644 index 000000000..535ddf3fe --- /dev/null +++ b/src/i18n/commands/telemetry/enable.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const TelemetryEnableCommandMessages = defineMessages({ + en: { + enabled: { + markdown: 'Telemetry enabled.', + json: () => null, + }, + alreadyEnabled: { + markdown: 'Telemetry is already enabled.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/commands/validate-schema.ts b/src/i18n/commands/validate-schema.ts new file mode 100644 index 000000000..b15c67671 --- /dev/null +++ b/src/i18n/commands/validate-schema.ts @@ -0,0 +1,38 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const ValidateSchemaCommandMessages = defineMessages({ + en: { + validatingInputSchemaAtPath: { + markdown: 'Validating input schema at {path}', + json: () => null, + }, + inputSchemaValid: { + markdown: 'Input schema is valid.', + json: () => null, + }, + validatingInputSchemaAtLocation: { + markdown: 'Validating input schema at {location}', + json: () => null, + }, + validatingInputSchemaEmbedded: { + markdown: 'Validating input schema embedded in {configPath}', + json: () => null, + }, + validatingNamedSchemaAtLocation: { + markdown: 'Validating {label} schema at {location}', + json: () => null, + }, + validatingNamedSchemaEmbedded: { + markdown: 'Validating {label} schema embedded in {configPath}', + json: () => null, + }, + namedSchemaValid: { + markdown: '{label} schema is valid.', + json: () => null, + }, + noSchemasFound: { + markdown: 'No schemas found. Make sure {configPath} exists and defines at least one schema.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/entrypoints/_shared.ts b/src/i18n/entrypoints/_shared.ts new file mode 100644 index 000000000..ef7b68eab --- /dev/null +++ b/src/i18n/entrypoints/_shared.ts @@ -0,0 +1,22 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const sharedEntrypointMessages = defineMessages({ + en: { + unsupportedNodeVersion: { + markdown: + '{cliName} CLI requires Node.js version {supportedRange}. Your current version is {currentVersion}.', + json: () => null, + }, + commandNotFound: { + markdown: (md, colors) => md(colors.gray(`Command ${colors.whiteBright('{commandName}')} not found`)), + json: () => null, + }, + commandNotFoundWithSuggestions: { + markdown: (md, colors) => + md( + `${colors.gray(`Command ${colors.whiteBright('{commandName}')} not found`)}\n ${colors.gray(`Did you mean: {suggestions}?`)}`, + ), + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/command-framework/apify-command.ts b/src/i18n/lib/command-framework/apify-command.ts new file mode 100644 index 000000000..0872f54fd --- /dev/null +++ b/src/i18n/lib/command-framework/apify-command.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const apifyCommandMessages = defineMessages({ + en: { + missingRequiredArgsHeader: { + markdown: 'Missing {count,number} required {count,plural,one{argument}other{arguments}}:', + json: () => null, + }, + seeMoreHelp: { + markdown: (md, colors) => md(colors.gray(' See more help with --help')), + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/command-framework/help.ts b/src/i18n/lib/command-framework/help.ts new file mode 100644 index 000000000..1c568ffbd --- /dev/null +++ b/src/i18n/lib/command-framework/help.ts @@ -0,0 +1,15 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const helpMessages = defineMessages({ + en: { + commandNameMisconfigured: { + markdown: + 'Command name "{commandName}" is not correctly set up internally. Make sure you fill out the "name" field in the command class extension.', + json: () => null, + }, + noHelpRenderer: { + markdown: 'No help renderer found for command {commandName}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/command-framework/help/CommandHelp.ts b/src/i18n/lib/command-framework/help/CommandHelp.ts new file mode 100644 index 000000000..d08a6daf5 --- /dev/null +++ b/src/i18n/lib/command-framework/help/CommandHelp.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../../../lib/i18n/index.js'; + +export const CommandHelpMessages = defineMessages({ + en: { + unhandledFlagTag: { + markdown: 'Unhandled flag tag: {flagTag}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/commands/resolve-input.ts b/src/i18n/lib/commands/resolve-input.ts new file mode 100644 index 000000000..a0aef6e6c --- /dev/null +++ b/src/i18n/lib/commands/resolve-input.ts @@ -0,0 +1,36 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const resolveInputMessages = defineMessages({ + en: { + inputMustBeObject: { + markdown: 'The provided input is invalid. It should be an object, not an array.', + json: () => null, + }, + cannotParseStdinJson: { + markdown: 'Cannot parse JSON input from standard input.\n {message}', + json: () => null, + }, + stdinDashRequiresPipe: { + markdown: 'You need to pipe something into standard input when you specify the `-` value to `--input`.', + json: () => null, + }, + inputFlagIsPath: { + markdown: + 'Providing a JSON file path in the --input flag is not supported. Use the "--input-file=" flag instead', + json: () => null, + }, + cannotParseInputJson: { + markdown: 'Cannot parse JSON input.\n {message}', + json: () => null, + }, + inputFileDashRequiresPipe: { + markdown: + 'You need to pipe something into standard input when you specify the `-` value to `--input-file`.', + json: () => null, + }, + cannotReadInputFile: { + markdown: 'Cannot read input file at path "{fullPath}".\n {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/commands/run-on-cloud.ts b/src/i18n/lib/commands/run-on-cloud.ts new file mode 100644 index 000000000..1673c910b --- /dev/null +++ b/src/i18n/lib/commands/run-on-cloud.ts @@ -0,0 +1,38 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const runOnCloudMessages = defineMessages({ + en: { + callingActorOrTask: { + markdown: (md, colors) => md(`Calling {type} {userFriendlyId} (${colors.gray('{id}')})\n`), + json: () => null, + }, + callingTaskWithTitle: { + markdown: (md, colors) => md(`Calling {type} {title} ({userFriendlyId}, ${colors.gray('{id}')})\n`), + json: () => null, + }, + notFound: { + markdown: '{type} {userFriendlyId} ({id}) not found!', + json: () => null, + }, + cannotGetLog: { + markdown: 'Can not get log:', + json: () => null, + }, + jobSucceeded: { + markdown: '{type} finished.', + json: () => null, + }, + jobStillRunning: { + markdown: '{type} is still running!', + json: () => null, + }, + jobAborted: { + markdown: '{type} was aborted!', + json: () => null, + }, + jobFailed: { + markdown: '{type} failed!', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/create-utils.ts b/src/i18n/lib/create-utils.ts new file mode 100644 index 000000000..71a8263c3 --- /dev/null +++ b/src/i18n/lib/create-utils.ts @@ -0,0 +1,33 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const createUtilsMessages = defineMessages({ + en: { + templateNotFound: { + markdown: 'Could not find the selected template: {templateName} in the list of templates.', + json: () => null, + }, + readmeSuffixFailed: { + markdown: 'Could not append local development instructions to README.md. Cause: {message}', + json: () => null, + }, + actorCreatedWithInstall: { + markdown: + '✅ Actor `{actorName}` created successfully!\n\nNext steps:\n\ncd "{actorName}"\napify run\n\n💡 Tip: Use `apify push` to deploy your Actor to the Apify platform\n📖 Docs: https://docs.apify.com/platform/actors/development', + json: () => null, + }, + actorCreatedWithoutInstall: { + markdown: + '✅ Actor `{actorName}` created successfully!\n\nNext steps:\n\ncd "{actorName}"\n{installLine}\napify run\n\n💡 Tip: Use `apify push` to deploy your Actor to the Apify platform\n📖 Docs: https://docs.apify.com/platform/actors/development', + json: () => null, + }, + installCommandFallback: { + markdown: 'install dependencies with your package manager', + json: () => null, + }, + gitInitialized: { + markdown: + '\n🌱 Git repository initialized in `{actorName}`. You can now commit and push your Actor to Git.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/exec.ts b/src/i18n/lib/exec.ts new file mode 100644 index 000000000..1439ed1c1 --- /dev/null +++ b/src/i18n/lib/exec.ts @@ -0,0 +1,18 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const execMessages = defineMessages({ + en: { + exitedWithCode: { + markdown: '{cmd} exited with code {exitCode,number}', + json: () => null, + }, + exitedDueToSignal: { + markdown: '{cmd} exited due to signal {signal}', + json: () => null, + }, + runningCommand: { + markdown: '{command} {args}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/hooks/telemetry/useTelemetryState.ts b/src/i18n/lib/hooks/telemetry/useTelemetryState.ts new file mode 100644 index 000000000..b7d276cc0 --- /dev/null +++ b/src/i18n/lib/hooks/telemetry/useTelemetryState.ts @@ -0,0 +1,11 @@ +import { defineMessages } from '../../../../lib/i18n/index.js'; + +export const useTelemetryStateMessages = defineMessages({ + en: { + telemetryNotice: { + markdown: + 'Apify collects telemetry data about general usage of Apify CLI to help us improve the product.\nThis feature is enabled by default, and you can disable it by setting the "APIFY_CLI_DISABLE_TELEMETRY" environment variable to "1", or by running "apify telemetry disable".\nYou can find more information about our telemetry in https://docs.apify.com/cli/docs/telemetry.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/hooks/useAbortJobOnSignal.ts b/src/i18n/lib/hooks/useAbortJobOnSignal.ts new file mode 100644 index 000000000..fc35de886 --- /dev/null +++ b/src/i18n/lib/hooks/useAbortJobOnSignal.ts @@ -0,0 +1,41 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const useAbortJobOnSignalMessages = defineMessages({ + en: { + abortingBuild: { + markdown: (md, colors) => + md( + colors.gray( + `Received ${colors.yellow('{signal}')}, aborting build "${colors.yellow('{jobId}')}" on the Apify platform...`, + ), + ), + json: () => null, + }, + abortBuildFailed: { + markdown: 'Failed to abort build "{jobId}": {message}', + json: () => null, + }, + abortingRunGracefully: { + markdown: (md, colors) => + md( + colors.gray( + `Received ${colors.yellow('{signal}')}, gracefully aborting {runLabel} "${colors.yellow('{jobId}')}" on the Apify platform... ${colors.dim('(press Ctrl+C again to abort immediately)')}`, + ), + ), + json: () => null, + }, + abortingRunImmediately: { + markdown: (md, colors) => + md( + colors.gray( + `Received ${colors.yellow('{signal}')} again, aborting {runLabel} "${colors.yellow('{jobId}')}" immediately...`, + ), + ), + json: () => null, + }, + abortRunFailed: { + markdown: 'Failed to abort run "{jobId}": {message}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/hooks/useActorConfig.ts b/src/i18n/lib/hooks/useActorConfig.ts new file mode 100644 index 000000000..8e89cfb58 --- /dev/null +++ b/src/i18n/lib/hooks/useActorConfig.ts @@ -0,0 +1,38 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const useActorConfigMessages = defineMessages({ + en: { + failedToReadConfig: { + markdown: "Failed to read local config at path: ''{configPath}'':", + json: () => null, + }, + ignoringDeprecatedConfig: { + markdown: + 'The "apify.json" file present in your Actor directory will be ignored, and the new ".actor/actor.json" file will be used instead. Please, either rename or remove the old file.', + json: () => null, + }, + renamedDeprecatedConfig: { + markdown: + 'The "apify.json" file has been renamed to "apify.json.deprecated". The deprecated file is no longer used by the CLI or Apify Console. If you do not need it for some specific purpose, it can be safely deleted.', + json: () => null, + }, + renameDeprecatedConfigFailed: { + markdown: 'Failed to rename the deprecated "apify.json" file to "apify.json.deprecated".\n {message}', + json: () => null, + }, + migrationDeclined: { + markdown: + 'Command can not run with old "apify.json" structure. Either let the CLI auto-update it or follow the guide on https://github.com/apify/apify-cli/blob/master/MIGRATIONS.md and update it manually.', + json: () => null, + }, + writeNewActorJsonFailed: { + markdown: "Failed to write the new \"actor.json\" file to path: ''{configPath}''.\n {message}", + json: () => null, + }, + migrationCompleted: { + markdown: + 'The "apify.json" file has been migrated to ".actor/actor.json" and the original file renamed to "apify.json.deprecated". The deprecated file is no longer used by the CLI or Apify Console. If you do not need it for some specific purpose, it can be safely deleted. Do not forget to commit the new file to your Git repository.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/hooks/useCLIMetadata.ts b/src/i18n/lib/hooks/useCLIMetadata.ts new file mode 100644 index 000000000..fb53d2acc --- /dev/null +++ b/src/i18n/lib/hooks/useCLIMetadata.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const useCLIMetadataMessages = defineMessages({ + en: { + failedToDetectInstallMethod: { + markdown: 'Failed to detect install method of CLI, assuming npm', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/hooks/useCLIVersionCheck.ts b/src/i18n/lib/hooks/useCLIVersionCheck.ts new file mode 100644 index 000000000..0c0c5cbc3 --- /dev/null +++ b/src/i18n/lib/hooks/useCLIVersionCheck.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const useCLIVersionCheckMessages = defineMessages({ + en: { + failedToFetchLatestVersion: { + markdown: 'Failed to fetch latest version of Apify CLI, using the cached version instead.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/hooks/useCwdProject.ts b/src/i18n/lib/hooks/useCwdProject.ts new file mode 100644 index 000000000..1bc22b313 --- /dev/null +++ b/src/i18n/lib/hooks/useCwdProject.ts @@ -0,0 +1,20 @@ +import { defineMessages } from '../../../lib/i18n/index.js'; + +export const useCwdProjectMessages = defineMessages({ + en: { + multiplePackagesFound: { + markdown: `Multiple Python packages found:\n{packageList}\n\nApify CLI cannot determine which package to run.\nPlease specify the package using the --entrypoint flag, e.g.:\n apify run --entrypoint '<'package_name'>'`, + json: () => null, + }, + nearMissPackages: { + markdown: + 'Found directories that appear to be Python packages but have issues:\n{suggestions}\n\nA valid Python package requires a directory with a valid identifier name (letters, numbers, underscores) and an __init__.py file.', + json: () => null, + }, + noValidPackageFound: { + markdown: + 'No Python package found. Found Python files, but no valid package structure detected.\nA Python package requires:\n - A directory with a valid Python identifier name (letters, numbers, underscores)\n - An __init__.py file inside the directory\n\nCommon package structures:\n my_package/\n __init__.py\n main.py\n\n src/\n my_package/\n __init__.py\n main.py', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/hooks/user-confirmations/_stdinCheckWrapper.ts b/src/i18n/lib/hooks/user-confirmations/_stdinCheckWrapper.ts new file mode 100644 index 000000000..e6fcffccb --- /dev/null +++ b/src/i18n/lib/hooks/user-confirmations/_stdinCheckWrapper.ts @@ -0,0 +1,10 @@ +import { defineMessages } from '../../../../lib/i18n/index.js'; + +export const stdinCheckWrapperMessages = defineMessages({ + en: { + useConfirmFlags: { + markdown: 'Please use the --{confirmFlag}/--{noConfirmFlag} flags to confirm the action.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/input_schema.ts b/src/i18n/lib/input_schema.ts new file mode 100644 index 000000000..c43c9adfe --- /dev/null +++ b/src/i18n/lib/input_schema.ts @@ -0,0 +1,27 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const inputSchemaMessages = defineMessages({ + en: { + inputSchemaFileMissing: { + markdown: 'Input schema file not found at {fullPath} (referenced in {configPath}).', + json: () => null, + }, + inputSchemaNotFoundAt: { + markdown: 'Input schema has not been found at {inputSchemaPath}.', + json: () => null, + }, + storageSchemaFileMissing: { + markdown: '{label} schema file not found at {fullPath} (referenced in {configPath}).', + json: () => null, + }, + createDefaultInputFailed: { + markdown: + 'Could not create default input based on input schema, creating empty input instead. Cause: {message}', + json: () => null, + }, + schemaInvalid: { + markdown: '{schemaName} schema is not valid:\n{details}', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/projects/scrapy/ScrapyProjectAnalyzer.ts b/src/i18n/lib/projects/scrapy/ScrapyProjectAnalyzer.ts new file mode 100644 index 000000000..e50551f9f --- /dev/null +++ b/src/i18n/lib/projects/scrapy/ScrapyProjectAnalyzer.ts @@ -0,0 +1,14 @@ +import { defineMessages } from '../../../../lib/i18n/index.js'; + +export const ScrapyProjectAnalyzerMessages = defineMessages({ + en: { + scrapyCfgNotFound: { + markdown: 'scrapy.cfg not found in "{scrapyCfgPath}".\nAre you sure there is a Scrapy project there?', + json: () => null, + }, + spiderModulesMissing: { + markdown: 'SPIDER_MODULES path not found in settings.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/projects/scrapy/wrapScrapyProject.ts b/src/i18n/lib/projects/scrapy/wrapScrapyProject.ts new file mode 100644 index 000000000..1a1432d92 --- /dev/null +++ b/src/i18n/lib/projects/scrapy/wrapScrapyProject.ts @@ -0,0 +1,27 @@ +import { defineMessages } from '../../../../lib/i18n/index.js'; + +export const wrapScrapyProjectMessages = defineMessages({ + en: { + bindingNotFound: { + markdown: 'Binding for {part} not found.', + json: () => null, + }, + apifySettingsAlreadyPresent: { + markdown: + "The Scrapy project configuration already contains Apify settings. Are you sure you didn't already wrap this project?", + json: () => null, + }, + downloadingTemplate: { + markdown: 'Downloading the latest Scrapy wrapper template...', + json: () => null, + }, + wrappingProject: { + markdown: 'Wrapping the Scrapy project...', + json: () => null, + }, + wrappedSuccessfully: { + markdown: 'The Scrapy project has been wrapped successfully.', + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/secrets.ts b/src/i18n/lib/secrets.ts new file mode 100644 index 000000000..2baaabcce --- /dev/null +++ b/src/i18n/lib/secrets.ts @@ -0,0 +1,31 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const secretsMessages = defineMessages({ + en: { + secretAlreadyExists: { + markdown: 'Secret with name {name} already exists. Call "apify secrets rm {name}" to remove it.', + json: () => null, + }, + secretNameTooLong: { + markdown: 'Secret name has to be string with maximum length {maxLength,number}.', + json: () => null, + }, + secretValueTooLong: { + markdown: 'Secret value has to be string with maximum length {maxLength,number}.', + json: () => null, + }, + secretNotFound: { + markdown: "Secret with name {name} doesn't exist.", + json: () => null, + }, + missingSecretWarning: { + markdown: + 'Value for {secretKey} not found in local secrets. Set it by calling "apify secrets add {secretKey} [SECRET_VALUE]"', + json: () => null, + }, + missingSecretsList: { + markdown: `The following secrets are missing:\n{secretsList}\n\nSet them by calling "apify secrets add '<'SECRET_NAME'>' '<'SECRET_VALUE'>'" for each missing secret.\nIf you want to skip missing secrets, run the command with the --allow-missing-secrets flag.`, + json: () => null, + }, + }, +}); diff --git a/src/i18n/lib/utils.ts b/src/i18n/lib/utils.ts new file mode 100644 index 000000000..42751cb06 --- /dev/null +++ b/src/i18n/lib/utils.ts @@ -0,0 +1,26 @@ +import { defineMessages } from '../../lib/i18n/index.js'; + +export const utilsMessages = defineMessages({ + en: { + corruptedLocalUserInfo: { + markdown: 'Corrupted local user info was found. Please run "apify login" to fix it.', + json: () => null, + }, + notLoggedIn: { + markdown: 'You are not logged in with your Apify account. Call "apify login" to fix that.', + json: () => null, + }, + actorNameInvalidDns: { + markdown: 'The Actor name must be a DNS hostname-friendly string (e.g. my-newest-actor).', + json: () => null, + }, + actorNameTooShort: { + markdown: 'The Actor name must be at least 3 characters long.', + json: () => null, + }, + actorNameTooLong: { + markdown: 'The Actor name must be a maximum of 30 characters long.', + json: () => null, + }, + }, +}); diff --git a/src/lib/command-framework/apify-command.ts b/src/lib/command-framework/apify-command.ts index 8c64af0d0..db2222499 100644 --- a/src/lib/command-framework/apify-command.ts +++ b/src/lib/command-framework/apify-command.ts @@ -4,6 +4,7 @@ import process from 'node:process'; import type { parseArgs, ParseArgsConfig, ParseArgsOptionDescriptor } from 'node:util'; import type { Awaitable } from '@crawlee/types'; +import { apifyCommandMessages } from '#i18n/lib/command-framework/apify-command.js'; import chalk from 'chalk'; import indentString from 'indent-string'; import widestLine from 'widest-line'; @@ -16,7 +17,10 @@ import { trackEvent } from '../hooks/telemetry/trackEvent.js'; import { checkAndUpdateLastCommand } from '../hooks/telemetry/useTelemetryState.js'; import { useCLIMetadata } from '../hooks/useCLIMetadata.js'; import { ProjectLanguage, useCwdProject } from '../hooks/useCwdProject.js'; -import { error } from '../outputs.js'; +import { t } from '../i18n/index.js'; +import type { TOptions } from '../i18n/t.js'; +import type { ArgsOfDescriptor, HasRequiredArgs, MessageDescriptor, TFormat } from '../i18n/types.js'; +import { logger } from '../logger.js'; import type { ArgTag, TaggedArgBuilder } from './args.js'; import { CommandError, CommandErrorCode } from './CommandError.js'; import type { FlagTag, TaggedFlagBuilder } from './flags.js'; @@ -120,6 +124,7 @@ type InferFlagsFromCommand< ? Record : _InferFlagsFromCommand, OptionalIfHasDefault>) & { json: boolean; + markdown: boolean; }; export function camelCaseString(str: string): string { @@ -145,6 +150,28 @@ const jsonFlagDefinition = { multiple: false, } as const satisfies ParseArgsOptionDescriptor; +const markdownFlagDefinition = { + type: 'boolean', + multiple: false, +} as const satisfies ParseArgsOptionDescriptor; + +/** + * Mirrors the runtime disambiguation in `t()`: `--props--` vs `--options--` + * collapse onto the same arg slot for messages with no required props, so we + * recognise the options bag structurally (only `format` / `locale` keys). + */ +function looksLikeOptions(value: unknown): value is TOptions { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return false; + } + for (const key of Object.keys(value as Record)) { + if (key !== 'format' && key !== 'locale') { + return false; + } + } + return true; +} + const userAgentFlagDefinition = { type: 'string', multiple: false, @@ -204,12 +231,20 @@ export abstract class ApifyCommand> & { - json?: 'Do not use json as the key of a flag, override the enableJsonFlag static property instead'; + json?: 'Do not use `json` as a flag key — the framework reserves it. Opt out via `static disableFormatOutputDefaults = true` instead'; + markdown?: 'Do not use `markdown` as a flag key — the framework reserves it. Opt out via `static disableFormatOutputDefaults = true` instead'; }; static subcommands?: (typeof BuiltApifyCommand)[]; - static enableJsonFlag = false; + /** + * By default every command gets two mutually-exclusive output flags — + * `--json` and `--markdown` — that `this.t()` reads to pick a + * {@link TFormat} automatically. Set this to `true` to suppress both + * flags (the command will still be able to call `this.t()`, but with no + * automatic format override). + */ + static disableFormatOutputDefaults = false; static name: string; @@ -262,6 +297,57 @@ export abstract class ApifyCommand(...)` for output meant to be piped / + * scripted against (raw values, JSON) and `this.logger.stderr.(...)` + * for progress, warnings, and errors the user reads but does not consume. + */ + protected get logger() { + return logger; + } + + /** + * Format a message via {@link t}, automatically picking the {@link TFormat} + * from the parsed `--json` / `--markdown` flags (unless the caller passes + * an explicit `format` in the options bag, which always wins). When + * neither flag is set, the call falls through to {@link t}'s own default + * (`'terminal'`). + */ + protected t( + message: M, + ...args: HasRequiredArgs> extends true + ? [props: ArgsOfDescriptor, options?: TOptions] + : [options?: TOptions] + ): string { + let formatFromFlags: TFormat | undefined; + if (this.flags.json) { + formatFromFlags = 'json'; + } else if (this.flags.markdown) { + formatFromFlags = 'markdown'; + } + + const inject = (options: TOptions | undefined): TOptions => ({ + ...(formatFromFlags != null ? { format: formatFromFlags } : {}), + ...options, + }); + + // Disambiguate which slot is options the same way `t()` does, then + // inject the format. An explicit `options.format` on the caller's + // side takes precedence over the flag-derived default. + const _t = t as (message: MessageDescriptor, ...rest: unknown[]) => string; + if (args.length >= 2) { + return _t(message, args[0], inject(args[1] as TOptions | undefined)); + } + if (args.length === 1) { + if (looksLikeOptions(args[0])) { + return _t(message, inject(args[0] as TOptions)); + } + return _t(message, args[0], inject(undefined)); + } + return _t(message, inject(undefined)); + } + public constructor(entrypoint: string, commandString: string, aliasUsed: string, subcommandAliasUsed?: string) { this.entrypoint = entrypoint; this.commandString = commandString; @@ -331,13 +417,20 @@ export abstract class ApifyCommand>(); @@ -386,7 +479,7 @@ export abstract class ApifyCommand = Omit< ExtractOptionalFlagKeys > as `flags_${string & K}`]: InferFlagsFromCommand[K]; }, - // Omit flags_json as it is used only to throw an error if the user provides it - 'flags_json' + // Omit framework-managed output flags — they are never caller-required + 'flags_json' | 'flags_markdown' > & Omit< { @@ -926,11 +1021,12 @@ type StaticArgsFlagsInput = Omit< true >[K]; }, - // Omit flags_json as it is used only to throw an error if the user provides it - 'flags_json' + // Omit framework-managed output flags — they are never caller-required + 'flags_json' | 'flags_markdown' > & { - // Define it at the end exactly like it is + // Define them at the end exactly as optional flags_json?: boolean; + flags_markdown?: boolean; }; export async function testRunCommand( diff --git a/src/lib/command-framework/help.ts b/src/lib/command-framework/help.ts index 848d690d8..2e4a3a08b 100644 --- a/src/lib/command-framework/help.ts +++ b/src/lib/command-framework/help.ts @@ -1,10 +1,12 @@ +import { helpMessages } from '#i18n/lib/command-framework/help.js'; import chalk from 'chalk'; import indentString from 'indent-string'; import widestLine from 'widest-line'; import wrapAnsi from 'wrap-ansi'; import { useCLIMetadata } from '../hooks/useCLIMetadata.js'; -import { error } from '../outputs.js'; +import { t } from '../i18n/index.js'; +import { logger } from '../logger.js'; import type { BuiltApifyCommand } from './apify-command.js'; import type { BaseCommandRenderer, SelectiveRenderOptions } from './help/_BaseCommandRenderer.js'; import { CommandHelp } from './help/CommandHelp.js'; @@ -15,9 +17,7 @@ const commands = new Map(); export function registerCommandForHelpGeneration(entrypoint: string, command: typeof BuiltApifyCommand) { if (command.name.toLowerCase() !== command.name) { - error({ - message: `Command name "${command.name}" is not correctly set up internally. Make sure you fill out the "name" field in the command class extension.`, - }); + logger.stderr.error(t(helpMessages.commandNameMisconfigured, { commandName: command.name })); return; } @@ -37,7 +37,7 @@ export function renderHelpForCommand(command: typeof BuiltApifyCommand) { const renderer = commands.get(command); if (!renderer) { - throw new Error(`No help renderer found for command ${command.name}`); + throw new Error(t(helpMessages.noHelpRenderer, { commandName: command.name })); } return renderer.render(); @@ -47,7 +47,7 @@ export function selectiveRenderHelpForCommand(command: typeof BuiltApifyCommand, const renderer = commands.get(command); if (!renderer) { - throw new Error(`No help renderer found for command ${command.name}`); + throw new Error(t(helpMessages.noHelpRenderer, { commandName: command.name })); } return renderer.selectiveRender(options); diff --git a/src/lib/command-framework/help/CommandHelp.ts b/src/lib/command-framework/help/CommandHelp.ts index 8f14114ba..3dbb6a948 100644 --- a/src/lib/command-framework/help/CommandHelp.ts +++ b/src/lib/command-framework/help/CommandHelp.ts @@ -1,3 +1,4 @@ +import { CommandHelpMessages } from '#i18n/lib/command-framework/help/CommandHelp.js'; import chalk from 'chalk'; import indent from 'indent-string'; import width from 'string-width'; @@ -5,6 +6,7 @@ import stripAnsi from 'strip-ansi'; import widestLine from 'widest-line'; import wrap from 'wrap-ansi'; +import { t } from '../../i18n/index.js'; import type { ArgTag, TaggedArgBuilder } from '../args.js'; import type { FlagTag, TaggedFlagBuilder } from '../flags.js'; import { BaseCommandRenderer, type SelectiveRenderOptions } from './_BaseCommandRenderer.js'; @@ -123,7 +125,7 @@ export class CommandHelp extends BaseCommandRenderer { return !flag.hidden; }); - if (this.command.enableJsonFlag) { + if (!this.command.disableFormatOutputDefaults) { flags.push([ 'json', { @@ -135,9 +137,25 @@ export class CommandHelp extends BaseCommandRenderer { builder: null as never, aliases: undefined, char: undefined, - description: 'Format the command output as JSON', + description: 'Format the command output as JSON (mutually exclusive with --markdown)', hidden: undefined, - exclusive: undefined, + exclusive: ['markdown'], + }, + ]); + flags.push([ + 'markdown', + { + choices: null, + flagTag: 'boolean', + hasDefault: false, + required: false, + stdin: null as never, + builder: null as never, + aliases: undefined, + char: undefined, + description: 'Format the command output as raw markdown (mutually exclusive with --json)', + hidden: undefined, + exclusive: ['json'], }, ]); } @@ -216,8 +234,18 @@ export class CommandHelp extends BaseCommandRenderer { this.pushArguments(result, args); } - if (flags.length) { - this.pushFlags(result, sortedFlags); + const outputFormatFlagNames = new Set(['json', 'markdown']); + const commandFlags = new Map([...sortedFlags].filter(([name]) => !outputFormatFlagNames.has(name))); + const formatFlags = !this.command.disableFormatOutputDefaults + ? new Map([...sortedFlags].filter(([name]) => outputFormatFlagNames.has(name))) + : new Map(); + + if (commandFlags.size) { + this.pushFlags(result, commandFlags); + } + + if (formatFlags.size) { + this.pushFlags(result, formatFlags, 'OUTPUT FORMAT'); } } @@ -249,12 +277,13 @@ export class CommandHelp extends BaseCommandRenderer { protected pushFlags( result: string[], flags: Map>, + sectionTitle = 'FLAGS', ) { if (!flags.size) { return; } - result.push(chalk.bold('FLAGS')); + result.push(chalk.bold(sectionTitle)); const linesOfFlags = new Map>(); @@ -279,7 +308,7 @@ export class CommandHelp extends BaseCommandRenderer { break; } default: - throw new Error(`Unhandled flag tag: ${flag.flagTag}`); + throw new Error(t(CommandHelpMessages.unhandledFlagTag, { flagTag: flag.flagTag })); } linesOfFlags.set(stringParts.join(' '), flag); diff --git a/src/lib/commands/resolve-input.ts b/src/lib/commands/resolve-input.ts index ef85bd383..1046b9044 100644 --- a/src/lib/commands/resolve-input.ts +++ b/src/lib/commands/resolve-input.ts @@ -2,11 +2,13 @@ import { access, readFile } from 'node:fs/promises'; import path, { resolve } from 'node:path'; import process from 'node:process'; +import { resolveInputMessages } from '#i18n/lib/commands/resolve-input.js'; import mime from 'mime'; import { cachedStdinInput } from '../../entrypoints/_shared.js'; import { CommandExitCodes } from '../consts.js'; -import { error } from '../outputs.js'; +import { t } from '../i18n/index.js'; +import { logger } from '../logger.js'; import { getLocalInput } from '../utils.js'; export function resolveInput(cwd: string, inputOverride: Record | undefined) { @@ -52,7 +54,7 @@ export async function getInputOverride(cwd: string, inputFlag: string | undefine const parsed = JSON.parse(stdin.toString('utf8')); if (Array.isArray(parsed)) { - error({ message: 'The provided input is invalid. It should be an object, not an array.' }); + logger.stderr.error(t(resolveInputMessages.inputMustBeObject)); process.exitCode = CommandExitCodes.InvalidInput; return false; } @@ -60,7 +62,7 @@ export async function getInputOverride(cwd: string, inputFlag: string | undefine input = parsed; source = 'stdin'; } catch (err) { - error({ message: `Cannot parse JSON input from standard input.\n ${(err as Error).message}` }); + logger.stderr.error(t(resolveInputMessages.cannotParseStdinJson, { message: (err as Error).message })); process.exitCode = CommandExitCodes.InvalidInput; return false; } @@ -70,10 +72,7 @@ export async function getInputOverride(cwd: string, inputFlag: string | undefine if (inputFlag) { switch (inputFlag[0]) { case '-': { - error({ - message: - 'You need to pipe something into standard input when you specify the `-` value to `--input`.', - }); + logger.stderr.error(t(resolveInputMessages.stdinDashRequiresPipe)); process.exitCode = CommandExitCodes.InvalidInput; return false; } @@ -98,9 +97,7 @@ export async function getInputOverride(cwd: string, inputFlag: string | undefine inputFlag.startsWith('..\\'); if (fileExists || inputLooksLikePath) { - error({ - message: `Providing a JSON file path in the --input flag is not supported. Use the "--input-file=" flag instead`, - }); + logger.stderr.error(t(resolveInputMessages.inputFlagIsPath)); process.exitCode = CommandExitCodes.InvalidInput; return false; } @@ -109,7 +106,7 @@ export async function getInputOverride(cwd: string, inputFlag: string | undefine const parsed = JSON.parse(inputFlag); if (Array.isArray(parsed)) { - error({ message: 'The provided input is invalid. It should be an object, not an array.' }); + logger.stderr.error(t(resolveInputMessages.inputMustBeObject)); process.exitCode = CommandExitCodes.InvalidInput; return false; } @@ -117,7 +114,9 @@ export async function getInputOverride(cwd: string, inputFlag: string | undefine input = parsed; source = 'input'; } catch (err) { - error({ message: `Cannot parse JSON input.\n ${(err as Error).message}` }); + logger.stderr.error( + t(resolveInputMessages.cannotParseInputJson, { message: (err as Error).message }), + ); process.exitCode = CommandExitCodes.InvalidInput; return false; } @@ -126,10 +125,7 @@ export async function getInputOverride(cwd: string, inputFlag: string | undefine } else if (inputFileFlag) { switch (inputFileFlag[0]) { case '-': { - error({ - message: - 'You need to pipe something into standard input when you specify the `-` value to `--input-file`.', - }); + logger.stderr.error(t(resolveInputMessages.inputFileDashRequiresPipe)); process.exitCode = CommandExitCodes.InvalidInput; return false; } @@ -145,7 +141,7 @@ export async function getInputOverride(cwd: string, inputFlag: string | undefine const parsed = JSON.parse(fileContent); if (Array.isArray(parsed)) { - error({ message: 'The provided input is invalid. It should be an object, not an array.' }); + logger.stderr.error(t(resolveInputMessages.inputMustBeObject)); process.exitCode = CommandExitCodes.InvalidInput; return false; } @@ -161,7 +157,7 @@ export async function getInputOverride(cwd: string, inputFlag: string | undefine const parsed = JSON.parse(inputFileFlag); if (Array.isArray(parsed)) { - error({ message: 'The provided input is invalid. It should be an object, not an array.' }); + logger.stderr.error(t(resolveInputMessages.inputMustBeObject)); process.exitCode = CommandExitCodes.InvalidInput; return false; } @@ -169,9 +165,12 @@ export async function getInputOverride(cwd: string, inputFlag: string | undefine input = parsed; source = inputFileFlag; } catch { - error({ - message: `Cannot read input file at path "${fullPath}".\n ${(fsError as Error).message}`, - }); + logger.stderr.error( + t(resolveInputMessages.cannotReadInputFile, { + fullPath, + message: (fsError as Error).message, + }), + ); process.exitCode = CommandExitCodes.InvalidInput; return false; } diff --git a/src/lib/commands/run-on-cloud.ts b/src/lib/commands/run-on-cloud.ts index 145605557..838985081 100644 --- a/src/lib/commands/run-on-cloud.ts +++ b/src/lib/commands/run-on-cloud.ts @@ -1,5 +1,6 @@ import process from 'node:process'; +import { runOnCloudMessages } from '#i18n/lib/commands/run-on-cloud.js'; import type { ActorRun, ApifyClient, TaskStartOptions } from 'apify-client'; import chalk from 'chalk'; @@ -8,7 +9,8 @@ import { ACTOR_JOB_STATUSES } from '@apify/consts'; import { Flags } from '../command-framework/flags.js'; import { CommandExitCodes } from '../consts.js'; import { useAbortJobOnSignal } from '../hooks/useAbortJobOnSignal.js'; -import { error, run as runLog, success, warning } from '../outputs.js'; +import { t } from '../i18n/index.js'; +import { logger } from '../logger.js'; import { outputJobLog } from '../utils.js'; import { resolveInput } from './resolve-input.js'; @@ -54,17 +56,30 @@ export async function* runActorOrTaskOnCloud(apifyClient: ApifyClient, options: if (!silent) { if (type === 'Actor') { - runLog({ - message: `Calling ${type} ${actorOrTaskData.userFriendlyId} (${chalk.gray(actorOrTaskData.id)})\n`, - }); + logger.stderr.run( + t(runOnCloudMessages.callingActorOrTask, { + type, + userFriendlyId: actorOrTaskData.userFriendlyId, + id: actorOrTaskData.id, + }), + ); } else if (actorOrTaskData.title) { - runLog({ - message: `Calling ${type} ${actorOrTaskData.title} (${actorOrTaskData.userFriendlyId}, ${chalk.gray(actorOrTaskData.id)})\n`, - }); + logger.stderr.run( + t(runOnCloudMessages.callingTaskWithTitle, { + type, + title: actorOrTaskData.title, + userFriendlyId: actorOrTaskData.userFriendlyId, + id: actorOrTaskData.id, + }), + ); } else { - runLog({ - message: `Calling ${type} ${actorOrTaskData.userFriendlyId} (${chalk.gray(actorOrTaskData.id)})\n`, - }); + logger.stderr.run( + t(runOnCloudMessages.callingActorOrTask, { + type, + userFriendlyId: actorOrTaskData.userFriendlyId, + id: actorOrTaskData.id, + }), + ); } } @@ -85,7 +100,13 @@ export async function* runActorOrTaskOnCloud(apifyClient: ApifyClient, options: } catch (err: any) { // TODO: Better error message in apify-client-js if (err.type === 'record-not-found') { - throw new Error(`${type} ${actorOrTaskData.userFriendlyId} (${actorOrTaskData.id}) not found!`); + throw new Error( + t(runOnCloudMessages.notFound, { + type, + userFriendlyId: actorOrTaskData.userFriendlyId, + id: actorOrTaskData.id, + }), + ); } throw err; @@ -118,7 +139,7 @@ export async function* runActorOrTaskOnCloud(apifyClient: ApifyClient, options: console.error(); } } catch (err) { - warning({ message: 'Can not get log:' }); + logger.stderr.warning(t(runOnCloudMessages.cannotGetLog)); console.error(err); } } @@ -142,14 +163,14 @@ export async function* runActorOrTaskOnCloud(apifyClient: ApifyClient, options: if (!silent) { if (run.status === ACTOR_JOB_STATUSES.SUCCEEDED) { - success({ message: `${type} finished.` }); + logger.stderr.success(t(runOnCloudMessages.jobSucceeded, { type })); } else if (run.status === ACTOR_JOB_STATUSES.RUNNING) { - warning({ message: `${type} is still running!` }); + logger.stderr.warning(t(runOnCloudMessages.jobStillRunning, { type })); } else if (run.status === ACTOR_JOB_STATUSES.ABORTED || run.status === ACTOR_JOB_STATUSES.ABORTING) { - warning({ message: `${type} was aborted!` }); + logger.stderr.warning(t(runOnCloudMessages.jobAborted, { type })); process.exitCode = CommandExitCodes.RunAborted; } else { - error({ message: `${type} failed!` }); + logger.stderr.error(t(runOnCloudMessages.jobFailed, { type })); process.exitCode = CommandExitCodes.RunFailed; } } diff --git a/src/lib/create-utils.ts b/src/lib/create-utils.ts index 72b973b83..66306400e 100644 --- a/src/lib/create-utils.ts +++ b/src/lib/create-utils.ts @@ -2,13 +2,15 @@ import { createWriteStream } from 'node:fs'; import { pipeline } from 'node:stream/promises'; import { Separator } from '@inquirer/core'; +import { createUtilsMessages } from '#i18n/lib/create-utils.js'; import type { Manifest, Template } from '@apify/actor-templates'; import type { ChoicesType } from './hooks/user-confirmations/useSelectFromList.js'; import { useSelectFromList } from './hooks/user-confirmations/useSelectFromList.js'; import { useUserInput } from './hooks/user-confirmations/useUserInput.js'; -import { warning } from './outputs.js'; +import { t } from './i18n/index.js'; +import { logger } from './logger.js'; import { httpsGet, validateActorName } from './utils.js'; const PROGRAMMING_LANGUAGES = ['JavaScript', 'TypeScript', 'Python']; @@ -33,9 +35,9 @@ export async function getTemplateDefinition( if (manifest instanceof Error) throw manifest; if (maybeTemplateName) { - const templateDefinition = manifest.templates.find((t) => t.name === maybeTemplateName); + const templateDefinition = manifest.templates.find((tmpl) => tmpl.name === maybeTemplateName); if (!templateDefinition) { - throw new Error(`Could not find the selected template: ${maybeTemplateName} in the list of templates.`); + throw new Error(t(createUtilsMessages.templateNotFound, { templateName: maybeTemplateName })); } return templateDefinition; } @@ -59,9 +61,7 @@ export async function enhanceReadmeWithLocalSuffix(readmePath: string, manifestP readmeStream.write('\n\n'); await pipeline(suffixStream, readmeStream); } catch (err) { - warning({ - message: `Could not append local development instructions to README.md. Cause: ${(err as Error).message}`, - }); + logger.stderr.warning(t(createUtilsMessages.readmeSuffixFailed, { message: (err as Error).message })); } } @@ -74,19 +74,15 @@ export function formatCreateSuccessMessage(params: { }) { const { actorName, dependenciesInstalled, postCreate, gitRepositoryInitialized, installCommandSuggestion } = params; - let message = `✅ Actor '${actorName}' created successfully!`; - - if (dependenciesInstalled) { - message += `\n\nNext steps:\n\ncd "${actorName}"\napify run`; - } else { - const installLine = installCommandSuggestion || 'install dependencies with your package manager'; - message += `\n\nNext steps:\n\ncd "${actorName}"\n${installLine}\napify run`; - } - - message += `\n\n💡 Tip: Use 'apify push' to deploy your Actor to the Apify platform\n📖 Docs: https://docs.apify.com/platform/actors/development`; + let message = dependenciesInstalled + ? t(createUtilsMessages.actorCreatedWithInstall, { actorName }) + : t(createUtilsMessages.actorCreatedWithoutInstall, { + actorName, + installLine: installCommandSuggestion || t(createUtilsMessages.installCommandFallback), + }); if (gitRepositoryInitialized) { - message += `\n🌱 Git repository initialized in '${actorName}'. You can now commit and push your Actor to Git.`; + message += t(createUtilsMessages.gitInitialized, { actorName }); } if (postCreate) { @@ -145,13 +141,13 @@ async function promptProgrammingLanguage() { async function promptTemplateDefinition(manifest: Manifest, programmingLanguage: string): Promise