From 1901433d41d3ae66eda6008a20c5d6c7d28d95ae Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Mon, 31 Mar 2025 10:48:07 -0700 Subject: [PATCH 01/38] security: Upgrade Vite (#517) * security: Upgrade Vite * fix lockfile * changeset * fix: Breaking change from acorn-typescript --- .changeset/chilly-bobcats-appear.md | 5 + packages/ast-tooling/index.ts | 2 +- packages/create/templates/demo/package.json | 2 +- .../templates/demo/package.template.json | 2 +- .../templates/library/package.template.json | 2 +- .../templates/minimal/package.template.json | 2 +- pnpm-lock.yaml | 418 ++++++++---------- 7 files changed, 199 insertions(+), 234 deletions(-) create mode 100644 .changeset/chilly-bobcats-appear.md diff --git a/.changeset/chilly-bobcats-appear.md b/.changeset/chilly-bobcats-appear.md new file mode 100644 index 00000000..a4b1d1e2 --- /dev/null +++ b/.changeset/chilly-bobcats-appear.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +security: Upgrade Vite to avoid CVE-2025-31125 diff --git a/packages/ast-tooling/index.ts b/packages/ast-tooling/index.ts index 27cc72cd..f7ac628c 100644 --- a/packages/ast-tooling/index.ts +++ b/packages/ast-tooling/index.ts @@ -61,7 +61,7 @@ export type { export function parseScript(content: string): TsEstree.Program { const comments: TsEstree.Comment[] = []; - const acornTs = acorn.Parser.extend(tsPlugin({ allowSatisfies: true })); + const acornTs = acorn.Parser.extend(tsPlugin()); // Acorn doesn't add comments to the AST by itself. This factory returns the capabilities to add them after the fact. const ast = acornTs.parse(content, { diff --git a/packages/create/templates/demo/package.json b/packages/create/templates/demo/package.json index 91c81909..0dbee191 100644 --- a/packages/create/templates/demo/package.json +++ b/packages/create/templates/demo/package.json @@ -16,6 +16,6 @@ "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.25.0", "typescript": "^5.3.3", - "vite": "^6.0.0" + "vite": "^6.2.4" } } diff --git a/packages/create/templates/demo/package.template.json b/packages/create/templates/demo/package.template.json index a3ceb4eb..7a06997e 100644 --- a/packages/create/templates/demo/package.template.json +++ b/packages/create/templates/demo/package.template.json @@ -16,6 +16,6 @@ "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.25.0", - "vite": "^6.0.0" + "vite": "^6.2.4" } } diff --git a/packages/create/templates/library/package.template.json b/packages/create/templates/library/package.template.json index 082f3804..61fbdfff 100644 --- a/packages/create/templates/library/package.template.json +++ b/packages/create/templates/library/package.template.json @@ -30,7 +30,7 @@ "publint": "^0.3.2", "svelte": "^5.0.0", "typescript": "^5.3.2", - "vite": "^6.0.0" + "vite": "^6.2.4" }, "keywords": ["svelte"] } diff --git a/packages/create/templates/minimal/package.template.json b/packages/create/templates/minimal/package.template.json index afcc928f..b23b6cf9 100644 --- a/packages/create/templates/minimal/package.template.json +++ b/packages/create/templates/minimal/package.template.json @@ -14,6 +14,6 @@ "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", - "vite": "^6.0.0" + "vite": "^6.2.4" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 992314a5..11a9ea78 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: devDependencies: '@changesets/cli': specifier: ^2.27.10 - version: 2.27.11 + version: 2.27.10 '@playwright/test': specifier: ^1.49.1 version: 1.49.1 @@ -19,7 +19,7 @@ importers: version: link:packages/create '@sveltejs/eslint-config': specifier: ^8.1.0 - version: 8.1.0(@stylistic/eslint-plugin-js@2.12.1(eslint@9.17.0))(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint-plugin-n@17.15.1(eslint@9.17.0))(eslint-plugin-svelte@2.46.1(eslint@9.17.0)(svelte@5.16.0))(eslint@9.17.0)(typescript-eslint@8.18.2(eslint@9.17.0)(typescript@5.7.2))(typescript@5.7.2) + version: 8.1.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.17.0))(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint-plugin-n@17.13.1(eslint@9.17.0))(eslint-plugin-svelte@2.46.0(eslint@9.17.0)(svelte@5.12.0))(eslint@9.17.0)(typescript-eslint@8.18.0(eslint@9.17.0)(typescript@5.7.2))(typescript@5.7.2) '@svitejs/changesets-changelog-github-compact': specifier: ^1.2.0 version: 1.2.0 @@ -28,7 +28,7 @@ importers: version: 22.10.2 '@vitest/ui': specifier: ^3.0.5 - version: 3.0.9(vitest@3.0.5) + version: 3.1.1(vitest@3.0.5) eslint: specifier: ^9.17.0 version: 9.17.0 @@ -43,7 +43,7 @@ importers: version: 2.5.6(prettier@3.4.2) prettier-plugin-svelte: specifier: ^3.3.2 - version: 3.3.2(prettier@3.4.2)(svelte@5.16.0) + version: 3.3.2(prettier@3.4.2)(svelte@5.12.0) rolldown: specifier: 1.0.0-beta.1 version: 1.0.0-beta.1(@babel/runtime@7.26.0) @@ -52,19 +52,19 @@ importers: version: link:packages/cli svelte: specifier: ^5.12.0 - version: 5.16.0 + version: 5.12.0 typescript: specifier: ^5.6.2 version: 5.7.2 typescript-eslint: specifier: ^8.18.0 - version: 8.18.2(eslint@9.17.0)(typescript@5.7.2) + version: 8.18.0(eslint@9.17.0)(typescript@5.7.2) unplugin-isolated-decl: specifier: ^0.8.3 version: 0.8.3(rollup@4.34.5)(typescript@5.7.2) vitest: specifier: ^3.0.5 - version: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.9) + version: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.1.1) community-addon-template: dependencies: @@ -80,7 +80,7 @@ importers: version: link:../packages/cli vitest: specifier: ^3.0.5 - version: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.5) + version: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.1.1) packages/addons: dependencies: @@ -92,7 +92,7 @@ importers: devDependencies: '@sveltejs/acorn-typescript': specifier: ^1.0.1 - version: 1.0.1(acorn@8.14.0) + version: 1.0.5(acorn@8.14.0) '@types/estree': specifier: ^1.0.6 version: 1.0.6 @@ -110,7 +110,7 @@ importers: version: 5.0.3 domutils: specifier: ^3.1.0 - version: 3.2.1 + version: 3.1.0 esrap: specifier: ^1.4.5 version: 1.4.5 @@ -119,7 +119,7 @@ importers: version: 9.1.0 postcss: specifier: ^8.4.49 - version: 8.5.3 + version: 8.5.1 silver-fleece: specifier: ^1.2.1 version: 1.2.1 @@ -188,7 +188,7 @@ importers: version: 1.0.0 package-manager-detector: specifier: ^0.2.7 - version: 0.2.8 + version: 0.2.7 picocolors: specifier: ^1.1.1 version: 1.1.1 @@ -246,7 +246,7 @@ importers: dependencies: '@clack/prompts': specifier: ^0.9.0 - version: 0.9.0 + version: 0.9.1 import-meta-resolve: specifier: ^4.1.0 version: 4.1.0 @@ -255,13 +255,13 @@ importers: version: 0.30.17 package-manager-detector: specifier: ^0.2.7 - version: 0.2.8 + version: 0.2.7 picocolors: specifier: ^1.1.1 version: 1.1.1 semver: specifier: ^7.6.3 - version: 7.7.1 + version: 7.6.3 tiny-glob: specifier: ^0.2.9 version: 0.2.9 @@ -298,8 +298,8 @@ packages: resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} - '@changesets/apply-release-plan@7.0.7': - resolution: {integrity: sha512-qnPOcmmmnD0MfMg9DjU1/onORFyRpDXkMMl2IJg9mECY6RnxL3wN0TCCc92b2sXt1jt8DgjAUUsZYGUGTdYIXA==} + '@changesets/apply-release-plan@7.0.6': + resolution: {integrity: sha512-TKhVLtiwtQOgMAC0fCJfmv93faiViKSDqr8oMEqrnNs99gtSC1sZh/aEMS9a+dseU1ESZRCK+ofLgGY7o0fw/Q==} '@changesets/assemble-release-plan@6.0.5': resolution: {integrity: sha512-IgvBWLNKZd6k4t72MBTBK3nkygi0j3t3zdC1zrfusYo0KpdsvnDjrMM9vPnTCLCMlfNs55jRL4gIMybxa64FCQ==} @@ -307,12 +307,12 @@ packages: '@changesets/changelog-git@0.2.0': resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} - '@changesets/cli@2.27.11': - resolution: {integrity: sha512-1QislpE+nvJgSZZo9+Lj3Lno5pKBgN46dAV8IVxKJy9wX8AOrs9nn5pYVZuDpoxWJJCALmbfOsHkyxujgetQSg==} + '@changesets/cli@2.27.10': + resolution: {integrity: sha512-PfeXjvs9OfQJV8QSFFHjwHX3QnUL9elPEQ47SgkiwzLgtKGyuikWjrdM+lO9MXzOE22FO9jEGkcs4b+B6D6X0Q==} hasBin: true - '@changesets/config@3.0.5': - resolution: {integrity: sha512-QyXLSSd10GquX7hY0Mt4yQFMEeqnO5z/XLpbIr4PAkNNoQNKwDyiSrx4yd749WddusH1v3OSiA0NRAYmH/APpQ==} + '@changesets/config@3.0.4': + resolution: {integrity: sha512-+DiIwtEBpvvv1z30f8bbOsUQGuccnZl9KRKMM/LxUHuDu5oEjmN+bJQ1RIBKNJjfYMQn8RZzoPiX0UgPaLQyXw==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} @@ -323,8 +323,8 @@ packages: '@changesets/get-github-info@0.6.0': resolution: {integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==} - '@changesets/get-release-plan@4.0.6': - resolution: {integrity: sha512-FHRwBkY7Eili04Y5YMOZb0ezQzKikTka4wL753vfUA5COSebt7KThqiuCN9BewE4/qFGgF/5t3AuzXx1/UAY4w==} + '@changesets/get-release-plan@4.0.5': + resolution: {integrity: sha512-E6wW7JoSMcctdVakut0UB76FrrN3KIeJSXvB+DHMFo99CnC3ZVnNYDCVNClMlqAhYGmLmAj77QfApaI3ca4Fkw==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} @@ -356,11 +356,11 @@ packages: '@changesets/write@0.3.2': resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} - '@clack/core@0.4.0': - resolution: {integrity: sha512-YJCYBsyJfNDaTbvDUVSJ3SgSuPrcujarRgkJ5NLjexDZKvaOiVVJvAQYx8lIgG0qRT8ff0fPgqyBCVivanIZ+A==} + '@clack/core@0.4.1': + resolution: {integrity: sha512-Pxhij4UXg8KSr7rPek6Zowm+5M22rbd2g1nfojHJkxp5YkFqiZ2+YLEM/XGVIzvGOcM0nqjIFxrpDwWRZYWYjA==} - '@clack/prompts@0.9.0': - resolution: {integrity: sha512-nGsytiExgUr4FL0pR/LeqxA28nz3E0cW7eLTSh3Iod9TGrbBt8Y7BHbV3mmkNC4G0evdYyQ3ZsbiBkk7ektArA==} + '@clack/prompts@0.9.1': + resolution: {integrity: sha512-JIpyaboYZeWYlyP0H+OoPPxd6nqueG/CmN6ixBiNFsIDHREevjIf0n0Ohh5gr5C8pEDknzgvz+pIJ8dMhzWIeg==} '@emnapi/core@1.3.1': resolution: {integrity: sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==} @@ -841,16 +841,16 @@ packages: cpu: [x64] os: [win32] - '@stylistic/eslint-plugin-js@2.12.1': - resolution: {integrity: sha512-5ybogtEgWIGCR6dMnaabztbWyVdAPDsf/5XOk6jBonWug875Q9/a6gm9QxnU3rhdyDEnckWKX7dduwYJMOWrVA==} + '@stylistic/eslint-plugin-js@2.10.1': + resolution: {integrity: sha512-IikL/RKy9Sk2UMDUUpqrEcwDeYzUEt6SaL2/UVCFuVQxKACHSgStT0NxXkxZmBOUforaU52FPf2Su07FYH5s5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.40.0' - '@sveltejs/acorn-typescript@1.0.1': - resolution: {integrity: sha512-MPvOVpdeRE5pA7hNPmPJwbVxoMC7dQWsIsn0PBJsfXlWyJJtwas4qSMNyArbLkpiNsMzlkyNU1k5Asckp57Srg==} + '@sveltejs/acorn-typescript@1.0.5': + resolution: {integrity: sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==} peerDependencies: - acorn: '>=8.9.0' + acorn: ^8.9.0 '@sveltejs/eslint-config@8.1.0': resolution: {integrity: sha512-cfgp4lPREYBjNd4ZzaP/jA85ufm7vfXiaV7h9vILXNogne80IbZRNhRCQ8XoOqTAOY/pChIzWTBuR8aDNMbAEA==} @@ -909,51 +909,51 @@ packages: '@types/tar-stream@3.1.3': resolution: {integrity: sha512-Zbnx4wpkWBMBSu5CytMbrT5ZpMiF55qgM+EpHzR4yIDu7mv52cej8hTkOc6K+LzpkOAbxwn/m7j3iO+/l42YkQ==} - '@typescript-eslint/eslint-plugin@8.18.2': - resolution: {integrity: sha512-adig4SzPLjeQ0Tm+jvsozSGiCliI2ajeURDGHjZ2llnA+A67HihCQ+a3amtPhUakd1GlwHxSRvzOZktbEvhPPg==} + '@typescript-eslint/eslint-plugin@8.18.0': + resolution: {integrity: sha512-NR2yS7qUqCL7AIxdJUQf2MKKNDVNaig/dEB0GBLU7D+ZdHgK1NoH/3wsgO3OnPVipn51tG3MAwaODEGil70WEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/parser@8.18.2': - resolution: {integrity: sha512-y7tcq4StgxQD4mDr9+Jb26dZ+HTZ/SkfqpXSiqeUXZHxOUyjWDKsmwKhJ0/tApR08DgOhrFAoAhyB80/p3ViuA==} + '@typescript-eslint/parser@8.18.0': + resolution: {integrity: sha512-hgUZ3kTEpVzKaK3uNibExUYm6SKKOmTU2BOxBSvOYwtJEPdVQ70kZJpPjstlnhCHcuc2WGfSbpKlb/69ttyN5Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/scope-manager@8.18.2': - resolution: {integrity: sha512-YJFSfbd0CJjy14r/EvWapYgV4R5CHzptssoag2M7y3Ra7XNta6GPAJPPP5KGB9j14viYXyrzRO5GkX7CRfo8/g==} + '@typescript-eslint/scope-manager@8.18.0': + resolution: {integrity: sha512-PNGcHop0jkK2WVYGotk/hxj+UFLhXtGPiGtiaWgVBVP1jhMoMCHlTyJA+hEj4rszoSdLTK3fN4oOatrL0Cp+Xw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.18.2': - resolution: {integrity: sha512-AB/Wr1Lz31bzHfGm/jgbFR0VB0SML/hd2P1yxzKDM48YmP7vbyJNHRExUE/wZsQj2wUCvbWH8poNHFuxLqCTnA==} + '@typescript-eslint/type-utils@8.18.0': + resolution: {integrity: sha512-er224jRepVAVLnMF2Q7MZJCq5CsdH2oqjP4dT7K6ij09Kyd+R21r7UVJrF0buMVdZS5QRhDzpvzAxHxabQadow==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/types@8.18.2': - resolution: {integrity: sha512-Z/zblEPp8cIvmEn6+tPDIHUbRu/0z5lqZ+NvolL5SvXWT5rQy7+Nch83M0++XzO0XrWRFWECgOAyE8bsJTl1GQ==} + '@typescript-eslint/types@8.18.0': + resolution: {integrity: sha512-FNYxgyTCAnFwTrzpBGq+zrnoTO4x0c1CKYY5MuUTzpScqmY5fmsh2o3+57lqdI3NZucBDCzDgdEbIaNfAjAHQA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.18.2': - resolution: {integrity: sha512-WXAVt595HjpmlfH4crSdM/1bcsqh+1weFRWIa9XMTx/XHZ9TCKMcr725tLYqWOgzKdeDrqVHxFotrvWcEsk2Tg==} + '@typescript-eslint/typescript-estree@8.18.0': + resolution: {integrity: sha512-rqQgFRu6yPkauz+ms3nQpohwejS8bvgbPyIDq13cgEDbkXt4LH4OkDMT0/fN1RUtzG8e8AKJyDBoocuQh8qNeg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/utils@8.18.2': - resolution: {integrity: sha512-Cr4A0H7DtVIPkauj4sTSXVl+VBWewE9/o40KcF3TV9aqDEOWoXF3/+oRXNby3DYzZeCATvbdksYsGZzplwnK/Q==} + '@typescript-eslint/utils@8.18.0': + resolution: {integrity: sha512-p6GLdY383i7h5b0Qrfbix3Vc3+J2k6QWw6UMUeY5JGfm3C5LbZ4QIZzJNoNOfgyRe0uuYKjvVOsO/jD4SJO+xg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/visitor-keys@8.18.2': - resolution: {integrity: sha512-zORcwn4C3trOWiCqFQP1x6G3xTRyZ1LYydnj51cRnJ6hxBlr/cKPckk+PKPUw/fXmvfKTcw7bwY3w9izgx5jZw==} + '@typescript-eslint/visitor-keys@8.18.0': + resolution: {integrity: sha512-pCh/qEA8Lb1wVIqNvBke8UaRjJ6wrAWkJO5yyIbs8Yx6TNGYyfNjOo61tLv+WwLvoLPp4BQ8B7AHKijl8NGUfw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@vitest/expect@3.0.5': @@ -973,8 +973,8 @@ packages: '@vitest/pretty-format@3.0.5': resolution: {integrity: sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==} - '@vitest/pretty-format@3.0.9': - resolution: {integrity: sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==} + '@vitest/pretty-format@3.1.1': + resolution: {integrity: sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==} '@vitest/runner@3.0.5': resolution: {integrity: sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==} @@ -985,21 +985,16 @@ packages: '@vitest/spy@3.0.5': resolution: {integrity: sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==} - '@vitest/ui@3.0.5': - resolution: {integrity: sha512-gw2noso6WI+2PeMVCZFntdATS6xl9qhQcbhkPQ9sOmx/Xn0f4Bx4KDSbD90jpJPF0l5wOzSoGCmKyVR3W612mg==} - peerDependencies: - vitest: 3.0.5 - - '@vitest/ui@3.0.9': - resolution: {integrity: sha512-FpZD4aIv/qNpwkV3XbLV6xldWFHMgoNWAJEgg5GmpObmAOLAErpYjew9dDwXdYdKOS3iZRKdwI+P3JOJcYeUBg==} + '@vitest/ui@3.1.1': + resolution: {integrity: sha512-2HpiRIYg3dlvAJBV9RtsVswFgUSJK4Sv7QhpxoP0eBGkYwzGIKP34PjaV00AULQi9Ovl6LGyZfsetxDWY5BQdQ==} peerDependencies: - vitest: 3.0.9 + vitest: 3.1.1 '@vitest/utils@3.0.5': resolution: {integrity: sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==} - '@vitest/utils@3.0.9': - resolution: {integrity: sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==} + '@vitest/utils@3.1.1': + resolution: {integrity: sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -1126,10 +1121,6 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - code-block-writer@13.0.3: resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} @@ -1229,8 +1220,8 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - domutils@3.2.1: - resolution: {integrity: sha512-xWXmuRnN9OMP6ptPd2+H0cCbcYBULa5YDTbMm/2lvkWvNA3O4wcW+GvzooqBuNM8yy6pl3VIAeJTUUWUbfI5Fw==} + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} dotenv@16.4.7: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} @@ -1255,8 +1246,8 @@ packages: end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + enhanced-resolve@5.18.0: + resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==} engines: {node: '>=10.13.0'} enquirer@2.4.1: @@ -1297,14 +1288,14 @@ packages: peerDependencies: eslint: '>=8' - eslint-plugin-n@17.15.1: - resolution: {integrity: sha512-KFw7x02hZZkBdbZEFQduRGH4VkIH4MW97ClsbAM4Y4E6KguBJWGfWG1P4HEIpZk2bkoWf0bojpnjNAhYQP8beA==} + eslint-plugin-n@17.13.1: + resolution: {integrity: sha512-97qzhk1z3DdSJNCqT45EslwCu5+LB9GDadSyBItgKUfGsXAmN/aa7LRQ0ZxHffUxUzvgbTPJL27/pE9ZQWHy7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.23.0' - eslint-plugin-svelte@2.46.1: - resolution: {integrity: sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw==} + eslint-plugin-svelte@2.46.0: + resolution: {integrity: sha512-1A7iEMkzmCZ9/Iz+EAfOGYL8IoIG6zeKEq1SmpxGeM5SXmoQq+ZNnCpXFVJpsxPWYx8jIVGMerQMzX20cqUl0g==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0-0 || ^9.0.0-0 @@ -1359,6 +1350,9 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} + esrap@1.2.3: + resolution: {integrity: sha512-ZlQmCCK+n7SGoqo7DnfKaP1sJZa49P01/dXzmjCASSo04p72w8EksT2NMK8CEX8DhKsfJXANioIw8VyHNsBfvQ==} + esrap@1.4.5: resolution: {integrity: sha512-CjNMjkBWWZeHn+VX+gS8YvFwJ5+NDhg8aWZBSFJPR8qQduDNjbJodA2WcwCm7uQa5Rjqj+nZvVmceg1RbHFB9g==} @@ -1410,8 +1404,8 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fastq@1.18.0: - resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} fdir@6.4.3: resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} @@ -1505,8 +1499,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.15.0: - resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + globals@15.14.0: + resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==} engines: {node: '>=18'} globalyzer@0.1.0: @@ -1653,6 +1647,9 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + loupe@3.1.3: resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} @@ -1770,8 +1767,8 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@0.2.8: - resolution: {integrity: sha512-ts9KSdroZisdvKMWVAVCXiKqnqNfXz4+IbrBG8/BWx/TR5le+jfenvoBuIZ6UWM9nz47W7AbD9qYfAwfWMIwzA==} + package-manager-detector@0.2.7: + resolution: {integrity: sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==} parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -1869,6 +1866,10 @@ packages: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} + postcss@8.5.1: + resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==} + engines: {node: ^10 || ^12 || >=14} + postcss@8.5.3: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} @@ -1961,8 +1962,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true @@ -2073,8 +2074,8 @@ packages: resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==} engines: {node: '>=16'} - svelte@5.16.0: - resolution: {integrity: sha512-Ygqsiac6UogVED2ruKclU+pOeMThxWtp9LG+li7BXeDKC2paVIsRTMkNmcON4Zejerd1s5sZHWx6ZtU85xklVg==} + svelte@5.12.0: + resolution: {integrity: sha512-nOd7uj0D/4A3IrHnltaFYndVPGViYSs0s+Zi3N4uQg3owJt9RoiUdwxYx8qjorj5CtaGsx8dNYsFVbH6czrGNg==} engines: {node: '>=18'} synckit@0.9.2: @@ -2171,8 +2172,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.18.2: - resolution: {integrity: sha512-KuXezG6jHkvC3MvizeXgupZzaG5wjhU3yE8E7e6viOvAvD9xAWYp8/vy0WULTGe9DYDWcQu7aW03YIV3mSitrQ==} + typescript-eslint@8.18.0: + resolution: {integrity: sha512-Xq2rRjn6tzVpAyHr3+nmSg1/9k9aIHnJ2iZeOH7cfGOWqTkXTm3kwpQglEuLGdNrYvPF+2gtAs+/KF5rjVo+WQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2358,9 +2359,9 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 - '@changesets/apply-release-plan@7.0.7': + '@changesets/apply-release-plan@7.0.6': dependencies: - '@changesets/config': 3.0.5 + '@changesets/config': 3.0.4 '@changesets/get-version-range-type': 0.4.0 '@changesets/git': 3.0.2 '@changesets/should-skip-package': 0.1.1 @@ -2372,7 +2373,7 @@ snapshots: outdent: 0.5.0 prettier: 2.8.8 resolve-from: 5.0.0 - semver: 7.7.1 + semver: 7.6.3 '@changesets/assemble-release-plan@6.0.5': dependencies: @@ -2381,21 +2382,21 @@ snapshots: '@changesets/should-skip-package': 0.1.1 '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 - semver: 7.7.1 + semver: 7.6.3 '@changesets/changelog-git@0.2.0': dependencies: '@changesets/types': 6.0.0 - '@changesets/cli@2.27.11': + '@changesets/cli@2.27.10': dependencies: - '@changesets/apply-release-plan': 7.0.7 + '@changesets/apply-release-plan': 7.0.6 '@changesets/assemble-release-plan': 6.0.5 '@changesets/changelog-git': 0.2.0 - '@changesets/config': 3.0.5 + '@changesets/config': 3.0.4 '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.2 - '@changesets/get-release-plan': 4.0.6 + '@changesets/get-release-plan': 4.0.5 '@changesets/git': 3.0.2 '@changesets/logger': 0.1.1 '@changesets/pre': 2.0.1 @@ -2411,14 +2412,14 @@ snapshots: fs-extra: 7.0.1 mri: 1.2.0 p-limit: 2.3.0 - package-manager-detector: 0.2.8 + package-manager-detector: 0.2.7 picocolors: 1.1.1 resolve-from: 5.0.0 - semver: 7.7.1 + semver: 7.6.3 spawndamnit: 3.0.1 term-size: 2.2.1 - '@changesets/config@3.0.5': + '@changesets/config@3.0.4': dependencies: '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.2 @@ -2437,7 +2438,7 @@ snapshots: '@changesets/types': 6.0.0 '@manypkg/get-packages': 1.1.3 picocolors: 1.1.1 - semver: 7.7.1 + semver: 7.6.3 '@changesets/get-github-info@0.6.0': dependencies: @@ -2446,10 +2447,10 @@ snapshots: transitivePeerDependencies: - encoding - '@changesets/get-release-plan@4.0.6': + '@changesets/get-release-plan@4.0.5': dependencies: '@changesets/assemble-release-plan': 6.0.5 - '@changesets/config': 3.0.5 + '@changesets/config': 3.0.4 '@changesets/pre': 2.0.1 '@changesets/read': 0.6.2 '@changesets/types': 6.0.0 @@ -2507,14 +2508,14 @@ snapshots: human-id: 1.0.2 prettier: 2.8.8 - '@clack/core@0.4.0': + '@clack/core@0.4.1': dependencies: picocolors: 1.1.1 sisteransi: 1.0.5 - '@clack/prompts@0.9.0': + '@clack/prompts@0.9.1': dependencies: - '@clack/core': 0.4.0 + '@clack/core': 0.4.1 picocolors: 1.1.1 sisteransi: 1.0.5 @@ -2722,7 +2723,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.18.0 + fastq: 1.17.1 '@oxc-parser/binding-darwin-arm64@0.37.0': optional: true @@ -2864,26 +2865,26 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.34.5': optional: true - '@stylistic/eslint-plugin-js@2.12.1(eslint@9.17.0)': + '@stylistic/eslint-plugin-js@2.10.1(eslint@9.17.0)': dependencies: eslint: 9.17.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 - '@sveltejs/acorn-typescript@1.0.1(acorn@8.14.0)': + '@sveltejs/acorn-typescript@1.0.5(acorn@8.14.0)': dependencies: acorn: 8.14.0 - '@sveltejs/eslint-config@8.1.0(@stylistic/eslint-plugin-js@2.12.1(eslint@9.17.0))(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint-plugin-n@17.15.1(eslint@9.17.0))(eslint-plugin-svelte@2.46.1(eslint@9.17.0)(svelte@5.16.0))(eslint@9.17.0)(typescript-eslint@8.18.2(eslint@9.17.0)(typescript@5.7.2))(typescript@5.7.2)': + '@sveltejs/eslint-config@8.1.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.17.0))(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint-plugin-n@17.13.1(eslint@9.17.0))(eslint-plugin-svelte@2.46.0(eslint@9.17.0)(svelte@5.12.0))(eslint@9.17.0)(typescript-eslint@8.18.0(eslint@9.17.0)(typescript@5.7.2))(typescript@5.7.2)': dependencies: - '@stylistic/eslint-plugin-js': 2.12.1(eslint@9.17.0) + '@stylistic/eslint-plugin-js': 2.10.1(eslint@9.17.0) eslint: 9.17.0 eslint-config-prettier: 9.1.0(eslint@9.17.0) - eslint-plugin-n: 17.15.1(eslint@9.17.0) - eslint-plugin-svelte: 2.46.1(eslint@9.17.0)(svelte@5.16.0) - globals: 15.15.0 + eslint-plugin-n: 17.13.1(eslint@9.17.0) + eslint-plugin-svelte: 2.46.0(eslint@9.17.0)(svelte@5.12.0) + globals: 15.14.0 typescript: 5.7.2 - typescript-eslint: 8.18.2(eslint@9.17.0)(typescript@5.7.2) + typescript-eslint: 8.18.0(eslint@9.17.0)(typescript@5.7.2) '@svitejs/changesets-changelog-github-compact@1.2.0': dependencies: @@ -2939,14 +2940,14 @@ snapshots: dependencies: '@types/node': 22.10.2 - '@typescript-eslint/eslint-plugin@8.18.2(@typescript-eslint/parser@8.18.2(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/eslint-plugin@8.18.0(@typescript-eslint/parser@8.18.0(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.18.2(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/scope-manager': 8.18.2 - '@typescript-eslint/type-utils': 8.18.2(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.18.2(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/visitor-keys': 8.18.2 + '@typescript-eslint/parser': 8.18.0(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/scope-manager': 8.18.0 + '@typescript-eslint/type-utils': 8.18.0(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/utils': 8.18.0(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/visitor-keys': 8.18.0 eslint: 9.17.0 graphemer: 1.4.0 ignore: 5.3.2 @@ -2956,27 +2957,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.18.2(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/parser@8.18.0(eslint@9.17.0)(typescript@5.7.2)': dependencies: - '@typescript-eslint/scope-manager': 8.18.2 - '@typescript-eslint/types': 8.18.2 - '@typescript-eslint/typescript-estree': 8.18.2(typescript@5.7.2) - '@typescript-eslint/visitor-keys': 8.18.2 + '@typescript-eslint/scope-manager': 8.18.0 + '@typescript-eslint/types': 8.18.0 + '@typescript-eslint/typescript-estree': 8.18.0(typescript@5.7.2) + '@typescript-eslint/visitor-keys': 8.18.0 debug: 4.4.0 eslint: 9.17.0 typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.18.2': + '@typescript-eslint/scope-manager@8.18.0': dependencies: - '@typescript-eslint/types': 8.18.2 - '@typescript-eslint/visitor-keys': 8.18.2 + '@typescript-eslint/types': 8.18.0 + '@typescript-eslint/visitor-keys': 8.18.0 - '@typescript-eslint/type-utils@8.18.2(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/type-utils@8.18.0(eslint@9.17.0)(typescript@5.7.2)': dependencies: - '@typescript-eslint/typescript-estree': 8.18.2(typescript@5.7.2) - '@typescript-eslint/utils': 8.18.2(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/typescript-estree': 8.18.0(typescript@5.7.2) + '@typescript-eslint/utils': 8.18.0(eslint@9.17.0)(typescript@5.7.2) debug: 4.4.0 eslint: 9.17.0 ts-api-utils: 1.4.3(typescript@5.7.2) @@ -2984,36 +2985,36 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.18.2': {} + '@typescript-eslint/types@8.18.0': {} - '@typescript-eslint/typescript-estree@8.18.2(typescript@5.7.2)': + '@typescript-eslint/typescript-estree@8.18.0(typescript@5.7.2)': dependencies: - '@typescript-eslint/types': 8.18.2 - '@typescript-eslint/visitor-keys': 8.18.2 + '@typescript-eslint/types': 8.18.0 + '@typescript-eslint/visitor-keys': 8.18.0 debug: 4.4.0 fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.1 + semver: 7.6.3 ts-api-utils: 1.4.3(typescript@5.7.2) typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.18.2(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/utils@8.18.0(eslint@9.17.0)(typescript@5.7.2)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) - '@typescript-eslint/scope-manager': 8.18.2 - '@typescript-eslint/types': 8.18.2 - '@typescript-eslint/typescript-estree': 8.18.2(typescript@5.7.2) + '@typescript-eslint/scope-manager': 8.18.0 + '@typescript-eslint/types': 8.18.0 + '@typescript-eslint/typescript-estree': 8.18.0(typescript@5.7.2) eslint: 9.17.0 typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.18.2': + '@typescript-eslint/visitor-keys@8.18.0': dependencies: - '@typescript-eslint/types': 8.18.2 + '@typescript-eslint/types': 8.18.0 eslint-visitor-keys: 4.2.0 '@vitest/expect@3.0.5': @@ -3035,7 +3036,7 @@ snapshots: dependencies: tinyrainbow: 2.0.0 - '@vitest/pretty-format@3.0.9': + '@vitest/pretty-format@3.1.1': dependencies: tinyrainbow: 2.0.0 @@ -3054,28 +3055,16 @@ snapshots: dependencies: tinyspy: 3.0.2 - '@vitest/ui@3.0.5(vitest@3.0.5)': + '@vitest/ui@3.1.1(vitest@3.0.5)': dependencies: - '@vitest/utils': 3.0.5 + '@vitest/utils': 3.1.1 fflate: 0.8.2 flatted: 3.3.3 pathe: 2.0.3 sirv: 3.0.1 tinyglobby: 0.2.12 tinyrainbow: 2.0.0 - vitest: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.5) - optional: true - - '@vitest/ui@3.0.9(vitest@3.0.5)': - dependencies: - '@vitest/utils': 3.0.9 - fflate: 0.8.2 - flatted: 3.3.3 - pathe: 2.0.3 - sirv: 3.0.1 - tinyglobby: 0.2.12 - tinyrainbow: 2.0.0 - vitest: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.9) + vitest: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.1.1) '@vitest/utils@3.0.5': dependencies: @@ -3083,9 +3072,9 @@ snapshots: loupe: 3.1.3 tinyrainbow: 2.0.0 - '@vitest/utils@3.0.9': + '@vitest/utils@3.1.1': dependencies: - '@vitest/pretty-format': 3.0.9 + '@vitest/pretty-format': 3.1.1 loupe: 3.1.3 tinyrainbow: 2.0.0 @@ -3187,7 +3176,7 @@ snapshots: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.3 + loupe: 3.1.2 pathval: 2.0.0 chalk@4.1.2: @@ -3201,8 +3190,6 @@ snapshots: ci-info@3.9.0: {} - clsx@2.1.1: {} - code-block-writer@13.0.3: {} code-red@1.0.4: @@ -3276,7 +3263,7 @@ snapshots: dependencies: domelementtype: 2.3.0 - domutils@3.2.1: + domutils@3.1.0: dependencies: dom-serializer: 2.0.0 domelementtype: 2.3.0 @@ -3298,7 +3285,7 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.18.1: + enhanced-resolve@5.18.0: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 @@ -3345,7 +3332,7 @@ snapshots: eslint-compat-utils@0.5.1(eslint@9.17.0): dependencies: eslint: 9.17.0 - semver: 7.7.1 + semver: 7.6.3 eslint-config-prettier@9.1.0(eslint@9.17.0): dependencies: @@ -3358,19 +3345,19 @@ snapshots: eslint: 9.17.0 eslint-compat-utils: 0.5.1(eslint@9.17.0) - eslint-plugin-n@17.15.1(eslint@9.17.0): + eslint-plugin-n@17.13.1(eslint@9.17.0): dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) - enhanced-resolve: 5.18.1 + enhanced-resolve: 5.18.0 eslint: 9.17.0 eslint-plugin-es-x: 7.8.0(eslint@9.17.0) get-tsconfig: 4.10.0 - globals: 15.15.0 + globals: 15.14.0 ignore: 5.3.2 minimatch: 9.0.5 - semver: 7.7.1 + semver: 7.6.3 - eslint-plugin-svelte@2.46.1(eslint@9.17.0)(svelte@5.16.0): + eslint-plugin-svelte@2.46.0(eslint@9.17.0)(svelte@5.12.0): dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) '@jridgewell/sourcemap-codec': 1.5.0 @@ -3382,10 +3369,10 @@ snapshots: postcss-load-config: 3.1.4(postcss@8.5.3) postcss-safe-parser: 6.0.0(postcss@8.5.3) postcss-selector-parser: 6.1.2 - semver: 7.7.1 - svelte-eslint-parser: 0.43.0(svelte@5.16.0) + semver: 7.6.3 + svelte-eslint-parser: 0.43.0(svelte@5.12.0) optionalDependencies: - svelte: 5.16.0 + svelte: 5.12.0 transitivePeerDependencies: - ts-node @@ -3462,6 +3449,11 @@ snapshots: dependencies: estraverse: 5.3.0 + esrap@1.2.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + '@types/estree': 1.0.6 + esrap@1.4.5: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -3516,7 +3508,7 @@ snapshots: fast-levenshtein@2.0.6: {} - fastq@1.18.0: + fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -3607,7 +3599,7 @@ snapshots: globals@14.0.0: {} - globals@15.15.0: {} + globals@15.14.0: {} globalyzer@0.1.0: {} @@ -3632,7 +3624,7 @@ snapshots: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.2.1 + domutils: 3.1.0 entities: 4.5.0 human-id@1.0.2: {} @@ -3734,6 +3726,8 @@ snapshots: lodash.startcase@4.4.0: {} + loupe@3.1.2: {} + loupe@3.1.3: {} lru-cache@10.4.3: {} @@ -3841,7 +3835,7 @@ snapshots: package-json-from-dist@1.0.1: {} - package-manager-detector@0.2.8: {} + package-manager-detector@0.2.7: {} parent-module@1.0.1: dependencies: @@ -3914,6 +3908,12 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss@8.5.1: + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + postcss@8.5.3: dependencies: nanoid: 3.3.8 @@ -3929,10 +3929,10 @@ snapshots: optionalDependencies: prettier: 3.4.2 - prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.16.0): + prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.12.0): dependencies: prettier: 3.4.2 - svelte: 5.16.0 + svelte: 5.12.0 prettier@2.8.8: {} @@ -4019,7 +4019,7 @@ snapshots: safer-buffer@2.1.2: {} - semver@7.7.1: {} + semver@7.6.3: {} shebang-command@2.0.0: dependencies: @@ -4052,7 +4052,7 @@ snapshots: get-stdin: 9.0.0 git-hooks-list: 3.1.0 is-plain-obj: 4.1.0 - semver: 7.7.1 + semver: 7.6.3 sort-object-keys: 1.1.3 tinyglobby: 0.2.10 @@ -4123,7 +4123,7 @@ snapshots: dependencies: has-flag: 4.0.0 - svelte-eslint-parser@0.43.0(svelte@5.16.0): + svelte-eslint-parser@0.43.0(svelte@5.12.0): dependencies: eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 @@ -4131,7 +4131,7 @@ snapshots: postcss: 8.5.3 postcss-scss: 4.0.9(postcss@8.5.3) optionalDependencies: - svelte: 5.16.0 + svelte: 5.12.0 svelte@4.2.19: dependencies: @@ -4150,7 +4150,7 @@ snapshots: magic-string: 0.30.17 periscopic: 3.1.0 - svelte@5.16.0: + svelte@5.12.0: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 @@ -4159,9 +4159,8 @@ snapshots: acorn-typescript: 1.4.13(acorn@8.14.0) aria-query: 5.3.2 axobject-query: 4.1.0 - clsx: 2.1.1 esm-env: 1.2.1 - esrap: 1.4.5 + esrap: 1.2.3 is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.17 @@ -4258,11 +4257,11 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.18.2(eslint@9.17.0)(typescript@5.7.2): + typescript-eslint@8.18.0(eslint@9.17.0)(typescript@5.7.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.18.2(@typescript-eslint/parser@8.18.2(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/parser': 8.18.2(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.18.2(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/eslint-plugin': 8.18.0(@typescript-eslint/parser@8.18.0(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/parser': 8.18.0(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/utils': 8.18.0(eslint@9.17.0)(typescript@5.7.2) eslint: 9.17.0 typescript: 5.7.2 transitivePeerDependencies: @@ -4328,52 +4327,13 @@ snapshots: vite@6.1.0(@types/node@22.10.2): dependencies: esbuild: 0.24.2 - postcss: 8.5.3 + postcss: 8.5.1 rollup: 4.34.5 optionalDependencies: '@types/node': 22.10.2 fsevents: 2.3.3 - vitest@3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.5): - dependencies: - '@vitest/expect': 3.0.5 - '@vitest/mocker': 3.0.5(vite@6.1.0(@types/node@22.10.2)) - '@vitest/pretty-format': 3.0.5 - '@vitest/runner': 3.0.5 - '@vitest/snapshot': 3.0.5 - '@vitest/spy': 3.0.5 - '@vitest/utils': 3.0.5 - chai: 5.1.2 - debug: 4.4.0 - expect-type: 1.1.0 - magic-string: 0.30.17 - pathe: 2.0.2 - std-env: 3.8.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinypool: 1.0.2 - tinyrainbow: 2.0.0 - vite: 6.1.0(@types/node@22.10.2) - vite-node: 3.0.5(@types/node@22.10.2) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 22.10.2 - '@vitest/ui': 3.0.5(vitest@3.0.5) - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vitest@3.0.5(@types/node@22.10.2)(@vitest/ui@3.0.9): + vitest@3.0.5(@types/node@22.10.2)(@vitest/ui@3.1.1): dependencies: '@vitest/expect': 3.0.5 '@vitest/mocker': 3.0.5(vite@6.1.0(@types/node@22.10.2)) @@ -4397,7 +4357,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.10.2 - '@vitest/ui': 3.0.9(vitest@3.0.5) + '@vitest/ui': 3.1.1(vitest@3.0.5) transitivePeerDependencies: - jiti - less From 7ff0770554aa682b71fc47ddde433b1e07afb407 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Thu, 3 Apr 2025 07:47:05 -0700 Subject: [PATCH 02/38] feat: remove `adapter-cloudflare-workers` and upgrade other adapters (#520) * chore: remove `adapter-cloudflare-workers` * Update packages/addons/sveltekit-adapter/index.ts * Create hip-brooms-yawn.md --- .changeset/hip-brooms-yawn.md | 5 +++++ packages/addons/sveltekit-adapter/index.ts | 11 +++++------ 2 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 .changeset/hip-brooms-yawn.md diff --git a/.changeset/hip-brooms-yawn.md b/.changeset/hip-brooms-yawn.md new file mode 100644 index 00000000..978c753d --- /dev/null +++ b/.changeset/hip-brooms-yawn.md @@ -0,0 +1,5 @@ +--- +"sv": minor +--- + +feat: remove `adapter-cloudflare-workers` and upgrade other adapters diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 59de5120..5f7de2d5 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -9,13 +9,12 @@ type Adapter = { }; const adapters: Adapter[] = [ - { id: 'auto', package: '@sveltejs/adapter-auto', version: '^4.0.0' }, - { id: 'node', package: '@sveltejs/adapter-node', version: '^5.2.11' }, + { id: 'auto', package: '@sveltejs/adapter-auto', version: '^6.0.0' }, + { id: 'node', package: '@sveltejs/adapter-node', version: '^5.2.12' }, { id: 'static', package: '@sveltejs/adapter-static', version: '^3.0.8' }, - { id: 'vercel', package: '@sveltejs/adapter-vercel', version: '^5.5.2' }, - { id: 'cloudflare-pages', package: '@sveltejs/adapter-cloudflare', version: '^5.0.1' }, - { id: 'cloudflare-workers', package: '@sveltejs/adapter-cloudflare-workers', version: '^2.7.0' }, - { id: 'netlify', package: '@sveltejs/adapter-netlify', version: '^4.4.0' } + { id: 'vercel', package: '@sveltejs/adapter-vercel', version: '^5.6.3' }, + { id: 'cloudflare-pages', package: '@sveltejs/adapter-cloudflare', version: '^7.0.0' }, + { id: 'netlify', package: '@sveltejs/adapter-netlify', version: '^5.0.0' } ]; const options = defineAddonOptions({ From 8b7dba05ce33938e639d2d3b8a11b37beeef6fec Mon Sep 17 00:00:00 2001 From: Manuel <30698007+manuel3108@users.noreply.github.com> Date: Thu, 3 Apr 2025 17:20:29 +0200 Subject: [PATCH 03/38] security: upgrade vite to avoid CVE-2025-31486 (#522) * security: upgrade vite to avoid CVE-2025-31486 * fix formatting --- .changeset/thin-ways-burn.md | 5 +++++ packages/create/templates/demo/package.template.json | 2 +- packages/create/templates/library/package.template.json | 2 +- packages/create/templates/minimal/package.template.json | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/thin-ways-burn.md diff --git a/.changeset/thin-ways-burn.md b/.changeset/thin-ways-burn.md new file mode 100644 index 00000000..a777f580 --- /dev/null +++ b/.changeset/thin-ways-burn.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +security: upgrade vite to avoid CVE-2025-31486 diff --git a/packages/create/templates/demo/package.template.json b/packages/create/templates/demo/package.template.json index 7a06997e..dd651203 100644 --- a/packages/create/templates/demo/package.template.json +++ b/packages/create/templates/demo/package.template.json @@ -16,6 +16,6 @@ "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.25.0", - "vite": "^6.2.4" + "vite": "^6.2.5" } } diff --git a/packages/create/templates/library/package.template.json b/packages/create/templates/library/package.template.json index 61fbdfff..b0c824e3 100644 --- a/packages/create/templates/library/package.template.json +++ b/packages/create/templates/library/package.template.json @@ -30,7 +30,7 @@ "publint": "^0.3.2", "svelte": "^5.0.0", "typescript": "^5.3.2", - "vite": "^6.2.4" + "vite": "^6.2.5" }, "keywords": ["svelte"] } diff --git a/packages/create/templates/minimal/package.template.json b/packages/create/templates/minimal/package.template.json index b23b6cf9..8d15b23d 100644 --- a/packages/create/templates/minimal/package.template.json +++ b/packages/create/templates/minimal/package.template.json @@ -14,6 +14,6 @@ "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", - "vite": "^6.2.4" + "vite": "^6.2.5" } } From 701626c63a1bdc47c2a0a24d027d2c9dd8ac12f3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 17:21:34 +0200 Subject: [PATCH 04/38] Version Packages (#518) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/chilly-bobcats-appear.md | 5 ----- .changeset/hip-brooms-yawn.md | 5 ----- .changeset/thin-ways-burn.md | 5 ----- packages/cli/CHANGELOG.md | 15 +++++++++++++++ packages/cli/package.json | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) delete mode 100644 .changeset/chilly-bobcats-appear.md delete mode 100644 .changeset/hip-brooms-yawn.md delete mode 100644 .changeset/thin-ways-burn.md diff --git a/.changeset/chilly-bobcats-appear.md b/.changeset/chilly-bobcats-appear.md deleted file mode 100644 index a4b1d1e2..00000000 --- a/.changeset/chilly-bobcats-appear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -security: Upgrade Vite to avoid CVE-2025-31125 diff --git a/.changeset/hip-brooms-yawn.md b/.changeset/hip-brooms-yawn.md deleted file mode 100644 index 978c753d..00000000 --- a/.changeset/hip-brooms-yawn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"sv": minor ---- - -feat: remove `adapter-cloudflare-workers` and upgrade other adapters diff --git a/.changeset/thin-ways-burn.md b/.changeset/thin-ways-burn.md deleted file mode 100644 index a777f580..00000000 --- a/.changeset/thin-ways-burn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -security: upgrade vite to avoid CVE-2025-31486 diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index a4c71bc5..f0d523f9 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,20 @@ # sv +## 0.8.0 +### Minor Changes + + +- feat: remove `adapter-cloudflare-workers` and upgrade other adapters ([#520](https://github.com/sveltejs/cli/pull/520)) + + +### Patch Changes + + +- security: Upgrade Vite to avoid CVE-2025-31125 ([#517](https://github.com/sveltejs/cli/pull/517)) + + +- security: upgrade vite to avoid CVE-2025-31486 ([#522](https://github.com/sveltejs/cli/pull/522)) + ## 0.7.2 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 71ab8a52..13de68d9 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "sv", - "version": "0.7.2", + "version": "0.8.0", "type": "module", "description": "A CLI for creating and updating SvelteKit projects", "license": "MIT", From c94db33f88b16cb32602638d7466c2616e89429b Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Thu, 10 Apr 2025 18:58:52 +0100 Subject: [PATCH 05/38] fix(prettier): skip non-JSON prettierrc config (#527) Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> Co-authored-by: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> --- .changeset/pretty-emus-breathe.md | 5 +++++ packages/addons/prettier/index.ts | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .changeset/pretty-emus-breathe.md diff --git a/.changeset/pretty-emus-breathe.md b/.changeset/pretty-emus-breathe.md new file mode 100644 index 00000000..09b5a016 --- /dev/null +++ b/.changeset/pretty-emus-breathe.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix: warn on an unparsable `.prettierrc` config file diff --git a/packages/addons/prettier/index.ts b/packages/addons/prettier/index.ts index 873ffd51..4c3f1117 100644 --- a/packages/addons/prettier/index.ts +++ b/packages/addons/prettier/index.ts @@ -24,7 +24,15 @@ export default defineAddon({ }); sv.file('.prettierrc', (content) => { - const { data, generateCode } = parseJson(content); + let data, generateCode; + try { + ({ data, generateCode } = parseJson(content)); + } catch { + log.warn( + `A ${colors.yellow('.prettierrc')} config already exists and cannot be parsed as JSON. Skipping initialization.` + ); + return content; + } if (Object.keys(data).length === 0) { // we'll only set these defaults if there is no pre-existing config data.useTabs = true; From e045a5407bfbd518e87bdf9182d056f439b86a10 Mon Sep 17 00:00:00 2001 From: Manuel <30698007+manuel3108@users.noreply.github.com> Date: Fri, 11 Apr 2025 20:47:27 +0200 Subject: [PATCH 06/38] chore: get rid of `@sveltejs/ast-tooling` (#534) Co-authored-by: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> --- packages/ast-tooling/README.md | 5 -- packages/ast-tooling/package.json | 40 --------- packages/ast-tooling/tsconfig.json | 9 -- packages/ast-tooling/utils.ts | 72 ---------------- packages/ast-tooling/vitest.config.ts | 8 -- packages/core/index.ts | 2 +- packages/core/package.json | 16 +++- packages/core/tests/css/index.ts | 2 +- packages/core/tests/html/index.ts | 2 +- packages/core/tests/js/index.ts | 2 +- packages/{ast-tooling => core}/tests/utils.ts | 9 +- packages/core/tooling/css/index.ts | 9 +- packages/core/tooling/html/index.ts | 2 +- .../{ast-tooling => core/tooling}/index.ts | 83 ++++++++++++++++--- packages/core/tooling/js/array.ts | 2 +- packages/core/tooling/js/common.ts | 8 +- packages/core/tooling/js/exports.ts | 2 +- packages/core/tooling/js/function.ts | 2 +- packages/core/tooling/js/imports.ts | 2 +- packages/core/tooling/js/index.ts | 2 +- packages/core/tooling/js/kit.ts | 2 +- packages/core/tooling/js/object.ts | 2 +- .../tooling/js}/ts-estree.ts | 0 packages/core/tooling/js/variables.ts | 2 +- packages/core/tooling/parsers.ts | 22 ++--- packages/core/vitest.config.ts | 2 +- pnpm-lock.yaml | 76 ++++++++--------- rolldown.config.js | 1 - 28 files changed, 151 insertions(+), 235 deletions(-) delete mode 100644 packages/ast-tooling/README.md delete mode 100644 packages/ast-tooling/package.json delete mode 100644 packages/ast-tooling/tsconfig.json delete mode 100644 packages/ast-tooling/utils.ts delete mode 100644 packages/ast-tooling/vitest.config.ts rename packages/{ast-tooling => core}/tests/utils.ts (95%) rename packages/{ast-tooling => core/tooling}/index.ts (72%) rename packages/{ast-tooling => core/tooling/js}/ts-estree.ts (100%) diff --git a/packages/ast-tooling/README.md b/packages/ast-tooling/README.md deleted file mode 100644 index 7f3a2c38..00000000 --- a/packages/ast-tooling/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# @sveltejs/ast-tooling - -This package provides tools and methods for parsing and serializing CSS, HTML and JS AST's. As the main [sv](https://svelte-add.com) project requires all of these tools they have been extracted into this separate project. - -Additionally this separate package allows us to bundle all (currently 8) required dependencies into on single package. diff --git a/packages/ast-tooling/package.json b/packages/ast-tooling/package.json deleted file mode 100644 index ee7629ce..00000000 --- a/packages/ast-tooling/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "@sveltejs/ast-tooling", - "private": true, - "version": "0.0.0", - "type": "module", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/sveltejs/cli/tree/main/packages/ast-tooling" - }, - "bugs": "https://github.com/sveltejs/cli/issues", - "scripts": { - "check": "tsc", - "format": "pnpm lint --write", - "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore" - }, - "files": [ - "dist" - ], - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } - }, - "devDependencies": { - "@sveltejs/acorn-typescript": "^1.0.1", - "@types/estree": "^1.0.6", - "acorn": "^8.14.0", - "dedent": "^1.5.3", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "esrap": "^1.4.5", - "htmlparser2": "^9.1.0", - "postcss": "^8.4.49", - "silver-fleece": "^1.2.1", - "zimmerframe": "^1.1.2" - } -} diff --git a/packages/ast-tooling/tsconfig.json b/packages/ast-tooling/tsconfig.json deleted file mode 100644 index c98d2852..00000000 --- a/packages/ast-tooling/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "checkJs": false, - "isolatedDeclarations": true, - "declaration": true - }, - "exclude": ["vitest.config.ts"] -} diff --git a/packages/ast-tooling/utils.ts b/packages/ast-tooling/utils.ts deleted file mode 100644 index b101faab..00000000 --- a/packages/ast-tooling/utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -import * as Walker from 'zimmerframe'; -import type { TsEstree } from './ts-estree.ts'; - -// Sourced from `golden-fleece` -// https://github.com/Rich-Harris/golden-fleece/blob/f2446f331640f325e13609ed99b74b6a45e755c2/src/patch.ts#L302 -export function guessIndentString(str: string | undefined): string { - if (!str) return '\t'; - - const lines = str.split('\n'); - - let tabs = 0; - let spaces = 0; - let minSpaces = 8; - - lines.forEach((line) => { - const match = /^(?: +|\t+)/.exec(line); - if (!match) return; - - const whitespace = match[0]; - if (whitespace.length === line.length) return; - - if (whitespace[0] === '\t') { - tabs += 1; - } else { - spaces += 1; - if (whitespace.length > 1 && whitespace.length < minSpaces) { - minSpaces = whitespace.length; - } - } - }); - - if (spaces > tabs) { - let result = ''; - while (minSpaces--) result += ' '; - return result; - } else { - return '\t'; - } -} - -export function guessQuoteStyle(ast: TsEstree.Node): 'single' | 'double' | undefined { - let singleCount = 0; - let doubleCount = 0; - - Walker.walk(ast, null, { - Literal(node) { - if (node.raw && node.raw.length >= 2) { - // we have at least two characters in the raw string that could represent both quotes - const quotes = [node.raw[0], node.raw[node.raw.length - 1]]; - for (const quote of quotes) { - switch (quote) { - case "'": - singleCount++; - break; - case '"': - doubleCount++; - break; - default: - break; - } - } - } - } - }); - - if (singleCount === 0 && doubleCount === 0) { - // new file or file without any quotes - return undefined; - } - - return singleCount > doubleCount ? 'single' : 'double'; -} diff --git a/packages/ast-tooling/vitest.config.ts b/packages/ast-tooling/vitest.config.ts deleted file mode 100644 index 01f7288b..00000000 --- a/packages/ast-tooling/vitest.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineProject } from 'vitest/config'; - -export default defineProject({ - test: { - name: 'ast-tooling', - include: ['./tests/*.ts'] - } -}); diff --git a/packages/core/index.ts b/packages/core/index.ts index 9ba5b086..e68a90e8 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -9,4 +9,4 @@ export type * from './addon/options.ts'; export type * from './addon/config.ts'; export type * from './addon/workspace.ts'; -export { Walker } from '@sveltejs/ast-tooling'; +export { Walker } from './tooling/index.ts'; diff --git a/packages/core/package.json b/packages/core/package.json index 4de33a4b..507fa17d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -41,15 +41,23 @@ "default": "./dist/parsers.js" } }, - "dependencies": { - "@sveltejs/ast-tooling": "workspace:*" - }, "devDependencies": { + "@sveltejs/acorn-typescript": "^1.0.1", "@sveltejs/clack-prompts": "workspace:*", + "@types/estree": "^1.0.6", + "acorn": "^8.14.0", "decircular": "^1.0.0", "dedent": "^1.5.3", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "esrap": "^1.4.5", + "htmlparser2": "^9.1.0", "magic-string": "^0.30.15", - "picocolors": "^1.1.1" + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "silver-fleece": "^1.2.1", + "zimmerframe": "^1.1.2" }, "keywords": [ "create", diff --git a/packages/core/tests/css/index.ts b/packages/core/tests/css/index.ts index d9d20386..6548abf7 100644 --- a/packages/core/tests/css/index.ts +++ b/packages/core/tests/css/index.ts @@ -3,7 +3,7 @@ import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import prettier from 'prettier'; import { describe, expect, test } from 'vitest'; -import { parseCss, serializeCss } from '@sveltejs/ast-tooling'; +import { parseCss, serializeCss } from '../../tooling/index.ts'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); diff --git a/packages/core/tests/html/index.ts b/packages/core/tests/html/index.ts index b5e33cd3..d327848b 100644 --- a/packages/core/tests/html/index.ts +++ b/packages/core/tests/html/index.ts @@ -3,7 +3,7 @@ import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import prettier from 'prettier'; import { describe, expect, test } from 'vitest'; -import { parseHtml, serializeHtml } from '@sveltejs/ast-tooling'; +import { parseHtml, serializeHtml } from '../../tooling/index.ts'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); diff --git a/packages/core/tests/js/index.ts b/packages/core/tests/js/index.ts index 6bcfda9f..bc6a37b1 100644 --- a/packages/core/tests/js/index.ts +++ b/packages/core/tests/js/index.ts @@ -3,7 +3,7 @@ import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import prettier from 'prettier'; import { describe, expect, test } from 'vitest'; -import { parseScript, serializeScript } from '@sveltejs/ast-tooling'; +import { parseScript, serializeScript } from '../../tooling/index.ts'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); diff --git a/packages/ast-tooling/tests/utils.ts b/packages/core/tests/utils.ts similarity index 95% rename from packages/ast-tooling/tests/utils.ts rename to packages/core/tests/utils.ts index fd65346d..a2a4405b 100644 --- a/packages/ast-tooling/tests/utils.ts +++ b/packages/core/tests/utils.ts @@ -1,7 +1,12 @@ import { expect, test } from 'vitest'; import dedent from 'dedent'; -import { guessIndentString, guessQuoteStyle } from '../utils.ts'; -import { parseScript, serializeScript, type AstTypes } from '../index.ts'; +import { + parseScript, + serializeScript, + guessIndentString, + guessQuoteStyle, + type AstTypes +} from '../tooling/index.ts'; test('guessIndentString - one tab', () => { const code = dedent` diff --git a/packages/core/tooling/css/index.ts b/packages/core/tooling/css/index.ts index f3a460ca..ab69813e 100644 --- a/packages/core/tooling/css/index.ts +++ b/packages/core/tooling/css/index.ts @@ -1,11 +1,4 @@ -import { - Declaration, - Rule, - AtRule, - Comment, - type CssAst, - type CssChildNode -} from '@sveltejs/ast-tooling'; +import { Declaration, Rule, AtRule, Comment, type CssAst, type CssChildNode } from '../index.ts'; export type { CssAst }; diff --git a/packages/core/tooling/html/index.ts b/packages/core/tooling/html/index.ts index a02e689a..94dcd881 100644 --- a/packages/core/tooling/html/index.ts +++ b/packages/core/tooling/html/index.ts @@ -5,7 +5,7 @@ import { HtmlElement, HtmlElementType, parseHtml -} from '@sveltejs/ast-tooling'; +} from '../index.ts'; import { addFromString } from '../js/common.ts'; export { HtmlElement, HtmlElementType }; diff --git a/packages/ast-tooling/index.ts b/packages/core/tooling/index.ts similarity index 72% rename from packages/ast-tooling/index.ts rename to packages/core/tooling/index.ts index f7ac628c..27e41cbe 100644 --- a/packages/ast-tooling/index.ts +++ b/packages/core/tooling/index.ts @@ -1,3 +1,5 @@ +import * as Walker from 'zimmerframe'; +import type { TsEstree } from './js/ts-estree.ts'; import { Document, Element, type ChildNode } from 'domhandler'; import { ElementType, parseDocument } from 'htmlparser2'; import serializeDom from 'dom-serializer'; @@ -11,21 +13,10 @@ import { type ChildNode as CssChildNode } from 'postcss'; import * as fleece from 'silver-fleece'; -import * as Walker from 'zimmerframe'; -import type { TsEstree } from './ts-estree.ts'; -import { guessIndentString, guessQuoteStyle } from './utils.ts'; import { print as esrapPrint } from 'esrap'; import * as acorn from 'acorn'; import { tsPlugin } from '@sveltejs/acorn-typescript'; -/** - * Most of the AST tooling is pretty big in bundle size and bundling takes forever. - * Nevertheless bundling of these tools seems smart, as they add many dependencies to each install. - * In order to avoid long bundling during development, all of the AST tools have been extracted - * into this separate package and are bundled only here. This package has been marked as external - * and will not be bundled into all other projects / bundles. - */ - export { // html Document as HtmlDocument, @@ -179,3 +170,73 @@ export function serializeJson(originalInput: string, data: unknown): string { return fleece.stringify(data, { spaces }); } + +// Sourced from `golden-fleece` +// https://github.com/Rich-Harris/golden-fleece/blob/f2446f331640f325e13609ed99b74b6a45e755c2/src/patch.ts#L302 +export function guessIndentString(str: string | undefined): string { + if (!str) return '\t'; + + const lines = str.split('\n'); + + let tabs = 0; + let spaces = 0; + let minSpaces = 8; + + lines.forEach((line) => { + const match = /^(?: +|\t+)/.exec(line); + if (!match) return; + + const whitespace = match[0]; + if (whitespace.length === line.length) return; + + if (whitespace[0] === '\t') { + tabs += 1; + } else { + spaces += 1; + if (whitespace.length > 1 && whitespace.length < minSpaces) { + minSpaces = whitespace.length; + } + } + }); + + if (spaces > tabs) { + let result = ''; + while (minSpaces--) result += ' '; + return result; + } else { + return '\t'; + } +} + +export function guessQuoteStyle(ast: TsEstree.Node): 'single' | 'double' | undefined { + let singleCount = 0; + let doubleCount = 0; + + Walker.walk(ast, null, { + Literal(node) { + if (node.raw && node.raw.length >= 2) { + // we have at least two characters in the raw string that could represent both quotes + const quotes = [node.raw[0], node.raw[node.raw.length - 1]]; + for (const quote of quotes) { + switch (quote) { + case "'": + singleCount++; + break; + case '"': + doubleCount++; + break; + default: + break; + } + } + } + } + }); + + if (singleCount === 0 && doubleCount === 0) { + // new file or file without any quotes + return undefined; + } + + return singleCount > doubleCount ? 'single' : 'double'; +} diff --git a/packages/core/tooling/js/array.ts b/packages/core/tooling/js/array.ts index 1565d10a..46da53ee 100644 --- a/packages/core/tooling/js/array.ts +++ b/packages/core/tooling/js/array.ts @@ -1,5 +1,5 @@ import { areNodesEqual } from './common.ts'; -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function createEmpty(): AstTypes.ArrayExpression { const arrayExpression: AstTypes.ArrayExpression = { diff --git a/packages/core/tooling/js/common.ts b/packages/core/tooling/js/common.ts index c50900f1..e7035b40 100644 --- a/packages/core/tooling/js/common.ts +++ b/packages/core/tooling/js/common.ts @@ -1,10 +1,4 @@ -import { - type AstTypes, - Walker, - parseScript, - serializeScript, - stripAst -} from '@sveltejs/ast-tooling'; +import { type AstTypes, Walker, parseScript, serializeScript, stripAst } from '../index.ts'; import decircular from 'decircular'; import dedent from 'dedent'; diff --git a/packages/core/tooling/js/exports.ts b/packages/core/tooling/js/exports.ts index d09f198d..6ccf0232 100644 --- a/packages/core/tooling/js/exports.ts +++ b/packages/core/tooling/js/exports.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export type ExportDefaultReturn = { astNode: AstTypes.ExportDefaultDeclaration; diff --git a/packages/core/tooling/js/function.ts b/packages/core/tooling/js/function.ts index 672394e5..f6701982 100644 --- a/packages/core/tooling/js/function.ts +++ b/packages/core/tooling/js/function.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function call(name: string, args: string[]): AstTypes.CallExpression { const callExpression: AstTypes.CallExpression = { diff --git a/packages/core/tooling/js/imports.ts b/packages/core/tooling/js/imports.ts index 61746676..877d747c 100644 --- a/packages/core/tooling/js/imports.ts +++ b/packages/core/tooling/js/imports.ts @@ -1,4 +1,4 @@ -import { Walker, type AstTypes } from '@sveltejs/ast-tooling'; +import { Walker, type AstTypes } from '../index.ts'; import { areNodesEqual } from './common.ts'; export function addEmpty(ast: AstTypes.Program, importFrom: string): void { diff --git a/packages/core/tooling/js/index.ts b/packages/core/tooling/js/index.ts index 7e556569..08482f14 100644 --- a/packages/core/tooling/js/index.ts +++ b/packages/core/tooling/js/index.ts @@ -6,4 +6,4 @@ export * as imports from './imports.ts'; export * as variables from './variables.ts'; export * as exports from './exports.ts'; export * as kit from './kit.ts'; -export type { AstTypes } from '@sveltejs/ast-tooling'; +export type { AstTypes } from '../index.ts'; diff --git a/packages/core/tooling/js/kit.ts b/packages/core/tooling/js/kit.ts index 9f4f25c9..d9a38a4a 100644 --- a/packages/core/tooling/js/kit.ts +++ b/packages/core/tooling/js/kit.ts @@ -1,4 +1,4 @@ -import { Walker, type AstTypes } from '@sveltejs/ast-tooling'; +import { Walker, type AstTypes } from '../index.ts'; import { common, functions, imports, variables, exports } from '../js/index.ts'; export function addGlobalAppInterface( diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index 22ffb19c..a909aa72 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function property( ast: AstTypes.ObjectExpression, diff --git a/packages/ast-tooling/ts-estree.ts b/packages/core/tooling/js/ts-estree.ts similarity index 100% rename from packages/ast-tooling/ts-estree.ts rename to packages/core/tooling/js/ts-estree.ts diff --git a/packages/core/tooling/js/variables.ts b/packages/core/tooling/js/variables.ts index 1390343c..bd652dfd 100644 --- a/packages/core/tooling/js/variables.ts +++ b/packages/core/tooling/js/variables.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function declaration( ast: AstTypes.Program | AstTypes.Declaration, diff --git a/packages/core/tooling/parsers.ts b/packages/core/tooling/parsers.ts index 846cb8ea..f7764d34 100644 --- a/packages/core/tooling/parsers.ts +++ b/packages/core/tooling/parsers.ts @@ -1,4 +1,4 @@ -import * as tools from '@sveltejs/ast-tooling'; +import * as utils from './index.ts'; import MagicString from 'magic-string'; type ParseBase = { @@ -6,31 +6,31 @@ type ParseBase = { generateCode(): string; }; -export function parseScript(source: string): { ast: tools.AstTypes.Program } & ParseBase { - const ast = tools.parseScript(source); - const generateCode = () => tools.serializeScript(ast, source); +export function parseScript(source: string): { ast: utils.AstTypes.Program } & ParseBase { + const ast = utils.parseScript(source); + const generateCode = () => utils.serializeScript(ast, source); return { ast, source, generateCode }; } -export function parseCss(source: string): { ast: tools.CssAst } & ParseBase { - const ast = tools.parseCss(source); +export function parseCss(source: string): { ast: utils.CssAst } & ParseBase { + const ast = utils.parseCss(source); const generateCode = () => ast.toString(); return { ast, source, generateCode }; } -export function parseHtml(source: string): { ast: tools.HtmlDocument } & ParseBase { - const ast = tools.parseHtml(source); - const generateCode = () => tools.serializeHtml(ast); +export function parseHtml(source: string): { ast: utils.HtmlDocument } & ParseBase { + const ast = utils.parseHtml(source); + const generateCode = () => utils.serializeHtml(ast); return { ast, source, generateCode }; } export function parseJson(source: string): { data: any } & ParseBase { if (!source) source = '{}'; - const data = tools.parseJson(source); - const generateCode = () => tools.serializeJson(source, data); + const data = utils.parseJson(source); + const generateCode = () => utils.serializeJson(source, data); return { data, source, generateCode }; } diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts index 8b52c7a6..6aa2d6af 100644 --- a/packages/core/vitest.config.ts +++ b/packages/core/vitest.config.ts @@ -3,6 +3,6 @@ import { defineProject } from 'vitest/config'; export default defineProject({ test: { name: 'core', - include: ['./tests/**/index.ts'] + include: ['./tests/**/index.ts', './tests/*.ts'] } }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11a9ea78..bd18dcc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -88,45 +88,6 @@ importers: specifier: workspace:* version: link:../core - packages/ast-tooling: - devDependencies: - '@sveltejs/acorn-typescript': - specifier: ^1.0.1 - version: 1.0.5(acorn@8.14.0) - '@types/estree': - specifier: ^1.0.6 - version: 1.0.6 - acorn: - specifier: ^8.14.0 - version: 8.14.0 - dedent: - specifier: ^1.5.3 - version: 1.5.3 - dom-serializer: - specifier: ^2.0.0 - version: 2.0.0 - domhandler: - specifier: ^5.0.3 - version: 5.0.3 - domutils: - specifier: ^3.1.0 - version: 3.1.0 - esrap: - specifier: ^1.4.5 - version: 1.4.5 - htmlparser2: - specifier: ^9.1.0 - version: 9.1.0 - postcss: - specifier: ^8.4.49 - version: 8.5.1 - silver-fleece: - specifier: ^1.2.1 - version: 1.2.1 - zimmerframe: - specifier: ^1.1.2 - version: 1.1.2 - packages/clack-core: devDependencies: picocolors: @@ -206,26 +167,55 @@ importers: version: 0.41.0(typescript@5.7.2) packages/core: - dependencies: - '@sveltejs/ast-tooling': - specifier: workspace:* - version: link:../ast-tooling devDependencies: + '@sveltejs/acorn-typescript': + specifier: ^1.0.1 + version: 1.0.5(acorn@8.14.0) '@sveltejs/clack-prompts': specifier: workspace:* version: link:../clack-prompts + '@types/estree': + specifier: ^1.0.6 + version: 1.0.6 + acorn: + specifier: ^8.14.0 + version: 8.14.0 decircular: specifier: ^1.0.0 version: 1.0.0 dedent: specifier: ^1.5.3 version: 1.5.3 + dom-serializer: + specifier: ^2.0.0 + version: 2.0.0 + domhandler: + specifier: ^5.0.3 + version: 5.0.3 + domutils: + specifier: ^3.1.0 + version: 3.1.0 + esrap: + specifier: ^1.4.5 + version: 1.4.5 + htmlparser2: + specifier: ^9.1.0 + version: 9.1.0 magic-string: specifier: ^0.30.15 version: 0.30.17 picocolors: specifier: ^1.1.1 version: 1.1.1 + postcss: + specifier: ^8.4.49 + version: 8.5.3 + silver-fleece: + specifier: ^1.2.1 + version: 1.2.1 + zimmerframe: + specifier: ^1.1.2 + version: 1.1.2 packages/create: devDependencies: diff --git a/rolldown.config.js b/rolldown.config.js index 5d193af7..3ffbb1da 100644 --- a/rolldown.config.js +++ b/rolldown.config.js @@ -121,7 +121,6 @@ function getConfig(project) { export default [ getConfig('clack-core'), getConfig('clack-prompts'), - getConfig('ast-tooling'), getConfig('create'), getConfig('core'), getConfig('cli') From b6eac28f4187770b041d8d2aaeeeb3564298efd7 Mon Sep 17 00:00:00 2001 From: Manuel <30698007+manuel3108@users.noreply.github.com> Date: Fri, 11 Apr 2025 21:09:57 +0200 Subject: [PATCH 07/38] chore: do not add redundant `ignores` property to `eslint` config (#533) Co-authored-by: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> --- .changeset/twelve-lizards-warn.md | 5 +++++ packages/addons/eslint/index.ts | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .changeset/twelve-lizards-warn.md diff --git a/.changeset/twelve-lizards-warn.md b/.changeset/twelve-lizards-warn.md new file mode 100644 index 00000000..b1814725 --- /dev/null +++ b/.changeset/twelve-lizards-warn.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +chore: remove redundant `ignores` property in `eslint` config diff --git a/packages/addons/eslint/index.ts b/packages/addons/eslint/index.ts index 786f8810..6f93778d 100644 --- a/packages/addons/eslint/index.ts +++ b/packages/addons/eslint/index.ts @@ -115,7 +115,6 @@ export default defineAddon({ if (typescript) { const svelteTSParserConfig = object.create({ files: common.expressionFromString("['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js']"), - ignores: common.expressionFromString("['eslint.config.js', 'svelte.config.js']"), languageOptions: object.create({ parserOptions: object.create({ projectService: common.expressionFromString('true'), From f11bae50ef3151bd06b7dc60850bb6436124ca27 Mon Sep 17 00:00:00 2001 From: Manuel <30698007+manuel3108@users.noreply.github.com> Date: Sat, 12 Apr 2025 04:15:43 +0200 Subject: [PATCH 08/38] chore: update dependencies (#523) Co-authored-by: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> --- community-addon-template/package.json | 4 +- .../tests/setup/global.ts | 4 +- package.json | 29 +- packages/addons/_tests/_setup/global.ts | 4 +- packages/addons/_tests/vitest/test.ts | 6 +- packages/cli/package.json | 8 +- packages/core/package.json | 2 +- packages/core/tooling/js/exports.ts | 3 +- packages/core/tooling/js/imports.ts | 6 +- packages/create/templates/demo/src/app.css | 12 +- packages/migrate/package.json | 14 +- pnpm-lock.yaml | 1726 ++++++++--------- 12 files changed, 899 insertions(+), 919 deletions(-) diff --git a/community-addon-template/package.json b/community-addon-template/package.json index 90d44a8e..c9ba0aa1 100644 --- a/community-addon-template/package.json +++ b/community-addon-template/package.json @@ -18,9 +18,9 @@ "@sveltejs/cli-core": "workspace:*" }, "devDependencies": { - "@playwright/test": "^1.49.1", + "@playwright/test": "^1.51.1", "sv": "workspace:*", - "vitest": "^3.0.5" + "vitest": "^3.0.9" }, "keywords": [ "svelte-add-on", diff --git a/community-addon-template/tests/setup/global.ts b/community-addon-template/tests/setup/global.ts index 872cd690..31b2ed10 100644 --- a/community-addon-template/tests/setup/global.ts +++ b/community-addon-template/tests/setup/global.ts @@ -1,11 +1,11 @@ import { fileURLToPath } from 'node:url'; import { setup, type ProjectVariant } from 'sv/testing'; -import type { GlobalSetupContext } from 'vitest/node'; +import type { TestProject } from 'vitest/node'; const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; const TEST_DIR = fileURLToPath(new URL('../../.test-output/', import.meta.url)); -export default async function ({ provide }: GlobalSetupContext) { +export default async function ({ provide }: TestProject) { // global setup (e.g. spin up docker containers) // downloads different project configurations (sveltekit, js/ts, vite-only, etc) diff --git a/package.json b/package.json index 433fd18c..391cd4f3 100644 --- a/package.json +++ b/package.json @@ -19,25 +19,26 @@ "update-addon-deps": "node ./scripts/update-addon-dependencies.js" }, "devDependencies": { - "@changesets/cli": "^2.27.10", - "@playwright/test": "^1.49.1", + "@changesets/cli": "^2.28.1", + "@playwright/test": "^1.51.1", "@sveltejs/create": "workspace:*", - "@sveltejs/eslint-config": "^8.1.0", + "@sveltejs/eslint-config": "^8.2.0", "@svitejs/changesets-changelog-github-compact": "^1.2.0", - "@types/node": "^22.10.2", - "@vitest/ui": "^3.0.5", - "eslint": "^9.17.0", - "magic-string": "^0.30.15", - "prettier": "^3.4.2", - "prettier-plugin-packagejson": "^2.5.6", - "prettier-plugin-svelte": "^3.3.2", + "@types/node": "^22.14.0", + "@vitest/ui": "^3.0.9", + "eslint": "^9.24.0", + "eslint-plugin-svelte": "^3.5.1", + "magic-string": "^0.30.17", + "prettier": "^3.5.3", + "prettier-plugin-packagejson": "^2.5.10", + "prettier-plugin-svelte": "^3.3.3", "rolldown": "1.0.0-beta.1", "sv": "workspace:*", - "svelte": "^5.12.0", - "typescript": "^5.6.2", - "typescript-eslint": "^8.18.0", + "svelte": "^5.25.7", + "typescript": "^5.8.3", + "typescript-eslint": "^8.29.0", "unplugin-isolated-decl": "^0.8.3", - "vitest": "^3.0.5" + "vitest": "^3.0.9" }, "packageManager": "pnpm@10.4.1", "pnpm": { diff --git a/packages/addons/_tests/_setup/global.ts b/packages/addons/_tests/_setup/global.ts index 5b99b41d..c078a3c6 100644 --- a/packages/addons/_tests/_setup/global.ts +++ b/packages/addons/_tests/_setup/global.ts @@ -1,11 +1,11 @@ import { fileURLToPath } from 'node:url'; import { setup, type ProjectVariant } from 'sv/testing'; -import type { GlobalSetupContext } from 'vitest/node'; +import type { TestProject } from 'vitest/node'; const TEST_DIR = fileURLToPath(new URL('../../../../.test-output/addons/', import.meta.url)); const variants: ProjectVariant[] = ['kit-js', 'kit-ts', 'vite-js', 'vite-ts']; -export default async function ({ provide }: GlobalSetupContext) { +export default async function ({ provide }: TestProject) { // downloads different project configurations (sveltekit, js/ts, vite-only, etc) const { templatesDir } = await setup({ cwd: TEST_DIR, variants }); diff --git a/packages/addons/_tests/vitest/test.ts b/packages/addons/_tests/vitest/test.ts index f6a0166d..41646ef8 100644 --- a/packages/addons/_tests/vitest/test.ts +++ b/packages/addons/_tests/vitest/test.ts @@ -8,9 +8,9 @@ const { test, variants, prepareServer } = setupTest({ vitest }); test.concurrent.for(variants)('core - %s', async (variant, { page, ...ctx }) => { const cwd = await ctx.run(variant, { vitest: {} }); - const { close } = await prepareServer({ cwd, page }, () => { - execSync('npm run test', { cwd, stdio: 'pipe' }); - }); + const { close } = await prepareServer({ cwd, page }); + + execSync('pnpm test', { cwd, stdio: 'pipe' }); // kill server process when we're done ctx.onTestFinished(async () => await close()); diff --git a/packages/cli/package.json b/packages/cli/package.json index 13de68d9..c576dd9d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -37,14 +37,14 @@ "@types/degit": "^2.8.6", "@types/ps-tree": "^1.1.6", "@types/tar-fs": "^2.0.4", - "commander": "^13.0.0", + "commander": "^13.1.0", "degit": "^2.8.4", "empathic": "^1.0.0", - "package-manager-detector": "^0.2.7", + "package-manager-detector": "^0.2.11", "picocolors": "^1.1.1", "ps-tree": "^1.2.0", - "tar-fs": "^3.0.6", - "tinyexec": "^0.3.1", + "tar-fs": "^3.0.8", + "tinyexec": "^0.3.2", "valibot": "^0.41.0" }, "keywords": [ diff --git a/packages/core/package.json b/packages/core/package.json index 507fa17d..41232984 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -53,7 +53,7 @@ "domutils": "^3.1.0", "esrap": "^1.4.5", "htmlparser2": "^9.1.0", - "magic-string": "^0.30.15", + "magic-string": "^0.30.17", "picocolors": "^1.1.1", "postcss": "^8.4.49", "silver-fleece": "^1.2.1", diff --git a/packages/core/tooling/js/exports.ts b/packages/core/tooling/js/exports.ts index 6ccf0232..ea12e764 100644 --- a/packages/core/tooling/js/exports.ts +++ b/packages/core/tooling/js/exports.ts @@ -71,7 +71,8 @@ export function namedExport( namedExport = { type: 'ExportNamedDeclaration', declaration: fallback, - specifiers: [] + specifiers: [], + attributes: [] }; ast.body.push(namedExport); return namedExport; diff --git a/packages/core/tooling/js/imports.ts b/packages/core/tooling/js/imports.ts index 877d747c..81ce9a35 100644 --- a/packages/core/tooling/js/imports.ts +++ b/packages/core/tooling/js/imports.ts @@ -9,6 +9,7 @@ export function addEmpty(ast: AstTypes.Program, importFrom: string): void { value: importFrom }, specifiers: [], + attributes: [], importKind: 'value' }; @@ -25,7 +26,8 @@ export function addNamespace(ast: AstTypes.Program, importFrom: string, importAs type: 'ImportNamespaceSpecifier', local: { type: 'Identifier', name: importAs } } - ] + ], + attributes: [] }; addImportIfNecessary(ast, expectedImportDeclaration); @@ -47,6 +49,7 @@ export function addDefault(ast: AstTypes.Program, importFrom: string, importAs: } } ], + attributes: [], importKind: 'value' }; @@ -109,6 +112,7 @@ export function addNamed( value: importFrom }, specifiers, + attributes: [], importKind: isType ? 'type' : 'value' }; diff --git a/packages/create/templates/demo/src/app.css b/packages/create/templates/demo/src/app.css index 1441d940..f62c2c7a 100644 --- a/packages/create/templates/demo/src/app.css +++ b/packages/create/templates/demo/src/app.css @@ -1,8 +1,9 @@ @import '@fontsource/fira-mono'; :root { - --font-body: Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, - Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --font-body: + Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, + 'Open Sans', 'Helvetica Neue', sans-serif; --font-mono: 'Fira Mono', monospace; --color-bg-0: rgb(202, 216, 228); --color-bg-1: hsl(209, 36%, 86%); @@ -22,11 +23,8 @@ body { background-attachment: fixed; background-color: var(--color-bg-1); background-size: 100vw 100vh; - background-image: radial-gradient( - 50% 50% at 50% 50%, - rgba(255, 255, 255, 0.75) 0%, - rgba(255, 255, 255, 0) 100% - ), + background-image: + radial-gradient(50% 50% at 50% 50%, rgba(255, 255, 255, 0.75) 0%, rgba(255, 255, 255, 0) 100%), linear-gradient(180deg, var(--color-bg-0) 0%, var(--color-bg-1) 15%, var(--color-bg-2) 50%); } diff --git a/packages/migrate/package.json b/packages/migrate/package.json index 6188b954..65ede312 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -27,21 +27,21 @@ "svelte-migrate": "./bin.js" }, "dependencies": { - "@clack/prompts": "^0.9.0", + "@clack/prompts": "^0.9.1", "import-meta-resolve": "^4.1.0", - "magic-string": "^0.30.15", - "package-manager-detector": "^0.2.7", + "magic-string": "^0.30.17", + "package-manager-detector": "^0.2.11", "picocolors": "^1.1.1", - "semver": "^7.6.3", + "semver": "^7.7.1", "tiny-glob": "^0.2.9", "ts-morph": "^24.0.0", - "typescript": "^5.7.2", + "typescript": "^5.8.3", "zimmerframe": "^1.1.2" }, "devDependencies": { - "@types/node": "^18.19.68", + "@types/node": "^18.19.86", "@types/prompts": "^2.4.9", - "@types/semver": "^7.5.8", + "@types/semver": "^7.7.0", "svelte": "^4.2.19" }, "keywords": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd18dcc7..7ad25f51 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,62 +9,65 @@ importers: .: devDependencies: '@changesets/cli': - specifier: ^2.27.10 - version: 2.27.10 + specifier: ^2.28.1 + version: 2.28.1 '@playwright/test': - specifier: ^1.49.1 - version: 1.49.1 + specifier: ^1.51.1 + version: 1.51.1 '@sveltejs/create': specifier: workspace:* version: link:packages/create '@sveltejs/eslint-config': - specifier: ^8.1.0 - version: 8.1.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.17.0))(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint-plugin-n@17.13.1(eslint@9.17.0))(eslint-plugin-svelte@2.46.0(eslint@9.17.0)(svelte@5.12.0))(eslint@9.17.0)(typescript-eslint@8.18.0(eslint@9.17.0)(typescript@5.7.2))(typescript@5.7.2) + specifier: ^8.2.0 + version: 8.2.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.24.0))(eslint-config-prettier@9.1.0(eslint@9.24.0))(eslint-plugin-n@17.13.1(eslint@9.24.0))(eslint-plugin-svelte@3.5.1(eslint@9.24.0)(svelte@5.25.7))(eslint@9.24.0)(typescript-eslint@8.29.0(eslint@9.24.0)(typescript@5.8.3))(typescript@5.8.3) '@svitejs/changesets-changelog-github-compact': specifier: ^1.2.0 version: 1.2.0 '@types/node': - specifier: ^22.10.2 - version: 22.10.2 + specifier: ^22.14.0 + version: 22.14.0 '@vitest/ui': - specifier: ^3.0.5 - version: 3.1.1(vitest@3.0.5) + specifier: ^3.0.9 + version: 3.0.9(vitest@3.0.9) eslint: - specifier: ^9.17.0 - version: 9.17.0 + specifier: ^9.24.0 + version: 9.24.0 + eslint-plugin-svelte: + specifier: ^3.5.1 + version: 3.5.1(eslint@9.24.0)(svelte@5.25.7) magic-string: - specifier: ^0.30.15 + specifier: ^0.30.17 version: 0.30.17 prettier: - specifier: ^3.4.2 - version: 3.4.2 + specifier: ^3.5.3 + version: 3.5.3 prettier-plugin-packagejson: - specifier: ^2.5.6 - version: 2.5.6(prettier@3.4.2) + specifier: ^2.5.10 + version: 2.5.10(prettier@3.5.3) prettier-plugin-svelte: - specifier: ^3.3.2 - version: 3.3.2(prettier@3.4.2)(svelte@5.12.0) + specifier: ^3.3.3 + version: 3.3.3(prettier@3.5.3)(svelte@5.25.7) rolldown: specifier: 1.0.0-beta.1 - version: 1.0.0-beta.1(@babel/runtime@7.26.0) + version: 1.0.0-beta.1(@babel/runtime@7.27.0) sv: specifier: workspace:* version: link:packages/cli svelte: - specifier: ^5.12.0 - version: 5.12.0 + specifier: ^5.25.7 + version: 5.25.7 typescript: - specifier: ^5.6.2 - version: 5.7.2 + specifier: ^5.8.3 + version: 5.8.3 typescript-eslint: - specifier: ^8.18.0 - version: 8.18.0(eslint@9.17.0)(typescript@5.7.2) + specifier: ^8.29.0 + version: 8.29.0(eslint@9.24.0)(typescript@5.8.3) unplugin-isolated-decl: specifier: ^0.8.3 - version: 0.8.3(rollup@4.34.5)(typescript@5.7.2) + version: 0.8.3(rollup@4.39.0)(typescript@5.8.3) vitest: - specifier: ^3.0.5 - version: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.1.1) + specifier: ^3.0.9 + version: 3.0.9(@types/node@22.14.0)(@vitest/ui@3.0.9) community-addon-template: dependencies: @@ -73,14 +76,14 @@ importers: version: link:../packages/core devDependencies: '@playwright/test': - specifier: ^1.49.1 - version: 1.49.1 + specifier: ^1.51.1 + version: 1.51.1 sv: specifier: workspace:* version: link:../packages/cli vitest: - specifier: ^3.0.5 - version: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.1.1) + specifier: ^3.0.9 + version: 3.0.9(@types/node@22.14.0)(@vitest/ui@3.0.9) packages/addons: dependencies: @@ -139,8 +142,8 @@ importers: specifier: ^2.0.4 version: 2.0.4 commander: - specifier: ^13.0.0 - version: 13.0.0 + specifier: ^13.1.0 + version: 13.1.0 degit: specifier: ^2.8.4 version: 2.8.4 @@ -148,8 +151,8 @@ importers: specifier: ^1.0.0 version: 1.0.0 package-manager-detector: - specifier: ^0.2.7 - version: 0.2.7 + specifier: ^0.2.11 + version: 0.2.11 picocolors: specifier: ^1.1.1 version: 1.1.1 @@ -157,29 +160,29 @@ importers: specifier: ^1.2.0 version: 1.2.0 tar-fs: - specifier: ^3.0.6 - version: 3.0.6 + specifier: ^3.0.8 + version: 3.0.8 tinyexec: - specifier: ^0.3.1 + specifier: ^0.3.2 version: 0.3.2 valibot: specifier: ^0.41.0 - version: 0.41.0(typescript@5.7.2) + version: 0.41.0(typescript@5.8.3) packages/core: devDependencies: '@sveltejs/acorn-typescript': specifier: ^1.0.1 - version: 1.0.5(acorn@8.14.0) + version: 1.0.5(acorn@8.14.1) '@sveltejs/clack-prompts': specifier: workspace:* version: link:../clack-prompts '@types/estree': specifier: ^1.0.6 - version: 1.0.6 + version: 1.0.7 acorn: specifier: ^8.14.0 - version: 8.14.0 + version: 8.14.1 decircular: specifier: ^1.0.0 version: 1.0.0 @@ -194,15 +197,15 @@ importers: version: 5.0.3 domutils: specifier: ^3.1.0 - version: 3.1.0 + version: 3.2.2 esrap: specifier: ^1.4.5 - version: 1.4.5 + version: 1.4.6 htmlparser2: specifier: ^9.1.0 version: 9.1.0 magic-string: - specifier: ^0.30.15 + specifier: ^0.30.17 version: 0.30.17 picocolors: specifier: ^1.1.1 @@ -235,23 +238,23 @@ importers: packages/migrate: dependencies: '@clack/prompts': - specifier: ^0.9.0 + specifier: ^0.9.1 version: 0.9.1 import-meta-resolve: specifier: ^4.1.0 version: 4.1.0 magic-string: - specifier: ^0.30.15 + specifier: ^0.30.17 version: 0.30.17 package-manager-detector: - specifier: ^0.2.7 - version: 0.2.7 + specifier: ^0.2.11 + version: 0.2.11 picocolors: specifier: ^1.1.1 version: 1.1.1 semver: - specifier: ^7.6.3 - version: 7.6.3 + specifier: ^7.7.1 + version: 7.7.1 tiny-glob: specifier: ^0.2.9 version: 0.2.9 @@ -259,21 +262,21 @@ importers: specifier: ^24.0.0 version: 24.0.0 typescript: - specifier: ^5.7.2 - version: 5.7.2 + specifier: ^5.8.3 + version: 5.8.3 zimmerframe: specifier: ^1.1.2 version: 1.1.2 devDependencies: '@types/node': - specifier: ^18.19.68 - version: 18.19.68 + specifier: ^18.19.86 + version: 18.19.86 '@types/prompts': specifier: ^2.4.9 version: 2.4.9 '@types/semver': - specifier: ^7.5.8 - version: 7.5.8 + specifier: ^7.7.0 + version: 7.7.0 svelte: specifier: ^4.2.19 version: 4.2.19 @@ -284,37 +287,37 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@babel/runtime@7.26.0': - resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + '@babel/runtime@7.27.0': + resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} - '@changesets/apply-release-plan@7.0.6': - resolution: {integrity: sha512-TKhVLtiwtQOgMAC0fCJfmv93faiViKSDqr8oMEqrnNs99gtSC1sZh/aEMS9a+dseU1ESZRCK+ofLgGY7o0fw/Q==} + '@changesets/apply-release-plan@7.0.10': + resolution: {integrity: sha512-wNyeIJ3yDsVspYvHnEz1xQDq18D9ifed3lI+wxRQRK4pArUcuHgCTrHv0QRnnwjhVCQACxZ+CBih3wgOct6UXw==} - '@changesets/assemble-release-plan@6.0.5': - resolution: {integrity: sha512-IgvBWLNKZd6k4t72MBTBK3nkygi0j3t3zdC1zrfusYo0KpdsvnDjrMM9vPnTCLCMlfNs55jRL4gIMybxa64FCQ==} + '@changesets/assemble-release-plan@6.0.6': + resolution: {integrity: sha512-Frkj8hWJ1FRZiY3kzVCKzS0N5mMwWKwmv9vpam7vt8rZjLL1JMthdh6pSDVSPumHPshTTkKZ0VtNbE0cJHZZUg==} - '@changesets/changelog-git@0.2.0': - resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} - '@changesets/cli@2.27.10': - resolution: {integrity: sha512-PfeXjvs9OfQJV8QSFFHjwHX3QnUL9elPEQ47SgkiwzLgtKGyuikWjrdM+lO9MXzOE22FO9jEGkcs4b+B6D6X0Q==} + '@changesets/cli@2.28.1': + resolution: {integrity: sha512-PiIyGRmSc6JddQJe/W1hRPjiN4VrMvb2VfQ6Uydy2punBioQrsxppyG5WafinKcW1mT0jOe/wU4k9Zy5ff21AA==} hasBin: true - '@changesets/config@3.0.4': - resolution: {integrity: sha512-+DiIwtEBpvvv1z30f8bbOsUQGuccnZl9KRKMM/LxUHuDu5oEjmN+bJQ1RIBKNJjfYMQn8RZzoPiX0UgPaLQyXw==} + '@changesets/config@3.1.1': + resolution: {integrity: sha512-bd+3Ap2TKXxljCggI0mKPfzCQKeV/TU4yO2h2C6vAihIo8tzseAn2e7klSuiyYYXvgu53zMN1OeYMIQkaQoWnA==} '@changesets/errors@0.2.0': resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} - '@changesets/get-dependents-graph@2.1.2': - resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} + '@changesets/get-dependents-graph@2.1.3': + resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} '@changesets/get-github-info@0.6.0': resolution: {integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==} - '@changesets/get-release-plan@4.0.5': - resolution: {integrity: sha512-E6wW7JoSMcctdVakut0UB76FrrN3KIeJSXvB+DHMFo99CnC3ZVnNYDCVNClMlqAhYGmLmAj77QfApaI3ca4Fkw==} + '@changesets/get-release-plan@4.0.8': + resolution: {integrity: sha512-MM4mq2+DQU1ZT7nqxnpveDMTkMBLnwNX44cX7NSxlXmr7f8hO6/S2MXNiXG54uf/0nYnefv0cfy4Czf/ZL/EKQ==} '@changesets/get-version-range-type@0.4.0': resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} @@ -325,26 +328,26 @@ packages: '@changesets/logger@0.1.1': resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} - '@changesets/parse@0.4.0': - resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} + '@changesets/parse@0.4.1': + resolution: {integrity: sha512-iwksMs5Bf/wUItfcg+OXrEpravm5rEd9Bf4oyIPL4kVTmJQ7PNDSd6MDYkpSJR1pn7tz/k8Zf2DhTCqX08Ou+Q==} - '@changesets/pre@2.0.1': - resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} - '@changesets/read@0.6.2': - resolution: {integrity: sha512-wjfQpJvryY3zD61p8jR87mJdyx2FIhEcdXhKUqkja87toMrP/3jtg/Yg29upN+N4Ckf525/uvV7a4tzBlpk6gg==} + '@changesets/read@0.6.3': + resolution: {integrity: sha512-9H4p/OuJ3jXEUTjaVGdQEhBdqoT2cO5Ts95JTFsQyawmKzpL8FnIeJSyhTDPW1MBRDnwZlHFEM9SpPwJDY5wIg==} - '@changesets/should-skip-package@0.1.1': - resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} '@changesets/types@4.1.0': resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} - '@changesets/types@6.0.0': - resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} - '@changesets/write@0.3.2': - resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} '@clack/core@0.4.1': resolution: {integrity: sha512-Pxhij4UXg8KSr7rPek6Zowm+5M22rbd2g1nfojHJkxp5YkFqiZ2+YLEM/XGVIzvGOcM0nqjIFxrpDwWRZYWYjA==} @@ -352,167 +355,167 @@ packages: '@clack/prompts@0.9.1': resolution: {integrity: sha512-JIpyaboYZeWYlyP0H+OoPPxd6nqueG/CmN6ixBiNFsIDHREevjIf0n0Ohh5gr5C8pEDknzgvz+pIJ8dMhzWIeg==} - '@emnapi/core@1.3.1': - resolution: {integrity: sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==} + '@emnapi/core@1.4.0': + resolution: {integrity: sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==} - '@emnapi/runtime@1.3.1': - resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + '@emnapi/runtime@1.4.0': + resolution: {integrity: sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==} '@emnapi/wasi-threads@1.0.1': resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} - '@esbuild/aix-ppc64@0.24.2': - resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + '@esbuild/aix-ppc64@0.25.2': + resolution: {integrity: sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.24.2': - resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + '@esbuild/android-arm64@0.25.2': + resolution: {integrity: sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.24.2': - resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + '@esbuild/android-arm@0.25.2': + resolution: {integrity: sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.24.2': - resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + '@esbuild/android-x64@0.25.2': + resolution: {integrity: sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.24.2': - resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + '@esbuild/darwin-arm64@0.25.2': + resolution: {integrity: sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.24.2': - resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + '@esbuild/darwin-x64@0.25.2': + resolution: {integrity: sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.24.2': - resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + '@esbuild/freebsd-arm64@0.25.2': + resolution: {integrity: sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.24.2': - resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + '@esbuild/freebsd-x64@0.25.2': + resolution: {integrity: sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.24.2': - resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + '@esbuild/linux-arm64@0.25.2': + resolution: {integrity: sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.24.2': - resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + '@esbuild/linux-arm@0.25.2': + resolution: {integrity: sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.24.2': - resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + '@esbuild/linux-ia32@0.25.2': + resolution: {integrity: sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.24.2': - resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + '@esbuild/linux-loong64@0.25.2': + resolution: {integrity: sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.24.2': - resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + '@esbuild/linux-mips64el@0.25.2': + resolution: {integrity: sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.24.2': - resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + '@esbuild/linux-ppc64@0.25.2': + resolution: {integrity: sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.24.2': - resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + '@esbuild/linux-riscv64@0.25.2': + resolution: {integrity: sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.24.2': - resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + '@esbuild/linux-s390x@0.25.2': + resolution: {integrity: sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.24.2': - resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + '@esbuild/linux-x64@0.25.2': + resolution: {integrity: sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.24.2': - resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + '@esbuild/netbsd-arm64@0.25.2': + resolution: {integrity: sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.24.2': - resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + '@esbuild/netbsd-x64@0.25.2': + resolution: {integrity: sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.24.2': - resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + '@esbuild/openbsd-arm64@0.25.2': + resolution: {integrity: sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.24.2': - resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + '@esbuild/openbsd-x64@0.25.2': + resolution: {integrity: sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.24.2': - resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + '@esbuild/sunos-x64@0.25.2': + resolution: {integrity: sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.24.2': - resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + '@esbuild/win32-arm64@0.25.2': + resolution: {integrity: sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.24.2': - resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + '@esbuild/win32-ia32@0.25.2': + resolution: {integrity: sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.24.2': - resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + '@esbuild/win32-x64@0.25.2': + resolution: {integrity: sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.4.1': - resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + '@eslint-community/eslint-utils@4.5.1': + resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -521,28 +524,36 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.19.1': - resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==} + '@eslint/config-array@0.20.0': + resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.2.1': + resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.9.1': - resolution: {integrity: sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==} + '@eslint/core@0.12.0': + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/eslintrc@3.2.0': - resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} + '@eslint/core@0.13.0': + resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.17.0': - resolution: {integrity: sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==} + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@2.1.5': - resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==} + '@eslint/js@9.24.0': + resolution: {integrity: sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.2.4': - resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.8': + resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@humanfs/core@0.19.1': @@ -561,8 +572,8 @@ packages: resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.1': - resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} + '@humanwhocodes/retry@0.4.2': + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} engines: {node: '>=18.18'} '@isaacs/cliui@8.0.2': @@ -593,8 +604,8 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - '@napi-rs/wasm-runtime@0.2.6': - resolution: {integrity: sha512-z8YVS3XszxFTO73iwvFDNpQIzdMmSDTP/mB3E/ucR37V3Sx57hSExcXyMoNwaucWxnsWf4xfbZv0iZ30jr0M4Q==} + '@napi-rs/wasm-runtime@0.2.8': + resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -655,12 +666,12 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@pkgr/core@0.1.1': - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + '@pkgr/core@0.1.2': + resolution: {integrity: sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.49.1': - resolution: {integrity: sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==} + '@playwright/test@1.51.1': + resolution: {integrity: sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q==} engines: {node: '>=18'} hasBin: true @@ -727,8 +738,8 @@ packages: cpu: [x64] os: [win32] - '@rollup/pluginutils@5.1.3': - resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -736,98 +747,103 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.34.5': - resolution: {integrity: sha512-JXmmQcKQtpf3Z6lvA8akkrHDZ5AEfgc2hLMix1/X5BhQbezBQ0AP5GYLdU8jsQRme8qr2sscCe3wizp7UT0L9g==} + '@rollup/rollup-android-arm-eabi@4.39.0': + resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.34.5': - resolution: {integrity: sha512-9/A8/ZBOprUjkrJoP9BBEq2vdSud6BPd3LChw09bJQiEZH5oN4kWIkHu90cA0Cj0cSF5cIaD76+0lA+d5KHmpQ==} + '@rollup/rollup-android-arm64@4.39.0': + resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.34.5': - resolution: {integrity: sha512-b9oCfgHKfc1AJEQ5sEpE8Kf6s7aeygj5bZAsl1hTpZc1V9cfZASFSXzzNj7o/BQNPbjmVkVxpCCLRhBfLXhJ5g==} + '@rollup/rollup-darwin-arm64@4.39.0': + resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.34.5': - resolution: {integrity: sha512-Gz42gKBQPoFdMYdsVqkcpttYOO/0aP7f+1CgMaeZEz0gss7dop1TsO3hT77Iroz/TV7PdPUG/RYlj9EA39L4dw==} + '@rollup/rollup-darwin-x64@4.39.0': + resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.34.5': - resolution: {integrity: sha512-JPkafjkOFaupd8VQYsXfGFKC2pfMr7hwSYGkVGNwhbW0k0lHHyIdhCSNBendJ4O7YlT4yRyKXoms1TL7saO7SQ==} + '@rollup/rollup-freebsd-arm64@4.39.0': + resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.34.5': - resolution: {integrity: sha512-j6Q8VFqyI8hZM33h1JC6DZK2w8ejkXqEMozTrtIEGfRVMpVZL3GrLOOYEUkAgUSpJ9sb2w+FEpjGj7IHRcQfdw==} + '@rollup/rollup-freebsd-x64@4.39.0': + resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.34.5': - resolution: {integrity: sha512-6jyiXKF9Xq6x9yQjct5xrRT0VghJk5VzAfed3o0hgncwacZkzOdR0TXLRNjexsEXWN8tG7jWWwsVk7WeFi//gw==} + '@rollup/rollup-linux-arm-gnueabihf@4.39.0': + resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.34.5': - resolution: {integrity: sha512-cOTYe5tLcGAvGztRLIqx87LE7j/qjaAqFrrHsPFlnuhhhFO5LSr2AzvdQYuxomJMzMBrXkMRNl9bQEpDZ5bjLQ==} + '@rollup/rollup-linux-arm-musleabihf@4.39.0': + resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.34.5': - resolution: {integrity: sha512-KHlrd+YqmS7rriW+LBb1kQNYmd5w1sAIG3z7HEpnQOrg/skeYYv9DAcclGL9gpFdpnzmiAEkzsTT74kZWUtChQ==} + '@rollup/rollup-linux-arm64-gnu@4.39.0': + resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.34.5': - resolution: {integrity: sha512-uOb6hzDqym4Sw+qw3+svS3SmwQGVUhyTdPKyHDdlYg1Z0aHjdNmjwRY7zw/90/UfBe/yD7Mv2mYKhQpOfy4RYA==} + '@rollup/rollup-linux-arm64-musl@4.39.0': + resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.34.5': - resolution: {integrity: sha512-pARu8ZKANZH4wINLdHLKG69EPwJswM6A+Ox1a9LpiclRQoyjacFFTtXN3akKQ2ufJXDasO/pWvxKN9ZfCgEoFA==} + '@rollup/rollup-linux-loongarch64-gnu@4.39.0': + resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.34.5': - resolution: {integrity: sha512-crUWn12NRmCdao2YwS1GvlPCVypMBMJlexTaantaP2+dAMd2eZBErFcKG8hZYEHjSbbk2UoH1aTlyeA4iKLqSA==} + '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': + resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.34.5': - resolution: {integrity: sha512-XtD/oMhCdixi3x8rCNyDRMUsLo1Z+1UQcK+oR7AsjglGov9ETiT3TNFhUPzaGC1jH+uaMtPhxrVRUub+pnAKTg==} + '@rollup/rollup-linux-riscv64-gnu@4.39.0': + resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.39.0': + resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.34.5': - resolution: {integrity: sha512-V3+BvgyHb21aF7lw0sc78Tv0+xLp4lm2OM7CKFVrBuppsMvtl/9O5y2OX4tdDT0EhIsDP/ObJPqDuEg1ZoTwSQ==} + '@rollup/rollup-linux-s390x-gnu@4.39.0': + resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.34.5': - resolution: {integrity: sha512-SkCIXLGk42yldTcH8UXh++m0snVxp9DLf4meb1mWm0lC8jzxjFBwSLGtUSeLgQDsC05iBaIhyjNX46DlByrApQ==} + '@rollup/rollup-linux-x64-gnu@4.39.0': + resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.34.5': - resolution: {integrity: sha512-iUcH3FBtBN2/Ce0rI84suRhD0+bB5BVEffqOwsGaX5py5TuYLOQa7S7oVBP0NKtB5rub3i9IvZtMXiD96l5v0A==} + '@rollup/rollup-linux-x64-musl@4.39.0': + resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.34.5': - resolution: {integrity: sha512-PUbWd+h/h6rUowalDYIdc9S9LJXbQDMcJe0BjABl3oT3efYRgZ8aUe8ZZDSie7y+fz6Z+rueNfdorIbkWv5Eqg==} + '@rollup/rollup-win32-arm64-msvc@4.39.0': + resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.34.5': - resolution: {integrity: sha512-3vncGhOJiAUR85fnAXJyvSp2GaDWYByIQmW68ZAr+e8kIxgvJ1VaZbfHD5BO5X6hwRQdY6Um/XfA3l5c2lV+OQ==} + '@rollup/rollup-win32-ia32-msvc@4.39.0': + resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.34.5': - resolution: {integrity: sha512-Mi8yVUlQOoeBpY72n75VLATptPGvj2lHa47rQdK9kZ4MoG5Ve86aVIU+PO3tBklTCBtILtdRfXS0EvIbXgmCAg==} + '@rollup/rollup-win32-x64-msvc@4.39.0': + resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==} cpu: [x64] os: [win32] @@ -842,16 +858,16 @@ packages: peerDependencies: acorn: ^8.9.0 - '@sveltejs/eslint-config@8.1.0': - resolution: {integrity: sha512-cfgp4lPREYBjNd4ZzaP/jA85ufm7vfXiaV7h9vILXNogne80IbZRNhRCQ8XoOqTAOY/pChIzWTBuR8aDNMbAEA==} + '@sveltejs/eslint-config@8.2.0': + resolution: {integrity: sha512-5ab8AXjLoY+H0dsYTGB+9L8AnOvOzd9NZkECj40VAk6Uh9u7+5d8jVk+YYW6NGsEQ+HwHBUi19yij+q+5Pm+aQ==} peerDependencies: '@stylistic/eslint-plugin-js': '>= 1' eslint: '>= 9' eslint-config-prettier: '>= 9' eslint-plugin-n: '>= 17' - eslint-plugin-svelte: '>= 2.36' + eslint-plugin-svelte: '>= 3' typescript: '>= 5' - typescript-eslint: '>= 7.5' + typescript-eslint: '>= 8' '@svitejs/changesets-changelog-github-compact@1.2.0': resolution: {integrity: sha512-08eKiDAjj4zLug1taXSIJ0kGL5cawjVCyJkBb6EWSg5fEPX6L+Wtr0CH2If4j5KYylz85iaZiFlUItvgJvll5g==} @@ -866,8 +882,8 @@ packages: '@types/degit@2.8.6': resolution: {integrity: sha512-y0M7sqzsnHB6cvAeTCBPrCQNQiZe8U4qdzf8uBVmOWYap5MMTN/gB2iEqrIqFiYcsyvP74GnGD5tgsHttielFw==} - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} '@types/gitignore-parser@0.0.3': resolution: {integrity: sha512-sbdu1sG2pQcwjEYWTsX78OqJo5pKnonwC4FV3m2JeQRE2xYb3q0icHHopCHEvpn4uIBuvWBTpJUCJ76ISK24CA==} @@ -878,11 +894,11 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@18.19.68': - resolution: {integrity: sha512-QGtpFH1vB99ZmTa63K4/FU8twThj4fuVSBkGddTp7uIL/cuoLWIUSL2RcOaigBhfR+hg5pgGkBnkoOxrTVBMKw==} + '@types/node@18.19.86': + resolution: {integrity: sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ==} - '@types/node@22.10.2': - resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==} + '@types/node@22.14.0': + resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==} '@types/prompts@2.4.9': resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} @@ -890,8 +906,8 @@ packages: '@types/ps-tree@1.1.6': resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==} - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + '@types/semver@7.7.0': + resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} '@types/tar-fs@2.0.4': resolution: {integrity: sha512-ipPec0CjTmVDWE+QKr9cTmIIoTl7dFG/yARCM5MqK8i6CNLIG1P8x4kwDsOQY1ChZOZjH0wO9nvfgBvWl4R3kA==} @@ -899,58 +915,58 @@ packages: '@types/tar-stream@3.1.3': resolution: {integrity: sha512-Zbnx4wpkWBMBSu5CytMbrT5ZpMiF55qgM+EpHzR4yIDu7mv52cej8hTkOc6K+LzpkOAbxwn/m7j3iO+/l42YkQ==} - '@typescript-eslint/eslint-plugin@8.18.0': - resolution: {integrity: sha512-NR2yS7qUqCL7AIxdJUQf2MKKNDVNaig/dEB0GBLU7D+ZdHgK1NoH/3wsgO3OnPVipn51tG3MAwaODEGil70WEw==} + '@typescript-eslint/eslint-plugin@8.29.0': + resolution: {integrity: sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.18.0': - resolution: {integrity: sha512-hgUZ3kTEpVzKaK3uNibExUYm6SKKOmTU2BOxBSvOYwtJEPdVQ70kZJpPjstlnhCHcuc2WGfSbpKlb/69ttyN5Q==} + '@typescript-eslint/parser@8.29.0': + resolution: {integrity: sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/scope-manager@8.18.0': - resolution: {integrity: sha512-PNGcHop0jkK2WVYGotk/hxj+UFLhXtGPiGtiaWgVBVP1jhMoMCHlTyJA+hEj4rszoSdLTK3fN4oOatrL0Cp+Xw==} + '@typescript-eslint/scope-manager@8.29.0': + resolution: {integrity: sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.18.0': - resolution: {integrity: sha512-er224jRepVAVLnMF2Q7MZJCq5CsdH2oqjP4dT7K6ij09Kyd+R21r7UVJrF0buMVdZS5QRhDzpvzAxHxabQadow==} + '@typescript-eslint/type-utils@8.29.0': + resolution: {integrity: sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/types@8.18.0': - resolution: {integrity: sha512-FNYxgyTCAnFwTrzpBGq+zrnoTO4x0c1CKYY5MuUTzpScqmY5fmsh2o3+57lqdI3NZucBDCzDgdEbIaNfAjAHQA==} + '@typescript-eslint/types@8.29.0': + resolution: {integrity: sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.18.0': - resolution: {integrity: sha512-rqQgFRu6yPkauz+ms3nQpohwejS8bvgbPyIDq13cgEDbkXt4LH4OkDMT0/fN1RUtzG8e8AKJyDBoocuQh8qNeg==} + '@typescript-eslint/typescript-estree@8.29.0': + resolution: {integrity: sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.18.0': - resolution: {integrity: sha512-p6GLdY383i7h5b0Qrfbix3Vc3+J2k6QWw6UMUeY5JGfm3C5LbZ4QIZzJNoNOfgyRe0uuYKjvVOsO/jD4SJO+xg==} + '@typescript-eslint/utils@8.29.0': + resolution: {integrity: sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/visitor-keys@8.18.0': - resolution: {integrity: sha512-pCh/qEA8Lb1wVIqNvBke8UaRjJ6wrAWkJO5yyIbs8Yx6TNGYyfNjOo61tLv+WwLvoLPp4BQ8B7AHKijl8NGUfw==} + '@typescript-eslint/visitor-keys@8.29.0': + resolution: {integrity: sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/expect@3.0.5': - resolution: {integrity: sha512-nNIOqupgZ4v5jWuQx2DSlHLEs7Q4Oh/7AYwNyE+k0UQzG7tSmjPXShUikn1mpNGzYEN2jJbTvLejwShMitovBA==} + '@vitest/expect@3.0.9': + resolution: {integrity: sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig==} - '@vitest/mocker@3.0.5': - resolution: {integrity: sha512-CLPNBFBIE7x6aEGbIjaQAX03ZZlBMaWwAjBdMkIf/cAn6xzLTiM3zYqO/WAbieEjsAZir6tO71mzeHZoodThvw==} + '@vitest/mocker@3.0.9': + resolution: {integrity: sha512-ryERPIBOnvevAkTq+L1lD+DTFBRcjueL9lOUfXsLfwP92h4e+Heb+PjiqS3/OURWPtywfafK0kj++yDFjWUmrA==} peerDependencies: msw: ^2.4.9 vite: ^5.0.0 || ^6.0.0 @@ -960,44 +976,36 @@ packages: vite: optional: true - '@vitest/pretty-format@3.0.5': - resolution: {integrity: sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==} + '@vitest/pretty-format@3.0.9': + resolution: {integrity: sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==} '@vitest/pretty-format@3.1.1': resolution: {integrity: sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==} - '@vitest/runner@3.0.5': - resolution: {integrity: sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==} + '@vitest/runner@3.0.9': + resolution: {integrity: sha512-NX9oUXgF9HPfJSwl8tUZCMP1oGx2+Sf+ru6d05QjzQz4OwWg0psEzwY6VexP2tTHWdOkhKHUIZH+fS6nA7jfOw==} - '@vitest/snapshot@3.0.5': - resolution: {integrity: sha512-GJPZYcd7v8QNUJ7vRvLDmRwl+a1fGg4T/54lZXe+UOGy47F9yUfE18hRCtXL5aHN/AONu29NGzIXSVFh9K0feA==} + '@vitest/snapshot@3.0.9': + resolution: {integrity: sha512-AiLUiuZ0FuA+/8i19mTYd+re5jqjEc2jZbgJ2up0VY0Ddyyxg/uUtBDpIFAy4uzKaQxOW8gMgBdAJJ2ydhu39A==} - '@vitest/spy@3.0.5': - resolution: {integrity: sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==} + '@vitest/spy@3.0.9': + resolution: {integrity: sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ==} - '@vitest/ui@3.1.1': - resolution: {integrity: sha512-2HpiRIYg3dlvAJBV9RtsVswFgUSJK4Sv7QhpxoP0eBGkYwzGIKP34PjaV00AULQi9Ovl6LGyZfsetxDWY5BQdQ==} + '@vitest/ui@3.0.9': + resolution: {integrity: sha512-FpZD4aIv/qNpwkV3XbLV6xldWFHMgoNWAJEgg5GmpObmAOLAErpYjew9dDwXdYdKOS3iZRKdwI+P3JOJcYeUBg==} peerDependencies: - vitest: 3.1.1 - - '@vitest/utils@3.0.5': - resolution: {integrity: sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==} + vitest: 3.0.9 - '@vitest/utils@3.1.1': - resolution: {integrity: sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==} + '@vitest/utils@3.0.9': + resolution: {integrity: sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-typescript@1.4.13: - resolution: {integrity: sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==} - peerDependencies: - acorn: '>=8.9.0' - - acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} engines: {node: '>=0.4.0'} hasBin: true @@ -1055,20 +1063,35 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - bare-events@2.5.0: - resolution: {integrity: sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==} + bare-events@2.5.4: + resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} - bare-fs@2.3.5: - resolution: {integrity: sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==} + bare-fs@4.1.2: + resolution: {integrity: sha512-8wSeOia5B7LwD4+h465y73KOdj5QHsbbuoUfPBi+pXgFJIPuG7SsiOdJuijWMyfid49eD+WivpfY7KT8gbAzBA==} + engines: {bare: '>=1.16.0'} + peerDependencies: + bare-buffer: '*' + peerDependenciesMeta: + bare-buffer: + optional: true - bare-os@2.4.4: - resolution: {integrity: sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==} + bare-os@3.6.1: + resolution: {integrity: sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==} + engines: {bare: '>=1.14.0'} - bare-path@2.1.3: - resolution: {integrity: sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==} + bare-path@3.0.0: + resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - bare-stream@2.6.1: - resolution: {integrity: sha512-eVZbtKM+4uehzrsj49KtCy3Pbg7kO1pJ3SKZ1SFrIH/0pnj9scuGGgUlNDf/7qS8WKtGdiJY5Kyhs/ivYPTB/g==} + bare-stream@2.6.5: + resolution: {integrity: sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==} + peerDependencies: + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + bare-events: + optional: true better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} @@ -1092,8 +1115,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - chai@5.1.2: - resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} engines: {node: '>=12'} chalk@4.1.2: @@ -1111,6 +1134,10 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + code-block-writer@13.0.3: resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} @@ -1124,8 +1151,8 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - commander@13.0.0: - resolution: {integrity: sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==} + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} commander@4.1.1: @@ -1210,8 +1237,8 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - domutils@3.1.0: - resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} dotenv@16.4.7: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} @@ -1236,8 +1263,8 @@ packages: end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - enhanced-resolve@5.18.0: - resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==} + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} engines: {node: '>=10.13.0'} enquirer@2.4.1: @@ -1251,8 +1278,8 @@ packages: es-module-lexer@1.6.0: resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} - esbuild@0.24.2: - resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + esbuild@0.25.2: + resolution: {integrity: sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==} engines: {node: '>=18'} hasBin: true @@ -1284,22 +1311,18 @@ packages: peerDependencies: eslint: '>=8.23.0' - eslint-plugin-svelte@2.46.0: - resolution: {integrity: sha512-1A7iEMkzmCZ9/Iz+EAfOGYL8IoIG6zeKEq1SmpxGeM5SXmoQq+ZNnCpXFVJpsxPWYx8jIVGMerQMzX20cqUl0g==} - engines: {node: ^14.17.0 || >=16.0.0} + eslint-plugin-svelte@3.5.1: + resolution: {integrity: sha512-Qn1slddZHfqYiDO6IN8/iN3YL+VuHlgYjm30FT+hh0Jf/TX0jeZMTJXQMajFm5f6f6hURi+XO8P+NPYD+T4jkg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^7.0.0 || ^8.0.0-0 || ^9.0.0-0 + eslint: ^8.57.1 || ^9.0.0 svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: svelte: optional: true - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-scope@8.2.0: - resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: @@ -1310,8 +1333,8 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.17.0: - resolution: {integrity: sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==} + eslint@9.24.0: + resolution: {integrity: sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -1320,17 +1343,13 @@ packages: jiti: optional: true - esm-env@1.2.1: - resolution: {integrity: sha512-U9JedYYjCnadUlXk7e1Kr+aENQhtUaoaV9+gZm1T8LC/YBAPJx3NSPIAurFOC0U5vrdSevnUJS2/wUVxGwPhng==} + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} espree@10.3.0: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} @@ -1340,11 +1359,8 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} - esrap@1.2.3: - resolution: {integrity: sha512-ZlQmCCK+n7SGoqo7DnfKaP1sJZa49P01/dXzmjCASSo04p72w8EksT2NMK8CEX8DhKsfJXANioIw8VyHNsBfvQ==} - - esrap@1.4.5: - resolution: {integrity: sha512-CjNMjkBWWZeHn+VX+gS8YvFwJ5+NDhg8aWZBSFJPR8qQduDNjbJodA2WcwCm7uQa5Rjqj+nZvVmceg1RbHFB9g==} + esrap@1.4.6: + resolution: {integrity: sha512-F/D2mADJ9SHY3IwksD4DAXjTt7qt7GWUf3/8RhCNWmC/67tyb55dpimHmy7EplakFaflV0R/PC+fdSPqrRHAQw==} esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} @@ -1367,8 +1383,8 @@ packages: event-stream@3.3.4: resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} - expect-type@1.1.0: - resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} engines: {node: '>=12.0.0'} extendable-error@0.1.7: @@ -1384,8 +1400,8 @@ packages: fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: @@ -1394,8 +1410,8 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} fdir@6.4.3: resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} @@ -1428,14 +1444,11 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flatted@3.3.2: - resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} - flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} from@0.1.7: @@ -1466,8 +1479,8 @@ packages: get-tsconfig@4.10.0: resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} - git-hooks-list@3.1.0: - resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==} + git-hooks-list@3.2.0: + resolution: {integrity: sha512-ZHG9a1gEhUMX1TvGrLdyWb9kDopCBbTnI8z4JgRMYxsijWipgjSEYoPWqBuIB0DnRnvqlQSEeVmzpeuPm7NdFQ==} gitignore-parser@0.0.2: resolution: {integrity: sha512-X6mpqUv59uWLGD4n3hZ8Cu8KbF2PMWPSFYmxZjdkpm3yOU7hSUYnzTkZI1mcWqchphvqyuz3/BhgBR4E/JtkCg==} @@ -1489,8 +1502,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.14.0: - resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==} + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} globalyzer@0.1.0: @@ -1516,8 +1529,9 @@ packages: htmlparser2@9.1.0: resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} - human-id@1.0.2: - resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + human-id@4.1.1: + resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} + hasBin: true iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} @@ -1527,8 +1541,8 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} import-meta-resolve@4.1.0: @@ -1637,9 +1651,6 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - loupe@3.1.2: - resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} - loupe@3.1.3: resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} @@ -1678,8 +1689,8 @@ packages: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} - mrmime@2.0.0: - resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} ms@2.1.3: @@ -1688,8 +1699,8 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nanoid@3.3.8: - resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -1757,8 +1768,8 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@0.2.7: - resolution: {integrity: sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==} + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -1783,9 +1794,6 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - pathe@2.0.2: - resolution: {integrity: sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -1814,17 +1822,17 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} - playwright-core@1.49.1: - resolution: {integrity: sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==} + playwright-core@1.51.1: + resolution: {integrity: sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==} engines: {node: '>=18'} hasBin: true - playwright@1.49.1: - resolution: {integrity: sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==} + playwright@1.51.1: + resolution: {integrity: sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==} engines: {node: '>=18'} hasBin: true @@ -1840,11 +1848,11 @@ packages: ts-node: optional: true - postcss-safe-parser@6.0.0: - resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} - engines: {node: '>=12.0'} + postcss-safe-parser@7.0.1: + resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} + engines: {node: '>=18.0'} peerDependencies: - postcss: ^8.3.3 + postcss: ^8.4.31 postcss-scss@4.0.9: resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} @@ -1852,14 +1860,10 @@ packages: peerDependencies: postcss: ^8.4.29 - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} - postcss@8.5.1: - resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.3: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} @@ -1868,16 +1872,16 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-plugin-packagejson@2.5.6: - resolution: {integrity: sha512-TY7KiLtyt6Tlf53BEbXUWkN0+TRdHKgIMmtXtDCyHH6yWnZ50Lwq6Vb6lyjapZrhDTXooC4EtlY5iLe1sCgi5w==} + prettier-plugin-packagejson@2.5.10: + resolution: {integrity: sha512-LUxATI5YsImIVSaaLJlJ3aE6wTD+nvots18U3GuQMJpUyClChaZlQrqx3dBnbhF20OnKWZyx8EgyZypQtBDtgQ==} peerDependencies: prettier: '>= 1.16.0' peerDependenciesMeta: prettier: optional: true - prettier-plugin-svelte@3.3.2: - resolution: {integrity: sha512-kRPjH8wSj2iu+dO+XaUv4vD8qr5mdDmlak3IT/7AOgGIMRG86z/EHOLauFcClKEnOUf4A4nOA7sre5KrJD4Raw==} + prettier-plugin-svelte@3.3.3: + resolution: {integrity: sha512-yViK9zqQ+H2qZD1w/bH7W8i+bVfKrD8GIFjkFe4Thl6kCT9SlAsXVNmt3jCvQOCsnOhcvYgsoVlRV/Eu6x5nNw==} peerDependencies: prettier: ^3.0.0 svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 @@ -1887,8 +1891,8 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - prettier@3.4.2: - resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} + prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} engines: {node: '>=14'} hasBin: true @@ -1904,12 +1908,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + quansync@0.2.10: + resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - queue-tick@1.0.1: - resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} - read-yaml-file@1.1.0: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} @@ -1928,8 +1932,8 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} rolldown@1.0.0-beta.1: @@ -1941,8 +1945,8 @@ packages: '@babel/runtime': optional: true - rollup@4.34.5: - resolution: {integrity: sha512-GyVCmpo9z/HYqFD8QWoBUnz1Q9xC22t8tPAZm/AvAcUg2U2/+DkboEvSioMwv042zE4I9N3FEhx7fiCT2YHzKQ==} + rollup@4.39.0: + resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1952,8 +1956,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} engines: {node: '>=10'} hasBin: true @@ -1989,8 +1993,8 @@ packages: sort-object-keys@1.1.3: resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} - sort-package-json@2.12.0: - resolution: {integrity: sha512-/HrPQAeeLaa+vbAH/znjuhwUluuiM/zL5XX9kop8UpDgjtyWKt43hGDk2vd/TBdDpzIyzIHVUgmYofzYrAQjew==} + sort-package-json@2.15.1: + resolution: {integrity: sha512-9x9+o8krTT2saA9liI4BljNjwAbvUnWf11Wq+i/iZt8nl2UGYnf3TH5uBydE7VALmP7AGwlfszuEeL8BDyb0YA==} hasBin: true source-map-js@1.2.1: @@ -2009,14 +2013,14 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - std-env@3.8.0: - resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} stream-combiner@0.0.4: resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} - streamx@2.21.1: - resolution: {integrity: sha512-PhP9wUnFLa+91CPy3N6tiQsK+gnYyUNuk15S3YG/zjYE7RuPeCjJngqnzpC31ow0lzBHQ+QGO4cNJnd0djYUsw==} + streamx@2.22.0: + resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} @@ -2051,9 +2055,9 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - svelte-eslint-parser@0.43.0: - resolution: {integrity: sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + svelte-eslint-parser@1.1.2: + resolution: {integrity: sha512-vqFBRamDKo1l70KMfxxXj1/0Cco5TfMDnqaAjgz6D8PyoMhfMcDOLRkAwPg8WkMyZjMtQL3wW66TZ0x59iqO2w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 peerDependenciesMeta: @@ -2064,8 +2068,8 @@ packages: resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==} engines: {node: '>=16'} - svelte@5.12.0: - resolution: {integrity: sha512-nOd7uj0D/4A3IrHnltaFYndVPGViYSs0s+Zi3N4uQg3owJt9RoiUdwxYx8qjorj5CtaGsx8dNYsFVbH6czrGNg==} + svelte@5.25.7: + resolution: {integrity: sha512-0fzXbXaKfSvFUs6Wxev2h4CoEhexZotbTF9EJ4+Cg7MHW64ZnZ9+xUedZyEpgj0Tt9HrYGv9aASHkqjn9b/cPw==} engines: {node: '>=18'} synckit@0.9.2: @@ -2076,8 +2080,8 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - tar-fs@3.0.6: - resolution: {integrity: sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==} + tar-fs@3.0.8: + resolution: {integrity: sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==} tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} @@ -2108,10 +2112,6 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.10: - resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} - engines: {node: '>=12.0.0'} - tinyglobby@0.2.12: resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} engines: {node: '>=12.0.0'} @@ -2143,11 +2143,11 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - ts-api-utils@1.4.3: - resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} - engines: {node: '>=16'} + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} peerDependencies: - typescript: '>=4.2.0' + typescript: '>=4.8.4' ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -2162,23 +2162,23 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.18.0: - resolution: {integrity: sha512-Xq2rRjn6tzVpAyHr3+nmSg1/9k9aIHnJ2iZeOH7cfGOWqTkXTm3kwpQglEuLGdNrYvPF+2gtAs+/KF5rjVo+WQ==} + typescript-eslint@8.29.0: + resolution: {integrity: sha512-ep9rVd9B4kQsZ7ZnWCVxUE/xDLUUUsRzE0poAeNu+4CkFErLfuvPt/qtm2EpnSyfvsR0S6QzDFSrPCFBwf64fg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <5.9.0' - typescript@5.7.2: - resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} @@ -2199,8 +2199,8 @@ packages: typescript: optional: true - unplugin@1.16.0: - resolution: {integrity: sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==} + unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} engines: {node: '>=14.0.0'} uri-js@4.4.1: @@ -2217,13 +2217,13 @@ packages: typescript: optional: true - vite-node@3.0.5: - resolution: {integrity: sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==} + vite-node@3.0.9: + resolution: {integrity: sha512-w3Gdx7jDcuT9cNn9jExXgOyKmf5UOTb6WMHz8LGAm54eS1Elf5OuBhCxl6zJxGhEeIkgsE1WbHuoL0mj/UXqXg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite@6.1.0: - resolution: {integrity: sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==} + vite@6.2.5: + resolution: {integrity: sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -2262,16 +2262,16 @@ packages: yaml: optional: true - vitest@3.0.5: - resolution: {integrity: sha512-4dof+HvqONw9bvsYxtkfUp2uHsTN9bV2CZIi1pWgoFpL1Lld8LA1ka9q/ONSsoScAKG7NVGf2stJTI7XRkXb2Q==} + vitest@3.0.9: + resolution: {integrity: sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.0.5 - '@vitest/ui': 3.0.5 + '@vitest/browser': 3.0.9 + '@vitest/ui': 3.0.9 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -2335,8 +2335,8 @@ packages: zimmerframe@1.1.2: resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} - zod@3.24.1: - resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} + zod@3.24.2: + resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} snapshots: @@ -2345,17 +2345,17 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - '@babel/runtime@7.26.0': + '@babel/runtime@7.27.0': dependencies: regenerator-runtime: 0.14.1 - '@changesets/apply-release-plan@7.0.6': + '@changesets/apply-release-plan@7.0.10': dependencies: - '@changesets/config': 3.0.4 + '@changesets/config': 3.1.1 '@changesets/get-version-range-type': 0.4.0 '@changesets/git': 3.0.2 - '@changesets/should-skip-package': 0.1.1 - '@changesets/types': 6.0.0 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 fs-extra: 7.0.1 @@ -2363,37 +2363,37 @@ snapshots: outdent: 0.5.0 prettier: 2.8.8 resolve-from: 5.0.0 - semver: 7.6.3 + semver: 7.7.1 - '@changesets/assemble-release-plan@6.0.5': + '@changesets/assemble-release-plan@6.0.6': dependencies: '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.2 - '@changesets/should-skip-package': 0.1.1 - '@changesets/types': 6.0.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 - semver: 7.6.3 + semver: 7.7.1 - '@changesets/changelog-git@0.2.0': + '@changesets/changelog-git@0.2.1': dependencies: - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 - '@changesets/cli@2.27.10': + '@changesets/cli@2.28.1': dependencies: - '@changesets/apply-release-plan': 7.0.6 - '@changesets/assemble-release-plan': 6.0.5 - '@changesets/changelog-git': 0.2.0 - '@changesets/config': 3.0.4 + '@changesets/apply-release-plan': 7.0.10 + '@changesets/assemble-release-plan': 6.0.6 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.1 '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.2 - '@changesets/get-release-plan': 4.0.5 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/get-release-plan': 4.0.8 '@changesets/git': 3.0.2 '@changesets/logger': 0.1.1 - '@changesets/pre': 2.0.1 - '@changesets/read': 0.6.2 - '@changesets/should-skip-package': 0.1.1 - '@changesets/types': 6.0.0 - '@changesets/write': 0.3.2 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 ci-info: 3.9.0 @@ -2402,19 +2402,19 @@ snapshots: fs-extra: 7.0.1 mri: 1.2.0 p-limit: 2.3.0 - package-manager-detector: 0.2.7 + package-manager-detector: 0.2.11 picocolors: 1.1.1 resolve-from: 5.0.0 - semver: 7.6.3 + semver: 7.7.1 spawndamnit: 3.0.1 term-size: 2.2.1 - '@changesets/config@3.0.4': + '@changesets/config@3.1.1': dependencies: '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-dependents-graph': 2.1.3 '@changesets/logger': 0.1.1 - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 micromatch: 4.0.8 @@ -2423,12 +2423,12 @@ snapshots: dependencies: extendable-error: 0.1.7 - '@changesets/get-dependents-graph@2.1.2': + '@changesets/get-dependents-graph@2.1.3': dependencies: - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 picocolors: 1.1.1 - semver: 7.6.3 + semver: 7.7.1 '@changesets/get-github-info@0.6.0': dependencies: @@ -2437,13 +2437,13 @@ snapshots: transitivePeerDependencies: - encoding - '@changesets/get-release-plan@4.0.5': + '@changesets/get-release-plan@4.0.8': dependencies: - '@changesets/assemble-release-plan': 6.0.5 - '@changesets/config': 3.0.4 - '@changesets/pre': 2.0.1 - '@changesets/read': 0.6.2 - '@changesets/types': 6.0.0 + '@changesets/assemble-release-plan': 6.0.6 + '@changesets/config': 3.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.3 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 '@changesets/get-version-range-type@0.4.0': {} @@ -2460,42 +2460,42 @@ snapshots: dependencies: picocolors: 1.1.1 - '@changesets/parse@0.4.0': + '@changesets/parse@0.4.1': dependencies: - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 js-yaml: 3.14.1 - '@changesets/pre@2.0.1': + '@changesets/pre@2.0.2': dependencies: '@changesets/errors': 0.2.0 - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - '@changesets/read@0.6.2': + '@changesets/read@0.6.3': dependencies: '@changesets/git': 3.0.2 '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.0 - '@changesets/types': 6.0.0 + '@changesets/parse': 0.4.1 + '@changesets/types': 6.1.0 fs-extra: 7.0.1 p-filter: 2.1.0 picocolors: 1.1.1 - '@changesets/should-skip-package@0.1.1': + '@changesets/should-skip-package@0.1.2': dependencies: - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 '@changesets/types@4.1.0': {} - '@changesets/types@6.0.0': {} + '@changesets/types@6.1.0': {} - '@changesets/write@0.3.2': + '@changesets/write@0.4.0': dependencies: - '@changesets/types': 6.0.0 + '@changesets/types': 6.1.0 fs-extra: 7.0.1 - human-id: 1.0.2 + human-id: 4.1.1 prettier: 2.8.8 '@clack/core@0.4.1': @@ -2509,13 +2509,13 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 - '@emnapi/core@1.3.1': + '@emnapi/core@1.4.0': dependencies: '@emnapi/wasi-threads': 1.0.1 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.3.1': + '@emnapi/runtime@1.4.0': dependencies: tslib: 2.8.1 optional: true @@ -2525,120 +2525,127 @@ snapshots: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.24.2': + '@esbuild/aix-ppc64@0.25.2': optional: true - '@esbuild/android-arm64@0.24.2': + '@esbuild/android-arm64@0.25.2': optional: true - '@esbuild/android-arm@0.24.2': + '@esbuild/android-arm@0.25.2': optional: true - '@esbuild/android-x64@0.24.2': + '@esbuild/android-x64@0.25.2': optional: true - '@esbuild/darwin-arm64@0.24.2': + '@esbuild/darwin-arm64@0.25.2': optional: true - '@esbuild/darwin-x64@0.24.2': + '@esbuild/darwin-x64@0.25.2': optional: true - '@esbuild/freebsd-arm64@0.24.2': + '@esbuild/freebsd-arm64@0.25.2': optional: true - '@esbuild/freebsd-x64@0.24.2': + '@esbuild/freebsd-x64@0.25.2': optional: true - '@esbuild/linux-arm64@0.24.2': + '@esbuild/linux-arm64@0.25.2': optional: true - '@esbuild/linux-arm@0.24.2': + '@esbuild/linux-arm@0.25.2': optional: true - '@esbuild/linux-ia32@0.24.2': + '@esbuild/linux-ia32@0.25.2': optional: true - '@esbuild/linux-loong64@0.24.2': + '@esbuild/linux-loong64@0.25.2': optional: true - '@esbuild/linux-mips64el@0.24.2': + '@esbuild/linux-mips64el@0.25.2': optional: true - '@esbuild/linux-ppc64@0.24.2': + '@esbuild/linux-ppc64@0.25.2': optional: true - '@esbuild/linux-riscv64@0.24.2': + '@esbuild/linux-riscv64@0.25.2': optional: true - '@esbuild/linux-s390x@0.24.2': + '@esbuild/linux-s390x@0.25.2': optional: true - '@esbuild/linux-x64@0.24.2': + '@esbuild/linux-x64@0.25.2': optional: true - '@esbuild/netbsd-arm64@0.24.2': + '@esbuild/netbsd-arm64@0.25.2': optional: true - '@esbuild/netbsd-x64@0.24.2': + '@esbuild/netbsd-x64@0.25.2': optional: true - '@esbuild/openbsd-arm64@0.24.2': + '@esbuild/openbsd-arm64@0.25.2': optional: true - '@esbuild/openbsd-x64@0.24.2': + '@esbuild/openbsd-x64@0.25.2': optional: true - '@esbuild/sunos-x64@0.24.2': + '@esbuild/sunos-x64@0.25.2': optional: true - '@esbuild/win32-arm64@0.24.2': + '@esbuild/win32-arm64@0.25.2': optional: true - '@esbuild/win32-ia32@0.24.2': + '@esbuild/win32-ia32@0.25.2': optional: true - '@esbuild/win32-x64@0.24.2': + '@esbuild/win32-x64@0.25.2': optional: true - '@eslint-community/eslint-utils@4.4.1(eslint@9.17.0)': + '@eslint-community/eslint-utils@4.5.1(eslint@9.24.0)': dependencies: - eslint: 9.17.0 + eslint: 9.24.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/config-array@0.19.1': + '@eslint/config-array@0.20.0': dependencies: - '@eslint/object-schema': 2.1.5 + '@eslint/object-schema': 2.1.6 debug: 4.4.0 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/core@0.9.1': + '@eslint/config-helpers@0.2.1': {} + + '@eslint/core@0.12.0': dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.2.0': + '@eslint/core@0.13.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 debug: 4.4.0 espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 - import-fresh: 3.3.0 + import-fresh: 3.3.1 js-yaml: 4.1.0 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.17.0': {} + '@eslint/js@9.24.0': {} - '@eslint/object-schema@2.1.5': {} + '@eslint/object-schema@2.1.6': {} - '@eslint/plugin-kit@0.2.4': + '@eslint/plugin-kit@0.2.8': dependencies: + '@eslint/core': 0.13.0 levn: 0.4.1 '@humanfs/core@0.19.1': {} @@ -2652,7 +2659,7 @@ snapshots: '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.1': {} + '@humanwhocodes/retry@0.4.2': {} '@isaacs/cliui@8.0.2': dependencies: @@ -2682,24 +2689,24 @@ snapshots: '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.26.0 + '@babel/runtime': 7.27.0 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.26.0 + '@babel/runtime': 7.27.0 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 globby: 11.1.0 read-yaml-file: 1.1.0 - '@napi-rs/wasm-runtime@0.2.6': + '@napi-rs/wasm-runtime@0.2.8': dependencies: - '@emnapi/core': 1.3.1 - '@emnapi/runtime': 1.3.1 + '@emnapi/core': 1.4.0 + '@emnapi/runtime': 1.4.0 '@tybys/wasm-util': 0.9.0 optional: true @@ -2713,7 +2720,7 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 + fastq: 1.19.1 '@oxc-parser/binding-darwin-arm64@0.37.0': optional: true @@ -2744,11 +2751,11 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pkgr/core@0.1.1': {} + '@pkgr/core@0.1.2': {} - '@playwright/test@1.49.1': + '@playwright/test@1.51.1': dependencies: - playwright: 1.49.1 + playwright: 1.51.1 '@polka/url@1.0.0-next.28': {} @@ -2778,7 +2785,7 @@ snapshots: '@rolldown/binding-wasm32-wasi@1.0.0-beta.1': dependencies: - '@napi-rs/wasm-runtime': 0.2.6 + '@napi-rs/wasm-runtime': 0.2.8 optional: true '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.1': @@ -2790,91 +2797,94 @@ snapshots: '@rolldown/binding-win32-x64-msvc@1.0.0-beta.1': optional: true - '@rollup/pluginutils@5.1.3(rollup@4.34.5)': + '@rollup/pluginutils@5.1.4(rollup@4.39.0)': dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 estree-walker: 2.0.2 picomatch: 4.0.2 optionalDependencies: - rollup: 4.34.5 + rollup: 4.39.0 - '@rollup/rollup-android-arm-eabi@4.34.5': + '@rollup/rollup-android-arm-eabi@4.39.0': optional: true - '@rollup/rollup-android-arm64@4.34.5': + '@rollup/rollup-android-arm64@4.39.0': optional: true - '@rollup/rollup-darwin-arm64@4.34.5': + '@rollup/rollup-darwin-arm64@4.39.0': optional: true - '@rollup/rollup-darwin-x64@4.34.5': + '@rollup/rollup-darwin-x64@4.39.0': optional: true - '@rollup/rollup-freebsd-arm64@4.34.5': + '@rollup/rollup-freebsd-arm64@4.39.0': optional: true - '@rollup/rollup-freebsd-x64@4.34.5': + '@rollup/rollup-freebsd-x64@4.39.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.34.5': + '@rollup/rollup-linux-arm-gnueabihf@4.39.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.34.5': + '@rollup/rollup-linux-arm-musleabihf@4.39.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.34.5': + '@rollup/rollup-linux-arm64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.34.5': + '@rollup/rollup-linux-arm64-musl@4.39.0': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.34.5': + '@rollup/rollup-linux-loongarch64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.34.5': + '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.34.5': + '@rollup/rollup-linux-riscv64-gnu@4.39.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.34.5': + '@rollup/rollup-linux-riscv64-musl@4.39.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.34.5': + '@rollup/rollup-linux-s390x-gnu@4.39.0': optional: true - '@rollup/rollup-linux-x64-musl@4.34.5': + '@rollup/rollup-linux-x64-gnu@4.39.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.34.5': + '@rollup/rollup-linux-x64-musl@4.39.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.34.5': + '@rollup/rollup-win32-arm64-msvc@4.39.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.34.5': + '@rollup/rollup-win32-ia32-msvc@4.39.0': optional: true - '@stylistic/eslint-plugin-js@2.10.1(eslint@9.17.0)': + '@rollup/rollup-win32-x64-msvc@4.39.0': + optional: true + + '@stylistic/eslint-plugin-js@2.10.1(eslint@9.24.0)': dependencies: - eslint: 9.17.0 + eslint: 9.24.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 - '@sveltejs/acorn-typescript@1.0.5(acorn@8.14.0)': + '@sveltejs/acorn-typescript@1.0.5(acorn@8.14.1)': dependencies: - acorn: 8.14.0 + acorn: 8.14.1 - '@sveltejs/eslint-config@8.1.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.17.0))(eslint-config-prettier@9.1.0(eslint@9.17.0))(eslint-plugin-n@17.13.1(eslint@9.17.0))(eslint-plugin-svelte@2.46.0(eslint@9.17.0)(svelte@5.12.0))(eslint@9.17.0)(typescript-eslint@8.18.0(eslint@9.17.0)(typescript@5.7.2))(typescript@5.7.2)': + '@sveltejs/eslint-config@8.2.0(@stylistic/eslint-plugin-js@2.10.1(eslint@9.24.0))(eslint-config-prettier@9.1.0(eslint@9.24.0))(eslint-plugin-n@17.13.1(eslint@9.24.0))(eslint-plugin-svelte@3.5.1(eslint@9.24.0)(svelte@5.25.7))(eslint@9.24.0)(typescript-eslint@8.29.0(eslint@9.24.0)(typescript@5.8.3))(typescript@5.8.3)': dependencies: - '@stylistic/eslint-plugin-js': 2.10.1(eslint@9.17.0) - eslint: 9.17.0 - eslint-config-prettier: 9.1.0(eslint@9.17.0) - eslint-plugin-n: 17.13.1(eslint@9.17.0) - eslint-plugin-svelte: 2.46.0(eslint@9.17.0)(svelte@5.12.0) - globals: 15.14.0 - typescript: 5.7.2 - typescript-eslint: 8.18.0(eslint@9.17.0)(typescript@5.7.2) + '@stylistic/eslint-plugin-js': 2.10.1(eslint@9.24.0) + eslint: 9.24.0 + eslint-config-prettier: 9.1.0(eslint@9.24.0) + eslint-plugin-n: 17.13.1(eslint@9.24.0) + eslint-plugin-svelte: 3.5.1(eslint@9.24.0)(svelte@5.25.7) + globals: 15.15.0 + typescript: 5.8.3 + typescript-eslint: 8.29.0(eslint@9.24.0)(typescript@5.8.3) '@svitejs/changesets-changelog-github-compact@1.2.0': dependencies: @@ -2887,7 +2897,7 @@ snapshots: dependencies: minimatch: 9.0.5 path-browserify: 1.0.1 - tinyglobby: 0.2.10 + tinyglobby: 0.2.12 '@tybys/wasm-util@0.9.0': dependencies: @@ -2896,7 +2906,7 @@ snapshots: '@types/degit@2.8.6': {} - '@types/estree@1.0.6': {} + '@types/estree@1.0.7': {} '@types/gitignore-parser@0.0.3': {} @@ -2904,125 +2914,125 @@ snapshots: '@types/node@12.20.55': {} - '@types/node@18.19.68': + '@types/node@18.19.86': dependencies: undici-types: 5.26.5 - '@types/node@22.10.2': + '@types/node@22.14.0': dependencies: - undici-types: 6.20.0 + undici-types: 6.21.0 '@types/prompts@2.4.9': dependencies: - '@types/node': 22.10.2 + '@types/node': 22.14.0 kleur: 3.0.3 '@types/ps-tree@1.1.6': {} - '@types/semver@7.5.8': {} + '@types/semver@7.7.0': {} '@types/tar-fs@2.0.4': dependencies: - '@types/node': 22.10.2 + '@types/node': 22.14.0 '@types/tar-stream': 3.1.3 '@types/tar-stream@3.1.3': dependencies: - '@types/node': 22.10.2 + '@types/node': 22.14.0 - '@typescript-eslint/eslint-plugin@8.18.0(@typescript-eslint/parser@8.18.0(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.18.0(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/scope-manager': 8.18.0 - '@typescript-eslint/type-utils': 8.18.0(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.18.0(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/visitor-keys': 8.18.0 - eslint: 9.17.0 + '@typescript-eslint/parser': 8.29.0(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/type-utils': 8.29.0(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/utils': 8.29.0(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.29.0 + eslint: 9.24.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.4.3(typescript@5.7.2) - typescript: 5.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.18.0(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/parser@8.29.0(eslint@9.24.0)(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.18.0 - '@typescript-eslint/types': 8.18.0 - '@typescript-eslint/typescript-estree': 8.18.0(typescript@5.7.2) - '@typescript-eslint/visitor-keys': 8.18.0 + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.29.0 debug: 4.4.0 - eslint: 9.17.0 - typescript: 5.7.2 + eslint: 9.24.0 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.18.0': + '@typescript-eslint/scope-manager@8.29.0': dependencies: - '@typescript-eslint/types': 8.18.0 - '@typescript-eslint/visitor-keys': 8.18.0 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/visitor-keys': 8.29.0 - '@typescript-eslint/type-utils@8.18.0(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/type-utils@8.29.0(eslint@9.24.0)(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.18.0(typescript@5.7.2) - '@typescript-eslint/utils': 8.18.0(eslint@9.17.0)(typescript@5.7.2) + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.3) + '@typescript-eslint/utils': 8.29.0(eslint@9.24.0)(typescript@5.8.3) debug: 4.4.0 - eslint: 9.17.0 - ts-api-utils: 1.4.3(typescript@5.7.2) - typescript: 5.7.2 + eslint: 9.24.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.18.0': {} + '@typescript-eslint/types@8.29.0': {} - '@typescript-eslint/typescript-estree@8.18.0(typescript@5.7.2)': + '@typescript-eslint/typescript-estree@8.29.0(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.18.0 - '@typescript-eslint/visitor-keys': 8.18.0 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/visitor-keys': 8.29.0 debug: 4.4.0 - fast-glob: 3.3.2 + fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.6.3 - ts-api-utils: 1.4.3(typescript@5.7.2) - typescript: 5.7.2 + semver: 7.7.1 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.18.0(eslint@9.17.0)(typescript@5.7.2)': + '@typescript-eslint/utils@8.29.0(eslint@9.24.0)(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) - '@typescript-eslint/scope-manager': 8.18.0 - '@typescript-eslint/types': 8.18.0 - '@typescript-eslint/typescript-estree': 8.18.0(typescript@5.7.2) - eslint: 9.17.0 - typescript: 5.7.2 + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) + '@typescript-eslint/scope-manager': 8.29.0 + '@typescript-eslint/types': 8.29.0 + '@typescript-eslint/typescript-estree': 8.29.0(typescript@5.8.3) + eslint: 9.24.0 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.18.0': + '@typescript-eslint/visitor-keys@8.29.0': dependencies: - '@typescript-eslint/types': 8.18.0 + '@typescript-eslint/types': 8.29.0 eslint-visitor-keys: 4.2.0 - '@vitest/expect@3.0.5': + '@vitest/expect@3.0.9': dependencies: - '@vitest/spy': 3.0.5 - '@vitest/utils': 3.0.5 - chai: 5.1.2 + '@vitest/spy': 3.0.9 + '@vitest/utils': 3.0.9 + chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.0.5(vite@6.1.0(@types/node@22.10.2))': + '@vitest/mocker@3.0.9(vite@6.2.5(@types/node@22.14.0))': dependencies: - '@vitest/spy': 3.0.5 + '@vitest/spy': 3.0.9 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.1.0(@types/node@22.10.2) + vite: 6.2.5(@types/node@22.14.0) - '@vitest/pretty-format@3.0.5': + '@vitest/pretty-format@3.0.9': dependencies: tinyrainbow: 2.0.0 @@ -3030,53 +3040,43 @@ snapshots: dependencies: tinyrainbow: 2.0.0 - '@vitest/runner@3.0.5': + '@vitest/runner@3.0.9': dependencies: - '@vitest/utils': 3.0.5 - pathe: 2.0.2 + '@vitest/utils': 3.0.9 + pathe: 2.0.3 - '@vitest/snapshot@3.0.5': + '@vitest/snapshot@3.0.9': dependencies: - '@vitest/pretty-format': 3.0.5 + '@vitest/pretty-format': 3.0.9 magic-string: 0.30.17 - pathe: 2.0.2 + pathe: 2.0.3 - '@vitest/spy@3.0.5': + '@vitest/spy@3.0.9': dependencies: tinyspy: 3.0.2 - '@vitest/ui@3.1.1(vitest@3.0.5)': + '@vitest/ui@3.0.9(vitest@3.0.9)': dependencies: - '@vitest/utils': 3.1.1 + '@vitest/utils': 3.0.9 fflate: 0.8.2 flatted: 3.3.3 pathe: 2.0.3 sirv: 3.0.1 tinyglobby: 0.2.12 tinyrainbow: 2.0.0 - vitest: 3.0.5(@types/node@22.10.2)(@vitest/ui@3.1.1) - - '@vitest/utils@3.0.5': - dependencies: - '@vitest/pretty-format': 3.0.5 - loupe: 3.1.3 - tinyrainbow: 2.0.0 + vitest: 3.0.9(@types/node@22.14.0)(@vitest/ui@3.0.9) - '@vitest/utils@3.1.1': + '@vitest/utils@3.0.9': dependencies: - '@vitest/pretty-format': 3.1.1 + '@vitest/pretty-format': 3.0.9 loupe: 3.1.3 tinyrainbow: 2.0.0 - acorn-jsx@5.3.2(acorn@8.14.0): - dependencies: - acorn: 8.14.0 - - acorn-typescript@1.4.13(acorn@8.14.0): + acorn-jsx@5.3.2(acorn@8.14.1): dependencies: - acorn: 8.14.0 + acorn: 8.14.1 - acorn@8.14.0: {} + acorn@8.14.1: {} ajv@6.12.6: dependencies: @@ -3117,27 +3117,29 @@ snapshots: balanced-match@1.0.2: {} - bare-events@2.5.0: + bare-events@2.5.4: optional: true - bare-fs@2.3.5: + bare-fs@4.1.2: dependencies: - bare-events: 2.5.0 - bare-path: 2.1.3 - bare-stream: 2.6.1 + bare-events: 2.5.4 + bare-path: 3.0.0 + bare-stream: 2.6.5(bare-events@2.5.4) optional: true - bare-os@2.4.4: + bare-os@3.6.1: optional: true - bare-path@2.1.3: + bare-path@3.0.0: dependencies: - bare-os: 2.4.4 + bare-os: 3.6.1 optional: true - bare-stream@2.6.1: + bare-stream@2.6.5(bare-events@2.5.4): dependencies: - streamx: 2.21.1 + streamx: 2.22.0 + optionalDependencies: + bare-events: 2.5.4 optional: true better-path-resolve@1.0.0: @@ -3161,12 +3163,12 @@ snapshots: callsites@3.1.0: {} - chai@5.1.2: + chai@5.2.0: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.2 + loupe: 3.1.3 pathval: 2.0.0 chalk@4.1.2: @@ -3180,13 +3182,15 @@ snapshots: ci-info@3.9.0: {} + clsx@2.1.1: {} + code-block-writer@13.0.3: {} code-red@1.0.4: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 - '@types/estree': 1.0.6 - acorn: 8.14.0 + '@types/estree': 1.0.7 + acorn: 8.14.1 estree-walker: 3.0.3 periscopic: 3.1.0 @@ -3196,7 +3200,7 @@ snapshots: color-name@1.1.4: {} - commander@13.0.0: {} + commander@13.1.0: {} commander@4.1.1: {} @@ -3253,7 +3257,7 @@ snapshots: dependencies: domelementtype: 2.3.0 - domutils@3.1.0: + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 domelementtype: 2.3.0 @@ -3275,7 +3279,7 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.18.0: + enhanced-resolve@5.18.1: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 @@ -3289,89 +3293,82 @@ snapshots: es-module-lexer@1.6.0: {} - esbuild@0.24.2: + esbuild@0.25.2: optionalDependencies: - '@esbuild/aix-ppc64': 0.24.2 - '@esbuild/android-arm': 0.24.2 - '@esbuild/android-arm64': 0.24.2 - '@esbuild/android-x64': 0.24.2 - '@esbuild/darwin-arm64': 0.24.2 - '@esbuild/darwin-x64': 0.24.2 - '@esbuild/freebsd-arm64': 0.24.2 - '@esbuild/freebsd-x64': 0.24.2 - '@esbuild/linux-arm': 0.24.2 - '@esbuild/linux-arm64': 0.24.2 - '@esbuild/linux-ia32': 0.24.2 - '@esbuild/linux-loong64': 0.24.2 - '@esbuild/linux-mips64el': 0.24.2 - '@esbuild/linux-ppc64': 0.24.2 - '@esbuild/linux-riscv64': 0.24.2 - '@esbuild/linux-s390x': 0.24.2 - '@esbuild/linux-x64': 0.24.2 - '@esbuild/netbsd-arm64': 0.24.2 - '@esbuild/netbsd-x64': 0.24.2 - '@esbuild/openbsd-arm64': 0.24.2 - '@esbuild/openbsd-x64': 0.24.2 - '@esbuild/sunos-x64': 0.24.2 - '@esbuild/win32-arm64': 0.24.2 - '@esbuild/win32-ia32': 0.24.2 - '@esbuild/win32-x64': 0.24.2 + '@esbuild/aix-ppc64': 0.25.2 + '@esbuild/android-arm': 0.25.2 + '@esbuild/android-arm64': 0.25.2 + '@esbuild/android-x64': 0.25.2 + '@esbuild/darwin-arm64': 0.25.2 + '@esbuild/darwin-x64': 0.25.2 + '@esbuild/freebsd-arm64': 0.25.2 + '@esbuild/freebsd-x64': 0.25.2 + '@esbuild/linux-arm': 0.25.2 + '@esbuild/linux-arm64': 0.25.2 + '@esbuild/linux-ia32': 0.25.2 + '@esbuild/linux-loong64': 0.25.2 + '@esbuild/linux-mips64el': 0.25.2 + '@esbuild/linux-ppc64': 0.25.2 + '@esbuild/linux-riscv64': 0.25.2 + '@esbuild/linux-s390x': 0.25.2 + '@esbuild/linux-x64': 0.25.2 + '@esbuild/netbsd-arm64': 0.25.2 + '@esbuild/netbsd-x64': 0.25.2 + '@esbuild/openbsd-arm64': 0.25.2 + '@esbuild/openbsd-x64': 0.25.2 + '@esbuild/sunos-x64': 0.25.2 + '@esbuild/win32-arm64': 0.25.2 + '@esbuild/win32-ia32': 0.25.2 + '@esbuild/win32-x64': 0.25.2 escape-string-regexp@4.0.0: {} - eslint-compat-utils@0.5.1(eslint@9.17.0): + eslint-compat-utils@0.5.1(eslint@9.24.0): dependencies: - eslint: 9.17.0 - semver: 7.6.3 + eslint: 9.24.0 + semver: 7.7.1 - eslint-config-prettier@9.1.0(eslint@9.17.0): + eslint-config-prettier@9.1.0(eslint@9.24.0): dependencies: - eslint: 9.17.0 + eslint: 9.24.0 - eslint-plugin-es-x@7.8.0(eslint@9.17.0): + eslint-plugin-es-x@7.8.0(eslint@9.24.0): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) '@eslint-community/regexpp': 4.12.1 - eslint: 9.17.0 - eslint-compat-utils: 0.5.1(eslint@9.17.0) + eslint: 9.24.0 + eslint-compat-utils: 0.5.1(eslint@9.24.0) - eslint-plugin-n@17.13.1(eslint@9.17.0): + eslint-plugin-n@17.13.1(eslint@9.24.0): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) - enhanced-resolve: 5.18.0 - eslint: 9.17.0 - eslint-plugin-es-x: 7.8.0(eslint@9.17.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) + enhanced-resolve: 5.18.1 + eslint: 9.24.0 + eslint-plugin-es-x: 7.8.0(eslint@9.24.0) get-tsconfig: 4.10.0 - globals: 15.14.0 + globals: 15.15.0 ignore: 5.3.2 minimatch: 9.0.5 - semver: 7.6.3 + semver: 7.7.1 - eslint-plugin-svelte@2.46.0(eslint@9.17.0)(svelte@5.12.0): + eslint-plugin-svelte@3.5.1(eslint@9.24.0)(svelte@5.25.7): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) '@jridgewell/sourcemap-codec': 1.5.0 - eslint: 9.17.0 - eslint-compat-utils: 0.5.1(eslint@9.17.0) + eslint: 9.24.0 esutils: 2.0.3 known-css-properties: 0.35.0 postcss: 8.5.3 postcss-load-config: 3.1.4(postcss@8.5.3) - postcss-safe-parser: 6.0.0(postcss@8.5.3) - postcss-selector-parser: 6.1.2 - semver: 7.6.3 - svelte-eslint-parser: 0.43.0(svelte@5.12.0) + postcss-safe-parser: 7.0.1(postcss@8.5.3) + semver: 7.7.1 + svelte-eslint-parser: 1.1.2(svelte@5.25.7) optionalDependencies: - svelte: 5.12.0 + svelte: 5.25.7 transitivePeerDependencies: - ts-node - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-scope@8.2.0: + eslint-scope@8.3.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 @@ -3380,26 +3377,27 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.17.0: + eslint@9.24.0: dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0) + '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.19.1 - '@eslint/core': 0.9.1 - '@eslint/eslintrc': 3.2.0 - '@eslint/js': 9.17.0 - '@eslint/plugin-kit': 0.2.4 + '@eslint/config-array': 0.20.0 + '@eslint/config-helpers': 0.2.1 + '@eslint/core': 0.12.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.24.0 + '@eslint/plugin-kit': 0.2.8 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.1 - '@types/estree': 1.0.6 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.7 '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.0 escape-string-regexp: 4.0.0 - eslint-scope: 8.2.0 + eslint-scope: 8.3.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 esquery: 1.6.0 @@ -3419,32 +3417,21 @@ snapshots: transitivePeerDependencies: - supports-color - esm-env@1.2.1: {} + esm-env@1.2.2: {} espree@10.3.0: dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) eslint-visitor-keys: 4.2.0 - espree@9.6.1: - dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) - eslint-visitor-keys: 3.4.3 - esprima@4.0.1: {} esquery@1.6.0: dependencies: estraverse: 5.3.0 - esrap@1.2.3: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - '@types/estree': 1.0.6 - - esrap@1.4.5: + esrap@1.4.6: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -3458,7 +3445,7 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 esutils@2.0.3: {} @@ -3472,7 +3459,7 @@ snapshots: stream-combiner: 0.0.4 through: 2.3.8 - expect-type@1.1.0: {} + expect-type@1.2.1: {} extendable-error@0.1.7: {} @@ -3486,7 +3473,7 @@ snapshots: fast-fifo@1.3.2: {} - fast-glob@3.3.2: + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 @@ -3498,9 +3485,9 @@ snapshots: fast-levenshtein@2.0.6: {} - fastq@1.17.1: + fastq@1.19.1: dependencies: - reusify: 1.0.4 + reusify: 1.1.0 fdir@6.4.3(picomatch@4.0.2): optionalDependencies: @@ -3528,14 +3515,12 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.3.2 + flatted: 3.3.3 keyv: 4.5.4 - flatted@3.3.2: {} - flatted@3.3.3: {} - foreground-child@3.3.0: + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 signal-exit: 4.1.0 @@ -3566,7 +3551,7 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - git-hooks-list@3.1.0: {} + git-hooks-list@3.2.0: {} gitignore-parser@0.0.2: {} @@ -3580,7 +3565,7 @@ snapshots: glob@10.4.5: dependencies: - foreground-child: 3.3.0 + foreground-child: 3.3.1 jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 @@ -3589,7 +3574,7 @@ snapshots: globals@14.0.0: {} - globals@15.14.0: {} + globals@15.15.0: {} globalyzer@0.1.0: {} @@ -3597,7 +3582,7 @@ snapshots: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.2 + fast-glob: 3.3.3 ignore: 5.3.2 merge2: 1.4.1 slash: 3.0.0 @@ -3614,10 +3599,10 @@ snapshots: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 entities: 4.5.0 - human-id@1.0.2: {} + human-id@4.1.1: {} iconv-lite@0.4.24: dependencies: @@ -3625,7 +3610,7 @@ snapshots: ignore@5.3.2: {} - import-fresh@3.3.0: + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 @@ -3648,7 +3633,7 @@ snapshots: is-reference@3.0.3: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 is-subdir@1.2.0: dependencies: @@ -3716,8 +3701,6 @@ snapshots: lodash.startcase@4.4.0: {} - loupe@3.1.2: {} - loupe@3.1.3: {} lru-cache@10.4.3: {} @@ -3749,7 +3732,7 @@ snapshots: mri@1.2.0: {} - mrmime@2.0.0: {} + mrmime@2.0.1: {} ms@2.1.3: {} @@ -3759,7 +3742,7 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nanoid@3.3.8: {} + nanoid@3.3.11: {} natural-compare@1.4.0: {} @@ -3825,7 +3808,9 @@ snapshots: package-json-from-dist@1.0.1: {} - package-manager-detector@0.2.7: {} + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.10 parent-module@1.0.1: dependencies: @@ -3844,8 +3829,6 @@ snapshots: path-type@4.0.0: {} - pathe@2.0.2: {} - pathe@2.0.3: {} pathval@2.0.0: {} @@ -3856,7 +3839,7 @@ snapshots: periscopic@3.1.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 estree-walker: 3.0.3 is-reference: 3.0.3 @@ -3868,13 +3851,13 @@ snapshots: pify@4.0.1: {} - pirates@4.0.6: {} + pirates@4.0.7: {} - playwright-core@1.49.1: {} + playwright-core@1.51.1: {} - playwright@1.49.1: + playwright@1.51.1: dependencies: - playwright-core: 1.49.1 + playwright-core: 1.51.1 optionalDependencies: fsevents: 2.3.2 @@ -3885,7 +3868,7 @@ snapshots: optionalDependencies: postcss: 8.5.3 - postcss-safe-parser@6.0.0(postcss@8.5.3): + postcss-safe-parser@7.0.1(postcss@8.5.3): dependencies: postcss: 8.5.3 @@ -3893,40 +3876,34 @@ snapshots: dependencies: postcss: 8.5.3 - postcss-selector-parser@6.1.2: + postcss-selector-parser@7.1.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss@8.5.1: - dependencies: - nanoid: 3.3.8 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.3: dependencies: - nanoid: 3.3.8 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 prelude-ls@1.2.1: {} - prettier-plugin-packagejson@2.5.6(prettier@3.4.2): + prettier-plugin-packagejson@2.5.10(prettier@3.5.3): dependencies: - sort-package-json: 2.12.0 + sort-package-json: 2.15.1 synckit: 0.9.2 optionalDependencies: - prettier: 3.4.2 + prettier: 3.5.3 - prettier-plugin-svelte@3.3.2(prettier@3.4.2)(svelte@5.12.0): + prettier-plugin-svelte@3.3.3(prettier@3.5.3)(svelte@5.25.7): dependencies: - prettier: 3.4.2 - svelte: 5.12.0 + prettier: 3.5.3 + svelte: 5.25.7 prettier@2.8.8: {} - prettier@3.4.2: {} + prettier@3.5.3: {} ps-tree@1.2.0: dependencies: @@ -3939,9 +3916,9 @@ snapshots: punycode@2.3.1: {} - queue-microtask@1.2.3: {} + quansync@0.2.10: {} - queue-tick@1.0.1: {} + queue-microtask@1.2.3: {} read-yaml-file@1.1.0: dependencies: @@ -3958,13 +3935,13 @@ snapshots: resolve-pkg-maps@1.0.0: {} - reusify@1.0.4: {} + reusify@1.1.0: {} - rolldown@1.0.0-beta.1(@babel/runtime@7.26.0): + rolldown@1.0.0-beta.1(@babel/runtime@7.27.0): dependencies: - zod: 3.24.1 + zod: 3.24.2 optionalDependencies: - '@babel/runtime': 7.26.0 + '@babel/runtime': 7.27.0 '@rolldown/binding-darwin-arm64': 1.0.0-beta.1 '@rolldown/binding-darwin-x64': 1.0.0-beta.1 '@rolldown/binding-freebsd-x64': 1.0.0-beta.1 @@ -3978,29 +3955,30 @@ snapshots: '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.1 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.1 - rollup@4.34.5: + rollup@4.39.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.34.5 - '@rollup/rollup-android-arm64': 4.34.5 - '@rollup/rollup-darwin-arm64': 4.34.5 - '@rollup/rollup-darwin-x64': 4.34.5 - '@rollup/rollup-freebsd-arm64': 4.34.5 - '@rollup/rollup-freebsd-x64': 4.34.5 - '@rollup/rollup-linux-arm-gnueabihf': 4.34.5 - '@rollup/rollup-linux-arm-musleabihf': 4.34.5 - '@rollup/rollup-linux-arm64-gnu': 4.34.5 - '@rollup/rollup-linux-arm64-musl': 4.34.5 - '@rollup/rollup-linux-loongarch64-gnu': 4.34.5 - '@rollup/rollup-linux-powerpc64le-gnu': 4.34.5 - '@rollup/rollup-linux-riscv64-gnu': 4.34.5 - '@rollup/rollup-linux-s390x-gnu': 4.34.5 - '@rollup/rollup-linux-x64-gnu': 4.34.5 - '@rollup/rollup-linux-x64-musl': 4.34.5 - '@rollup/rollup-win32-arm64-msvc': 4.34.5 - '@rollup/rollup-win32-ia32-msvc': 4.34.5 - '@rollup/rollup-win32-x64-msvc': 4.34.5 + '@rollup/rollup-android-arm-eabi': 4.39.0 + '@rollup/rollup-android-arm64': 4.39.0 + '@rollup/rollup-darwin-arm64': 4.39.0 + '@rollup/rollup-darwin-x64': 4.39.0 + '@rollup/rollup-freebsd-arm64': 4.39.0 + '@rollup/rollup-freebsd-x64': 4.39.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.39.0 + '@rollup/rollup-linux-arm-musleabihf': 4.39.0 + '@rollup/rollup-linux-arm64-gnu': 4.39.0 + '@rollup/rollup-linux-arm64-musl': 4.39.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.39.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-musl': 4.39.0 + '@rollup/rollup-linux-s390x-gnu': 4.39.0 + '@rollup/rollup-linux-x64-gnu': 4.39.0 + '@rollup/rollup-linux-x64-musl': 4.39.0 + '@rollup/rollup-win32-arm64-msvc': 4.39.0 + '@rollup/rollup-win32-ia32-msvc': 4.39.0 + '@rollup/rollup-win32-x64-msvc': 4.39.0 fsevents: 2.3.3 run-parallel@1.2.0: @@ -4009,7 +3987,7 @@ snapshots: safer-buffer@2.1.2: {} - semver@7.6.3: {} + semver@7.7.1: {} shebang-command@2.0.0: dependencies: @@ -4026,7 +4004,7 @@ snapshots: sirv@3.0.1: dependencies: '@polka/url': 1.0.0-next.28 - mrmime: 2.0.0 + mrmime: 2.0.1 totalist: 3.0.1 sisteransi@1.0.5: {} @@ -4035,16 +4013,16 @@ snapshots: sort-object-keys@1.1.3: {} - sort-package-json@2.12.0: + sort-package-json@2.15.1: dependencies: detect-indent: 7.0.1 detect-newline: 4.0.1 get-stdin: 9.0.0 - git-hooks-list: 3.1.0 + git-hooks-list: 3.2.0 is-plain-obj: 4.1.0 - semver: 7.6.3 + semver: 7.7.1 sort-object-keys: 1.1.3 - tinyglobby: 0.2.10 + tinyglobby: 0.2.12 source-map-js@1.2.1: {} @@ -4061,19 +4039,18 @@ snapshots: stackback@0.0.2: {} - std-env@3.8.0: {} + std-env@3.9.0: {} stream-combiner@0.0.4: dependencies: duplexer: 0.1.2 - streamx@2.21.1: + streamx@2.22.0: dependencies: fast-fifo: 1.3.2 - queue-tick: 1.0.1 text-decoder: 1.2.3 optionalDependencies: - bare-events: 2.5.0 + bare-events: 2.5.4 string-width@4.2.3: dependencies: @@ -4106,30 +4083,31 @@ snapshots: glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 - pirates: 4.0.6 + pirates: 4.0.7 ts-interface-checker: 0.1.13 supports-color@7.2.0: dependencies: has-flag: 4.0.0 - svelte-eslint-parser@0.43.0(svelte@5.12.0): + svelte-eslint-parser@1.1.2(svelte@5.25.7): dependencies: - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 postcss: 8.5.3 postcss-scss: 4.0.9(postcss@8.5.3) + postcss-selector-parser: 7.1.0 optionalDependencies: - svelte: 5.12.0 + svelte: 5.25.7 svelte@4.2.19: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 - '@types/estree': 1.0.6 - acorn: 8.14.0 + '@types/estree': 1.0.7 + acorn: 8.14.1 aria-query: 5.3.2 axobject-query: 4.1.0 code-red: 1.0.4 @@ -4140,17 +4118,18 @@ snapshots: magic-string: 0.30.17 periscopic: 3.1.0 - svelte@5.12.0: + svelte@5.25.7: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 - '@types/estree': 1.0.6 - acorn: 8.14.0 - acorn-typescript: 1.4.13(acorn@8.14.0) + '@sveltejs/acorn-typescript': 1.0.5(acorn@8.14.1) + '@types/estree': 1.0.7 + acorn: 8.14.1 aria-query: 5.3.2 axobject-query: 4.1.0 - esm-env: 1.2.1 - esrap: 1.2.3 + clsx: 2.1.1 + esm-env: 1.2.2 + esrap: 1.4.6 is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.17 @@ -4158,24 +4137,26 @@ snapshots: synckit@0.9.2: dependencies: - '@pkgr/core': 0.1.1 + '@pkgr/core': 0.1.2 tslib: 2.8.1 tapable@2.2.1: {} - tar-fs@3.0.6: + tar-fs@3.0.8: dependencies: pump: 3.0.2 tar-stream: 3.1.7 optionalDependencies: - bare-fs: 2.3.5 - bare-path: 2.1.3 + bare-fs: 4.1.2 + bare-path: 3.0.0 + transitivePeerDependencies: + - bare-buffer tar-stream@3.1.7: dependencies: b4a: 1.6.7 fast-fifo: 1.3.2 - streamx: 2.21.1 + streamx: 2.22.0 term-size@2.2.1: {} @@ -4202,11 +4183,6 @@ snapshots: tinyexec@0.3.2: {} - tinyglobby@0.2.10: - dependencies: - fdir: 6.4.3(picomatch@4.0.2) - picomatch: 4.0.2 - tinyglobby@0.2.12: dependencies: fdir: 6.4.3(picomatch@4.0.2) @@ -4230,9 +4206,9 @@ snapshots: tr46@0.0.3: {} - ts-api-utils@1.4.3(typescript@5.7.2): + ts-api-utils@2.1.0(typescript@5.8.3): dependencies: - typescript: 5.7.2 + typescript: 5.8.3 ts-interface-checker@0.1.13: {} @@ -4247,40 +4223,40 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.18.0(eslint@9.17.0)(typescript@5.7.2): + typescript-eslint@8.29.0(eslint@9.24.0)(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.18.0(@typescript-eslint/parser@8.18.0(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/parser': 8.18.0(eslint@9.17.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.18.0(eslint@9.17.0)(typescript@5.7.2) - eslint: 9.17.0 - typescript: 5.7.2 + '@typescript-eslint/eslint-plugin': 8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/parser': 8.29.0(eslint@9.24.0)(typescript@5.8.3) + '@typescript-eslint/utils': 8.29.0(eslint@9.24.0)(typescript@5.8.3) + eslint: 9.24.0 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - typescript@5.7.2: {} + typescript@5.8.3: {} undici-types@5.26.5: {} - undici-types@6.20.0: {} + undici-types@6.21.0: {} universalify@0.1.2: {} - unplugin-isolated-decl@0.8.3(rollup@4.34.5)(typescript@5.7.2): + unplugin-isolated-decl@0.8.3(rollup@4.39.0)(typescript@5.8.3): dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.34.5) + '@rollup/pluginutils': 5.1.4(rollup@4.39.0) debug: 4.4.0 magic-string: 0.30.17 oxc-parser: 0.37.0 - unplugin: 1.16.0 + unplugin: 1.16.1 optionalDependencies: - typescript: 5.7.2 + typescript: 5.8.3 transitivePeerDependencies: - rollup - supports-color - unplugin@1.16.0: + unplugin@1.16.1: dependencies: - acorn: 8.14.0 + acorn: 8.14.1 webpack-virtual-modules: 0.6.2 uri-js@4.4.1: @@ -4289,17 +4265,17 @@ snapshots: util-deprecate@1.0.2: {} - valibot@0.41.0(typescript@5.7.2): + valibot@0.41.0(typescript@5.8.3): optionalDependencies: - typescript: 5.7.2 + typescript: 5.8.3 - vite-node@3.0.5(@types/node@22.10.2): + vite-node@3.0.9(@types/node@22.14.0): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 - pathe: 2.0.2 - vite: 6.1.0(@types/node@22.10.2) + pathe: 2.0.3 + vite: 6.2.5(@types/node@22.14.0) transitivePeerDependencies: - '@types/node' - jiti @@ -4314,40 +4290,40 @@ snapshots: - tsx - yaml - vite@6.1.0(@types/node@22.10.2): + vite@6.2.5(@types/node@22.14.0): dependencies: - esbuild: 0.24.2 - postcss: 8.5.1 - rollup: 4.34.5 + esbuild: 0.25.2 + postcss: 8.5.3 + rollup: 4.39.0 optionalDependencies: - '@types/node': 22.10.2 + '@types/node': 22.14.0 fsevents: 2.3.3 - vitest@3.0.5(@types/node@22.10.2)(@vitest/ui@3.1.1): + vitest@3.0.9(@types/node@22.14.0)(@vitest/ui@3.0.9): dependencies: - '@vitest/expect': 3.0.5 - '@vitest/mocker': 3.0.5(vite@6.1.0(@types/node@22.10.2)) - '@vitest/pretty-format': 3.0.5 - '@vitest/runner': 3.0.5 - '@vitest/snapshot': 3.0.5 - '@vitest/spy': 3.0.5 - '@vitest/utils': 3.0.5 - chai: 5.1.2 + '@vitest/expect': 3.0.9 + '@vitest/mocker': 3.0.9(vite@6.2.5(@types/node@22.14.0)) + '@vitest/pretty-format': 3.1.1 + '@vitest/runner': 3.0.9 + '@vitest/snapshot': 3.0.9 + '@vitest/spy': 3.0.9 + '@vitest/utils': 3.0.9 + chai: 5.2.0 debug: 4.4.0 - expect-type: 1.1.0 + expect-type: 1.2.1 magic-string: 0.30.17 - pathe: 2.0.2 - std-env: 3.8.0 + pathe: 2.0.3 + std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.1.0(@types/node@22.10.2) - vite-node: 3.0.5(@types/node@22.10.2) + vite: 6.2.5(@types/node@22.14.0) + vite-node: 3.0.9(@types/node@22.14.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.10.2 - '@vitest/ui': 3.1.1(vitest@3.0.5) + '@types/node': 22.14.0 + '@vitest/ui': 3.0.9(vitest@3.0.9) transitivePeerDependencies: - jiti - less @@ -4402,4 +4378,4 @@ snapshots: zimmerframe@1.1.2: {} - zod@3.24.1: {} + zod@3.24.2: {} From c36a6a43e403e9e6a76ddd0440c3a92546fa1d10 Mon Sep 17 00:00:00 2001 From: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 13 Apr 2025 10:26:40 -0400 Subject: [PATCH 09/38] feat: adds `--install ` flag to `create` and `add` (#531) * adds `--install ` flag * changeset * fix check * docs * forgot the arg * fix docs --------- Co-authored-by: Manuel Serret --- .changeset/happy-moles-glow.md | 5 +++++ community-addon-template/tests/setup/suite.ts | 4 ++-- documentation/docs/20-commands/10-sv-create.md | 12 +++++++++++- documentation/docs/20-commands/20-sv-add.md | 3 ++- packages/addons/_tests/_setup/suite.ts | 4 ++-- packages/cli/commands/add/index.ts | 14 +++++++++----- packages/cli/commands/create.ts | 18 +++++++++++------- packages/cli/lib/testing.ts | 2 +- packages/cli/utils/package-manager.ts | 12 +++++++++--- 9 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 .changeset/happy-moles-glow.md diff --git a/.changeset/happy-moles-glow.md b/.changeset/happy-moles-glow.md new file mode 100644 index 00000000..26143f52 --- /dev/null +++ b/.changeset/happy-moles-glow.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +feat: adds `--install ` flag to `create` and `add` diff --git a/community-addon-template/tests/setup/suite.ts b/community-addon-template/tests/setup/suite.ts index 9b2dc0a5..3b7c0413 100644 --- a/community-addon-template/tests/setup/suite.ts +++ b/community-addon-template/tests/setup/suite.ts @@ -4,7 +4,7 @@ import { execSync } from 'node:child_process'; import * as vitest from 'vitest'; import { installAddon, type AddonMap, type OptionMap } from 'sv'; import { - addPnpmBuildDependendencies, + addPnpmBuildDependencies, createProject, startPreview, type CreateProject, @@ -78,7 +78,7 @@ export function setupTest(addons: Addons) { options, packageManager: 'pnpm' }); - addPnpmBuildDependendencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); + addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); return cwd; }; diff --git a/documentation/docs/20-commands/10-sv-create.md b/documentation/docs/20-commands/10-sv-create.md index 7425d3f3..ae5d29be 100644 --- a/documentation/docs/20-commands/10-sv-create.md +++ b/documentation/docs/20-commands/10-sv-create.md @@ -35,9 +35,19 @@ Prevent typechecking from being added. Not recommended! Run the command without the interactive add-ons prompt +### `--install ` + +Installs dependencies with a specified package manager: + +- `npm` +- `pnpm` +- `yarn` +- `bun` +- `deno` + ### `--no-install` -Skip dependency installation +Prevents installing dependencies. -- `--no-install` — skip dependency installation +- `--install` — installs dependencies with a specified package manager +- `--no-install` — prevents installing dependencies ## Official add-ons diff --git a/packages/addons/_tests/_setup/suite.ts b/packages/addons/_tests/_setup/suite.ts index 5c6e5a1b..65615a8c 100644 --- a/packages/addons/_tests/_setup/suite.ts +++ b/packages/addons/_tests/_setup/suite.ts @@ -6,7 +6,7 @@ import { installAddon, type AddonMap, type OptionMap } from 'sv'; import { createProject, startPreview, - addPnpmBuildDependendencies, + addPnpmBuildDependencies, type CreateProject, type ProjectVariant } from 'sv/testing'; @@ -75,7 +75,7 @@ export function setupTest(addons: Addons) { options, packageManager: 'pnpm' }); - addPnpmBuildDependendencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); + addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]); return cwd; }; diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index bd11bf73..3359ef7e 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -19,8 +19,10 @@ import { createWorkspace } from './workspace.ts'; import { formatFiles, getHighlighter } from './utils.ts'; import { Directive, downloadPackage, getPackageJSON } from './fetch-packages.ts'; import { - addPnpmBuildDependendencies, + addPnpmBuildDependencies, + AGENT_NAMES, installDependencies, + installOption, packageManagerPrompt } from '../../utils/package-manager.ts'; import { getGlobalPreconditions } from './preconditions.ts'; @@ -41,7 +43,7 @@ const AddonsSchema = v.array(v.string()); const AddonOptionFlagsSchema = v.object(addonOptionFlags); const OptionsSchema = v.strictObject({ cwd: v.string(), - install: v.boolean(), + install: v.union([v.boolean(), v.picklist(AGENT_NAMES)]), preconditions: v.boolean(), community: v.optional(v.union([AddonsSchema, v.boolean()])), ...AddonOptionFlagsSchema.entries @@ -56,8 +58,9 @@ export const add = new Command('add') .description('applies specified add-ons into a project') .argument('[add-on...]', 'add-ons to install') .option('-C, --cwd ', 'path to working directory', defaultCwd) - .option('--no-install', 'skip installing dependencies') .option('--no-preconditions', 'skip validating preconditions') + .option('--no-install', 'skip installing dependencies') + .addOption(installOption) //.option('--community [add-on...]', 'community addons to install') .configureHelp(common.helpConfig) .action((addonArgs, opts) => { @@ -449,12 +452,13 @@ export async function runAddCommand( // prompt for package manager and install dependencies let packageManager: PackageManager | undefined; if (options.install) { - packageManager = await packageManagerPrompt(options.cwd); + packageManager = + options.install === true ? await packageManagerPrompt(options.cwd) : options.install; if (packageManager) { workspace.packageManager = packageManager; - addPnpmBuildDependendencies(workspace.cwd, packageManager, [ + addPnpmBuildDependencies(workspace.cwd, packageManager, [ 'esbuild', ...addonPnpmBuildDependencies ]); diff --git a/packages/cli/commands/create.ts b/packages/cli/commands/create.ts index a42b1893..72a27f66 100644 --- a/packages/cli/commands/create.ts +++ b/packages/cli/commands/create.ts @@ -15,9 +15,11 @@ import * as common from '../utils/common.ts'; import { runAddCommand } from './add/index.ts'; import { detect, resolveCommand, type AgentName } from 'package-manager-detector'; import { - addPnpmBuildDependendencies, + addPnpmBuildDependencies, + AGENT_NAMES, getUserAgent, installDependencies, + installOption, packageManagerPrompt } from '../utils/package-manager.ts'; @@ -40,7 +42,7 @@ const OptionsSchema = v.strictObject({ v.transform((lang) => langMap[String(lang)]) ), addOns: v.boolean(), - install: v.boolean(), + install: v.union([v.boolean(), v.picklist(AGENT_NAMES)]), template: v.optional(v.picklist(templateChoices)) }); type Options = v.InferOutput; @@ -54,6 +56,7 @@ export const create = new Command('create') .option('--no-types') .option('--no-add-ons', 'skips interactive add-on installer') .option('--no-install', 'skip installing dependencies') + .addOption(installOption) .configureHelp(common.helpConfig) .action((projectPath, opts) => { const cwd = v.parse(ProjectPathSchema, projectPath); @@ -164,9 +167,10 @@ async function createProject(cwd: ProjectPath, options: Options) { let packageManager: AgentName | undefined | null; let addOnNextSteps: string | undefined; - const installDeps = async () => { - packageManager = await packageManagerPrompt(projectPath); - addPnpmBuildDependendencies(projectPath, packageManager, ['esbuild']); + + const installDeps = async (install: true | AgentName) => { + packageManager = install === true ? await packageManagerPrompt(projectPath) : install; + addPnpmBuildDependencies(projectPath, packageManager, ['esbuild']); if (packageManager) await installDependencies(packageManager, projectPath); }; @@ -180,13 +184,13 @@ async function createProject(cwd: ProjectPath, options: Options) { addOnNextSteps = nextSteps; } else if (options.install) { // `--no-add-ons` was set, so we'll prompt to install deps manually - await installDeps(); + await installDeps(options.install); } // no add-ons were selected (which means the install prompt was skipped in `runAddCommand`), // so we'll prompt to install if (packageManager === null && options.install) { - await installDeps(); + await installDeps(options.install); } return { directory: projectPath, addOnNextSteps, packageManager }; diff --git a/packages/cli/lib/testing.ts b/packages/cli/lib/testing.ts index 101214bf..98f5cdae 100644 --- a/packages/cli/lib/testing.ts +++ b/packages/cli/lib/testing.ts @@ -6,7 +6,7 @@ import { exec } from 'tinyexec'; import { create } from '@sveltejs/create'; import pstree, { type PS } from 'ps-tree'; -export { addPnpmBuildDependendencies } from '../utils/package-manager.ts'; +export { addPnpmBuildDependencies } from '../utils/package-manager.ts'; export type ProjectVariant = 'kit-js' | 'kit-ts' | 'vite-js' | 'vite-ts'; const TEMPLATES_DIR = '.templates'; diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index f747dedd..90829424 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -3,6 +3,7 @@ import path from 'node:path'; import process from 'node:process'; import * as find from 'empathic/find'; import { exec } from 'tinyexec'; +import { Option } from 'commander'; import * as p from '@sveltejs/clack-prompts'; import { AGENTS, @@ -13,10 +14,15 @@ import { } from 'package-manager-detector'; import { parseJson } from '@sveltejs/cli-core/parsers'; -const agents = AGENTS.filter((agent): agent is AgentName => !agent.includes('@')); -const agentOptions: PackageManagerOptions = agents.map((pm) => ({ value: pm, label: pm })); +export const AGENT_NAMES = AGENTS.filter((agent): agent is AgentName => !agent.includes('@')); +const agentOptions: PackageManagerOptions = AGENT_NAMES.map((pm) => ({ value: pm, label: pm })); agentOptions.unshift({ label: 'None', value: undefined }); +export const installOption = new Option( + '--install ', + 'installs dependencies with a specified package manager' +).choices(AGENT_NAMES); + type PackageManagerOptions = Array<{ value: AgentName | undefined; label: AgentName | 'None' }>; export async function packageManagerPrompt(cwd: string): Promise { const detected = await detect({ cwd }); @@ -76,7 +82,7 @@ export function getUserAgent(): AgentName | undefined { return AGENTS.includes(name) ? name : undefined; } -export function addPnpmBuildDependendencies( +export function addPnpmBuildDependencies( cwd: string, packageManager: AgentName | null | undefined, allowedPackages: string[] From da9b4f4cae72b16c1a214a50548386f250d5fc44 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 13 Apr 2025 16:33:55 +0200 Subject: [PATCH 10/38] Version Packages (#532) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/happy-moles-glow.md | 5 ----- .changeset/pretty-emus-breathe.md | 5 ----- .changeset/twelve-lizards-warn.md | 5 ----- packages/cli/CHANGELOG.md | 12 ++++++++++++ packages/cli/package.json | 2 +- 5 files changed, 13 insertions(+), 16 deletions(-) delete mode 100644 .changeset/happy-moles-glow.md delete mode 100644 .changeset/pretty-emus-breathe.md delete mode 100644 .changeset/twelve-lizards-warn.md diff --git a/.changeset/happy-moles-glow.md b/.changeset/happy-moles-glow.md deleted file mode 100644 index 26143f52..00000000 --- a/.changeset/happy-moles-glow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -feat: adds `--install ` flag to `create` and `add` diff --git a/.changeset/pretty-emus-breathe.md b/.changeset/pretty-emus-breathe.md deleted file mode 100644 index 09b5a016..00000000 --- a/.changeset/pretty-emus-breathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -fix: warn on an unparsable `.prettierrc` config file diff --git a/.changeset/twelve-lizards-warn.md b/.changeset/twelve-lizards-warn.md deleted file mode 100644 index b1814725..00000000 --- a/.changeset/twelve-lizards-warn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -chore: remove redundant `ignores` property in `eslint` config diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index f0d523f9..bf288c19 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,17 @@ # sv +## 0.8.1 +### Patch Changes + + +- feat: adds `--install ` flag to `create` and `add` ([#531](https://github.com/sveltejs/cli/pull/531)) + + +- fix: warn on an unparsable `.prettierrc` config file ([#527](https://github.com/sveltejs/cli/pull/527)) + + +- chore: remove redundant `ignores` property in `eslint` config ([#533](https://github.com/sveltejs/cli/pull/533)) + ## 0.8.0 ### Minor Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index c576dd9d..05bb5c0e 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "sv", - "version": "0.8.0", + "version": "0.8.1", "type": "module", "description": "A CLI for creating and updating SvelteKit projects", "license": "MIT", From 8da5fc90238608b067fdb5ecc69818e812e32415 Mon Sep 17 00:00:00 2001 From: netbrum <130702882+netbrum@users.noreply.github.com> Date: Fri, 18 Apr 2025 15:17:09 +0000 Subject: [PATCH 11/38] fix: mysql2 closed state (drizzle addon) (#537) * fix: mysql closed state * add changeset * update changeset summary Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> * fix changeset --------- Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> Co-authored-by: Manuel Serret --- .changeset/poor-ducks-own.md | 5 +++++ packages/addons/drizzle/index.ts | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .changeset/poor-ducks-own.md diff --git a/.changeset/poor-ducks-own.md b/.changeset/poor-ducks-own.md new file mode 100644 index 00000000..b87d4e50 --- /dev/null +++ b/.changeset/poor-ducks-own.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix: use connection pool when using mysql2 with `drizzle` diff --git a/packages/addons/drizzle/index.ts b/packages/addons/drizzle/index.ts index 01fd7234..ed1810b2 100644 --- a/packages/addons/drizzle/index.ts +++ b/packages/addons/drizzle/index.ts @@ -309,9 +309,7 @@ export default defineAddon({ imports.addDefault(ast, 'mysql2/promise', 'mysql'); imports.addNamed(ast, 'drizzle-orm/mysql2', { drizzle: 'drizzle' }); - clientExpression = common.expressionFromString( - 'await mysql.createConnection(env.DATABASE_URL)' - ); + clientExpression = common.expressionFromString('mysql.createPool(env.DATABASE_URL)'); } // PostgreSQL if (options.postgresql === 'neon') { From cd3ecfe4a5d14aa24f57b3f0c198bd1f1c333ae9 Mon Sep 17 00:00:00 2001 From: Hyunbin Seo <47051820+hyunbinseo@users.noreply.github.com> Date: Tue, 22 Apr 2025 22:20:43 +0900 Subject: [PATCH 12/38] chore: use the latest adapter-auto (#542) Co-authored-by: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> --- .changeset/late-rockets-argue.md | 5 +++++ packages/create/templates/demo/package.template.json | 2 +- packages/create/templates/library/package.template.json | 2 +- packages/create/templates/minimal/package.template.json | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/late-rockets-argue.md diff --git a/.changeset/late-rockets-argue.md b/.changeset/late-rockets-argue.md new file mode 100644 index 00000000..f5dbf11c --- /dev/null +++ b/.changeset/late-rockets-argue.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +chore: update `adapter-auto` diff --git a/packages/create/templates/demo/package.template.json b/packages/create/templates/demo/package.template.json index dd651203..b2b4ab19 100644 --- a/packages/create/templates/demo/package.template.json +++ b/packages/create/templates/demo/package.template.json @@ -12,7 +12,7 @@ "devDependencies": { "@fontsource/fira-mono": "^5.0.0", "@neoconfetti/svelte": "^2.0.0", - "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.25.0", diff --git a/packages/create/templates/library/package.template.json b/packages/create/templates/library/package.template.json index b0c824e3..a13cd36d 100644 --- a/packages/create/templates/library/package.template.json +++ b/packages/create/templates/library/package.template.json @@ -23,7 +23,7 @@ "svelte": "^5.0.0" }, "devDependencies": { - "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/kit": "^2.16.0", "@sveltejs/package": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", diff --git a/packages/create/templates/minimal/package.template.json b/packages/create/templates/minimal/package.template.json index 8d15b23d..5a4c5bc5 100644 --- a/packages/create/templates/minimal/package.template.json +++ b/packages/create/templates/minimal/package.template.json @@ -10,7 +10,7 @@ "prepare": "svelte-kit sync || echo ''" }, "devDependencies": { - "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", From 985dec662df97030c59116ae70a687631f816614 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Wed, 23 Apr 2025 23:15:01 +0800 Subject: [PATCH 13/38] fix: rename `cloudflare-pages` to `cloudflare` (#545) Co-authored-by: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> --- .changeset/honest-eels-fly.md | 5 +++++ packages/addons/sveltekit-adapter/index.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/honest-eels-fly.md diff --git a/.changeset/honest-eels-fly.md b/.changeset/honest-eels-fly.md new file mode 100644 index 00000000..3d6ce1c9 --- /dev/null +++ b/.changeset/honest-eels-fly.md @@ -0,0 +1,5 @@ +--- +"sv": patch +--- + +fix: rename Cloudflare adapter option from `cloudflare-pages` to `cloudflare` diff --git a/packages/addons/sveltekit-adapter/index.ts b/packages/addons/sveltekit-adapter/index.ts index 5f7de2d5..7bbdef6d 100644 --- a/packages/addons/sveltekit-adapter/index.ts +++ b/packages/addons/sveltekit-adapter/index.ts @@ -13,7 +13,7 @@ const adapters: Adapter[] = [ { id: 'node', package: '@sveltejs/adapter-node', version: '^5.2.12' }, { id: 'static', package: '@sveltejs/adapter-static', version: '^3.0.8' }, { id: 'vercel', package: '@sveltejs/adapter-vercel', version: '^5.6.3' }, - { id: 'cloudflare-pages', package: '@sveltejs/adapter-cloudflare', version: '^7.0.0' }, + { id: 'cloudflare', package: '@sveltejs/adapter-cloudflare', version: '^7.0.0' }, { id: 'netlify', package: '@sveltejs/adapter-netlify', version: '^5.0.0' } ]; From b6f94e27c4a64dadc2e9f9b6791e0dc38898cbeb Mon Sep 17 00:00:00 2001 From: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 24 Apr 2025 11:28:24 -0400 Subject: [PATCH 14/38] fix: add `@types/node` to `drizzle` and `storybook` add-ons (#541) * install node types for drizzle and storybook * changeset * exclude minor and patch --- .changeset/odd-bikes-like.md | 5 +++++ packages/addons/common.ts | 20 ++++++++++++++++++++ packages/addons/drizzle/index.ts | 2 ++ packages/addons/storybook/index.ts | 2 ++ 4 files changed, 29 insertions(+) create mode 100644 .changeset/odd-bikes-like.md diff --git a/.changeset/odd-bikes-like.md b/.changeset/odd-bikes-like.md new file mode 100644 index 00000000..72aed1bb --- /dev/null +++ b/.changeset/odd-bikes-like.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix: add `@types/node` as a dev dependency to the `drizzle` and `storybook` add-ons diff --git a/packages/addons/common.ts b/packages/addons/common.ts index 5795e133..90fb9eba 100644 --- a/packages/addons/common.ts +++ b/packages/addons/common.ts @@ -1,5 +1,6 @@ import { imports, exports, common } from '@sveltejs/cli-core/js'; import { parseScript, parseSvelte } from '@sveltejs/cli-core/parsers'; +import process from 'node:process'; export function addEslintConfigPrettier(content: string): string { const { ast, generateCode } = parseScript(content); @@ -75,3 +76,22 @@ export function addToDemoPage(content: string, path: string): string { const src = template.source + `${newLine}${path}`; return generateCode({ template: src }); } + +/** + * Returns the corresponding `@types/node` version for the version of Node.js running in the current process. + * + * If the installed version of Node.js is from a `Current` release, then the major is decremented to + * the nearest `LTS` release version. + */ +export function getNodeTypesVersion(): string { + const nodeVersion = process.versions.node; + const [major] = nodeVersion.split('.'); + + const isLTS = Number(major) % 2 === 0; + if (isLTS) { + return `^${major}`; + } + + const previousLTSMajor = Number(major) - 1; + return `^${previousLTSMajor}`; +} diff --git a/packages/addons/drizzle/index.ts b/packages/addons/drizzle/index.ts index ed1810b2..859e418a 100644 --- a/packages/addons/drizzle/index.ts +++ b/packages/addons/drizzle/index.ts @@ -1,6 +1,7 @@ import { common, exports, functions, imports, object, variables } from '@sveltejs/cli-core/js'; import { defineAddon, defineAddonOptions, dedent, type OptionValues } from '@sveltejs/cli-core'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; +import { getNodeTypesVersion } from '../common.ts'; const PORTS = { mysql: '3306', @@ -76,6 +77,7 @@ export default defineAddon({ sv.dependency('drizzle-orm', '^0.40.0'); sv.devDependency('drizzle-kit', '^0.30.2'); + sv.devDependency('@types/node', getNodeTypesVersion()); // MySQL if (options.mysql === 'mysql2') sv.dependency('mysql2', '^3.12.0'); diff --git a/packages/addons/storybook/index.ts b/packages/addons/storybook/index.ts index 82edb41f..d75ffcf0 100644 --- a/packages/addons/storybook/index.ts +++ b/packages/addons/storybook/index.ts @@ -1,4 +1,5 @@ import { defineAddon } from '@sveltejs/cli-core'; +import { getNodeTypesVersion } from '../common.ts'; export default defineAddon({ id: 'storybook', @@ -7,5 +8,6 @@ export default defineAddon({ options: {}, run: async ({ sv }) => { await sv.execute(['storybook@latest', 'init', '--skip-install', '--no-dev'], 'inherit'); + sv.devDependency(`@types/node`, getNodeTypesVersion()); } }); From 01524b65ff391fd0f41db9e04fc585e1d78d050d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 18:49:52 +0200 Subject: [PATCH 15/38] Version Packages (#538) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/honest-eels-fly.md | 5 ----- .changeset/late-rockets-argue.md | 5 ----- .changeset/odd-bikes-like.md | 5 ----- .changeset/poor-ducks-own.md | 5 ----- packages/cli/CHANGELOG.md | 15 +++++++++++++++ packages/cli/package.json | 2 +- 6 files changed, 16 insertions(+), 21 deletions(-) delete mode 100644 .changeset/honest-eels-fly.md delete mode 100644 .changeset/late-rockets-argue.md delete mode 100644 .changeset/odd-bikes-like.md delete mode 100644 .changeset/poor-ducks-own.md diff --git a/.changeset/honest-eels-fly.md b/.changeset/honest-eels-fly.md deleted file mode 100644 index 3d6ce1c9..00000000 --- a/.changeset/honest-eels-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"sv": patch ---- - -fix: rename Cloudflare adapter option from `cloudflare-pages` to `cloudflare` diff --git a/.changeset/late-rockets-argue.md b/.changeset/late-rockets-argue.md deleted file mode 100644 index f5dbf11c..00000000 --- a/.changeset/late-rockets-argue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -chore: update `adapter-auto` diff --git a/.changeset/odd-bikes-like.md b/.changeset/odd-bikes-like.md deleted file mode 100644 index 72aed1bb..00000000 --- a/.changeset/odd-bikes-like.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -fix: add `@types/node` as a dev dependency to the `drizzle` and `storybook` add-ons diff --git a/.changeset/poor-ducks-own.md b/.changeset/poor-ducks-own.md deleted file mode 100644 index b87d4e50..00000000 --- a/.changeset/poor-ducks-own.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -fix: use connection pool when using mysql2 with `drizzle` diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index bf288c19..c400b691 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,20 @@ # sv +## 0.8.2 +### Patch Changes + + +- fix: rename Cloudflare adapter option from `cloudflare-pages` to `cloudflare` ([#545](https://github.com/sveltejs/cli/pull/545)) + + +- chore: update `adapter-auto` ([#542](https://github.com/sveltejs/cli/pull/542)) + + +- fix: add `@types/node` as a dev dependency to the `drizzle` and `storybook` add-ons ([#541](https://github.com/sveltejs/cli/pull/541)) + + +- fix: use connection pool when using mysql2 with `drizzle` ([#537](https://github.com/sveltejs/cli/pull/537)) + ## 0.8.1 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 05bb5c0e..76807c8f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "sv", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "A CLI for creating and updating SvelteKit projects", "license": "MIT", From 8cdab6cc4333190399acd6bd3a6036aa71e749c1 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 25 Apr 2025 20:59:43 +0200 Subject: [PATCH 16/38] fix: Always add Storybook last (#547) * fix: always handle storybook as the last addon * Add changesets * Update packages/cli/lib/install.ts * fix lint * fix changeset --------- Co-authored-by: Manuel <30698007+manuel3108@users.noreply.github.com> Co-authored-by: Manuel Serret --- .changeset/slimy-rivers-think.md | 5 +++++ packages/cli/lib/install.ts | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 .changeset/slimy-rivers-think.md diff --git a/.changeset/slimy-rivers-think.md b/.changeset/slimy-rivers-think.md new file mode 100644 index 00000000..06625d9b --- /dev/null +++ b/.changeset/slimy-rivers-think.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix: always add `storybook` after all other add-ons diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 03932917..9c0bfb7e 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -182,9 +182,12 @@ async function runAddon({ addon, multiple, workspace }: RunAddon) { // orders addons by putting addons that don't require any other addon in the front. // This is a drastic simplification, as this could still cause some inconvenient cituations, -// but works for now in contrary to the previouse implementation +// but works for now in contrary to the previous implementation function orderAddons(addons: Array>, setupResults: Record) { - return addons.sort( - (a, b) => setupResults[a.id]?.dependsOn?.length - setupResults[b.id]?.dependsOn?.length - ); + return addons.sort((a, b) => { + // Adding storybook last means it will correctly detect and integrate with other addons like vitest and eslint + if (a.id === 'storybook') return 1; + if (b.id === 'storybook') return -1; + return setupResults[a.id]?.dependsOn?.length - setupResults[b.id]?.dependsOn?.length; + }); } From 9dde45f07d822ebf19265f9d4608e2c37d722731 Mon Sep 17 00:00:00 2001 From: Hyunbin Seo <47051820+hyunbinseo@users.noreply.github.com> Date: Sat, 26 Apr 2025 04:01:54 +0900 Subject: [PATCH 17/38] security: upgrade vite to avoid CVE-2025-32395 (#548) --- .changeset/yummy-things-learn.md | 5 +++++ packages/create/templates/demo/package.template.json | 2 +- packages/create/templates/library/package.template.json | 2 +- packages/create/templates/minimal/package.template.json | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .changeset/yummy-things-learn.md diff --git a/.changeset/yummy-things-learn.md b/.changeset/yummy-things-learn.md new file mode 100644 index 00000000..a30290d0 --- /dev/null +++ b/.changeset/yummy-things-learn.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +security: upgrade vite to avoid CVE-2025-32395 diff --git a/packages/create/templates/demo/package.template.json b/packages/create/templates/demo/package.template.json index b2b4ab19..07362f14 100644 --- a/packages/create/templates/demo/package.template.json +++ b/packages/create/templates/demo/package.template.json @@ -16,6 +16,6 @@ "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.25.0", - "vite": "^6.2.5" + "vite": "^6.2.6" } } diff --git a/packages/create/templates/library/package.template.json b/packages/create/templates/library/package.template.json index a13cd36d..d4c30ccd 100644 --- a/packages/create/templates/library/package.template.json +++ b/packages/create/templates/library/package.template.json @@ -30,7 +30,7 @@ "publint": "^0.3.2", "svelte": "^5.0.0", "typescript": "^5.3.2", - "vite": "^6.2.5" + "vite": "^6.2.6" }, "keywords": ["svelte"] } diff --git a/packages/create/templates/minimal/package.template.json b/packages/create/templates/minimal/package.template.json index 5a4c5bc5..96f3f0d2 100644 --- a/packages/create/templates/minimal/package.template.json +++ b/packages/create/templates/minimal/package.template.json @@ -14,6 +14,6 @@ "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", - "vite": "^6.2.5" + "vite": "^6.2.6" } } From 3d2ac28cfe6914d8b707cc6aca09229a10536f14 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Fri, 25 Apr 2025 12:05:26 -0700 Subject: [PATCH 18/38] docs: add-on docs (#546) * docs: add `add-on` docs * Apply suggestions from code review Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> * docs: add-on docs * Update documentation/docs/30-add-ons/05-drizzle.md Co-authored-by: Manuel <30698007+manuel3108@users.noreply.github.com> * Update documentation/docs/30-add-ons/50-tailwind.md Co-authored-by: Manuel <30698007+manuel3108@users.noreply.github.com> * Update documentation/docs/30-add-ons/25-paraglide.md Co-authored-by: Manuel <30698007+manuel3108@users.noreply.github.com> --------- Co-authored-by: Manuel Serret Co-authored-by: Manuel <30698007+manuel3108@users.noreply.github.com> --- documentation/docs/30-add-ons/05-drizzle.md | 57 +++++++++++++++++++ documentation/docs/30-add-ons/10-eslint.md | 18 ++++++ documentation/docs/30-add-ons/15-lucia.md | 26 +++++++++ documentation/docs/30-add-ons/20-mdsvex.md | 15 +++++ documentation/docs/30-add-ons/25-paraglide.md | 38 +++++++++++++ .../docs/30-add-ons/30-playwright.md | 18 ++++++ documentation/docs/30-add-ons/35-prettier.md | 17 ++++++ documentation/docs/30-add-ons/40-storybook.md | 16 ++++++ .../docs/30-add-ons/45-sveltekit-adapter.md | 32 +++++++++++ documentation/docs/30-add-ons/50-tailwind.md | 31 ++++++++++ documentation/docs/30-add-ons/55-vitest.md | 17 ++++++ documentation/docs/30-add-ons/index.md | 3 + 12 files changed, 288 insertions(+) create mode 100644 documentation/docs/30-add-ons/05-drizzle.md create mode 100644 documentation/docs/30-add-ons/10-eslint.md create mode 100644 documentation/docs/30-add-ons/15-lucia.md create mode 100644 documentation/docs/30-add-ons/20-mdsvex.md create mode 100644 documentation/docs/30-add-ons/25-paraglide.md create mode 100644 documentation/docs/30-add-ons/30-playwright.md create mode 100644 documentation/docs/30-add-ons/35-prettier.md create mode 100644 documentation/docs/30-add-ons/40-storybook.md create mode 100644 documentation/docs/30-add-ons/45-sveltekit-adapter.md create mode 100644 documentation/docs/30-add-ons/50-tailwind.md create mode 100644 documentation/docs/30-add-ons/55-vitest.md create mode 100644 documentation/docs/30-add-ons/index.md diff --git a/documentation/docs/30-add-ons/05-drizzle.md b/documentation/docs/30-add-ons/05-drizzle.md new file mode 100644 index 00000000..7cf06ca9 --- /dev/null +++ b/documentation/docs/30-add-ons/05-drizzle.md @@ -0,0 +1,57 @@ +--- +title: drizzle +--- + +[Drizzle ORM](https://orm.drizzle.team/) is a TypeScript ORM offering both relational and SQL-like query APIs, and which is serverless-ready by design. + +## Usage + +```bash +npx sv add drizzle +``` + +## What you get + +- a setup that keeps your database access in SvelteKit's server files +- an `.env` file to store your credentials +- compatibility with the Lucia auth add-on +- an optional Docker configuration to help with running a local database + +## Options + +### database + +Which database variant to use: + +- `postgresql` — the most popular open source database +- `mysql` — another popular open source database +- `sqlite` — file-based database not requiring a database server + +```bash +npx sv add --drizzle=postgresql +``` + +### client + +The SQL client to use, depends on `database`: + +- For `postgresql`: `postgres.js`, `neon`, +- For `mysql`: `mysql2`, `planetscale` +- For `sqlite`: `better-sqlite3`, `libsql`, `turso` + +```bash +npx sv add --drizzle=postgresql,postgres.js +``` + +Drizzle is compatible with well over a dozen database drivers. We just offer a few of the most common ones here for simplicity, but if you'd like to use another one you can choose one as a placeholder and swap it out for another after setup by choosing from [Drizzle's full list of compatible drivers](https://orm.drizzle.team/docs/connect-overview#next-steps). + +### docker + +Whether to add Docker Compose configuration. Only available for [`database`](#Options-database) `postgresql` or `mysql` + +- `docker` - generates `docker-compose.yml` +- `no-docker` - does not generate docker config + +```bash +npx sv add --drizzle=postgresql,postgres.js,docker +``` diff --git a/documentation/docs/30-add-ons/10-eslint.md b/documentation/docs/30-add-ons/10-eslint.md new file mode 100644 index 00000000..318bb504 --- /dev/null +++ b/documentation/docs/30-add-ons/10-eslint.md @@ -0,0 +1,18 @@ +--- +title: eslint +--- + +[ESLint](https://eslint.org/) finds and fixes problems in your code. + +## Usage + +```bash +npx sv add eslint +``` + +## What you get + +- the relevant packages installed including `eslint-plugin-svelte` +- an `eslint.config.js` file +- updated `.vscode/settings.json` +- configured to work with TypeScript and `prettier` if you're using those packages diff --git a/documentation/docs/30-add-ons/15-lucia.md b/documentation/docs/30-add-ons/15-lucia.md new file mode 100644 index 00000000..2eb21f9e --- /dev/null +++ b/documentation/docs/30-add-ons/15-lucia.md @@ -0,0 +1,26 @@ +--- +title: lucia +--- + +An auth setup following [the Lucia auth guide](https://lucia-auth.com/). + +## Usage + +```bash +npx sv add lucia +``` + +## What you get + +- an auth setup for SvelteKit and Drizzle following the best practices from the Lucia auth guide +- optional demo registration and login pages + +## Options + +### demo + +Whether to include demo registration and login pages. + +```bash +npx sv add --lucia=demo +``` diff --git a/documentation/docs/30-add-ons/20-mdsvex.md b/documentation/docs/30-add-ons/20-mdsvex.md new file mode 100644 index 00000000..00b95c45 --- /dev/null +++ b/documentation/docs/30-add-ons/20-mdsvex.md @@ -0,0 +1,15 @@ +--- +title: mdsvex +--- + +[mdsvex](https://mdsvex.pngwn.io) is a markdown preprocessor for Svelte components - basically MDX for Svelte. It allows you to use Svelte components in your markdown, or markdown in your Svelte components. + +## Usage + +```bash +npx sv add mdsvex +``` + +## What you get + +- mdsvex installed and configured in your `svelte.config.js` diff --git a/documentation/docs/30-add-ons/25-paraglide.md b/documentation/docs/30-add-ons/25-paraglide.md new file mode 100644 index 00000000..be006f27 --- /dev/null +++ b/documentation/docs/30-add-ons/25-paraglide.md @@ -0,0 +1,38 @@ +--- +title: paraglide +--- + +[Paraglide from Inlang](https://inlang.com/m/gerre34r/library-inlang-paraglideJs) is a compiler-based i18n library that emits tree-shakable message functions with small bundle sizes, no async waterfalls, full type-safety, and more. + +## Usage + +```bash +npx sv add paraglide +``` + +## What you get + +- Inlang project settings +- paraglide Vite plugin +- SvelteKit `reroute` and `handle` hooks +- `text-direction` and `lang` attributes in `app.html` +- updated `.gitignore` +- an optional demo page showing how to use paraglide + +## Options + +### availableLanguageTags + +The languages you'd like to support specified as IETF BCP 47 language tags. + +```bash +npx sv add --paraglide=en,es +``` + +### demo + +Whether to generate an optional demo page showing how to use paraglide. + +```bash +npx sv add --paraglide=demo +``` diff --git a/documentation/docs/30-add-ons/30-playwright.md b/documentation/docs/30-add-ons/30-playwright.md new file mode 100644 index 00000000..0c16d86f --- /dev/null +++ b/documentation/docs/30-add-ons/30-playwright.md @@ -0,0 +1,18 @@ +--- +title: playwright +--- + +[Playwright](https://playwright.dev) browser testing. + +## Usage + +```bash +npx sv add playwright +``` + +## What you get + +- scripts added in your `package.json` +- a Playwright config file +- an updated `.gitignore` +- a demo test diff --git a/documentation/docs/30-add-ons/35-prettier.md b/documentation/docs/30-add-ons/35-prettier.md new file mode 100644 index 00000000..68014ae4 --- /dev/null +++ b/documentation/docs/30-add-ons/35-prettier.md @@ -0,0 +1,17 @@ +--- +title: prettier +--- + +[Prettier](https://prettier.io) is an opinionated code formatter. + +## Usage + +```bash +npx sv add prettier +``` + +## What you get + +- scripts in your `package.json` +- `.prettierignore` and `.prettierrc` files +- updates to your eslint config if you're using that package diff --git a/documentation/docs/30-add-ons/40-storybook.md b/documentation/docs/30-add-ons/40-storybook.md new file mode 100644 index 00000000..9ba57adb --- /dev/null +++ b/documentation/docs/30-add-ons/40-storybook.md @@ -0,0 +1,16 @@ +--- +title: storybook +--- + +[Storybook](https://storybook.js.org/) is a frontend component workshop. + +## Usage + +```bash +npx sv add storybook +``` + +## What you get + +- `npx storybook init` run for you from the same convenient `sv` CLI used for all other add-ons +- [Storybook for SvelteKit](https://storybook.js.org/docs/get-started/frameworks/sveltekit) or [Storybook for Svelte & Vite](https://storybook.js.org/docs/get-started/frameworks/svelte-vite) with default config provided, easy mocking of many SvelteKit modules, automatic link handling, and more. diff --git a/documentation/docs/30-add-ons/45-sveltekit-adapter.md b/documentation/docs/30-add-ons/45-sveltekit-adapter.md new file mode 100644 index 00000000..d9012752 --- /dev/null +++ b/documentation/docs/30-add-ons/45-sveltekit-adapter.md @@ -0,0 +1,32 @@ +--- +title: sveltekit-adapter +--- + +[SvelteKit adapters](/docs/kit/adapters) allow you to deploy your site to numerous platforms. This add-on allows you to configure officially provided SvelteKit adapters, but a number of [community-provided adapters](https://www.sveltesociety.dev/packages?category=sveltekit-adapters) are also available. + +## Usage + +```bash +npx sv add sveltekit-adapter +``` + +## What you get + +- the chosen SvelteKit adapter installed and configured in your `svelte.config.js` + +## Options + +### adapter + +Which SvelteKit adapter to use: + +- `auto` — [`@sveltejs/adapter-auto`](/docs/kit/adapter-auto) automatically chooses the proper adapter to use, but is less configurable +- `node` — [`@sveltejs/adapter-node`](/docs/kit/adapter-node) generates a standalone Node server +- `static` — [`@sveltejs/adapter-static`](/docs/kit/adapter-static) allows you to use SvelteKit as a static site generator (SSG) +- `vercel` — [`@sveltejs/adapter-vercel`](/docs/kit/adapter-vercel) allows you to deploy to Vercel +- `cloudflare` — [`@sveltejs/adapter-cloudflare`](/docs/kit/adapter-cloudflare) allows you to deploy to Cloudflare +- `netlify` — [`@sveltejs/adapter-netlify`](/docs/kit/adapter-netlify) allows you to deploy to Netlify + +```bash +npx sv add --sveltekit-adapter=node +``` diff --git a/documentation/docs/30-add-ons/50-tailwind.md b/documentation/docs/30-add-ons/50-tailwind.md new file mode 100644 index 00000000..1b454a22 --- /dev/null +++ b/documentation/docs/30-add-ons/50-tailwind.md @@ -0,0 +1,31 @@ +--- +title: tailwindcss +--- + +[Tailwind CSS](https://tailwindcss.com/) allows you to rapidly build modern websites without ever leaving your HTML. + +## Usage + +```bash +npx sv add tailwindcss +``` + +## What you get + +- Tailwind setup following the [Tailwind for SvelteKit guide](https://tailwindcss.com/docs/installation/framework-guides/sveltekit) +- Tailwind Vite plugin +- updated `app.css` and `+layout.svelte` (for SvelteKit) or `App.svelte` (for non-SvelteKit Vite apps) +- integration with `prettier` if using that package + +## Options + +### plugins + +Which plugin to use: + +- `typography` — [`@tailwindcss/typography`](https://github.com/tailwindlabs/tailwindcss-typography) +- `forms` — [`@tailwindcss/forms`](https://github.com/tailwindlabs/tailwindcss-forms) + +```bash +npx sv add --tailwindcss=typography +``` diff --git a/documentation/docs/30-add-ons/55-vitest.md b/documentation/docs/30-add-ons/55-vitest.md new file mode 100644 index 00000000..e2ee77c6 --- /dev/null +++ b/documentation/docs/30-add-ons/55-vitest.md @@ -0,0 +1,17 @@ +--- +title: vitest +--- + +[Vitest](https://vitest.dev/) is a Vite-native testing framework. + +## Usage + +```bash +npx sv add vitest +``` + +## What you get + +- the relevant packages installed and scripts added to your `package.json` +- client/server-aware testing setup for Svelte in your Vite config file +- demo tests diff --git a/documentation/docs/30-add-ons/index.md b/documentation/docs/30-add-ons/index.md new file mode 100644 index 00000000..61874f22 --- /dev/null +++ b/documentation/docs/30-add-ons/index.md @@ -0,0 +1,3 @@ +--- +title: Add-ons +--- From c7fd9aa6137257481783cd2d47e0a30d8be72e99 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 25 Apr 2025 21:06:05 +0200 Subject: [PATCH 19/38] Version Packages (#551) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/slimy-rivers-think.md | 5 ----- .changeset/yummy-things-learn.md | 5 ----- packages/cli/CHANGELOG.md | 9 +++++++++ packages/cli/package.json | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) delete mode 100644 .changeset/slimy-rivers-think.md delete mode 100644 .changeset/yummy-things-learn.md diff --git a/.changeset/slimy-rivers-think.md b/.changeset/slimy-rivers-think.md deleted file mode 100644 index 06625d9b..00000000 --- a/.changeset/slimy-rivers-think.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -fix: always add `storybook` after all other add-ons diff --git a/.changeset/yummy-things-learn.md b/.changeset/yummy-things-learn.md deleted file mode 100644 index a30290d0..00000000 --- a/.changeset/yummy-things-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -security: upgrade vite to avoid CVE-2025-32395 diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index c400b691..7492d294 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,14 @@ # sv +## 0.8.3 +### Patch Changes + + +- fix: always add `storybook` after all other add-ons ([#547](https://github.com/sveltejs/cli/pull/547)) + + +- security: upgrade vite to avoid CVE-2025-32395 ([#548](https://github.com/sveltejs/cli/pull/548)) + ## 0.8.2 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 76807c8f..189e847d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "sv", - "version": "0.8.2", + "version": "0.8.3", "type": "module", "description": "A CLI for creating and updating SvelteKit projects", "license": "MIT", From e9485a2c8e6df490291490d91059a2540ab9653a Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Sat, 3 May 2025 09:51:14 -0700 Subject: [PATCH 20/38] docs: link to individual pages from docs list (#552) --- documentation/docs/20-commands/20-sv-add.md | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/documentation/docs/20-commands/20-sv-add.md b/documentation/docs/20-commands/20-sv-add.md index 232d1a96..d627a937 100644 --- a/documentation/docs/20-commands/20-sv-add.md +++ b/documentation/docs/20-commands/20-sv-add.md @@ -25,16 +25,16 @@ You can select multiple space-separated add-ons from [the list below](#Official- ## Official add-ons - - -- `drizzle` -- `eslint` -- `sveltekit-adapter` -- `lucia` -- `mdsvex` -- `paraglide` -- `playwright` -- `prettier` -- `storybook` -- `tailwindcss` -- `vitest` + + +- [`drizzle`](drizzle) +- [`eslint`](eslint) +- [`lucia`](lucia) +- [`mdsvex`](mdsvex) +- [`paraglide`](paraglide) +- [`playwright`](playwright) +- [`prettier`](prettier) +- [`storybook`](storybook) +- [`sveltekit-adapter`](sveltekit-adapter) +- [`tailwindcss`](tailwind) +- [`vitest`](vitest) From e0e8b0aea08084f02979e7ee5f9e9a70b63b3ba0 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Wed, 7 May 2025 07:24:33 -0700 Subject: [PATCH 21/38] chore: leverage expressionFromString more in drizzle adder (#556) * chore: leverage expressionFromString more in drizzle adder * fix drizzle output * do not format js test results with prettier * do not format js test results with prettier * add failing quote test * fix drizzle output * fix drizzle output * use stripAst to remove raw property * remove undefined * extra comma * fix test * error on preexisting files --------- Co-authored-by: Manuel Serret Co-authored-by: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> --- packages/addons/_tests/drizzle/test.ts | 2 +- packages/addons/drizzle/index.ts | 69 ++++++++++--------- .../common/expression-from-string/output.ts | 1 + .../js/common/expression-from-string/run.ts | 13 ++++ packages/core/tests/js/index.ts | 11 +-- packages/core/tooling/js/common.ts | 1 + 6 files changed, 54 insertions(+), 43 deletions(-) create mode 100644 packages/core/tests/js/common/expression-from-string/output.ts create mode 100644 packages/core/tests/js/common/expression-from-string/run.ts diff --git a/packages/addons/_tests/drizzle/test.ts b/packages/addons/_tests/drizzle/test.ts index 2a6d7230..c1e49076 100644 --- a/packages/addons/_tests/drizzle/test.ts +++ b/packages/addons/_tests/drizzle/test.ts @@ -43,7 +43,7 @@ test.concurrent.for(testCases)( const ts = variant === 'kit-ts'; const drizzleConfig = path.resolve(cwd, `drizzle.config.${ts ? 'ts' : 'js'}`); - const content = fs.readFileSync(drizzleConfig, 'utf8').replace('strict: true,', ''); + const content = fs.readFileSync(drizzleConfig, 'utf8').replace(/strict: true[,\s]/, ''); fs.writeFileSync(drizzleConfig, content, 'utf8'); const routes = path.resolve(cwd, 'src', 'routes'); diff --git a/packages/addons/drizzle/index.ts b/packages/addons/drizzle/index.ts index 859e418a..681ffc7c 100644 --- a/packages/addons/drizzle/index.ts +++ b/packages/addons/drizzle/index.ts @@ -1,3 +1,5 @@ +import fs from 'node:fs'; +import path from 'node:path'; import { common, exports, functions, imports, object, variables } from '@sveltejs/cli-core/js'; import { defineAddon, defineAddonOptions, dedent, type OptionValues } from '@sveltejs/cli-core'; import { parseJson, parseScript } from '@sveltejs/cli-core/parsers'; @@ -69,8 +71,21 @@ export default defineAddon({ shortDescription: 'database orm', homepage: 'https://orm.drizzle.team', options, - setup: ({ kit, unsupported }) => { + setup: ({ kit, unsupported, cwd, typescript }) => { + const ext = typescript ? 'ts' : 'js'; if (!kit) unsupported('Requires SvelteKit'); + + const baseDBPath = path.resolve(kit!.libDirectory, 'server', 'db'); + const paths = { + 'drizzle config': path.relative(cwd, path.resolve(cwd, `drizzle.config.${ext}`)), + 'database schema': path.relative(cwd, path.resolve(baseDBPath, `schema.${ext}`)), + database: path.relative(cwd, path.resolve(baseDBPath, `index.${ext}`)) + }; + for (const [fileType, filePath] of Object.entries(paths)) { + if (fs.existsSync(filePath)) { + unsupported(`Preexisting ${fileType} file at '${filePath}'`); + } + } }, run: ({ sv, typescript, options, kit }) => { const ext = typescript ? 'ts' : 'js'; @@ -178,41 +193,27 @@ export default defineAddon({ imports.addNamed(ast, 'drizzle-kit', { defineConfig: 'defineConfig' }); - const envCheckStatement = common.statementFromString( - "if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');" + common.addStatement( + ast, + common.statementFromString( + "if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');" + ) ); - common.addStatement(ast, envCheckStatement); - - const fallback = common.expressionFromString('defineConfig({})'); - const { value: exportDefault } = exports.defaultExport(ast, fallback); - if (exportDefault.type !== 'CallExpression') return content; - - const objExpression = exportDefault.arguments?.[0]; - if (!objExpression || objExpression.type !== 'ObjectExpression') return content; - - const authToken = - options.sqlite === 'turso' - ? common.expressionFromString('process.env.DATABASE_AUTH_TOKEN') - : undefined; - - object.properties(objExpression, { - schema: common.createLiteral(`./src/lib/server/db/schema.${typescript ? 'ts' : 'js'}`), - dbCredentials: object.create({ - url: common.expressionFromString('process.env.DATABASE_URL'), - authToken - }), - verbose: { type: 'Literal', value: true }, - strict: { type: 'Literal', value: true } - }); - - const dialect = options.sqlite === 'turso' ? 'turso' : options.database; - object.overrideProperties(objExpression, { - dialect: common.createLiteral(dialect) - }); - // The `driver` property is only required for _some_ sqlite DBs. - // We'll need to remove it if it's anything but sqlite - if (options.database !== 'sqlite') object.removeProperty(objExpression, 'driver'); + exports.defaultExport( + ast, + common.expressionFromString(` + defineConfig({ + schema: "./src/lib/server/db/schema.${typescript ? 'ts' : 'js'}", + dialect: "${options.sqlite === 'turso' ? 'turso' : options.database}", + dbCredentials: { + ${options.sqlite === 'turso' ? 'authToken: process.env.DATABASE_AUTH_TOKEN,' : ''} + url: process.env.DATABASE_URL + }, + verbose: true, + strict: true + })`) + ); return generateCode(); }); diff --git a/packages/core/tests/js/common/expression-from-string/output.ts b/packages/core/tests/js/common/expression-from-string/output.ts new file mode 100644 index 00000000..a5aea556 --- /dev/null +++ b/packages/core/tests/js/common/expression-from-string/output.ts @@ -0,0 +1 @@ +export default defineConfig({ path: 'some/string/as/path.js', valid: true }); diff --git a/packages/core/tests/js/common/expression-from-string/run.ts b/packages/core/tests/js/common/expression-from-string/run.ts new file mode 100644 index 00000000..f831db6c --- /dev/null +++ b/packages/core/tests/js/common/expression-from-string/run.ts @@ -0,0 +1,13 @@ +import { common, exports, type AstTypes } from '@sveltejs/cli-core/js'; + +export function run(ast: AstTypes.Program): void { + exports.defaultExport( + ast, + common.expressionFromString(` + defineConfig({ + path: "some/string/as/path.js", + valid: true + }) + `) + ); +} diff --git a/packages/core/tests/js/index.ts b/packages/core/tests/js/index.ts index bc6a37b1..c7f2021e 100644 --- a/packages/core/tests/js/index.ts +++ b/packages/core/tests/js/index.ts @@ -1,17 +1,12 @@ import fs from 'node:fs'; import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; -import prettier from 'prettier'; import { describe, expect, test } from 'vitest'; import { parseScript, serializeScript } from '../../tooling/index.ts'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); -const prettierConfig = await prettier.resolveConfig(import.meta.url); -if (!prettierConfig) throw new Error('Failed to resolve prettier config'); -prettierConfig.filepath = 'output.ts'; - for (const categoryDirectory of categoryDirectories) { describe(categoryDirectory, () => { const testNames = getDirectoryNames(join(baseDir, categoryDirectory)); @@ -27,9 +22,9 @@ for (const categoryDirectory of categoryDirectories) { const module = await import(`./${categoryDirectory}/${testName}/run.ts`); module.run(ast); - const output = serializeScript(ast, input); - const formattedOutput = await prettier.format(output, prettierConfig); - await expect(formattedOutput).toMatchFileSnapshot(`${testDirectoryPath}/output.ts`); + let output = serializeScript(ast, input); + if (!output.endsWith('\n')) output += '\n'; + await expect(output).toMatchFileSnapshot(`${testDirectoryPath}/output.ts`); }); } }); diff --git a/packages/core/tooling/js/common.ts b/packages/core/tooling/js/common.ts index e7035b40..c6b328ca 100644 --- a/packages/core/tooling/js/common.ts +++ b/packages/core/tooling/js/common.ts @@ -115,6 +115,7 @@ export function addFromString( export function expressionFromString(value: string): AstTypes.Expression { const program = parseScript(dedent(value)); + stripAst(program, ['raw']); const statement = program.body[0]!; if (statement.type !== 'ExpressionStatement') { throw new Error('value passed was not an expression'); From bfc8aa78a6e4e51d12f6ad7ff151176ea2564659 Mon Sep 17 00:00:00 2001 From: Brett <100062845+brettearle@users.noreply.github.com> Date: Sat, 10 May 2025 19:31:41 +0930 Subject: [PATCH 22/38] docs: contributing.md (#549) * init * skeleton and sveltekit reference * workflow and preparing * 1st draft * Update CONTRIBUTING.md Co-authored-by: Manuel <30698007+manuel3108@users.noreply.github.com> * docs: update based on feedback * docs: changelog added * docs: added change set directions for sv and svelte-migrate only * docs: removed cd to packages in specific tests * docs: reworded project test explanation * docs: Integration testing explanation * docs: updated headings for readability and grammar * docs: second round fixes * docs: added debug test starting point * docs: added debug test starting point - edited * docs: added running individual tests * docs: added running individual tests - edited * update: redundant example removed. Removed specified js --------- Co-authored-by: Manuel <30698007+manuel3108@users.noreply.github.com> --- CONTRIBUTING.md | 122 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..c4714b86 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,122 @@ +# SV Contributing Guide + +## Workflow + +We follow the standard fork-based workflow: + +1. **Fork** this repository to your GitHub account. +2. **Clone** your fork locally. +3. **Create a new branch** for your change: + `git checkout -b your-feature-name` +4. **Commit and push** your changes to your branch. +5. **Open a pull request** from your branch to the `main` branch of this repository. + +Please keep your pull requests focused to feature or issue. Focused smaller changes are easier to review and faster to merge. + +## Preparing +This is a monorepo, meaning the repo holds multiple packages. It requires the use of [pnpm](https://pnpm.io/). You can [install pnpm](https://pnpm.io/installation) with: + +```bash +npm i -g pnpm +``` + +For running certain packages and tests locally you will need to install [docker](https://docs.docker.com/get-started/get-docker). +Linux users, you will have to ensure 'sudo' is not required. See [docker post install](https://docs.docker.com/engine/install/linux-postinstall/) + +`pnpm` commands run in the project's root directory will run on all sub-projects. You can checkout the code and install the dependencies with: + +```bash +cd cli +pnpm install +``` + +## Build and run +To build the project and all packages. Run the 'build' script: + +```bash +# from root of project +pnpm build +``` +This outputs into /packages/PACKAGE/dist/. + +Run the 'cli' package: +```bash +pnpm sv +``` + +Run build with watch mode: +```bash +pnpm dev +``` + +## Testing + +For each add-on we have integration tests setup. These install the deps, build the app, run the dev server and then run a few small snippets against the add-on to see if the changes introduced by the add-on are working as expected. + +Run all tests: +```bash +# from root of project +pnpm test +``` + +Run tests with vitest ui: +```bash +# from root of project +pnpm test:ui +``` + +Run package specific tests by specifying a project flag to the package and running the test command. Eg: +```bash +pnpm test --project core # addons / create / migrate / etc. +``` + +To run a individual test. `cd` into the package. Run the local `test` script to that package, with a path arg to the individual peice you want tested. Eg: +```bash +pnpm test [path-to-test] +``` + +To debug a failing test. A good starting point is to `cd` into the failing tests dir. Proceed to `build` it. Then `preview` it. From here you will have increased information to help in the debug process. Eg: +```bash +# Each test is a standalone app +cd .test-output/addons/[addon-test]/[test-id] +pnpm build +pnpm preview +``` + +## Style Guide + +### Coding style + +There are a few guidelines we follow: + +- Ensure `pnpm lint` and `pnpm check` pass. You can run `pnpm format` to format the code +- linting +```bash +# from root of project +pnpm lint +``` +- formatting +```bash +# from root of project +pnpm format +``` +- type checking +```bash +# from root of project +pnpm check +``` + +## svelte-migrate +To run svelte-migrate locally: +```bash +# from root of project +node ./packages/migrate/bin.js +``` + +## Generating changelogs +Only publish a change set if it is in 'sv' or 'svelte-migrate' as all other packages are bundled. +For changes to be reflected in package changelogs: +```bash +# from root of project +pnpm changeset:publish +``` From 30c09ac985b60539411bb192cb1769bc73a46d17 Mon Sep 17 00:00:00 2001 From: Manuel <30698007+manuel3108@users.noreply.github.com> Date: Mon, 12 May 2025 17:43:10 +0200 Subject: [PATCH 23/38] chore: unfork clack (#526) * chore: unfork clack * update * update * improve limit of `taskLog` * task log should print the error on its own * fix lint * update * update package * fix check * fix lint * update packages * add format * use correct import * tweaks + remove unnecessary white coloring --------- Co-authored-by: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> --- packages/clack-core/LICENSE | 23 - packages/clack-core/README.md | 22 - packages/clack-core/index.ts | 10 - packages/clack-core/package.json | 34 - packages/clack-core/src/prompts/confirm.ts | 37 - .../src/prompts/group-multiselect.ts | 82 -- .../clack-core/src/prompts/multi-select.ts | 60 -- packages/clack-core/src/prompts/password.ts | 33 - packages/clack-core/src/prompts/prompt.ts | 273 ------ packages/clack-core/src/prompts/select-key.ts | 27 - packages/clack-core/src/prompts/select.ts | 41 - packages/clack-core/src/prompts/text.ts | 33 - packages/clack-core/src/utils.ts | 60 -- packages/clack-core/tsconfig.json | 8 - packages/clack-prompts/LICENSE | 23 - packages/clack-prompts/README.md | 174 ---- packages/clack-prompts/index.ts | 894 ------------------ packages/clack-prompts/package.json | 34 - packages/clack-prompts/tsconfig.json | 8 - packages/cli/commands/add/index.ts | 6 +- packages/cli/commands/create.ts | 6 +- packages/cli/lib/install.ts | 2 +- packages/cli/package.json | 2 +- packages/cli/utils/common.ts | 2 +- packages/cli/utils/package-manager.ts | 15 +- packages/core/index.ts | 2 +- packages/core/package.json | 2 +- packages/migrate/package.json | 2 +- packages/migrate/utils.js | 4 +- pnpm-lock.yaml | 63 +- rolldown.config.js | 8 +- 31 files changed, 41 insertions(+), 1949 deletions(-) delete mode 100644 packages/clack-core/LICENSE delete mode 100644 packages/clack-core/README.md delete mode 100644 packages/clack-core/index.ts delete mode 100644 packages/clack-core/package.json delete mode 100644 packages/clack-core/src/prompts/confirm.ts delete mode 100644 packages/clack-core/src/prompts/group-multiselect.ts delete mode 100644 packages/clack-core/src/prompts/multi-select.ts delete mode 100644 packages/clack-core/src/prompts/password.ts delete mode 100644 packages/clack-core/src/prompts/prompt.ts delete mode 100644 packages/clack-core/src/prompts/select-key.ts delete mode 100644 packages/clack-core/src/prompts/select.ts delete mode 100644 packages/clack-core/src/prompts/text.ts delete mode 100644 packages/clack-core/src/utils.ts delete mode 100644 packages/clack-core/tsconfig.json delete mode 100644 packages/clack-prompts/LICENSE delete mode 100644 packages/clack-prompts/README.md delete mode 100644 packages/clack-prompts/index.ts delete mode 100644 packages/clack-prompts/package.json delete mode 100644 packages/clack-prompts/tsconfig.json diff --git a/packages/clack-core/LICENSE b/packages/clack-core/LICENSE deleted file mode 100644 index a95d8e47..00000000 --- a/packages/clack-core/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -MIT License - -Copyright (c) Nate Moore - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---- - -`ansi-regex` is adapted from https://github.com/chalk/ansi-regex - -MIT License - -Copyright (c) Sindre Sorhus (https://sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/clack-core/README.md b/packages/clack-core/README.md deleted file mode 100644 index 57ac05f2..00000000 --- a/packages/clack-core/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# `@clack/core` - -Clack contains low-level primitives for implementing your own command-line applications. - -Currently, `TextPrompt`, `SelectPrompt`, and `ConfirmPrompt` are exposed as well as the base `Prompt` class. - -Each `Prompt` accepts a `render` function. - -```js -import { TextPrompt, isCancel } from '@clack/core'; - -const p = new TextPrompt({ - render() { - return `What's your name?\n${this.valueWithCursor}`; - } -}); - -const name = await p.prompt(); -if (isCancel(name)) { - process.exit(0); -} -``` diff --git a/packages/clack-core/index.ts b/packages/clack-core/index.ts deleted file mode 100644 index 37313080..00000000 --- a/packages/clack-core/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export { default as ConfirmPrompt } from './src/prompts/confirm.ts'; -export { default as GroupMultiSelectPrompt } from './src/prompts/group-multiselect.ts'; -export { default as MultiSelectPrompt } from './src/prompts/multi-select.ts'; -export { default as PasswordPrompt } from './src/prompts/password.ts'; -export { default as Prompt, isCancel } from './src/prompts/prompt.ts'; -export type { State } from './src/prompts/prompt.ts'; -export { default as SelectPrompt } from './src/prompts/select.ts'; -export { default as SelectKeyPrompt } from './src/prompts/select-key.ts'; -export { default as TextPrompt } from './src/prompts/text.ts'; -export { block } from './src/utils.ts'; diff --git a/packages/clack-core/package.json b/packages/clack-core/package.json deleted file mode 100644 index 4727de98..00000000 --- a/packages/clack-core/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "@sveltejs/clack-core", - "private": true, - "version": "0.4.2", - "type": "module", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/sveltejs/cli/tree/main/packages/clack-prompts" - }, - "bugs": "https://github.com/sveltejs/cli/issues", - "scripts": { - "check": "tsc", - "format": "pnpm lint --write", - "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore" - }, - "files": [ - "dist" - ], - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "./package.json": "./package.json" - }, - "devDependencies": { - "picocolors": "^1.1.1", - "sisteransi": "^1.0.5", - "wrap-ansi": "^8.1.0" - } -} diff --git a/packages/clack-core/src/prompts/confirm.ts b/packages/clack-core/src/prompts/confirm.ts deleted file mode 100644 index 50e2a8a9..00000000 --- a/packages/clack-core/src/prompts/confirm.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { cursor } from 'sisteransi'; -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface ConfirmOptions extends PromptOptions { - active: string; - inactive: string; - initialValue?: boolean; -} -export default class ConfirmPrompt extends Prompt { - get cursor(): 0 | 1 { - return this.value ? 0 : 1; - } - - private get _value() { - return this.cursor === 0; - } - - constructor(opts: ConfirmOptions) { - super(opts, false); - this.value = opts.initialValue ? true : false; - - this.on('value', () => { - this.value = this._value; - }); - - this.on('confirm', (confirm) => { - this.output.write(cursor.move(0, -1)); - this.value = confirm; - this.state = 'submit'; - this.close(); - }); - - this.on('cursor', () => { - this.value = !this.value; - }); - } -} diff --git a/packages/clack-core/src/prompts/group-multiselect.ts b/packages/clack-core/src/prompts/group-multiselect.ts deleted file mode 100644 index e0601f44..00000000 --- a/packages/clack-core/src/prompts/group-multiselect.ts +++ /dev/null @@ -1,82 +0,0 @@ -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface GroupMultiSelectOptions - extends PromptOptions> { - options: Record; - initialValues?: Array; - required?: boolean; - cursorAt?: T['value']; - selectableGroups?: boolean; -} -export default class GroupMultiSelectPrompt extends Prompt { - options: Array; - cursor: number = 0; - #selectableGroups: boolean; - - getGroupItems(group: string): T[] { - return this.options.filter((o) => o.group === group); - } - - isGroupSelected(group: string): boolean { - const items = this.getGroupItems(group); - return this.#selectableGroups && items.every((i) => this.value.includes(i.value)); - } - - private toggleValue() { - const item = this.options[this.cursor]!; - if (item.group === true) { - const group = item.value; - const groupedItems = this.getGroupItems(group); - if (this.isGroupSelected(group)) { - this.value = this.value.filter( - (v: string) => groupedItems.findIndex((i) => i.value === v) === -1 - ); - } else { - this.value = [...this.value, ...groupedItems.map((i) => i.value)]; - } - this.value = Array.from(new Set(this.value)); - } else { - const selected = this.value.includes(item.value); - this.value = selected - ? this.value.filter((v: T['value']) => v !== item.value) - : [...this.value, item.value]; - } - } - - constructor(opts: GroupMultiSelectOptions) { - super(opts, false); - const { options } = opts; - this.#selectableGroups = opts.selectableGroups ?? true; - this.options = Object.entries(options).flatMap(([key, option]) => [ - { value: key, group: true, label: key }, - ...option.map((opt) => ({ ...opt, group: key })) - ]) as any; - this.value = [...(opts.initialValues ?? [])]; - this.cursor = Math.max( - this.options.findIndex(({ value }) => value === opts.cursorAt), - this.#selectableGroups ? 0 : 1 - ); - - this.on('cursor', (key) => { - switch (key) { - case 'left': - case 'up': - this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; - if (!this.#selectableGroups && this.options[this.cursor]!.group === true) { - this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; - } - break; - case 'down': - case 'right': - this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; - if (!this.#selectableGroups && this.options[this.cursor]!.group === true) { - this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; - } - break; - case 'space': - this.toggleValue(); - break; - } - }); - } -} diff --git a/packages/clack-core/src/prompts/multi-select.ts b/packages/clack-core/src/prompts/multi-select.ts deleted file mode 100644 index d708d50e..00000000 --- a/packages/clack-core/src/prompts/multi-select.ts +++ /dev/null @@ -1,60 +0,0 @@ -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface MultiSelectOptions extends PromptOptions> { - options: T[]; - initialValues?: Array; - required?: boolean; - cursorAt?: T['value']; -} -export default class MultiSelectPrompt extends Prompt { - options: T[]; - cursor: number = 0; - - private get _value() { - return this.options[this.cursor]!.value; - } - - private toggleAll() { - const allSelected = this.value.length === this.options.length; - this.value = allSelected ? [] : this.options.map((v) => v.value); - } - - private toggleValue() { - const selected = this.value.includes(this._value); - this.value = selected - ? this.value.filter((value: T['value']) => value !== this._value) - : [...this.value, this._value]; - } - - constructor(opts: MultiSelectOptions) { - super(opts, false); - - this.options = opts.options; - this.value = [...(opts.initialValues ?? [])]; - this.cursor = Math.max( - this.options.findIndex(({ value }) => value === opts.cursorAt), - 0 - ); - this.on('key', (char) => { - if (char === 'a') { - this.toggleAll(); - } - }); - - this.on('cursor', (key) => { - switch (key) { - case 'left': - case 'up': - this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; - break; - case 'down': - case 'right': - this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; - break; - case 'space': - this.toggleValue(); - break; - } - }); - } -} diff --git a/packages/clack-core/src/prompts/password.ts b/packages/clack-core/src/prompts/password.ts deleted file mode 100644 index fa2c55ce..00000000 --- a/packages/clack-core/src/prompts/password.ts +++ /dev/null @@ -1,33 +0,0 @@ -import color from 'picocolors'; -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface PasswordOptions extends PromptOptions { - mask?: string; -} -export default class PasswordPrompt extends Prompt { - valueWithCursor = ''; - private _mask = '•'; - get cursor(): number { - return this._cursor; - } - get masked(): string { - return this.value.replaceAll(/./g, this._mask); - } - constructor({ mask, ...opts }: PasswordOptions) { - super(opts); - this._mask = mask ?? '•'; - - this.on('finalize', () => { - this.valueWithCursor = this.masked; - }); - this.on('value', () => { - if (this.cursor >= this.value.length) { - this.valueWithCursor = `${this.masked}${color.inverse(color.hidden('_'))}`; - } else { - const s1 = this.masked.slice(0, this.cursor); - const s2 = this.masked.slice(this.cursor); - this.valueWithCursor = `${s1}${color.inverse(s2[0])}${s2.slice(1)}`; - } - }); - } -} diff --git a/packages/clack-core/src/prompts/prompt.ts b/packages/clack-core/src/prompts/prompt.ts deleted file mode 100644 index 40a2a057..00000000 --- a/packages/clack-core/src/prompts/prompt.ts +++ /dev/null @@ -1,273 +0,0 @@ -import readline, { type Key, type ReadLine } from 'node:readline'; -import process, { stdin, stdout } from 'node:process'; -import { WriteStream } from 'node:tty'; -import type { Readable, Writable } from 'node:stream'; -import { cursor, erase } from 'sisteransi'; -import wrap from 'wrap-ansi'; - -function diffLines(a: string, b: string) { - if (a === b) return; - - const aLines = a.split('\n'); - const bLines = b.split('\n'); - const diff: number[] = []; - - for (let i = 0; i < Math.max(aLines.length, bLines.length); i++) { - if (aLines[i] !== bLines[i]) diff.push(i); - } - - return diff; -} - -const cancel = Symbol('clack:cancel'); -export function isCancel(value: unknown): value is symbol { - return value === cancel; -} - -function setRawMode(input: Readable, value: boolean) { - if ((input as typeof stdin).isTTY) (input as typeof stdin).setRawMode(value); -} - -const aliases = new Map([ - ['k', 'up'], - ['j', 'down'], - ['h', 'left'], - ['l', 'right'] -]); -const keys = new Set(['up', 'down', 'left', 'right', 'space', 'enter']); - -export interface PromptOptions { - render(this: Omit): string | void; - placeholder?: string; - initialValue?: any; - validate?: ((value: any) => string | void) | undefined; - input?: Readable; - output?: Writable; - debug?: boolean; -} - -export type State = 'initial' | 'active' | 'cancel' | 'submit' | 'error'; - -export default class Prompt { - protected input: Readable; - protected output: Writable; - private rl!: ReadLine; - private opts: Omit, 'render' | 'input' | 'output'>; - private _track: boolean = false; - private _render: (context: Omit) => string | void; - protected _cursor: number = 0; - - public state: State = 'initial'; - public value: any; - public error: string = ''; - - constructor( - { render, input = stdin, output = stdout, ...opts }: PromptOptions, - trackValue: boolean = true - ) { - this.opts = opts; - this.onKeypress = this.onKeypress.bind(this); - this.close = this.close.bind(this); - this.render = this.render.bind(this); - this._render = render.bind(this); - this._track = trackValue; - - this.input = input; - this.output = output; - } - - public prompt(): Promise { - const sink = new WriteStream(0); - sink._write = (chunk, encoding, done) => { - if (this._track) { - this.value = this.rl.line.replace(/\t/g, ''); - this._cursor = this.rl.cursor; - this.emit('value', this.value); - } - done(); - }; - this.input.pipe(sink); - - this.rl = readline.createInterface({ - input: this.input, - output: sink, - tabSize: 2, - prompt: '', - escapeCodeTimeout: 50 - }); - readline.emitKeypressEvents(this.input, this.rl); - this.rl.prompt(); - if (this.opts.initialValue !== undefined && this._track) { - this.rl.write(this.opts.initialValue); - } - - this.input.on('keypress', this.onKeypress); - setRawMode(this.input, true); - this.output.on('resize', this.render); - - this.render(); - - return new Promise((resolve) => { - this.once('submit', () => { - this.output.write(cursor.show); - this.output.off('resize', this.render); - setRawMode(this.input, false); - resolve(this.value); - }); - this.once('cancel', () => { - this.output.write(cursor.show); - this.output.off('resize', this.render); - setRawMode(this.input, false); - resolve(cancel); - }); - }); - } - - private subscribers = new Map any; once?: boolean }>>(); - public on(event: string, cb: (...args: any) => any): void { - const arr = this.subscribers.get(event) ?? []; - arr.push({ cb }); - this.subscribers.set(event, arr); - } - public once(event: string, cb: (...args: any) => any): void { - const arr = this.subscribers.get(event) ?? []; - arr.push({ cb, once: true }); - this.subscribers.set(event, arr); - } - public emit(event: string, ...data: any[]): void { - const cbs = this.subscribers.get(event) ?? []; - const cleanup: Array<() => void> = []; - for (const subscriber of cbs) { - subscriber.cb(...data); - if (subscriber.once) { - cleanup.push(() => cbs.splice(cbs.indexOf(subscriber), 1)); - } - } - for (const cb of cleanup) { - cb(); - } - } - private unsubscribe() { - this.subscribers.clear(); - } - - private onKeypress(char: string, key?: Key) { - if (this.state === 'error') { - this.state = 'active'; - } - if (key?.name && !this._track && aliases.has(key.name)) { - this.emit('cursor', aliases.get(key.name)); - } - if (key?.name && keys.has(key.name)) { - this.emit('cursor', key.name); - } - if (char && (char.toLowerCase() === 'y' || char.toLowerCase() === 'n')) { - this.emit('confirm', char.toLowerCase() === 'y'); - } - if (char === '\t' && this.opts.placeholder) { - if (!this.value) { - this.rl.write(this.opts.placeholder); - this.emit('value', this.opts.placeholder); - } - } - if (char) { - this.emit('key', char.toLowerCase()); - } - - if (key?.name === 'return') { - if (this.opts.validate) { - const problem = this.opts.validate(this.value); - if (problem) { - this.error = problem; - this.state = 'error'; - this.rl.write(this.value); - } - } - if (this.state !== 'error') { - this.state = 'submit'; - } - } - if (char === '\x03') { - this.state = 'cancel'; - } - if (this.state === 'submit' || this.state === 'cancel') { - this.emit('finalize'); - } - this.render(); - if (this.state === 'submit' || this.state === 'cancel') { - this.close(); - } - } - - protected close(): void { - this.input.unpipe(); - this.input.removeListener('keypress', this.onKeypress); - this.output.write('\n'); - setRawMode(this.input, false); - this.rl.close(); - this.emit(this.state, this.value); - this.unsubscribe(); - } - - private restoreCursor() { - const lines = - wrap(this._prevFrame, process.stdout.columns, { hard: true }).split('\n').length - 1; - this.output.write(cursor.move(-999, lines * -1)); - } - - private _prevFrame = ''; - private render() { - const frame = wrap(this._render(this) ?? '', process.stdout.columns, { hard: true }); - if (frame === this._prevFrame) return; - - if (this.state === 'initial') { - this.output.write(cursor.hide); - } - - const diff = diffLines(this._prevFrame, frame); - this.restoreCursor(); - if (diff) { - const diffLine = diff[0]!; - const lines = frame.split('\n'); - let newLines: string[] = []; - - // If we don't have enough vertical space to print all of the lines simultaneously, - // then we'll sticky the prompt message (first 3 lines) to the top so it's always shown. - // We'll then take the remaining space and render a snippet of the list that's relative - // to the currently selected option - if (lines.length > process.stdout.rows) { - const OFFSET = 3; - const PAGE_SIZE = process.stdout.rows - OFFSET; - - // @ts-expect-error `cursor` is a property that's implemented by prompts extending this class. - const pos: number = this.cursor; - - // page positions - const start = pos <= OFFSET ? OFFSET : pos; - const end = start + PAGE_SIZE; - - this.output.write(erase.down()); - - // stickied headers - const header = lines.slice(0, OFFSET); - const content = lines.slice(start, end); - newLines = newLines.concat(header, content); - } else { - this.output.write(cursor.move(0, diffLine)); - this.output.write(erase.down()); - - newLines = lines.slice(diffLine); - } - - this.output.write(newLines.join('\n')); - this._prevFrame = frame; - return; - } - - this.output.write(frame); - if (this.state === 'initial') { - this.state = 'active'; - } - this._prevFrame = frame; - } -} diff --git a/packages/clack-core/src/prompts/select-key.ts b/packages/clack-core/src/prompts/select-key.ts deleted file mode 100644 index b0c703e6..00000000 --- a/packages/clack-core/src/prompts/select-key.ts +++ /dev/null @@ -1,27 +0,0 @@ -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface SelectKeyOptions extends PromptOptions> { - options: T[]; -} -export default class SelectKeyPrompt extends Prompt { - options: T[]; - cursor: number = 0; - - constructor(opts: SelectKeyOptions) { - super(opts, false); - - this.options = opts.options; - const keys = this.options.map(({ value: [initial] }) => initial?.toLowerCase()); - this.cursor = Math.max(keys.indexOf(opts.initialValue), 0); - - this.on('key', (key) => { - if (!keys.includes(key)) return; - const value = this.options.find(({ value: [initial] }) => initial?.toLowerCase() === key); - if (value) { - this.value = value.value; - this.state = 'submit'; - this.emit('submit'); - } - }); - } -} diff --git a/packages/clack-core/src/prompts/select.ts b/packages/clack-core/src/prompts/select.ts deleted file mode 100644 index ee5f2627..00000000 --- a/packages/clack-core/src/prompts/select.ts +++ /dev/null @@ -1,41 +0,0 @@ -import Prompt, { type PromptOptions } from './prompt.ts'; - -interface SelectOptions extends PromptOptions> { - options: T[]; - initialValue?: T['value']; -} -export default class SelectPrompt extends Prompt { - options: T[]; - cursor: number = 0; - - private get _value() { - return this.options[this.cursor]; - } - - private changeValue() { - this.value = this._value!.value; - } - - constructor(opts: SelectOptions) { - super(opts, false); - - this.options = opts.options; - this.cursor = this.options.findIndex(({ value }) => value === opts.initialValue); - if (this.cursor === -1) this.cursor = 0; - this.changeValue(); - - this.on('cursor', (key) => { - switch (key) { - case 'left': - case 'up': - this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; - break; - case 'down': - case 'right': - this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; - break; - } - this.changeValue(); - }); - } -} diff --git a/packages/clack-core/src/prompts/text.ts b/packages/clack-core/src/prompts/text.ts deleted file mode 100644 index b2a89a71..00000000 --- a/packages/clack-core/src/prompts/text.ts +++ /dev/null @@ -1,33 +0,0 @@ -import color from 'picocolors'; -import Prompt, { type PromptOptions } from './prompt.ts'; - -export interface TextOptions extends PromptOptions { - placeholder?: string; - defaultValue?: string; -} - -export default class TextPrompt extends Prompt { - valueWithCursor = ''; - get cursor(): number { - return this._cursor; - } - constructor(opts: TextOptions) { - super(opts); - - this.on('finalize', () => { - if (!this.value) { - this.value = opts.defaultValue; - } - this.valueWithCursor = this.value; - }); - this.on('value', () => { - if (this.cursor >= this.value.length) { - this.valueWithCursor = `${this.value}${color.inverse(color.hidden('_'))}`; - } else { - const s1 = this.value.slice(0, this.cursor); - const s2 = this.value.slice(this.cursor); - this.valueWithCursor = `${s1}${color.inverse(s2[0])}${s2.slice(1)}`; - } - }); - } -} diff --git a/packages/clack-core/src/utils.ts b/packages/clack-core/src/utils.ts deleted file mode 100644 index b4a101e0..00000000 --- a/packages/clack-core/src/utils.ts +++ /dev/null @@ -1,60 +0,0 @@ -import type { Key } from 'node:readline'; - -import process, { stdin, stdout } from 'node:process'; -import * as readline from 'node:readline'; -import { cursor } from 'sisteransi'; - -const isWindows = process.platform.startsWith('win'); - -export type BlockOptions = { - input?: NodeJS.ReadStream | undefined; - output?: NodeJS.WriteStream | undefined; - overwrite?: boolean | undefined; - hideCursor?: boolean | undefined; -}; - -export function block({ - input = stdin, - output = stdout, - overwrite = true, - hideCursor = true -}: BlockOptions = {}) { - const rl = readline.createInterface({ - input, - output, - prompt: '', - tabSize: 1 - }); - readline.emitKeypressEvents(input, rl); - if (input.isTTY) input.setRawMode(true); - - const clear = (data: Buffer, { name }: Key) => { - const str = String(data); - if (str === '\x03') { - process.exit(0); - } - if (!overwrite) return; - const dx = name === 'return' ? 0 : -1; - const dy = name === 'return' ? -1 : 0; - - readline.moveCursor(output, dx, dy, () => { - readline.clearLine(output, 1, () => { - input.once('keypress', clear); - }); - }); - }; - if (hideCursor) process.stdout.write(cursor.hide); - input.once('keypress', clear); - - return (): void => { - input.off('keypress', clear); - if (hideCursor) process.stdout.write(cursor.show); - - // Prevent Windows specific issues: https://github.com/natemoo-re/clack/issues/176 - if (input.isTTY && !isWindows) input.setRawMode(false); - - // @ts-expect-error fix for https://github.com/nodejs/node/issues/31762#issuecomment-1441223907 - rl.terminal = false; - rl.close(); - }; -} diff --git a/packages/clack-core/tsconfig.json b/packages/clack-core/tsconfig.json deleted file mode 100644 index a1fcf6c9..00000000 --- a/packages/clack-core/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "checkJs": false, - "isolatedDeclarations": true, - "declaration": true - } -} diff --git a/packages/clack-prompts/LICENSE b/packages/clack-prompts/LICENSE deleted file mode 100644 index a95d8e47..00000000 --- a/packages/clack-prompts/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -MIT License - -Copyright (c) Nate Moore - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---- - -`ansi-regex` is adapted from https://github.com/chalk/ansi-regex - -MIT License - -Copyright (c) Sindre Sorhus (https://sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/clack-prompts/README.md b/packages/clack-prompts/README.md deleted file mode 100644 index e5837fd6..00000000 --- a/packages/clack-prompts/README.md +++ /dev/null @@ -1,174 +0,0 @@ -# `@clack/prompts` - -Effortlessly build beautiful command-line apps 🪄 [Try the demo](https://stackblitz.com/edit/clack-prompts?file=index.js) - -![clack-prompt](https://github.com/natemoo-re/clack/blob/main/.github/assets/clack-demo.gif) - ---- - -`@clack/prompts` is an opinionated, pre-styled wrapper around [`@clack/core`](https://www.npmjs.com/package/@clack/core). - -- 🤏 80% smaller than other options -- 💎 Beautiful, minimal UI -- ✅ Simple API -- 🧱 Comes with `text`, `confirm`, `select`, `multiselect`, and `spinner` components - -## Basics - -### Setup - -The `intro` and `outro` functions will print a message to begin or end a prompt session, respectively. - -```js -import { intro, outro } from '@clack/prompts'; - -intro(`create-my-app`); -// Do stuff -outro(`You're all set!`); -``` - -### Cancellation - -The `isCancel` function is a guard that detects when a user cancels a question with `CTRL + C`. You should handle this situation for each prompt, optionally providing a nice cancellation message with the `cancel` utility. - -```js -import { isCancel, cancel, text } from '@clack/prompts'; - -const value = await text(/* TODO */); - -if (isCancel(value)) { - cancel('Operation cancelled.'); - process.exit(0); -} -``` - -## Components - -### Text - -The text component accepts a single line of text. - -```js -import { text } from '@clack/prompts'; - -const meaning = await text({ - message: 'What is the meaning of life?', - placeholder: 'Not sure', - initialValue: '42', - validate(value) { - if (value.length === 0) return `Value is required!`; - } -}); -``` - -### Confirm - -The confirm component accepts a yes or no answer. The result is a boolean value of `true` or `false`. - -```js -import { confirm } from '@clack/prompts'; - -const shouldContinue = await confirm({ - message: 'Do you want to continue?' -}); -``` - -### Select - -The select component allows a user to choose one value from a list of options. The result is the `value` prop of a given option. - -```js -import { select } from '@clack/prompts'; - -const projectType = await select({ - message: 'Pick a project type.', - options: [ - { value: 'ts', label: 'TypeScript' }, - { value: 'js', label: 'JavaScript' }, - { value: 'coffee', label: 'CoffeeScript', hint: 'oh no' } - ] -}); -``` - -### Multi-Select - -The `multiselect` component allows a user to choose many values from a list of options. The result is an array with all selected `value` props. - -```js -import { multiselect } from '@clack/prompts'; - -const additionalTools = await multiselect({ - message: 'Select additional tools.', - options: [ - { value: 'eslint', label: 'ESLint', hint: 'recommended' }, - { value: 'prettier', label: 'Prettier' }, - { value: 'gh-action', label: 'GitHub Action' } - ], - required: false -}); -``` - -### Spinner - -The spinner component surfaces a pending action, such as a long-running download or dependency installation. - -```js -import { spinner } from '@clack/prompts'; - -const s = spinner(); -s.start('Installing via npm'); -// Do installation here -s.stop('Installed via npm'); -``` - -## Utilities - -### Grouping - -Grouping prompts together is a great way to keep your code organized. This accepts a JSON object with a name that can be used to reference the group later. The second argument is an optional but has a `onCancel` callback that will be called if the user cancels one of the prompts in the group. - -```js -import * as p from '@clack/prompts'; - -const group = await p.group( - { - name: () => p.text({ message: 'What is your name?' }), - age: () => p.text({ message: 'What is your age?' }), - color: ({ results }) => - p.multiselect({ - message: `What is your favorite color ${results.name}?`, - options: [ - { value: 'red', label: 'Red' }, - { value: 'green', label: 'Green' }, - { value: 'blue', label: 'Blue' } - ] - }) - }, - { - // On Cancel callback that wraps the group - // So if the user cancels one of the prompts in the group this function will be called - onCancel: ({ results }) => { - p.cancel('Operation cancelled.'); - process.exit(0); - } - } -); - -console.log(group.name, group.age, group.color); -``` - -### Tasks - -Execute multiple tasks in spinners. - -```js -await p.tasks([ - { - title: 'Installing via npm', - task: async (message) => { - // Do installation here - return 'Installed via npm'; - } - } -]); -``` diff --git a/packages/clack-prompts/index.ts b/packages/clack-prompts/index.ts deleted file mode 100644 index d93f8c0f..00000000 --- a/packages/clack-prompts/index.ts +++ /dev/null @@ -1,894 +0,0 @@ -import process from 'node:process'; -import { - block, - ConfirmPrompt, - GroupMultiSelectPrompt, - isCancel, - MultiSelectPrompt, - PasswordPrompt, - SelectKeyPrompt, - SelectPrompt, - type State, - TextPrompt -} from '@sveltejs/clack-core'; -import isUnicodeSupported from 'is-unicode-supported'; -import color from 'picocolors'; -import { cursor, erase } from 'sisteransi'; - -export { isCancel } from '@sveltejs/clack-core'; - -const unicode = isUnicodeSupported(); -const s = (c: string, fallback: string) => (unicode ? c : fallback); -const S_STEP_ACTIVE = s('◆', '*'); -const S_STEP_CANCEL = s('■', 'x'); -const S_STEP_ERROR = s('▲', 'x'); -const S_STEP_SUBMIT = s('◇', 'o'); - -const S_BAR_START = s('┌', 'T'); -const S_BAR = s('│', '|'); -const S_BAR_END = s('└', '—'); - -const S_RADIO_ACTIVE = s('●', '>'); -const S_RADIO_INACTIVE = s('○', ' '); -const S_CHECKBOX_ACTIVE = s('◻', '[•]'); -const S_CHECKBOX_SELECTED = s('◼', '[+]'); -const S_CHECKBOX_INACTIVE = s('◻', '[ ]'); -const S_PASSWORD_MASK = s('▪', '•'); - -const S_BAR_H = s('─', '-'); -const S_CORNER_TOP_RIGHT = s('╮', '+'); -const S_CONNECT_LEFT = s('├', '+'); -const S_CORNER_BOTTOM_RIGHT = s('╯', '+'); - -const S_INFO = s('●', '•'); -const S_SUCCESS = s('◆', '*'); -const S_WARN = s('▲', '!'); -const S_ERROR = s('■', 'x'); - -const symbol = (state: State) => { - switch (state) { - case 'initial': - case 'active': - return color.cyan(S_STEP_ACTIVE); - case 'cancel': - return color.red(S_STEP_CANCEL); - case 'error': - return color.yellow(S_STEP_ERROR); - case 'submit': - return color.green(S_STEP_SUBMIT); - } -}; - -interface LimitOptionsParams { - options: TOption[]; - maxItems: number | undefined; - cursor: number; - style: (option: TOption, active: boolean) => string; -} - -const limitOptions = (params: LimitOptionsParams): string[] => { - const { cursor, options, style } = params; - - const paramMaxItems = params.maxItems ?? Infinity; - const outputMaxItems = Math.max(process.stdout.rows - 4, 0); - // We clamp to minimum 5 because anything less doesn't make sense UX wise - const maxItems = Math.min(outputMaxItems, Math.max(paramMaxItems, 5)); - let slidingWindowLocation = 0; - - if (cursor >= slidingWindowLocation + maxItems - 3) { - slidingWindowLocation = Math.max(Math.min(cursor - maxItems + 3, options.length - maxItems), 0); - } else if (cursor < slidingWindowLocation + 2) { - slidingWindowLocation = Math.max(cursor - 2, 0); - } - - const shouldRenderTopEllipsis = maxItems < options.length && slidingWindowLocation > 0; - const shouldRenderBottomEllipsis = - maxItems < options.length && slidingWindowLocation + maxItems < options.length; - - return options - .slice(slidingWindowLocation, slidingWindowLocation + maxItems) - .map((option, i, arr) => { - const isTopLimit = i === 0 && shouldRenderTopEllipsis; - const isBottomLimit = i === arr.length - 1 && shouldRenderBottomEllipsis; - return isTopLimit || isBottomLimit - ? color.dim('...') - : style(option, i + slidingWindowLocation === cursor); - }); -}; - -export interface TextOptions { - message: string; - placeholder?: string; - defaultValue?: string; - initialValue?: string; - validate?: (value: string) => string | void; -} -export const text = (opts: TextOptions): Promise => { - return new TextPrompt({ - validate: opts.validate, - placeholder: opts.placeholder, - defaultValue: opts.defaultValue, - initialValue: opts.initialValue, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - const placeholder = opts.placeholder - ? color.inverse(opts.placeholder[0]) + color.dim(opts.placeholder.slice(1)) - : color.inverse(color.hidden('_')); - const value = !this.value ? placeholder : this.valueWithCursor; - - switch (this.state) { - case 'error': - return `${title.trim()}\n${color.yellow(S_BAR)} ${value}\n${color.yellow( - S_BAR_END - )} ${color.yellow(this.error)}\n`; - case 'submit': - return `${title}${color.gray(S_BAR)} ${color.dim(this.value || opts.placeholder)}`; - case 'cancel': - return `${title}${color.gray(S_BAR)} ${color.strikethrough( - color.dim(this.value ?? '') - )}${this.value?.trim() ? '\n' + color.gray(S_BAR) : ''}`; - default: - return `${title}${color.cyan(S_BAR)} ${value}\n${color.cyan(S_BAR_END)}\n`; - } - } - }).prompt(); -}; - -export interface PasswordOptions { - message: string; - mask?: string; - validate?: (value: string) => string | void; -} -export const password = (opts: PasswordOptions): Promise => { - return new PasswordPrompt({ - validate: opts.validate, - mask: opts.mask ?? S_PASSWORD_MASK, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - const value = this.valueWithCursor; - const masked = this.masked; - - switch (this.state) { - case 'error': - return `${title.trim()}\n${color.yellow(S_BAR)} ${masked}\n${color.yellow( - S_BAR_END - )} ${color.yellow(this.error)}\n`; - case 'submit': - return `${title}${color.gray(S_BAR)} ${color.dim(masked)}`; - case 'cancel': - return `${title}${color.gray(S_BAR)} ${color.strikethrough(color.dim(masked ?? ''))}${ - masked ? '\n' + color.gray(S_BAR) : '' - }`; - default: - return `${title}${color.cyan(S_BAR)} ${value}\n${color.cyan(S_BAR_END)}\n`; - } - } - }).prompt(); -}; - -export interface ConfirmOptions { - message: string; - active?: string; - inactive?: string; - initialValue?: boolean; -} -export const confirm = (opts: ConfirmOptions) => { - const active = opts.active ?? 'Yes'; - const inactive = opts.inactive ?? 'No'; - return new ConfirmPrompt({ - active, - inactive, - initialValue: opts.initialValue ?? true, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - const value = this.value ? active : inactive; - - switch (this.state) { - case 'submit': - return `${title}${color.gray(S_BAR)} ${color.dim(value)}`; - case 'cancel': - return `${title}${color.gray(S_BAR)} ${color.strikethrough( - color.dim(value) - )}\n${color.gray(S_BAR)}`; - default: { - return `${title}${color.cyan(S_BAR)} ${ - this.value - ? `${color.green(S_RADIO_ACTIVE)} ${active}` - : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(active)}` - } ${color.dim('/')} ${ - !this.value - ? `${color.green(S_RADIO_ACTIVE)} ${inactive}` - : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(inactive)}` - }\n${color.cyan(S_BAR_END)}\n`; - } - } - } - }).prompt() as Promise; -}; - -type Primitive = Readonly; - -type Option = Value extends Primitive - ? { value: Value; label?: string; hint?: string } - : { value: Value; label: string; hint?: string }; - -export interface SelectOptions { - message: string; - options: Array>; - initialValue?: Value; - maxItems?: number; -} - -export const select = (opts: SelectOptions) => { - const opt = (option: Option, state: 'inactive' | 'active' | 'selected' | 'cancelled') => { - const label = option.label ?? String(option.value); - switch (state) { - case 'selected': - return color.dim(label); - case 'active': - return `${color.green(S_RADIO_ACTIVE)} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - case 'cancelled': - return color.strikethrough(color.dim(label)); - default: - return `${color.dim(S_RADIO_INACTIVE)} ${color.dim(label)}`; - } - }; - - return new SelectPrompt({ - options: opts.options, - initialValue: opts.initialValue, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - - switch (this.state) { - case 'submit': - return `${title}${color.gray(S_BAR)} ${opt(this.options[this.cursor]!, 'selected')}`; - case 'cancel': - return `${title}${color.gray(S_BAR)} ${opt( - this.options[this.cursor]!, - 'cancelled' - )}\n${color.gray(S_BAR)}`; - default: { - return `${title}${color.cyan(S_BAR)} ${limitOptions({ - cursor: this.cursor, - options: this.options, - maxItems: opts.maxItems, - style: (item, active) => opt(item, active ? 'active' : 'inactive') - }).join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; - } - } - } - }).prompt() as Promise; -}; - -export const selectKey = (opts: SelectOptions) => { - const opt = ( - option: Option, - state: 'inactive' | 'active' | 'selected' | 'cancelled' = 'inactive' - ) => { - const label = option.label ?? String(option.value); - if (state === 'selected') { - return color.dim(label); - } else if (state === 'cancelled') { - return color.strikethrough(color.dim(label)); - } else if (state === 'active') { - return `${color.bgCyan(color.gray(` ${option.value} `))} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - } - return `${color.gray(color.bgWhite(color.inverse(` ${option.value} `)))} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - }; - - return new SelectKeyPrompt({ - options: opts.options, - initialValue: opts.initialValue, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - - switch (this.state) { - case 'submit': - return `${title}${color.gray(S_BAR)} ${opt( - this.options.find((opt) => opt.value === this.value)!, - 'selected' - )}`; - case 'cancel': - return `${title}${color.gray(S_BAR)} ${opt(this.options[0]!, 'cancelled')}\n${color.gray( - S_BAR - )}`; - default: { - return `${title}${color.cyan(S_BAR)} ${this.options - .map((option, i) => opt(option, i === this.cursor ? 'active' : 'inactive')) - .join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; - } - } - } - }).prompt() as Promise; -}; - -export interface MultiSelectOptions { - message: string; - options: Array>; - initialValues?: Value[]; - maxItems?: number; - required?: boolean; - cursorAt?: Value; -} -export const multiselect = (opts: MultiSelectOptions) => { - const opt = ( - option: Option, - state: 'inactive' | 'active' | 'selected' | 'active-selected' | 'submitted' | 'cancelled' - ) => { - const label = option.label ?? String(option.value); - if (state === 'active') { - return `${color.cyan(S_CHECKBOX_ACTIVE)} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - } else if (state === 'selected') { - return `${color.green(S_CHECKBOX_SELECTED)} ${color.dim(label)}`; - } else if (state === 'cancelled') { - return color.strikethrough(color.dim(label)); - } else if (state === 'active-selected') { - return `${color.green(S_CHECKBOX_SELECTED)} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - } else if (state === 'submitted') { - return color.dim(label); - } - return `${color.dim(S_CHECKBOX_INACTIVE)} ${color.dim(label)}`; - }; - - return new MultiSelectPrompt({ - options: opts.options, - initialValues: opts.initialValues, - required: opts.required ?? true, - cursorAt: opts.cursorAt, - validate(selected: Value[]) { - if (this.required && selected.length === 0) - return `Please select at least one option.\n${color.reset( - color.dim( - `Press ${color.gray(color.bgWhite(color.inverse(' space ')))} to select, ${color.gray( - color.bgWhite(color.inverse(' enter ')) - )} to submit` - ) - )}`; - }, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - - const styleOption = (option: Option, active: boolean) => { - const selected = this.value.includes(option.value); - if (active && selected) { - return opt(option, 'active-selected'); - } - if (selected) { - return opt(option, 'selected'); - } - return opt(option, active ? 'active' : 'inactive'); - }; - - switch (this.state) { - case 'submit': { - return `${title}${color.gray(S_BAR)} ${ - this.options - .filter(({ value }) => this.value.includes(value)) - .map((option) => opt(option, 'submitted')) - .join(color.dim(', ')) || color.dim('none') - }`; - } - case 'cancel': { - const label = this.options - .filter(({ value }) => this.value.includes(value)) - .map((option) => opt(option, 'cancelled')) - .join(color.dim(', ')); - return `${title}${color.gray(S_BAR)} ${ - label.trim() ? `${label}\n${color.gray(S_BAR)}` : '' - }`; - } - case 'error': { - const footer = this.error - .split('\n') - .map((ln, i) => - i === 0 ? `${color.yellow(S_BAR_END)} ${color.yellow(ln)}` : ` ${ln}` - ) - .join('\n'); - return ( - title + - color.yellow(S_BAR) + - ' ' + - limitOptions({ - options: this.options, - cursor: this.cursor, - maxItems: opts.maxItems, - style: styleOption - }).join(`\n${color.yellow(S_BAR)} `) + - '\n' + - footer + - '\n' - ); - } - default: { - return `${title}${color.cyan(S_BAR)} ${limitOptions({ - options: this.options, - cursor: this.cursor, - maxItems: opts.maxItems, - style: styleOption - }).join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; - } - } - } - }).prompt() as Promise; -}; - -export interface GroupMultiSelectOptions { - message: string; - options: Record>>; - initialValues?: Value[]; - required?: boolean; - cursorAt?: Value; - selectableGroups?: boolean; - spacedGroups?: boolean; -} - -export const groupMultiselect = (opts: GroupMultiSelectOptions) => { - const { selectableGroups = false, spacedGroups = false } = opts; - const opt = ( - option: Option, - state: - | 'inactive' - | 'active' - | 'selected' - | 'active-selected' - | 'group-active' - | 'group-active-selected' - | 'submitted' - | 'cancelled', - options: Array> = [] - ) => { - const label = option.label ?? String(option.value); - const isItem = typeof (option as any).group === 'string'; - const next = isItem && (options[options.indexOf(option) + 1] ?? { group: true }); - // @ts-ignore - const isLast = isItem && next.group === true; - const prefix = isItem ? (selectableGroups ? `${isLast ? S_BAR_END : S_BAR} ` : ' ') : ''; - const spacingPrefix = spacedGroups && !isItem ? `\n${color.cyan(S_BAR)} ` : ''; - - if (state === 'active') { - return `${spacingPrefix}${color.dim(prefix)}${color.cyan(S_CHECKBOX_ACTIVE)} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - } else if (state === 'group-active') { - return `${spacingPrefix}${prefix}${color.cyan(S_CHECKBOX_ACTIVE)} ${color.dim(label)}`; - } else if (state === 'group-active-selected') { - return `${spacingPrefix}${prefix}${color.green(S_CHECKBOX_SELECTED)} ${color.dim(label)}`; - } else if (state === 'selected') { - return `${spacingPrefix}${color.dim(prefix)}${color.green(S_CHECKBOX_SELECTED)} ${color.dim( - label - )}`; - } else if (state === 'cancelled') { - return color.strikethrough(color.dim(label)); - } else if (state === 'active-selected') { - return `${spacingPrefix}${color.dim(prefix)}${color.green(S_CHECKBOX_SELECTED)} ${label} ${ - option.hint ? color.dim(`(${option.hint})`) : '' - }`; - } else if (state === 'submitted') { - return color.dim(label); - } - return `${spacingPrefix}${color.dim(prefix)}${ - isItem || selectableGroups ? `${color.dim(S_CHECKBOX_INACTIVE)} ` : '' - }${color.dim(label)}`; - }; - - return new GroupMultiSelectPrompt({ - options: opts.options, - initialValues: opts.initialValues, - required: opts.required ?? true, - cursorAt: opts.cursorAt, - selectableGroups, - validate(selected: Value[]) { - if (this.required && selected.length === 0) - return `Please select at least one option.\n${color.reset( - color.dim( - `Press ${color.gray(color.bgWhite(color.inverse(' space ')))} to select, ${color.gray( - color.bgWhite(color.inverse(' enter ')) - )} to submit` - ) - )}`; - }, - render() { - const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; - - switch (this.state) { - case 'submit': { - return `${title}${color.gray(S_BAR)} ${this.options - .filter(({ value }) => this.value.includes(value)) - .map((option) => opt(option, 'submitted')) - .join(color.dim(', '))}`; - } - case 'cancel': { - const label = this.options - .filter(({ value }) => this.value.includes(value)) - .map((option) => opt(option, 'cancelled')) - .join(color.dim(', ')); - return `${title}${color.gray(S_BAR)} ${ - label.trim() ? `${label}\n${color.gray(S_BAR)}` : '' - }`; - } - case 'error': { - const footer = this.error - .split('\n') - .map((ln, i) => - i === 0 ? `${color.yellow(S_BAR_END)} ${color.yellow(ln)}` : ` ${ln}` - ) - .join('\n'); - return `${title}${color.yellow(S_BAR)} ${this.options - .map((option, i, options) => { - const selected = - this.value.includes(option.value) || - (option.group === true && this.isGroupSelected(`${option.value}`)); - const active = i === this.cursor; - const groupActive = - !active && - typeof option.group === 'string' && - this.options[this.cursor]!.value === option.group; - if (groupActive) { - return opt(option, selected ? 'group-active-selected' : 'group-active', options); - } - if (active && selected) { - return opt(option, 'active-selected', options); - } - if (selected) { - return opt(option, 'selected', options); - } - return opt(option, active ? 'active' : 'inactive', options); - }) - .join(`\n${color.yellow(S_BAR)} `)}\n${footer}\n`; - } - default: { - return `${title}${color.cyan(S_BAR)} ${this.options - .map((option, i, options) => { - const selected = - this.value.includes(option.value) || - (option.group === true && this.isGroupSelected(`${option.value}`)); - const active = i === this.cursor; - const groupActive = - !active && - typeof option.group === 'string' && - this.options[this.cursor]!.value === option.group; - if (groupActive) { - return opt(option, selected ? 'group-active-selected' : 'group-active', options); - } - if (active && selected) { - return opt(option, 'active-selected', options); - } - if (selected) { - return opt(option, 'selected', options); - } - return opt(option, active ? 'active' : 'inactive', options); - }) - .join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; - } - } - } - }).prompt() as Promise; -}; - -const strip = (str: string) => str.replace(ansiRegex(), ''); -function buildBox(message = '', title = '', dimmed = true) { - const lines = `\n${message}\n`.split('\n'); - const titleLen = strip(title).length; - const len = - Math.max( - lines.reduce((sum, ln) => { - ln = strip(ln); - return ln.length > sum ? ln.length : sum; - }, 0), - titleLen - ) + 2; - const msg = lines - .map( - (ln) => - `${color.gray(S_BAR)} ${dimmed ? color.dim(ln) : ln}${' '.repeat(len - strip(ln).length)}${color.gray(S_BAR)}` - ) - .join('\n'); - process.stdout.write( - `${color.gray(S_BAR)}\n${color.green(S_STEP_SUBMIT)} ${color.reset(title)} ${color.gray( - S_BAR_H.repeat(Math.max(len - titleLen - 1, 1)) + S_CORNER_TOP_RIGHT - )}\n${msg}\n${color.gray(S_CONNECT_LEFT + S_BAR_H.repeat(len + 2) + S_CORNER_BOTTOM_RIGHT)}\n` - ); -} - -export const note = (message = '', title = ''): void => buildBox(message, title, true); -export const box = (message = '', title = ''): void => buildBox(message, title, false); -export const taskLog = (title: string) => { - const BAR = color.dim(S_BAR); - const ACTIVE = color.green(S_STEP_SUBMIT); - const SUCCESS = color.green(S_SUCCESS); - const ERROR = color.red(S_ERROR); - - // heading - process.stdout.write(`${BAR}\n`); - process.stdout.write(`${ACTIVE} ${title}\n`); - - let output = ''; - let frame = ''; - - // clears previous output - const clear = (eraseTitle = false): void => { - if (!frame) return; - const terminalWidth = process.stdout.columns; - const frameHeight = frame.split('\n').reduce((height, line) => { - // accounts for line wraps - height += Math.ceil(line.length / terminalWidth); - return height; - }, 0); - const lines = frameHeight + (eraseTitle ? 1 : 0); - - process.stdout.write(cursor.up(lines)); - process.stdout.write(erase.down()); - }; - - // logs the output - const print = (limit = 0): void => { - const lines = output.split('\n').slice(-limit); - // reset frame - frame = ''; - for (const line of lines) { - frame += `${BAR} ${line}\n`; - } - process.stdout.write(color.dim(frame)); - }; - - return { - set text(data: string) { - clear(); - output += data; - // half the height of the terminal - const frameHeight = Math.ceil(process.stdout.rows / 2); - print(frameHeight); - }, - fail(message: string): void { - clear(true); - process.stdout.write(`${ERROR} ${message}\n`); - print(); // log the output on failure - }, - success(message: string): void { - clear(true); - process.stdout.write(`${SUCCESS} ${message}\n`); - } - }; -}; - -export const cancel = (message = ''): void => { - process.stdout.write(`${color.gray(S_BAR_END)} ${color.red(message)}\n\n`); -}; - -export const intro = (title = ''): void => { - process.stdout.write(`${color.gray(S_BAR_START)} ${title}\n`); -}; - -export const outro = (message = ''): void => { - process.stdout.write(`${color.gray(S_BAR)}\n${color.gray(S_BAR_END)} ${message}\n\n`); -}; - -export type LogMessageOptions = { - symbol?: string; -}; -export const log = { - message: (message = '', { symbol = color.gray(S_BAR) }: LogMessageOptions = {}): void => { - const parts = [color.gray(S_BAR)]; - if (message) { - const [firstLine, ...lines] = message.split('\n'); - parts.push(`${symbol} ${firstLine}`, ...lines.map((ln) => `${color.gray(S_BAR)} ${ln}`)); - } - process.stdout.write(`${parts.join('\n')}\n`); - }, - info: (message: string): void => { - log.message(message, { symbol: color.blue(S_INFO) }); - }, - success: (message: string): void => { - log.message(message, { symbol: color.green(S_SUCCESS) }); - }, - step: (message: string): void => { - log.message(message, { symbol: color.green(S_STEP_SUBMIT) }); - }, - warn: (message: string): void => { - log.message(message, { symbol: color.yellow(S_WARN) }); - }, - /** alias for `log.warn()`. */ - warning: (message: string): void => { - log.warn(message); - }, - error: (message: string): void => { - log.message(message, { symbol: color.red(S_ERROR) }); - } -}; - -export const spinner = (): { - start: (msg?: string) => void; - stop: (msg?: string, code?: number) => void; - message: (msg?: string) => void; -} => { - const frames = unicode ? ['◒', '◐', '◓', '◑'] : ['•', 'o', 'O', '0']; - const delay = unicode ? 80 : 120; - - let unblock: () => void; - let loop: NodeJS.Timeout; - let isSpinnerActive: boolean = false; - let _message: string = ''; - - const handleExit = (code: number) => { - const msg = code > 1 ? 'Something went wrong' : 'Canceled'; - if (isSpinnerActive) stop(msg, code); - }; - - const errorEventHandler = () => { - handleExit(2); - }; - const signalEventHandler = () => { - handleExit(1); - }; - - const registerHooks = () => { - // Reference: https://nodejs.org/api/process.html#event-uncaughtexception - process.on('uncaughtExceptionMonitor', errorEventHandler); - // Reference: https://nodejs.org/api/process.html#event-unhandledrejection - process.on('unhandledRejection', errorEventHandler); - // Reference Signal Events: https://nodejs.org/api/process.html#signal-events - process.on('SIGINT', signalEventHandler); - process.on('SIGTERM', signalEventHandler); - process.on('exit', handleExit); - }; - - const clearHooks = () => { - process.removeListener('uncaughtExceptionMonitor', errorEventHandler); - process.removeListener('unhandledRejection', errorEventHandler); - process.removeListener('SIGINT', signalEventHandler); - process.removeListener('SIGTERM', signalEventHandler); - process.removeListener('exit', handleExit); - }; - - const start = (msg: string = ''): void => { - isSpinnerActive = true; - unblock = block(); - _message = msg.replace(/\.+$/, ''); - process.stdout.write(`${color.gray(S_BAR)}\n`); - let frameIndex = 0; - let dotsTimer = 0; - registerHooks(); - loop = setInterval(() => { - const frame = color.magenta(frames[frameIndex]); - const loadingDots = '.'.repeat(Math.floor(dotsTimer)).slice(0, 3); - process.stdout.write(cursor.move(-999, 0)); - process.stdout.write(erase.down(1)); - process.stdout.write(`${frame} ${_message}${loadingDots}`); - frameIndex = frameIndex + 1 < frames.length ? frameIndex + 1 : 0; - dotsTimer = dotsTimer < frames.length ? dotsTimer + 0.125 : 0; - }, delay); - }; - - const stop = (msg: string = '', code: number = 0): void => { - _message = msg ?? _message; - isSpinnerActive = false; - clearInterval(loop); - const step = - code === 0 - ? color.green(S_STEP_SUBMIT) - : code === 1 - ? color.red(S_STEP_CANCEL) - : color.red(S_STEP_ERROR); - process.stdout.write(cursor.move(-999, 0)); - process.stdout.write(erase.down(1)); - process.stdout.write(`${step} ${_message}\n`); - clearHooks(); - unblock(); - }; - - const message = (msg: string = ''): void => { - _message = msg ?? _message; - }; - - return { - start, - stop, - message - }; -}; - -// Adapted from https://github.com/chalk/ansi-regex -// @see LICENSE -function ansiRegex() { - const pattern = [ - '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', - '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))' - ].join('|'); - - return new RegExp(pattern, 'g'); -} - -export type PromptGroupAwaitedReturn = { - [P in keyof T]: Exclude, symbol>; -}; - -export interface PromptGroupOptions { - /** - * Control how the group can be canceled - * if one of the prompts is canceled. - */ - onCancel?: (opts: { results: Prettify>> }) => void; -} - -type Prettify = { - [P in keyof T]: T[P]; -} & {}; - -export type PromptGroup = { - [P in keyof T]: (opts: { - results: Prettify>>>; - }) => void | Promise; -}; - -/** - * Define a group of prompts to be displayed - * and return a results of objects within the group - */ -export const group = async ( - prompts: PromptGroup, - opts?: PromptGroupOptions -): Promise>> => { - const results = {} as any; - const promptNames = Object.keys(prompts); - - for (const name of promptNames) { - const prompt = prompts[name as keyof T]; - const result = await prompt({ results })?.catch((e) => { - throw e; - }); - - // Pass the results to the onCancel function - // so the user can decide what to do with the results - // TODO: Switch to callback within core to avoid isCancel Fn - if (typeof opts?.onCancel === 'function' && isCancel(result)) { - results[name] = 'canceled'; - opts.onCancel({ results }); - continue; - } - - results[name] = result; - } - - return results; -}; - -export type Task = { - /** - * Task title - */ - title: string; - /** - * Task function - */ - task: (message: (string: string) => void) => string | Promise | void | Promise; - - /** - * If enabled === false the task will be skipped - */ - enabled?: boolean; -}; - -/** - * Define a group of tasks to be executed - */ -export const tasks = async (tasks: Task[]): Promise => { - for (const task of tasks) { - if (task.enabled === false) continue; - - const s = spinner(); - s.start(task.title); - const result = await task.task(s.message); - s.stop(result || task.title); - } -}; diff --git a/packages/clack-prompts/package.json b/packages/clack-prompts/package.json deleted file mode 100644 index 733d8445..00000000 --- a/packages/clack-prompts/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "@sveltejs/clack-prompts", - "private": true, - "version": "0.9.1", - "type": "module", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/sveltejs/cli/tree/main/packages/clack-prompts" - }, - "bugs": "https://github.com/sveltejs/cli/issues", - "scripts": { - "check": "tsc", - "format": "pnpm lint --write", - "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore" - }, - "files": [ - "dist" - ], - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "./package.json": "./package.json" - }, - "devDependencies": { - "@sveltejs/clack-core": "workspace:*", - "is-unicode-supported": "^1.3.0", - "picocolors": "^1.1.1", - "sisteransi": "^1.0.5" - } -} diff --git a/packages/clack-prompts/tsconfig.json b/packages/clack-prompts/tsconfig.json deleted file mode 100644 index a1fcf6c9..00000000 --- a/packages/clack-prompts/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "checkJs": false, - "isolatedDeclarations": true, - "declaration": true - } -} diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 3359ef7e..a6795911 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -4,7 +4,7 @@ import process from 'node:process'; import pc from 'picocolors'; import * as v from 'valibot'; import * as pkg from 'empathic/package'; -import * as p from '@sveltejs/clack-prompts'; +import * as p from '@clack/prompts'; import { Command, Option } from 'commander'; import { officialAddons, @@ -92,7 +92,7 @@ export const add = new Command('add') const selectedAddons = transformAliases(specifiedAddons); common.runCommand(async () => { const { nextSteps } = await runAddCommand(options, selectedAddons); - if (nextSteps) p.box(nextSteps, 'Next steps'); + if (nextSteps) p.note(nextSteps, 'Next steps', { format: (line) => line }); }); }); @@ -356,7 +356,7 @@ export async function runAddCommand( .map(({ name, message }) => pc.yellow(`${name} (${message})`)) .join('\n- '); - p.note(`- ${message}`, 'Preconditions not met'); + p.note(`- ${message}`, 'Preconditions not met', { format: (line) => line }); const force = await p.confirm({ message: 'Preconditions failed. Do you wish to continue?', diff --git a/packages/cli/commands/create.ts b/packages/cli/commands/create.ts index 72a27f66..6ab92948 100644 --- a/packages/cli/commands/create.ts +++ b/packages/cli/commands/create.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import process from 'node:process'; import * as v from 'valibot'; import { Command, Option } from 'commander'; -import * as p from '@sveltejs/clack-prompts'; +import * as p from '@clack/prompts'; import pc from 'picocolors'; import { create as createKit, @@ -93,8 +93,8 @@ export const create = new Command('create') `Stuck? Visit us at ${pc.cyan('https://svelte.dev/chat')}` ]; - p.box(steps.join('\n'), 'Project next steps'); - if (addOnNextSteps) p.box(addOnNextSteps, 'Add-on next steps'); + p.note(steps.join('\n'), 'Project next steps', { format: (line) => line }); + if (addOnNextSteps) p.note(addOnNextSteps, 'Add-on next steps', { format: (line) => line }); }); }); diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 9c0bfb7e..6574130b 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -9,7 +9,7 @@ import type { AddonWithoutExplicitArgs } from '@sveltejs/cli-core'; import pc from 'picocolors'; -import * as p from '@sveltejs/clack-prompts'; +import * as p from '@clack/prompts'; import { exec, NonZeroExitError } from 'tinyexec'; import { resolveCommand } from 'package-manager-detector'; import { TESTING } from '../utils/env.ts'; diff --git a/packages/cli/package.json b/packages/cli/package.json index 189e847d..1fa2ef4b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -30,8 +30,8 @@ } }, "devDependencies": { + "@clack/prompts": "^1.0.0-alpha.0", "@sveltejs/addons": "workspace:*", - "@sveltejs/clack-prompts": "workspace:*", "@sveltejs/cli-core": "workspace:*", "@sveltejs/create": "workspace:*", "@types/degit": "^2.8.6", diff --git a/packages/cli/utils/common.ts b/packages/cli/utils/common.ts index 935024bf..b2282f97 100644 --- a/packages/cli/utils/common.ts +++ b/packages/cli/utils/common.ts @@ -1,6 +1,6 @@ import pc from 'picocolors'; import pkg from '../package.json' with { type: 'json' }; -import * as p from '@sveltejs/clack-prompts'; +import * as p from '@clack/prompts'; import type { Argument, HelpConfiguration, Option } from 'commander'; import { UnsupportedError } from './errors.ts'; import process from 'node:process'; diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index 90829424..f53e4878 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -4,7 +4,7 @@ import process from 'node:process'; import * as find from 'empathic/find'; import { exec } from 'tinyexec'; import { Option } from 'commander'; -import * as p from '@sveltejs/clack-prompts'; +import * as p from '@clack/prompts'; import { AGENTS, COMMANDS, @@ -46,7 +46,12 @@ export async function packageManagerPrompt(cwd: string): Promise { - const task = p.taskLog(`Installing dependencies with ${agent}...`); + const task = p.taskLog({ + title: `Installing dependencies with ${agent}...`, + limit: Math.ceil(process.stdout.rows / 2), + spacing: 0, + retainLog: true + }); try { const { command, args } = constructCommand(COMMANDS[agent].install, [])!; @@ -56,17 +61,17 @@ export async function installDependencies(agent: AgentName, cwd: string): Promis }); proc.process?.stdout?.on('data', (data) => { - task.text = data; + task.message(data.toString(), { raw: true }); }); proc.process?.stderr?.on('data', (data) => { - task.text = data; + task.message(data.toString(), { raw: true }); }); await proc; task.success('Successfully installed dependencies'); } catch { - task.fail('Failed to install dependencies'); + task.error('Failed to install dependencies'); p.cancel('Operation failed.'); process.exit(2); } diff --git a/packages/core/index.ts b/packages/core/index.ts index e68a90e8..e22448cb 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -1,5 +1,5 @@ export { defineAddon, defineAddonOptions } from './addon/config.ts'; -export { log } from '@sveltejs/clack-prompts'; +export { log } from '@clack/prompts'; export { default as colors } from 'picocolors'; export { default as dedent } from 'dedent'; export * as utils from './utils.ts'; diff --git a/packages/core/package.json b/packages/core/package.json index 41232984..59ba0aec 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -42,8 +42,8 @@ } }, "devDependencies": { + "@clack/prompts": "^1.0.0-alpha.0", "@sveltejs/acorn-typescript": "^1.0.1", - "@sveltejs/clack-prompts": "workspace:*", "@types/estree": "^1.0.6", "acorn": "^8.14.0", "decircular": "^1.0.0", diff --git a/packages/migrate/package.json b/packages/migrate/package.json index 65ede312..3a4c1ee9 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -27,7 +27,7 @@ "svelte-migrate": "./bin.js" }, "dependencies": { - "@clack/prompts": "^0.9.1", + "@clack/prompts": "^1.0.0-alpha.0", "import-meta-resolve": "^4.1.0", "magic-string": "^0.30.17", "package-manager-detector": "^0.2.11", diff --git a/packages/migrate/utils.js b/packages/migrate/utils.js index 4fd00665..cd401068 100644 --- a/packages/migrate/utils.js +++ b/packages/migrate/utils.js @@ -440,5 +440,7 @@ export function migration_succeeded(next_steps) { messages.push(`${i + 1}: ${step}`); }); - p.note(messages.join('\n'), 'Recommended next steps:'); + p.note(messages.join('\n'), 'Recommended next steps:', { + format: (line) => pc.white(line) + }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ad25f51..4a119bb8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -91,41 +91,14 @@ importers: specifier: workspace:* version: link:../core - packages/clack-core: - devDependencies: - picocolors: - specifier: ^1.1.1 - version: 1.1.1 - sisteransi: - specifier: ^1.0.5 - version: 1.0.5 - wrap-ansi: - specifier: ^8.1.0 - version: 8.1.0 - - packages/clack-prompts: - devDependencies: - '@sveltejs/clack-core': - specifier: workspace:* - version: link:../clack-core - is-unicode-supported: - specifier: ^1.3.0 - version: 1.3.0 - picocolors: - specifier: ^1.1.1 - version: 1.1.1 - sisteransi: - specifier: ^1.0.5 - version: 1.0.5 - packages/cli: devDependencies: + '@clack/prompts': + specifier: ^1.0.0-alpha.0 + version: 1.0.0-alpha.0 '@sveltejs/addons': specifier: workspace:* version: link:../addons - '@sveltejs/clack-prompts': - specifier: workspace:* - version: link:../clack-prompts '@sveltejs/cli-core': specifier: workspace:* version: link:../core @@ -171,12 +144,12 @@ importers: packages/core: devDependencies: + '@clack/prompts': + specifier: ^1.0.0-alpha.0 + version: 1.0.0-alpha.0 '@sveltejs/acorn-typescript': specifier: ^1.0.1 version: 1.0.5(acorn@8.14.1) - '@sveltejs/clack-prompts': - specifier: workspace:* - version: link:../clack-prompts '@types/estree': specifier: ^1.0.6 version: 1.0.7 @@ -238,8 +211,8 @@ importers: packages/migrate: dependencies: '@clack/prompts': - specifier: ^0.9.1 - version: 0.9.1 + specifier: ^1.0.0-alpha.0 + version: 1.0.0-alpha.0 import-meta-resolve: specifier: ^4.1.0 version: 4.1.0 @@ -349,11 +322,11 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} - '@clack/core@0.4.1': - resolution: {integrity: sha512-Pxhij4UXg8KSr7rPek6Zowm+5M22rbd2g1nfojHJkxp5YkFqiZ2+YLEM/XGVIzvGOcM0nqjIFxrpDwWRZYWYjA==} + '@clack/core@1.0.0-alpha.0': + resolution: {integrity: sha512-Cp/bPW/pMUCkJ7Lr8VFixvFrlnJ4tQPDHqfTNQ51z50qwX1fSIAstQLfel2NquVHqbfjyrUkBsal8OJRBPJVjw==} - '@clack/prompts@0.9.1': - resolution: {integrity: sha512-JIpyaboYZeWYlyP0H+OoPPxd6nqueG/CmN6ixBiNFsIDHREevjIf0n0Ohh5gr5C8pEDknzgvz+pIJ8dMhzWIeg==} + '@clack/prompts@1.0.0-alpha.0': + resolution: {integrity: sha512-Aem7r4U2A4jdOh0PIv51Ugi+4vDgzJjGVMnuPUNVVHDGhFHEO//u6F/JY6NsZQFtXrd7ZmfePSiipikr/e5wWg==} '@emnapi/core@1.4.0': resolution: {integrity: sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==} @@ -1579,10 +1552,6 @@ packages: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} - is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -2498,14 +2467,14 @@ snapshots: human-id: 4.1.1 prettier: 2.8.8 - '@clack/core@0.4.1': + '@clack/core@1.0.0-alpha.0': dependencies: picocolors: 1.1.1 sisteransi: 1.0.5 - '@clack/prompts@0.9.1': + '@clack/prompts@1.0.0-alpha.0': dependencies: - '@clack/core': 0.4.1 + '@clack/core': 1.0.0-alpha.0 picocolors: 1.1.1 sisteransi: 1.0.5 @@ -3639,8 +3608,6 @@ snapshots: dependencies: better-path-resolve: 1.0.0 - is-unicode-supported@1.3.0: {} - is-windows@1.0.2: {} isexe@2.0.0: {} diff --git a/rolldown.config.js b/rolldown.config.js index 3ffbb1da..a9eb3aa7 100644 --- a/rolldown.config.js +++ b/rolldown.config.js @@ -118,13 +118,7 @@ function getConfig(project) { } /** @type {RolldownOptions[]} */ -export default [ - getConfig('clack-core'), - getConfig('clack-prompts'), - getConfig('create'), - getConfig('core'), - getConfig('cli') -]; +export default [getConfig('create'), getConfig('core'), getConfig('cli')]; /** * @param {PackageJson} pkg From c3810510dd0144d9885b7a8eb1261959fed3545b Mon Sep 17 00:00:00 2001 From: Manuel <30698007+manuel3108@users.noreply.github.com> Date: Sat, 17 May 2025 17:18:40 +0200 Subject: [PATCH 24/38] feat: expose `runsAfter` to add-ons (#554) --- .changeset/loose-colts-sin.md | 5 +++++ packages/addons/storybook/index.ts | 4 ++++ packages/cli/lib/install.ts | 17 +++++++++-------- packages/core/addon/config.ts | 3 ++- 4 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 .changeset/loose-colts-sin.md diff --git a/.changeset/loose-colts-sin.md b/.changeset/loose-colts-sin.md new file mode 100644 index 00000000..627bfd30 --- /dev/null +++ b/.changeset/loose-colts-sin.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +feat: expose `runsAfter` to add-ons diff --git a/packages/addons/storybook/index.ts b/packages/addons/storybook/index.ts index d75ffcf0..ad35e16d 100644 --- a/packages/addons/storybook/index.ts +++ b/packages/addons/storybook/index.ts @@ -6,6 +6,10 @@ export default defineAddon({ shortDescription: 'frontend workshop', homepage: 'https://storybook.js.org', options: {}, + setup: ({ runsAfter }) => { + runsAfter('vitest'); + runsAfter('eslint'); + }, run: async ({ sv }) => { await sv.execute(['storybook@latest', 'init', '--skip-install', '--no-dev'], 'inherit'); sv.devDependency(`@types/node`, getNodeTypesVersion()); diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 6574130b..958a8ee4 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -87,11 +87,15 @@ export function setupAddons( const addonSetupResults: Record = {}; for (const addon of addons) { - const setupResult: AddonSetupResult = { unsupported: [], dependsOn: [] }; + const setupResult: AddonSetupResult = { unsupported: [], dependsOn: [], runsAfter: [] }; addon.setup?.({ ...workspace, - dependsOn: (name) => setupResult.dependsOn.push(name), - unsupported: (reason) => setupResult.unsupported.push(reason) + dependsOn: (name) => { + setupResult.dependsOn.push(name); + setupResult.runsAfter.push(name); + }, + unsupported: (reason) => setupResult.unsupported.push(reason), + runsAfter: (name) => setupResult.runsAfter.push(name) }); addonSetupResults[addon.id] = setupResult; } @@ -181,13 +185,10 @@ async function runAddon({ addon, multiple, workspace }: RunAddon) { } // orders addons by putting addons that don't require any other addon in the front. -// This is a drastic simplification, as this could still cause some inconvenient cituations, +// This is a drastic simplification, as this could still cause some inconvenient circumstances, // but works for now in contrary to the previous implementation function orderAddons(addons: Array>, setupResults: Record) { return addons.sort((a, b) => { - // Adding storybook last means it will correctly detect and integrate with other addons like vitest and eslint - if (a.id === 'storybook') return 1; - if (b.id === 'storybook') return -1; - return setupResults[a.id]?.dependsOn?.length - setupResults[b.id]?.dependsOn?.length; + return setupResults[a.id]?.runsAfter?.length - setupResults[b.id]?.runsAfter?.length; }); } diff --git a/packages/core/addon/config.ts b/packages/core/addon/config.ts index be36f777..fbce3775 100644 --- a/packages/core/addon/config.ts +++ b/packages/core/addon/config.ts @@ -37,6 +37,7 @@ export type Addon = { workspace: Workspace & { dependsOn: (name: string) => void; unsupported: (reason: string) => void; + runsAfter: (addonName: string) => void; } ) => MaybePromise; run: (workspace: Workspace & { sv: SvApi }) => MaybePromise; @@ -59,7 +60,7 @@ export function defineAddon(config: Addon): return config; } -export type AddonSetupResult = { dependsOn: string[]; unsupported: string[] }; +export type AddonSetupResult = { dependsOn: string[]; unsupported: string[]; runsAfter: string[] }; export type AddonWithoutExplicitArgs = Addon>; export type AddonConfigWithoutExplicitArgs = Addon>; From c2302467a057ae21afa617e0ccd26946022624a6 Mon Sep 17 00:00:00 2001 From: Brett <100062845+brettearle@users.noreply.github.com> Date: Sun, 18 May 2025 00:52:57 +0930 Subject: [PATCH 25/38] fix:Tailwind style to lucia login (#540) * Tailwind style to lucia login * Tailwind classes added to lucia demo when tailwind present in dependencies * Tailwind classes added to lucia demo when tailwind present in dependencies + formatted nicer * Fix build issue with missing quote * make optional dependency to tailwindcss explicit --------- Co-authored-by: Manuel Serret --- packages/addons/lucia/index.ts | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/addons/lucia/index.ts b/packages/addons/lucia/index.ts index 355cdea2..b3b323fd 100644 --- a/packages/addons/lucia/index.ts +++ b/packages/addons/lucia/index.ts @@ -38,9 +38,11 @@ export default defineAddon({ shortDescription: 'auth guide', homepage: 'https://lucia-auth.com', options, - setup: ({ kit, dependencyVersion, unsupported, dependsOn }) => { + setup: ({ kit, dependencyVersion, unsupported, dependsOn, runsAfter }) => { if (!kit) unsupported('Requires SvelteKit'); if (!dependencyVersion('drizzle-orm')) dependsOn('drizzle'); + + runsAfter('tailwindcss'); }, run: ({ sv, typescript, options, kit, dependencyVersion }) => { const ext = typescript ? 'ts' : 'js'; @@ -505,6 +507,12 @@ export default defineAddon({ return content; } + const tailwind = dependencyVersion('@tailwindcss/vite') !== undefined; + const twInputClasses = + 'class="mt-1 px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"'; + const twBtnClasses = + 'class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition"'; + const svelte5 = !!dependencyVersion('svelte')?.startsWith('5'); const [ts, s5] = utils.createPrinter(typescript, svelte5); return dedent` @@ -515,17 +523,28 @@ export default defineAddon({

Login/Register

-
+ - - + +

{form?.message ?? ''}

`; From ca07fcd3134ba3c3f205b37aab68182fbe98455a Mon Sep 17 00:00:00 2001 From: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 17 May 2025 11:26:51 -0400 Subject: [PATCH 26/38] feat: specify add-on options in command args (#543) * rename language tags * specify add-on options as command args * fix check * implement `addon=option:value` variant * separate questions by `+` * update add-on docs * remove quotes * fix --- documentation/docs/30-add-ons/05-drizzle.md | 9 +- documentation/docs/30-add-ons/15-lucia.md | 2 +- documentation/docs/30-add-ons/25-paraglide.md | 6 +- .../docs/30-add-ons/45-sveltekit-adapter.md | 2 +- documentation/docs/30-add-ons/50-tailwind.md | 2 +- packages/addons/_tests/paraglide/test.ts | 2 +- packages/addons/paraglide/index.ts | 8 +- packages/cli/commands/add/index.ts | 260 ++++++++++++------ packages/cli/commands/create.ts | 8 +- 9 files changed, 200 insertions(+), 99 deletions(-) diff --git a/documentation/docs/30-add-ons/05-drizzle.md b/documentation/docs/30-add-ons/05-drizzle.md index 7cf06ca9..97766fde 100644 --- a/documentation/docs/30-add-ons/05-drizzle.md +++ b/documentation/docs/30-add-ons/05-drizzle.md @@ -28,7 +28,7 @@ Which database variant to use: - `sqlite` — file-based database not requiring a database server ```bash -npx sv add --drizzle=postgresql +npx sv add drizzle=database:postgresql ``` ### client @@ -40,7 +40,7 @@ The SQL client to use, depends on `database`: - For `sqlite`: `better-sqlite3`, `libsql`, `turso` ```bash -npx sv add --drizzle=postgresql,postgres.js +npx sv add drizzle=database:postgresql+client:postgres.js ``` Drizzle is compatible with well over a dozen database drivers. We just offer a few of the most common ones here for simplicity, but if you'd like to use another one you can choose one as a placeholder and swap it out for another after setup by choosing from [Drizzle's full list of compatible drivers](https://orm.drizzle.team/docs/connect-overview#next-steps). @@ -49,9 +49,6 @@ Drizzle is compatible with well over a dozen database drivers. We just offer a f Whether to add Docker Compose configuration. Only available for [`database`](#Options-database) `postgresql` or `mysql` -- `docker` - generates `docker-compose.yml` -- `no-docker` - does not generate docker config - ```bash -npx sv add --drizzle=postgresql,postgres.js,docker +npx sv add drizzle=database:postgresql+client:postgres.js+docker:yes ``` diff --git a/documentation/docs/30-add-ons/15-lucia.md b/documentation/docs/30-add-ons/15-lucia.md index 2eb21f9e..eb7b68e1 100644 --- a/documentation/docs/30-add-ons/15-lucia.md +++ b/documentation/docs/30-add-ons/15-lucia.md @@ -22,5 +22,5 @@ npx sv add lucia Whether to include demo registration and login pages. ```bash -npx sv add --lucia=demo +npx sv add lucia=demo:yes ``` diff --git a/documentation/docs/30-add-ons/25-paraglide.md b/documentation/docs/30-add-ons/25-paraglide.md index be006f27..e4658e0f 100644 --- a/documentation/docs/30-add-ons/25-paraglide.md +++ b/documentation/docs/30-add-ons/25-paraglide.md @@ -21,12 +21,12 @@ npx sv add paraglide ## Options -### availableLanguageTags +### languageTags The languages you'd like to support specified as IETF BCP 47 language tags. ```bash -npx sv add --paraglide=en,es +npx sv add paraglide="languageTags:en,es" ``` ### demo @@ -34,5 +34,5 @@ npx sv add --paraglide=en,es Whether to generate an optional demo page showing how to use paraglide. ```bash -npx sv add --paraglide=demo +npx sv add paraglide="demo:yes" ``` diff --git a/documentation/docs/30-add-ons/45-sveltekit-adapter.md b/documentation/docs/30-add-ons/45-sveltekit-adapter.md index d9012752..1bc77cc6 100644 --- a/documentation/docs/30-add-ons/45-sveltekit-adapter.md +++ b/documentation/docs/30-add-ons/45-sveltekit-adapter.md @@ -28,5 +28,5 @@ Which SvelteKit adapter to use: - `netlify` — [`@sveltejs/adapter-netlify`](/docs/kit/adapter-netlify) allows you to deploy to Netlify ```bash -npx sv add --sveltekit-adapter=node +npx sv add sveltekit-adapter=adapter:node ``` diff --git a/documentation/docs/30-add-ons/50-tailwind.md b/documentation/docs/30-add-ons/50-tailwind.md index 1b454a22..a0926b51 100644 --- a/documentation/docs/30-add-ons/50-tailwind.md +++ b/documentation/docs/30-add-ons/50-tailwind.md @@ -27,5 +27,5 @@ Which plugin to use: - `forms` — [`@tailwindcss/forms`](https://github.com/tailwindlabs/tailwindcss-forms) ```bash -npx sv add --tailwindcss=typography +npx sv add tailwindcss="plugins:typography" ``` diff --git a/packages/addons/_tests/paraglide/test.ts b/packages/addons/_tests/paraglide/test.ts index e2d2ac01..67c68eff 100644 --- a/packages/addons/_tests/paraglide/test.ts +++ b/packages/addons/_tests/paraglide/test.ts @@ -6,7 +6,7 @@ const { test, variants, prepareServer } = setupTest({ paraglide }); const kitOnly = variants.filter((v) => v.includes('kit')); test.concurrent.for(kitOnly)('core - %s', async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { paraglide: { demo: true, availableLanguageTags: 'en' } }); + const cwd = await ctx.run(variant, { paraglide: { demo: true, languageTags: 'en' } }); const { close } = await prepareServer({ cwd, page }); // kill server process when we're done diff --git a/packages/addons/paraglide/index.ts b/packages/addons/paraglide/index.ts index 822b30a7..455ee24b 100644 --- a/packages/addons/paraglide/index.ts +++ b/packages/addons/paraglide/index.ts @@ -26,7 +26,7 @@ const DEFAULT_INLANG_PROJECT = { }; const options = defineAddonOptions({ - availableLanguageTags: { + languageTags: { question: `Which languages would you like to support? ${colors.gray('(e.g. en,de-ch)')}`, type: 'string', default: 'en, es', @@ -78,7 +78,7 @@ export default defineAddon({ for (const key in DEFAULT_INLANG_PROJECT) { data[key] = DEFAULT_INLANG_PROJECT[key as keyof typeof DEFAULT_INLANG_PROJECT]; } - const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); + const { validLanguageTags } = parseLanguageTagInput(options.languageTags); const baseLocale = validLanguageTags[0]; data.baseLocale = baseLocale; @@ -205,7 +205,7 @@ export default defineAddon({ // add links to other localized pages, the first one is the default // language, thus it does not require any localized route - const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); + const { validLanguageTags } = parseLanguageTagInput(options.languageTags); const links = validLanguageTags .map( (x) => @@ -222,7 +222,7 @@ export default defineAddon({ }); } - const { validLanguageTags } = parseLanguageTagInput(options.availableLanguageTags); + const { validLanguageTags } = parseLanguageTagInput(options.languageTags); for (const languageTag of validLanguageTags) { sv.file(`messages/${languageTag}.json`, (content) => { const { data, generateCode } = parseJson(content); diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index a6795911..d0670c89 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -5,7 +5,7 @@ import pc from 'picocolors'; import * as v from 'valibot'; import * as pkg from 'empathic/package'; import * as p from '@clack/prompts'; -import { Command, Option } from 'commander'; +import { Command } from 'commander'; import { officialAddons, getAddonDetails, @@ -29,41 +29,149 @@ import { getGlobalPreconditions } from './preconditions.ts'; import { type AddonMap, applyAddons, setupAddons } from '../../lib/install.ts'; const aliases = officialAddons.map((c) => c.alias).filter((v) => v !== undefined); -const addonsOptions = getAddonOptionFlags(); +const addonOptions = getAddonOptionFlags(); const communityDetails: AddonWithoutExplicitArgs[] = []; -const OptionFlagSchema = v.optional(v.array(v.string())); - -const addonOptionFlags = addonsOptions.reduce( - (flags, opt) => Object.assign(flags, { [opt.attributeName()]: OptionFlagSchema }), - {} -); - const AddonsSchema = v.array(v.string()); -const AddonOptionFlagsSchema = v.object(addonOptionFlags); const OptionsSchema = v.strictObject({ cwd: v.string(), install: v.union([v.boolean(), v.picklist(AGENT_NAMES)]), preconditions: v.boolean(), community: v.optional(v.union([AddonsSchema, v.boolean()])), - ...AddonOptionFlagsSchema.entries + addons: v.record(v.string(), v.optional(v.array(v.string()))) }); type Options = v.InferOutput; +type AddonArgs = { id: string; options: string[] | undefined }; + // infers the workspace cwd if a `package.json` resides in a parent directory const defaultPkgPath = pkg.up(); const defaultCwd = defaultPkgPath ? path.dirname(defaultPkgPath) : undefined; - export const add = new Command('add') .description('applies specified add-ons into a project') - .argument('[add-on...]', 'add-ons to install') + .argument('[add-on...]', `add-ons to install`, (value, prev: AddonArgs[] = []) => { + const [addonId, optionFlags] = value.split('=', 2); + + // validates that there are no repeated add-ons (e.g. `sv add foo=demo:yes foo=demo:no`) + const repeatedAddons = prev.find(({ id }) => id === addonId); + if (repeatedAddons) { + console.error(`Malformed arguments: Add-on '${addonId}' is repeated multiple times.`); + process.exit(1); + } + + // occurs when an `=` isn't present (e.g. `sv add foo`) + if (optionFlags === undefined) { + prev.push({ id: addonId, options: undefined }); + return prev; + } + + // validates that the options are relatively well-formed. + // occurs when no or is specified (e.g. `sv add foo=demo`). + if (optionFlags.length > 0 && !/.+:.*/.test(optionFlags)) { + console.error( + `Malformed arguments: An add-on's option in '${value}' is missing it's option name or value (e.g. 'addon=option:value').` + ); + process.exit(1); + } + + // parses the option flags into a array of `:` strings + const options: string[] = optionFlags.match(/[^+]*:[^:]*(?=\+|$)/g) ?? []; + + prev.push({ id: addonId, options }); + return prev; + }) .option('-C, --cwd ', 'path to working directory', defaultCwd) .option('--no-preconditions', 'skip validating preconditions') .option('--no-install', 'skip installing dependencies') .addOption(installOption) //.option('--community [add-on...]', 'community addons to install') - .configureHelp(common.helpConfig) - .action((addonArgs, opts) => { + .configureHelp({ + ...common.helpConfig, + formatHelp(cmd, helper) { + const termWidth = helper.padWidth(cmd, helper); + const helpWidth = helper.helpWidth ?? 80; // in case prepareContext() was not called + + function callFormatItem(term: string, description: string) { + return helper.formatItem(term, termWidth, description, helper); + } + + // Usage + let output = [ + `${helper.styleTitle('Usage:')} ${helper.styleUsage(helper.commandUsage(cmd))}`, + '' + ]; + + // Description + const commandDescription = helper.commandDescription(cmd); + if (commandDescription.length > 0) { + output = output.concat([ + helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth), + '' + ]); + } + + // Arguments + const argumentList = helper.visibleArguments(cmd).map((argument) => { + return callFormatItem( + helper.styleArgumentTerm(helper.argumentTerm(argument)), + helper.styleArgumentDescription(helper.argumentDescription(argument)) + ); + }); + if (argumentList.length > 0) { + output = output.concat([helper.styleTitle('Arguments:'), ...argumentList, '']); + } + + // Addon Options + const addonList = addonOptions.map((option) => { + // const description = `${pc.dim(`(preset: ${option.preset})`)}\n${option.choices}`; + const description = option.choices; + return callFormatItem( + helper.styleArgumentTerm(option.id), + helper.styleArgumentDescription(description) + ); + }); + if (addonList.length > 0) { + output = output.concat([helper.styleTitle('Add-On Options:'), ...addonList, '']); + } + + // Options + const optionList = helper.visibleOptions(cmd).map((option) => { + return callFormatItem( + helper.styleOptionTerm(helper.optionTerm(option)), + helper.styleOptionDescription(helper.optionDescription(option)) + ); + }); + if (optionList.length > 0) { + output = output.concat([helper.styleTitle('Options:'), ...optionList, '']); + } + + if (helper.showGlobalOptions) { + const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => { + return callFormatItem( + helper.styleOptionTerm(helper.optionTerm(option)), + helper.styleOptionDescription(helper.optionDescription(option)) + ); + }); + if (globalOptionList.length > 0) { + output = output.concat([helper.styleTitle('Global Options:'), ...globalOptionList, '']); + } + } + + // Commands + const commandList = helper.visibleCommands(cmd).map((cmd) => { + return callFormatItem( + helper.styleSubcommandTerm(helper.subcommandTerm(cmd)), + helper.styleSubcommandDescription(helper.subcommandDescription(cmd)) + ); + }); + if (commandList.length > 0) { + output = output.concat([helper.styleTitle('Commands:'), ...commandList, '']); + } + + return output.join('\n'); + } + }) + .action((addonArgs: AddonArgs[], opts) => { // validate workspace if (opts.cwd === undefined) { console.error( @@ -78,29 +186,26 @@ export const add = new Command('add') process.exit(1); } - const specifiedAddons = v.parse(AddonsSchema, addonArgs); - const options = v.parse(OptionsSchema, opts); const addonIds = officialAddons.map((addon) => addon.id); - const invalidAddons = specifiedAddons.filter( - (a) => !addonIds.includes(a) && !aliases.includes(a) - ); + const invalidAddons = addonArgs + .filter(({ id }) => !addonIds.includes(id) && !aliases.includes(id)) + .map(({ id }) => id); if (invalidAddons.length > 0) { console.error(`Invalid add-ons specified: ${invalidAddons.join(', ')}`); process.exit(1); } - const selectedAddons = transformAliases(specifiedAddons); + const options = v.parse(OptionsSchema, { ...opts, addons: {} }); + const selectedAddons = transformAliases(addonArgs); + selectedAddons.forEach((addon) => (options.addons[addon.id] = addon.options)); + common.runCommand(async () => { - const { nextSteps } = await runAddCommand(options, selectedAddons); + const selectedAddonIds = selectedAddons.map(({ id }) => id); + const { nextSteps } = await runAddCommand(options, selectedAddonIds); if (nextSteps) p.note(nextSteps, 'Next steps', { format: (line) => line }); }); }); -// adds addon specific option flags to the `add` command -for (const option of addonsOptions) { - add.addOption(option); -} - type SelectedAddon = { type: 'official' | 'community'; addon: AddonWithoutExplicitArgs }; export async function runAddCommand( options: Options, @@ -119,11 +224,9 @@ export async function runAddCommand( const community: AddonOption = {}; // apply specified options from flags - for (const addonOption of addonsOptions) { - const addonId = addonOption.name() as keyof Options; - // if the add-on flag contains a `-`, it'll be camelcased (e.g. `sveltekit-adapter` is `sveltekitAdapter`) - const aliased = addonOption.attributeName() as keyof Options; - const specifiedOptions = (options[addonId] || options[aliased]) as string[] | undefined; + for (const addonOption of addonOptions) { + const addonId = addonOption.id; + const specifiedOptions = options.addons[addonId]; if (!specifiedOptions) continue; const details = getAddonDetails(addonId); @@ -134,42 +237,44 @@ export async function runAddCommand( official[addonId] ??= {}; const optionEntries = Object.entries(details.options); - for (const specifiedOption of specifiedOptions) { - // we'll skip empty string and `none` options so that default values can be applied later - if (!specifiedOption || specifiedOption === 'none') continue; - - // figure out which option it belongs to - const optionEntry = optionEntries.find(([id, question]) => { - if (question.type === 'boolean') { - return id === specifiedOption || `no-${id}` === specifiedOption; - } - if (question.type === 'select' || question.type === 'multiselect') { - return question.options.some((o) => o.value === specifiedOption); - } - }); + for (const option of specifiedOptions) { + let [optionId, optionValue] = option.split(':', 2); + + // validates that the option exists + const optionEntry = optionEntries.find( + ([id, question]) => id === optionId || question.group === optionId + ); if (!optionEntry) { const { choices } = getOptionChoices(details); throw new Error( - `Invalid '--${addonId}' option: '${specifiedOption}'\nAvailable options: ${choices.join(', ')}` + `Invalid '${addonId}' option: '${option}'\nAvailable options: ${choices.join(', ')}` ); } const [questionId, question] = optionEntry; + // multiselect options can be specified with a `none` option, which equates to an empty string + if (question.type === 'multiselect' && optionValue === 'none') optionValue = ''; + // validate that there are no conflicts let existingOption = official[addonId][questionId]; if (existingOption !== undefined) { if (typeof existingOption === 'boolean') { - // need to transform the boolean back to `no-{id}` or `{id}` - existingOption = existingOption ? questionId : `no-${questionId}`; + // need to transform the boolean back to `yes` or `no` + existingOption = existingOption ? 'yes' : 'no'; } throw new Error( - `Conflicting '--${addonId}' option: '${specifiedOption}' conflicts with '${existingOption}'` + `Conflicting '${addonId}' option: '${option}' conflicts with '${questionId}:${existingOption}'` ); } - official[addonId][questionId] = - question.type === 'boolean' ? !specifiedOption.startsWith('no-') : specifiedOption; + if (question.type === 'boolean') { + official[addonId][questionId] = optionValue === 'yes'; + } else if (question.type === 'number') { + official[addonId][questionId] = Number(optionValue); + } else { + official[addonId][questionId] = optionValue; + } } // apply defaults to unspecified options @@ -178,12 +283,10 @@ export async function runAddCommand( if (question.condition?.(official[addonId]) !== false) { official[addonId][id] ??= question.default; } else { - // we'll also error out if they specified an option that is incompatible with other options. - // (e.g. the client isn't available for a given database `--drizzle sqlite mysql2`) + // we'll also error out if a specified option is incompatible with other options. + // (e.g. `libsql` isn't a valid client for a `mysql` database: `sv add drizzle=database:mysql2,client:libsql`) if (official[addonId][id] !== undefined) { - throw new Error( - `Incompatible '--${addonId}' option specified: '${official[addonId][id]}'` - ); + throw new Error(`Incompatible '${addonId}' option specified: '${official[addonId][id]}'`); } } } @@ -510,21 +613,22 @@ export async function runAddCommand( /** * Dedupes and transforms aliases into their respective addon id */ -function transformAliases(ids: string[]): string[] { - const set = new Set(); - for (const id of ids) { - if (aliases.includes(id)) { - const addon = officialAddons.find((a) => a.alias === id)!; - set.add(addon.id); +function transformAliases(addons: AddonArgs[]): AddonArgs[] { + const set = new Map(); + + for (const addon of addons) { + if (aliases.includes(addon.id)) { + const officialAddon = officialAddons.find((a) => a.alias === addon.id)!; + set.set(officialAddon.id, { id: officialAddon.id, options: addon.options }); } else { - set.add(id); + set.set(addon.id, addon); } } - return Array.from(set); + return Array.from(set.values()); } -function getAddonOptionFlags(): Option[] { - const options: Option[] = []; +function getAddonOptionFlags() { + const options: Array<{ id: string; choices: string; preset: string }> = []; for (const addon of officialAddons) { const id = addon.id; const details = getAddonDetails(id); @@ -535,19 +639,7 @@ function getAddonOptionFlags(): Option[] { .map(([group, choices]) => `${pc.dim(`${group}:`)} ${choices.join(', ')}`) .join('\n'); const preset = defaults.join(', ') || 'none'; - const option = new Option( - `--${id} [options...]`, - `${id} add-on options ${pc.dim(`(preset: ${preset})`)}\n${choices}` - ) - // presets are applied when `--{addonName}` is specified with no options - .preset(preset) - .argParser((value, prev: string[]) => { - prev ??= []; - prev = prev.concat(value.split(/\s|,/)); - return prev; - }); - - options.push(option); + options.push({ id, choices, preset }); } return options; } @@ -561,7 +653,7 @@ function getOptionChoices(details: AddonWithoutExplicitArgs) { let values: string[] = []; const applyDefault = question.condition?.(options) !== false; if (question.type === 'boolean') { - values = [id, `no-${id}`]; + values = ['yes', `no`]; if (applyDefault) { options[id] = question.default; defaults.push((question.default ? values[0] : values[1])!); @@ -581,9 +673,15 @@ function getOptionChoices(details: AddonWithoutExplicitArgs) { defaults.push(...question.default); } } + if (question.type === 'string' || question.type === 'number') { + values = ['']; + if (applyDefault) { + options[id] = question.default; + defaults.push(question.default.toString()); + } + } choices.push(...values); - // we'll fallback to the question's id const groupId = question.group ?? id; groups[groupId] ??= []; diff --git a/packages/cli/commands/create.ts b/packages/cli/commands/create.ts index 6ab92948..5d259c31 100644 --- a/packages/cli/commands/create.ts +++ b/packages/cli/commands/create.ts @@ -177,7 +177,13 @@ async function createProject(cwd: ProjectPath, options: Options) { if (options.addOns) { // `runAddCommand` includes installing dependencies const { nextSteps, packageManager: pm } = await runAddCommand( - { cwd: projectPath, install: options.install, preconditions: false, community: [] }, + { + cwd: projectPath, + install: options.install, + preconditions: false, + community: [], + addons: {} + }, [] ); packageManager = pm; From 956528d6e0ab3822a29ad61e3569adcd8e00ee67 Mon Sep 17 00:00:00 2001 From: Brett <100062845+brettearle@users.noreply.github.com> Date: Sun, 18 May 2025 01:05:16 +0930 Subject: [PATCH 27/38] fix: lucia require user redirect moved to auth guard function (#558) * fix: lucia require user redirect moved to auth guard function * Create clever-chicken-compete.md --------- Co-authored-by: Manuel <30698007+manuel3108@users.noreply.github.com> --- .changeset/clever-chicken-compete.md | 5 +++++ packages/addons/lucia/index.ts | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 .changeset/clever-chicken-compete.md diff --git a/.changeset/clever-chicken-compete.md b/.changeset/clever-chicken-compete.md new file mode 100644 index 00000000..fb9f95f6 --- /dev/null +++ b/.changeset/clever-chicken-compete.md @@ -0,0 +1,5 @@ +--- +"sv": patch +--- + +fix: lucia require user redirect moved to auth guard function diff --git a/packages/addons/lucia/index.ts b/packages/addons/lucia/index.ts index b3b323fd..d9791328 100644 --- a/packages/addons/lucia/index.ts +++ b/packages/addons/lucia/index.ts @@ -561,12 +561,11 @@ export default defineAddon({ return dedent` import * as auth from '$lib/server/auth'; import { fail, redirect } from '@sveltejs/kit'; + import { getRequestEvent } from '$app/server'; ${ts("import type { Actions, PageServerLoad } from './$types';\n")} - export const load${ts(': PageServerLoad')} = async (event) => { - if (!event.locals.user) { - return redirect(302, '/demo/lucia/login'); - } - return { user: event.locals.user }; + export const load${ts(': PageServerLoad')} = async () => { + const user = requireLogin() + return { user }; }; export const actions${ts(': Actions')} = { @@ -580,6 +579,16 @@ export default defineAddon({ return redirect(302, '/demo/lucia/login'); }, }; + + function requireLogin() { + const { locals } = getRequestEvent(); + + if (!locals.user) { + return redirect(302, "/demo/lucia/login"); + } + + return locals.user; + } `; }); From 7438f8c2add0a62e3922a82528d62930facda075 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 17:42:38 +0200 Subject: [PATCH 28/38] Version Packages (#562) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/clever-chicken-compete.md | 5 ----- .changeset/loose-colts-sin.md | 5 ----- packages/cli/CHANGELOG.md | 9 +++++++++ packages/cli/package.json | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) delete mode 100644 .changeset/clever-chicken-compete.md delete mode 100644 .changeset/loose-colts-sin.md diff --git a/.changeset/clever-chicken-compete.md b/.changeset/clever-chicken-compete.md deleted file mode 100644 index fb9f95f6..00000000 --- a/.changeset/clever-chicken-compete.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"sv": patch ---- - -fix: lucia require user redirect moved to auth guard function diff --git a/.changeset/loose-colts-sin.md b/.changeset/loose-colts-sin.md deleted file mode 100644 index 627bfd30..00000000 --- a/.changeset/loose-colts-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -feat: expose `runsAfter` to add-ons diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 7492d294..3eb90e77 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,14 @@ # sv +## 0.8.4 +### Patch Changes + + +- fix: lucia require user redirect moved to auth guard function ([#558](https://github.com/sveltejs/cli/pull/558)) + + +- feat: expose `runsAfter` to add-ons ([#554](https://github.com/sveltejs/cli/pull/554)) + ## 0.8.3 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 1fa2ef4b..01dba37d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "sv", - "version": "0.8.3", + "version": "0.8.4", "type": "module", "description": "A CLI for creating and updating SvelteKit projects", "license": "MIT", From 83af4280fb96c58e15780e8b2f3c0afee7f4bea4 Mon Sep 17 00:00:00 2001 From: Manuel <30698007+manuel3108@users.noreply.github.com> Date: Sat, 17 May 2025 19:02:33 +0200 Subject: [PATCH 29/38] fix: revert clack unfork (#564) * Revert "chore: unfork clack (#526)" This reverts commit 30c09ac985b60539411bb192cb1769bc73a46d17. * changeset * remvoed unused import --- .changeset/chilly-clocks-run.md | 5 + packages/clack-core/LICENSE | 23 + packages/clack-core/README.md | 22 + packages/clack-core/index.ts | 10 + packages/clack-core/package.json | 34 + packages/clack-core/src/prompts/confirm.ts | 37 + .../src/prompts/group-multiselect.ts | 82 ++ .../clack-core/src/prompts/multi-select.ts | 60 ++ packages/clack-core/src/prompts/password.ts | 33 + packages/clack-core/src/prompts/prompt.ts | 273 ++++++ packages/clack-core/src/prompts/select-key.ts | 27 + packages/clack-core/src/prompts/select.ts | 41 + packages/clack-core/src/prompts/text.ts | 33 + packages/clack-core/src/utils.ts | 60 ++ packages/clack-core/tsconfig.json | 8 + packages/clack-prompts/LICENSE | 23 + packages/clack-prompts/README.md | 174 ++++ packages/clack-prompts/index.ts | 894 ++++++++++++++++++ packages/clack-prompts/package.json | 34 + packages/clack-prompts/tsconfig.json | 8 + packages/cli/commands/add/index.ts | 6 +- packages/cli/commands/create.ts | 6 +- packages/cli/lib/install.ts | 2 +- packages/cli/package.json | 2 +- packages/cli/utils/common.ts | 2 +- packages/cli/utils/package-manager.ts | 15 +- packages/core/index.ts | 2 +- packages/core/package.json | 2 +- packages/migrate/package.json | 2 +- packages/migrate/utils.js | 4 +- pnpm-lock.yaml | 63 +- rolldown.config.js | 8 +- 32 files changed, 1954 insertions(+), 41 deletions(-) create mode 100644 .changeset/chilly-clocks-run.md create mode 100644 packages/clack-core/LICENSE create mode 100644 packages/clack-core/README.md create mode 100644 packages/clack-core/index.ts create mode 100644 packages/clack-core/package.json create mode 100644 packages/clack-core/src/prompts/confirm.ts create mode 100644 packages/clack-core/src/prompts/group-multiselect.ts create mode 100644 packages/clack-core/src/prompts/multi-select.ts create mode 100644 packages/clack-core/src/prompts/password.ts create mode 100644 packages/clack-core/src/prompts/prompt.ts create mode 100644 packages/clack-core/src/prompts/select-key.ts create mode 100644 packages/clack-core/src/prompts/select.ts create mode 100644 packages/clack-core/src/prompts/text.ts create mode 100644 packages/clack-core/src/utils.ts create mode 100644 packages/clack-core/tsconfig.json create mode 100644 packages/clack-prompts/LICENSE create mode 100644 packages/clack-prompts/README.md create mode 100644 packages/clack-prompts/index.ts create mode 100644 packages/clack-prompts/package.json create mode 100644 packages/clack-prompts/tsconfig.json diff --git a/.changeset/chilly-clocks-run.md b/.changeset/chilly-clocks-run.md new file mode 100644 index 00000000..0ff0f71b --- /dev/null +++ b/.changeset/chilly-clocks-run.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix: directory selection placeholder value was taken as folder path diff --git a/packages/clack-core/LICENSE b/packages/clack-core/LICENSE new file mode 100644 index 00000000..a95d8e47 --- /dev/null +++ b/packages/clack-core/LICENSE @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) Nate Moore + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +`ansi-regex` is adapted from https://github.com/chalk/ansi-regex + +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/clack-core/README.md b/packages/clack-core/README.md new file mode 100644 index 00000000..57ac05f2 --- /dev/null +++ b/packages/clack-core/README.md @@ -0,0 +1,22 @@ +# `@clack/core` + +Clack contains low-level primitives for implementing your own command-line applications. + +Currently, `TextPrompt`, `SelectPrompt`, and `ConfirmPrompt` are exposed as well as the base `Prompt` class. + +Each `Prompt` accepts a `render` function. + +```js +import { TextPrompt, isCancel } from '@clack/core'; + +const p = new TextPrompt({ + render() { + return `What's your name?\n${this.valueWithCursor}`; + } +}); + +const name = await p.prompt(); +if (isCancel(name)) { + process.exit(0); +} +``` diff --git a/packages/clack-core/index.ts b/packages/clack-core/index.ts new file mode 100644 index 00000000..37313080 --- /dev/null +++ b/packages/clack-core/index.ts @@ -0,0 +1,10 @@ +export { default as ConfirmPrompt } from './src/prompts/confirm.ts'; +export { default as GroupMultiSelectPrompt } from './src/prompts/group-multiselect.ts'; +export { default as MultiSelectPrompt } from './src/prompts/multi-select.ts'; +export { default as PasswordPrompt } from './src/prompts/password.ts'; +export { default as Prompt, isCancel } from './src/prompts/prompt.ts'; +export type { State } from './src/prompts/prompt.ts'; +export { default as SelectPrompt } from './src/prompts/select.ts'; +export { default as SelectKeyPrompt } from './src/prompts/select-key.ts'; +export { default as TextPrompt } from './src/prompts/text.ts'; +export { block } from './src/utils.ts'; diff --git a/packages/clack-core/package.json b/packages/clack-core/package.json new file mode 100644 index 00000000..4727de98 --- /dev/null +++ b/packages/clack-core/package.json @@ -0,0 +1,34 @@ +{ + "name": "@sveltejs/clack-core", + "private": true, + "version": "0.4.2", + "type": "module", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/sveltejs/cli/tree/main/packages/clack-prompts" + }, + "bugs": "https://github.com/sveltejs/cli/issues", + "scripts": { + "check": "tsc", + "format": "pnpm lint --write", + "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore" + }, + "files": [ + "dist" + ], + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./package.json": "./package.json" + }, + "devDependencies": { + "picocolors": "^1.1.1", + "sisteransi": "^1.0.5", + "wrap-ansi": "^8.1.0" + } +} diff --git a/packages/clack-core/src/prompts/confirm.ts b/packages/clack-core/src/prompts/confirm.ts new file mode 100644 index 00000000..50e2a8a9 --- /dev/null +++ b/packages/clack-core/src/prompts/confirm.ts @@ -0,0 +1,37 @@ +import { cursor } from 'sisteransi'; +import Prompt, { type PromptOptions } from './prompt.ts'; + +interface ConfirmOptions extends PromptOptions { + active: string; + inactive: string; + initialValue?: boolean; +} +export default class ConfirmPrompt extends Prompt { + get cursor(): 0 | 1 { + return this.value ? 0 : 1; + } + + private get _value() { + return this.cursor === 0; + } + + constructor(opts: ConfirmOptions) { + super(opts, false); + this.value = opts.initialValue ? true : false; + + this.on('value', () => { + this.value = this._value; + }); + + this.on('confirm', (confirm) => { + this.output.write(cursor.move(0, -1)); + this.value = confirm; + this.state = 'submit'; + this.close(); + }); + + this.on('cursor', () => { + this.value = !this.value; + }); + } +} diff --git a/packages/clack-core/src/prompts/group-multiselect.ts b/packages/clack-core/src/prompts/group-multiselect.ts new file mode 100644 index 00000000..e0601f44 --- /dev/null +++ b/packages/clack-core/src/prompts/group-multiselect.ts @@ -0,0 +1,82 @@ +import Prompt, { type PromptOptions } from './prompt.ts'; + +interface GroupMultiSelectOptions + extends PromptOptions> { + options: Record; + initialValues?: Array; + required?: boolean; + cursorAt?: T['value']; + selectableGroups?: boolean; +} +export default class GroupMultiSelectPrompt extends Prompt { + options: Array; + cursor: number = 0; + #selectableGroups: boolean; + + getGroupItems(group: string): T[] { + return this.options.filter((o) => o.group === group); + } + + isGroupSelected(group: string): boolean { + const items = this.getGroupItems(group); + return this.#selectableGroups && items.every((i) => this.value.includes(i.value)); + } + + private toggleValue() { + const item = this.options[this.cursor]!; + if (item.group === true) { + const group = item.value; + const groupedItems = this.getGroupItems(group); + if (this.isGroupSelected(group)) { + this.value = this.value.filter( + (v: string) => groupedItems.findIndex((i) => i.value === v) === -1 + ); + } else { + this.value = [...this.value, ...groupedItems.map((i) => i.value)]; + } + this.value = Array.from(new Set(this.value)); + } else { + const selected = this.value.includes(item.value); + this.value = selected + ? this.value.filter((v: T['value']) => v !== item.value) + : [...this.value, item.value]; + } + } + + constructor(opts: GroupMultiSelectOptions) { + super(opts, false); + const { options } = opts; + this.#selectableGroups = opts.selectableGroups ?? true; + this.options = Object.entries(options).flatMap(([key, option]) => [ + { value: key, group: true, label: key }, + ...option.map((opt) => ({ ...opt, group: key })) + ]) as any; + this.value = [...(opts.initialValues ?? [])]; + this.cursor = Math.max( + this.options.findIndex(({ value }) => value === opts.cursorAt), + this.#selectableGroups ? 0 : 1 + ); + + this.on('cursor', (key) => { + switch (key) { + case 'left': + case 'up': + this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; + if (!this.#selectableGroups && this.options[this.cursor]!.group === true) { + this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; + } + break; + case 'down': + case 'right': + this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; + if (!this.#selectableGroups && this.options[this.cursor]!.group === true) { + this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; + } + break; + case 'space': + this.toggleValue(); + break; + } + }); + } +} diff --git a/packages/clack-core/src/prompts/multi-select.ts b/packages/clack-core/src/prompts/multi-select.ts new file mode 100644 index 00000000..d708d50e --- /dev/null +++ b/packages/clack-core/src/prompts/multi-select.ts @@ -0,0 +1,60 @@ +import Prompt, { type PromptOptions } from './prompt.ts'; + +interface MultiSelectOptions extends PromptOptions> { + options: T[]; + initialValues?: Array; + required?: boolean; + cursorAt?: T['value']; +} +export default class MultiSelectPrompt extends Prompt { + options: T[]; + cursor: number = 0; + + private get _value() { + return this.options[this.cursor]!.value; + } + + private toggleAll() { + const allSelected = this.value.length === this.options.length; + this.value = allSelected ? [] : this.options.map((v) => v.value); + } + + private toggleValue() { + const selected = this.value.includes(this._value); + this.value = selected + ? this.value.filter((value: T['value']) => value !== this._value) + : [...this.value, this._value]; + } + + constructor(opts: MultiSelectOptions) { + super(opts, false); + + this.options = opts.options; + this.value = [...(opts.initialValues ?? [])]; + this.cursor = Math.max( + this.options.findIndex(({ value }) => value === opts.cursorAt), + 0 + ); + this.on('key', (char) => { + if (char === 'a') { + this.toggleAll(); + } + }); + + this.on('cursor', (key) => { + switch (key) { + case 'left': + case 'up': + this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; + break; + case 'down': + case 'right': + this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; + break; + case 'space': + this.toggleValue(); + break; + } + }); + } +} diff --git a/packages/clack-core/src/prompts/password.ts b/packages/clack-core/src/prompts/password.ts new file mode 100644 index 00000000..fa2c55ce --- /dev/null +++ b/packages/clack-core/src/prompts/password.ts @@ -0,0 +1,33 @@ +import color from 'picocolors'; +import Prompt, { type PromptOptions } from './prompt.ts'; + +interface PasswordOptions extends PromptOptions { + mask?: string; +} +export default class PasswordPrompt extends Prompt { + valueWithCursor = ''; + private _mask = '•'; + get cursor(): number { + return this._cursor; + } + get masked(): string { + return this.value.replaceAll(/./g, this._mask); + } + constructor({ mask, ...opts }: PasswordOptions) { + super(opts); + this._mask = mask ?? '•'; + + this.on('finalize', () => { + this.valueWithCursor = this.masked; + }); + this.on('value', () => { + if (this.cursor >= this.value.length) { + this.valueWithCursor = `${this.masked}${color.inverse(color.hidden('_'))}`; + } else { + const s1 = this.masked.slice(0, this.cursor); + const s2 = this.masked.slice(this.cursor); + this.valueWithCursor = `${s1}${color.inverse(s2[0])}${s2.slice(1)}`; + } + }); + } +} diff --git a/packages/clack-core/src/prompts/prompt.ts b/packages/clack-core/src/prompts/prompt.ts new file mode 100644 index 00000000..40a2a057 --- /dev/null +++ b/packages/clack-core/src/prompts/prompt.ts @@ -0,0 +1,273 @@ +import readline, { type Key, type ReadLine } from 'node:readline'; +import process, { stdin, stdout } from 'node:process'; +import { WriteStream } from 'node:tty'; +import type { Readable, Writable } from 'node:stream'; +import { cursor, erase } from 'sisteransi'; +import wrap from 'wrap-ansi'; + +function diffLines(a: string, b: string) { + if (a === b) return; + + const aLines = a.split('\n'); + const bLines = b.split('\n'); + const diff: number[] = []; + + for (let i = 0; i < Math.max(aLines.length, bLines.length); i++) { + if (aLines[i] !== bLines[i]) diff.push(i); + } + + return diff; +} + +const cancel = Symbol('clack:cancel'); +export function isCancel(value: unknown): value is symbol { + return value === cancel; +} + +function setRawMode(input: Readable, value: boolean) { + if ((input as typeof stdin).isTTY) (input as typeof stdin).setRawMode(value); +} + +const aliases = new Map([ + ['k', 'up'], + ['j', 'down'], + ['h', 'left'], + ['l', 'right'] +]); +const keys = new Set(['up', 'down', 'left', 'right', 'space', 'enter']); + +export interface PromptOptions { + render(this: Omit): string | void; + placeholder?: string; + initialValue?: any; + validate?: ((value: any) => string | void) | undefined; + input?: Readable; + output?: Writable; + debug?: boolean; +} + +export type State = 'initial' | 'active' | 'cancel' | 'submit' | 'error'; + +export default class Prompt { + protected input: Readable; + protected output: Writable; + private rl!: ReadLine; + private opts: Omit, 'render' | 'input' | 'output'>; + private _track: boolean = false; + private _render: (context: Omit) => string | void; + protected _cursor: number = 0; + + public state: State = 'initial'; + public value: any; + public error: string = ''; + + constructor( + { render, input = stdin, output = stdout, ...opts }: PromptOptions, + trackValue: boolean = true + ) { + this.opts = opts; + this.onKeypress = this.onKeypress.bind(this); + this.close = this.close.bind(this); + this.render = this.render.bind(this); + this._render = render.bind(this); + this._track = trackValue; + + this.input = input; + this.output = output; + } + + public prompt(): Promise { + const sink = new WriteStream(0); + sink._write = (chunk, encoding, done) => { + if (this._track) { + this.value = this.rl.line.replace(/\t/g, ''); + this._cursor = this.rl.cursor; + this.emit('value', this.value); + } + done(); + }; + this.input.pipe(sink); + + this.rl = readline.createInterface({ + input: this.input, + output: sink, + tabSize: 2, + prompt: '', + escapeCodeTimeout: 50 + }); + readline.emitKeypressEvents(this.input, this.rl); + this.rl.prompt(); + if (this.opts.initialValue !== undefined && this._track) { + this.rl.write(this.opts.initialValue); + } + + this.input.on('keypress', this.onKeypress); + setRawMode(this.input, true); + this.output.on('resize', this.render); + + this.render(); + + return new Promise((resolve) => { + this.once('submit', () => { + this.output.write(cursor.show); + this.output.off('resize', this.render); + setRawMode(this.input, false); + resolve(this.value); + }); + this.once('cancel', () => { + this.output.write(cursor.show); + this.output.off('resize', this.render); + setRawMode(this.input, false); + resolve(cancel); + }); + }); + } + + private subscribers = new Map any; once?: boolean }>>(); + public on(event: string, cb: (...args: any) => any): void { + const arr = this.subscribers.get(event) ?? []; + arr.push({ cb }); + this.subscribers.set(event, arr); + } + public once(event: string, cb: (...args: any) => any): void { + const arr = this.subscribers.get(event) ?? []; + arr.push({ cb, once: true }); + this.subscribers.set(event, arr); + } + public emit(event: string, ...data: any[]): void { + const cbs = this.subscribers.get(event) ?? []; + const cleanup: Array<() => void> = []; + for (const subscriber of cbs) { + subscriber.cb(...data); + if (subscriber.once) { + cleanup.push(() => cbs.splice(cbs.indexOf(subscriber), 1)); + } + } + for (const cb of cleanup) { + cb(); + } + } + private unsubscribe() { + this.subscribers.clear(); + } + + private onKeypress(char: string, key?: Key) { + if (this.state === 'error') { + this.state = 'active'; + } + if (key?.name && !this._track && aliases.has(key.name)) { + this.emit('cursor', aliases.get(key.name)); + } + if (key?.name && keys.has(key.name)) { + this.emit('cursor', key.name); + } + if (char && (char.toLowerCase() === 'y' || char.toLowerCase() === 'n')) { + this.emit('confirm', char.toLowerCase() === 'y'); + } + if (char === '\t' && this.opts.placeholder) { + if (!this.value) { + this.rl.write(this.opts.placeholder); + this.emit('value', this.opts.placeholder); + } + } + if (char) { + this.emit('key', char.toLowerCase()); + } + + if (key?.name === 'return') { + if (this.opts.validate) { + const problem = this.opts.validate(this.value); + if (problem) { + this.error = problem; + this.state = 'error'; + this.rl.write(this.value); + } + } + if (this.state !== 'error') { + this.state = 'submit'; + } + } + if (char === '\x03') { + this.state = 'cancel'; + } + if (this.state === 'submit' || this.state === 'cancel') { + this.emit('finalize'); + } + this.render(); + if (this.state === 'submit' || this.state === 'cancel') { + this.close(); + } + } + + protected close(): void { + this.input.unpipe(); + this.input.removeListener('keypress', this.onKeypress); + this.output.write('\n'); + setRawMode(this.input, false); + this.rl.close(); + this.emit(this.state, this.value); + this.unsubscribe(); + } + + private restoreCursor() { + const lines = + wrap(this._prevFrame, process.stdout.columns, { hard: true }).split('\n').length - 1; + this.output.write(cursor.move(-999, lines * -1)); + } + + private _prevFrame = ''; + private render() { + const frame = wrap(this._render(this) ?? '', process.stdout.columns, { hard: true }); + if (frame === this._prevFrame) return; + + if (this.state === 'initial') { + this.output.write(cursor.hide); + } + + const diff = diffLines(this._prevFrame, frame); + this.restoreCursor(); + if (diff) { + const diffLine = diff[0]!; + const lines = frame.split('\n'); + let newLines: string[] = []; + + // If we don't have enough vertical space to print all of the lines simultaneously, + // then we'll sticky the prompt message (first 3 lines) to the top so it's always shown. + // We'll then take the remaining space and render a snippet of the list that's relative + // to the currently selected option + if (lines.length > process.stdout.rows) { + const OFFSET = 3; + const PAGE_SIZE = process.stdout.rows - OFFSET; + + // @ts-expect-error `cursor` is a property that's implemented by prompts extending this class. + const pos: number = this.cursor; + + // page positions + const start = pos <= OFFSET ? OFFSET : pos; + const end = start + PAGE_SIZE; + + this.output.write(erase.down()); + + // stickied headers + const header = lines.slice(0, OFFSET); + const content = lines.slice(start, end); + newLines = newLines.concat(header, content); + } else { + this.output.write(cursor.move(0, diffLine)); + this.output.write(erase.down()); + + newLines = lines.slice(diffLine); + } + + this.output.write(newLines.join('\n')); + this._prevFrame = frame; + return; + } + + this.output.write(frame); + if (this.state === 'initial') { + this.state = 'active'; + } + this._prevFrame = frame; + } +} diff --git a/packages/clack-core/src/prompts/select-key.ts b/packages/clack-core/src/prompts/select-key.ts new file mode 100644 index 00000000..b0c703e6 --- /dev/null +++ b/packages/clack-core/src/prompts/select-key.ts @@ -0,0 +1,27 @@ +import Prompt, { type PromptOptions } from './prompt.ts'; + +interface SelectKeyOptions extends PromptOptions> { + options: T[]; +} +export default class SelectKeyPrompt extends Prompt { + options: T[]; + cursor: number = 0; + + constructor(opts: SelectKeyOptions) { + super(opts, false); + + this.options = opts.options; + const keys = this.options.map(({ value: [initial] }) => initial?.toLowerCase()); + this.cursor = Math.max(keys.indexOf(opts.initialValue), 0); + + this.on('key', (key) => { + if (!keys.includes(key)) return; + const value = this.options.find(({ value: [initial] }) => initial?.toLowerCase() === key); + if (value) { + this.value = value.value; + this.state = 'submit'; + this.emit('submit'); + } + }); + } +} diff --git a/packages/clack-core/src/prompts/select.ts b/packages/clack-core/src/prompts/select.ts new file mode 100644 index 00000000..ee5f2627 --- /dev/null +++ b/packages/clack-core/src/prompts/select.ts @@ -0,0 +1,41 @@ +import Prompt, { type PromptOptions } from './prompt.ts'; + +interface SelectOptions extends PromptOptions> { + options: T[]; + initialValue?: T['value']; +} +export default class SelectPrompt extends Prompt { + options: T[]; + cursor: number = 0; + + private get _value() { + return this.options[this.cursor]; + } + + private changeValue() { + this.value = this._value!.value; + } + + constructor(opts: SelectOptions) { + super(opts, false); + + this.options = opts.options; + this.cursor = this.options.findIndex(({ value }) => value === opts.initialValue); + if (this.cursor === -1) this.cursor = 0; + this.changeValue(); + + this.on('cursor', (key) => { + switch (key) { + case 'left': + case 'up': + this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1; + break; + case 'down': + case 'right': + this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1; + break; + } + this.changeValue(); + }); + } +} diff --git a/packages/clack-core/src/prompts/text.ts b/packages/clack-core/src/prompts/text.ts new file mode 100644 index 00000000..b2a89a71 --- /dev/null +++ b/packages/clack-core/src/prompts/text.ts @@ -0,0 +1,33 @@ +import color from 'picocolors'; +import Prompt, { type PromptOptions } from './prompt.ts'; + +export interface TextOptions extends PromptOptions { + placeholder?: string; + defaultValue?: string; +} + +export default class TextPrompt extends Prompt { + valueWithCursor = ''; + get cursor(): number { + return this._cursor; + } + constructor(opts: TextOptions) { + super(opts); + + this.on('finalize', () => { + if (!this.value) { + this.value = opts.defaultValue; + } + this.valueWithCursor = this.value; + }); + this.on('value', () => { + if (this.cursor >= this.value.length) { + this.valueWithCursor = `${this.value}${color.inverse(color.hidden('_'))}`; + } else { + const s1 = this.value.slice(0, this.cursor); + const s2 = this.value.slice(this.cursor); + this.valueWithCursor = `${s1}${color.inverse(s2[0])}${s2.slice(1)}`; + } + }); + } +} diff --git a/packages/clack-core/src/utils.ts b/packages/clack-core/src/utils.ts new file mode 100644 index 00000000..b4a101e0 --- /dev/null +++ b/packages/clack-core/src/utils.ts @@ -0,0 +1,60 @@ +import type { Key } from 'node:readline'; + +import process, { stdin, stdout } from 'node:process'; +import * as readline from 'node:readline'; +import { cursor } from 'sisteransi'; + +const isWindows = process.platform.startsWith('win'); + +export type BlockOptions = { + input?: NodeJS.ReadStream | undefined; + output?: NodeJS.WriteStream | undefined; + overwrite?: boolean | undefined; + hideCursor?: boolean | undefined; +}; + +export function block({ + input = stdin, + output = stdout, + overwrite = true, + hideCursor = true +}: BlockOptions = {}) { + const rl = readline.createInterface({ + input, + output, + prompt: '', + tabSize: 1 + }); + readline.emitKeypressEvents(input, rl); + if (input.isTTY) input.setRawMode(true); + + const clear = (data: Buffer, { name }: Key) => { + const str = String(data); + if (str === '\x03') { + process.exit(0); + } + if (!overwrite) return; + const dx = name === 'return' ? 0 : -1; + const dy = name === 'return' ? -1 : 0; + + readline.moveCursor(output, dx, dy, () => { + readline.clearLine(output, 1, () => { + input.once('keypress', clear); + }); + }); + }; + if (hideCursor) process.stdout.write(cursor.hide); + input.once('keypress', clear); + + return (): void => { + input.off('keypress', clear); + if (hideCursor) process.stdout.write(cursor.show); + + // Prevent Windows specific issues: https://github.com/natemoo-re/clack/issues/176 + if (input.isTTY && !isWindows) input.setRawMode(false); + + // @ts-expect-error fix for https://github.com/nodejs/node/issues/31762#issuecomment-1441223907 + rl.terminal = false; + rl.close(); + }; +} diff --git a/packages/clack-core/tsconfig.json b/packages/clack-core/tsconfig.json new file mode 100644 index 00000000..a1fcf6c9 --- /dev/null +++ b/packages/clack-core/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "checkJs": false, + "isolatedDeclarations": true, + "declaration": true + } +} diff --git a/packages/clack-prompts/LICENSE b/packages/clack-prompts/LICENSE new file mode 100644 index 00000000..a95d8e47 --- /dev/null +++ b/packages/clack-prompts/LICENSE @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) Nate Moore + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +`ansi-regex` is adapted from https://github.com/chalk/ansi-regex + +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/clack-prompts/README.md b/packages/clack-prompts/README.md new file mode 100644 index 00000000..e5837fd6 --- /dev/null +++ b/packages/clack-prompts/README.md @@ -0,0 +1,174 @@ +# `@clack/prompts` + +Effortlessly build beautiful command-line apps 🪄 [Try the demo](https://stackblitz.com/edit/clack-prompts?file=index.js) + +![clack-prompt](https://github.com/natemoo-re/clack/blob/main/.github/assets/clack-demo.gif) + +--- + +`@clack/prompts` is an opinionated, pre-styled wrapper around [`@clack/core`](https://www.npmjs.com/package/@clack/core). + +- 🤏 80% smaller than other options +- 💎 Beautiful, minimal UI +- ✅ Simple API +- 🧱 Comes with `text`, `confirm`, `select`, `multiselect`, and `spinner` components + +## Basics + +### Setup + +The `intro` and `outro` functions will print a message to begin or end a prompt session, respectively. + +```js +import { intro, outro } from '@clack/prompts'; + +intro(`create-my-app`); +// Do stuff +outro(`You're all set!`); +``` + +### Cancellation + +The `isCancel` function is a guard that detects when a user cancels a question with `CTRL + C`. You should handle this situation for each prompt, optionally providing a nice cancellation message with the `cancel` utility. + +```js +import { isCancel, cancel, text } from '@clack/prompts'; + +const value = await text(/* TODO */); + +if (isCancel(value)) { + cancel('Operation cancelled.'); + process.exit(0); +} +``` + +## Components + +### Text + +The text component accepts a single line of text. + +```js +import { text } from '@clack/prompts'; + +const meaning = await text({ + message: 'What is the meaning of life?', + placeholder: 'Not sure', + initialValue: '42', + validate(value) { + if (value.length === 0) return `Value is required!`; + } +}); +``` + +### Confirm + +The confirm component accepts a yes or no answer. The result is a boolean value of `true` or `false`. + +```js +import { confirm } from '@clack/prompts'; + +const shouldContinue = await confirm({ + message: 'Do you want to continue?' +}); +``` + +### Select + +The select component allows a user to choose one value from a list of options. The result is the `value` prop of a given option. + +```js +import { select } from '@clack/prompts'; + +const projectType = await select({ + message: 'Pick a project type.', + options: [ + { value: 'ts', label: 'TypeScript' }, + { value: 'js', label: 'JavaScript' }, + { value: 'coffee', label: 'CoffeeScript', hint: 'oh no' } + ] +}); +``` + +### Multi-Select + +The `multiselect` component allows a user to choose many values from a list of options. The result is an array with all selected `value` props. + +```js +import { multiselect } from '@clack/prompts'; + +const additionalTools = await multiselect({ + message: 'Select additional tools.', + options: [ + { value: 'eslint', label: 'ESLint', hint: 'recommended' }, + { value: 'prettier', label: 'Prettier' }, + { value: 'gh-action', label: 'GitHub Action' } + ], + required: false +}); +``` + +### Spinner + +The spinner component surfaces a pending action, such as a long-running download or dependency installation. + +```js +import { spinner } from '@clack/prompts'; + +const s = spinner(); +s.start('Installing via npm'); +// Do installation here +s.stop('Installed via npm'); +``` + +## Utilities + +### Grouping + +Grouping prompts together is a great way to keep your code organized. This accepts a JSON object with a name that can be used to reference the group later. The second argument is an optional but has a `onCancel` callback that will be called if the user cancels one of the prompts in the group. + +```js +import * as p from '@clack/prompts'; + +const group = await p.group( + { + name: () => p.text({ message: 'What is your name?' }), + age: () => p.text({ message: 'What is your age?' }), + color: ({ results }) => + p.multiselect({ + message: `What is your favorite color ${results.name}?`, + options: [ + { value: 'red', label: 'Red' }, + { value: 'green', label: 'Green' }, + { value: 'blue', label: 'Blue' } + ] + }) + }, + { + // On Cancel callback that wraps the group + // So if the user cancels one of the prompts in the group this function will be called + onCancel: ({ results }) => { + p.cancel('Operation cancelled.'); + process.exit(0); + } + } +); + +console.log(group.name, group.age, group.color); +``` + +### Tasks + +Execute multiple tasks in spinners. + +```js +await p.tasks([ + { + title: 'Installing via npm', + task: async (message) => { + // Do installation here + return 'Installed via npm'; + } + } +]); +``` diff --git a/packages/clack-prompts/index.ts b/packages/clack-prompts/index.ts new file mode 100644 index 00000000..d93f8c0f --- /dev/null +++ b/packages/clack-prompts/index.ts @@ -0,0 +1,894 @@ +import process from 'node:process'; +import { + block, + ConfirmPrompt, + GroupMultiSelectPrompt, + isCancel, + MultiSelectPrompt, + PasswordPrompt, + SelectKeyPrompt, + SelectPrompt, + type State, + TextPrompt +} from '@sveltejs/clack-core'; +import isUnicodeSupported from 'is-unicode-supported'; +import color from 'picocolors'; +import { cursor, erase } from 'sisteransi'; + +export { isCancel } from '@sveltejs/clack-core'; + +const unicode = isUnicodeSupported(); +const s = (c: string, fallback: string) => (unicode ? c : fallback); +const S_STEP_ACTIVE = s('◆', '*'); +const S_STEP_CANCEL = s('■', 'x'); +const S_STEP_ERROR = s('▲', 'x'); +const S_STEP_SUBMIT = s('◇', 'o'); + +const S_BAR_START = s('┌', 'T'); +const S_BAR = s('│', '|'); +const S_BAR_END = s('└', '—'); + +const S_RADIO_ACTIVE = s('●', '>'); +const S_RADIO_INACTIVE = s('○', ' '); +const S_CHECKBOX_ACTIVE = s('◻', '[•]'); +const S_CHECKBOX_SELECTED = s('◼', '[+]'); +const S_CHECKBOX_INACTIVE = s('◻', '[ ]'); +const S_PASSWORD_MASK = s('▪', '•'); + +const S_BAR_H = s('─', '-'); +const S_CORNER_TOP_RIGHT = s('╮', '+'); +const S_CONNECT_LEFT = s('├', '+'); +const S_CORNER_BOTTOM_RIGHT = s('╯', '+'); + +const S_INFO = s('●', '•'); +const S_SUCCESS = s('◆', '*'); +const S_WARN = s('▲', '!'); +const S_ERROR = s('■', 'x'); + +const symbol = (state: State) => { + switch (state) { + case 'initial': + case 'active': + return color.cyan(S_STEP_ACTIVE); + case 'cancel': + return color.red(S_STEP_CANCEL); + case 'error': + return color.yellow(S_STEP_ERROR); + case 'submit': + return color.green(S_STEP_SUBMIT); + } +}; + +interface LimitOptionsParams { + options: TOption[]; + maxItems: number | undefined; + cursor: number; + style: (option: TOption, active: boolean) => string; +} + +const limitOptions = (params: LimitOptionsParams): string[] => { + const { cursor, options, style } = params; + + const paramMaxItems = params.maxItems ?? Infinity; + const outputMaxItems = Math.max(process.stdout.rows - 4, 0); + // We clamp to minimum 5 because anything less doesn't make sense UX wise + const maxItems = Math.min(outputMaxItems, Math.max(paramMaxItems, 5)); + let slidingWindowLocation = 0; + + if (cursor >= slidingWindowLocation + maxItems - 3) { + slidingWindowLocation = Math.max(Math.min(cursor - maxItems + 3, options.length - maxItems), 0); + } else if (cursor < slidingWindowLocation + 2) { + slidingWindowLocation = Math.max(cursor - 2, 0); + } + + const shouldRenderTopEllipsis = maxItems < options.length && slidingWindowLocation > 0; + const shouldRenderBottomEllipsis = + maxItems < options.length && slidingWindowLocation + maxItems < options.length; + + return options + .slice(slidingWindowLocation, slidingWindowLocation + maxItems) + .map((option, i, arr) => { + const isTopLimit = i === 0 && shouldRenderTopEllipsis; + const isBottomLimit = i === arr.length - 1 && shouldRenderBottomEllipsis; + return isTopLimit || isBottomLimit + ? color.dim('...') + : style(option, i + slidingWindowLocation === cursor); + }); +}; + +export interface TextOptions { + message: string; + placeholder?: string; + defaultValue?: string; + initialValue?: string; + validate?: (value: string) => string | void; +} +export const text = (opts: TextOptions): Promise => { + return new TextPrompt({ + validate: opts.validate, + placeholder: opts.placeholder, + defaultValue: opts.defaultValue, + initialValue: opts.initialValue, + render() { + const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; + const placeholder = opts.placeholder + ? color.inverse(opts.placeholder[0]) + color.dim(opts.placeholder.slice(1)) + : color.inverse(color.hidden('_')); + const value = !this.value ? placeholder : this.valueWithCursor; + + switch (this.state) { + case 'error': + return `${title.trim()}\n${color.yellow(S_BAR)} ${value}\n${color.yellow( + S_BAR_END + )} ${color.yellow(this.error)}\n`; + case 'submit': + return `${title}${color.gray(S_BAR)} ${color.dim(this.value || opts.placeholder)}`; + case 'cancel': + return `${title}${color.gray(S_BAR)} ${color.strikethrough( + color.dim(this.value ?? '') + )}${this.value?.trim() ? '\n' + color.gray(S_BAR) : ''}`; + default: + return `${title}${color.cyan(S_BAR)} ${value}\n${color.cyan(S_BAR_END)}\n`; + } + } + }).prompt(); +}; + +export interface PasswordOptions { + message: string; + mask?: string; + validate?: (value: string) => string | void; +} +export const password = (opts: PasswordOptions): Promise => { + return new PasswordPrompt({ + validate: opts.validate, + mask: opts.mask ?? S_PASSWORD_MASK, + render() { + const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; + const value = this.valueWithCursor; + const masked = this.masked; + + switch (this.state) { + case 'error': + return `${title.trim()}\n${color.yellow(S_BAR)} ${masked}\n${color.yellow( + S_BAR_END + )} ${color.yellow(this.error)}\n`; + case 'submit': + return `${title}${color.gray(S_BAR)} ${color.dim(masked)}`; + case 'cancel': + return `${title}${color.gray(S_BAR)} ${color.strikethrough(color.dim(masked ?? ''))}${ + masked ? '\n' + color.gray(S_BAR) : '' + }`; + default: + return `${title}${color.cyan(S_BAR)} ${value}\n${color.cyan(S_BAR_END)}\n`; + } + } + }).prompt(); +}; + +export interface ConfirmOptions { + message: string; + active?: string; + inactive?: string; + initialValue?: boolean; +} +export const confirm = (opts: ConfirmOptions) => { + const active = opts.active ?? 'Yes'; + const inactive = opts.inactive ?? 'No'; + return new ConfirmPrompt({ + active, + inactive, + initialValue: opts.initialValue ?? true, + render() { + const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; + const value = this.value ? active : inactive; + + switch (this.state) { + case 'submit': + return `${title}${color.gray(S_BAR)} ${color.dim(value)}`; + case 'cancel': + return `${title}${color.gray(S_BAR)} ${color.strikethrough( + color.dim(value) + )}\n${color.gray(S_BAR)}`; + default: { + return `${title}${color.cyan(S_BAR)} ${ + this.value + ? `${color.green(S_RADIO_ACTIVE)} ${active}` + : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(active)}` + } ${color.dim('/')} ${ + !this.value + ? `${color.green(S_RADIO_ACTIVE)} ${inactive}` + : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(inactive)}` + }\n${color.cyan(S_BAR_END)}\n`; + } + } + } + }).prompt() as Promise; +}; + +type Primitive = Readonly; + +type Option = Value extends Primitive + ? { value: Value; label?: string; hint?: string } + : { value: Value; label: string; hint?: string }; + +export interface SelectOptions { + message: string; + options: Array>; + initialValue?: Value; + maxItems?: number; +} + +export const select = (opts: SelectOptions) => { + const opt = (option: Option, state: 'inactive' | 'active' | 'selected' | 'cancelled') => { + const label = option.label ?? String(option.value); + switch (state) { + case 'selected': + return color.dim(label); + case 'active': + return `${color.green(S_RADIO_ACTIVE)} ${label} ${ + option.hint ? color.dim(`(${option.hint})`) : '' + }`; + case 'cancelled': + return color.strikethrough(color.dim(label)); + default: + return `${color.dim(S_RADIO_INACTIVE)} ${color.dim(label)}`; + } + }; + + return new SelectPrompt({ + options: opts.options, + initialValue: opts.initialValue, + render() { + const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; + + switch (this.state) { + case 'submit': + return `${title}${color.gray(S_BAR)} ${opt(this.options[this.cursor]!, 'selected')}`; + case 'cancel': + return `${title}${color.gray(S_BAR)} ${opt( + this.options[this.cursor]!, + 'cancelled' + )}\n${color.gray(S_BAR)}`; + default: { + return `${title}${color.cyan(S_BAR)} ${limitOptions({ + cursor: this.cursor, + options: this.options, + maxItems: opts.maxItems, + style: (item, active) => opt(item, active ? 'active' : 'inactive') + }).join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; + } + } + } + }).prompt() as Promise; +}; + +export const selectKey = (opts: SelectOptions) => { + const opt = ( + option: Option, + state: 'inactive' | 'active' | 'selected' | 'cancelled' = 'inactive' + ) => { + const label = option.label ?? String(option.value); + if (state === 'selected') { + return color.dim(label); + } else if (state === 'cancelled') { + return color.strikethrough(color.dim(label)); + } else if (state === 'active') { + return `${color.bgCyan(color.gray(` ${option.value} `))} ${label} ${ + option.hint ? color.dim(`(${option.hint})`) : '' + }`; + } + return `${color.gray(color.bgWhite(color.inverse(` ${option.value} `)))} ${label} ${ + option.hint ? color.dim(`(${option.hint})`) : '' + }`; + }; + + return new SelectKeyPrompt({ + options: opts.options, + initialValue: opts.initialValue, + render() { + const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; + + switch (this.state) { + case 'submit': + return `${title}${color.gray(S_BAR)} ${opt( + this.options.find((opt) => opt.value === this.value)!, + 'selected' + )}`; + case 'cancel': + return `${title}${color.gray(S_BAR)} ${opt(this.options[0]!, 'cancelled')}\n${color.gray( + S_BAR + )}`; + default: { + return `${title}${color.cyan(S_BAR)} ${this.options + .map((option, i) => opt(option, i === this.cursor ? 'active' : 'inactive')) + .join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; + } + } + } + }).prompt() as Promise; +}; + +export interface MultiSelectOptions { + message: string; + options: Array>; + initialValues?: Value[]; + maxItems?: number; + required?: boolean; + cursorAt?: Value; +} +export const multiselect = (opts: MultiSelectOptions) => { + const opt = ( + option: Option, + state: 'inactive' | 'active' | 'selected' | 'active-selected' | 'submitted' | 'cancelled' + ) => { + const label = option.label ?? String(option.value); + if (state === 'active') { + return `${color.cyan(S_CHECKBOX_ACTIVE)} ${label} ${ + option.hint ? color.dim(`(${option.hint})`) : '' + }`; + } else if (state === 'selected') { + return `${color.green(S_CHECKBOX_SELECTED)} ${color.dim(label)}`; + } else if (state === 'cancelled') { + return color.strikethrough(color.dim(label)); + } else if (state === 'active-selected') { + return `${color.green(S_CHECKBOX_SELECTED)} ${label} ${ + option.hint ? color.dim(`(${option.hint})`) : '' + }`; + } else if (state === 'submitted') { + return color.dim(label); + } + return `${color.dim(S_CHECKBOX_INACTIVE)} ${color.dim(label)}`; + }; + + return new MultiSelectPrompt({ + options: opts.options, + initialValues: opts.initialValues, + required: opts.required ?? true, + cursorAt: opts.cursorAt, + validate(selected: Value[]) { + if (this.required && selected.length === 0) + return `Please select at least one option.\n${color.reset( + color.dim( + `Press ${color.gray(color.bgWhite(color.inverse(' space ')))} to select, ${color.gray( + color.bgWhite(color.inverse(' enter ')) + )} to submit` + ) + )}`; + }, + render() { + const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; + + const styleOption = (option: Option, active: boolean) => { + const selected = this.value.includes(option.value); + if (active && selected) { + return opt(option, 'active-selected'); + } + if (selected) { + return opt(option, 'selected'); + } + return opt(option, active ? 'active' : 'inactive'); + }; + + switch (this.state) { + case 'submit': { + return `${title}${color.gray(S_BAR)} ${ + this.options + .filter(({ value }) => this.value.includes(value)) + .map((option) => opt(option, 'submitted')) + .join(color.dim(', ')) || color.dim('none') + }`; + } + case 'cancel': { + const label = this.options + .filter(({ value }) => this.value.includes(value)) + .map((option) => opt(option, 'cancelled')) + .join(color.dim(', ')); + return `${title}${color.gray(S_BAR)} ${ + label.trim() ? `${label}\n${color.gray(S_BAR)}` : '' + }`; + } + case 'error': { + const footer = this.error + .split('\n') + .map((ln, i) => + i === 0 ? `${color.yellow(S_BAR_END)} ${color.yellow(ln)}` : ` ${ln}` + ) + .join('\n'); + return ( + title + + color.yellow(S_BAR) + + ' ' + + limitOptions({ + options: this.options, + cursor: this.cursor, + maxItems: opts.maxItems, + style: styleOption + }).join(`\n${color.yellow(S_BAR)} `) + + '\n' + + footer + + '\n' + ); + } + default: { + return `${title}${color.cyan(S_BAR)} ${limitOptions({ + options: this.options, + cursor: this.cursor, + maxItems: opts.maxItems, + style: styleOption + }).join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; + } + } + } + }).prompt() as Promise; +}; + +export interface GroupMultiSelectOptions { + message: string; + options: Record>>; + initialValues?: Value[]; + required?: boolean; + cursorAt?: Value; + selectableGroups?: boolean; + spacedGroups?: boolean; +} + +export const groupMultiselect = (opts: GroupMultiSelectOptions) => { + const { selectableGroups = false, spacedGroups = false } = opts; + const opt = ( + option: Option, + state: + | 'inactive' + | 'active' + | 'selected' + | 'active-selected' + | 'group-active' + | 'group-active-selected' + | 'submitted' + | 'cancelled', + options: Array> = [] + ) => { + const label = option.label ?? String(option.value); + const isItem = typeof (option as any).group === 'string'; + const next = isItem && (options[options.indexOf(option) + 1] ?? { group: true }); + // @ts-ignore + const isLast = isItem && next.group === true; + const prefix = isItem ? (selectableGroups ? `${isLast ? S_BAR_END : S_BAR} ` : ' ') : ''; + const spacingPrefix = spacedGroups && !isItem ? `\n${color.cyan(S_BAR)} ` : ''; + + if (state === 'active') { + return `${spacingPrefix}${color.dim(prefix)}${color.cyan(S_CHECKBOX_ACTIVE)} ${label} ${ + option.hint ? color.dim(`(${option.hint})`) : '' + }`; + } else if (state === 'group-active') { + return `${spacingPrefix}${prefix}${color.cyan(S_CHECKBOX_ACTIVE)} ${color.dim(label)}`; + } else if (state === 'group-active-selected') { + return `${spacingPrefix}${prefix}${color.green(S_CHECKBOX_SELECTED)} ${color.dim(label)}`; + } else if (state === 'selected') { + return `${spacingPrefix}${color.dim(prefix)}${color.green(S_CHECKBOX_SELECTED)} ${color.dim( + label + )}`; + } else if (state === 'cancelled') { + return color.strikethrough(color.dim(label)); + } else if (state === 'active-selected') { + return `${spacingPrefix}${color.dim(prefix)}${color.green(S_CHECKBOX_SELECTED)} ${label} ${ + option.hint ? color.dim(`(${option.hint})`) : '' + }`; + } else if (state === 'submitted') { + return color.dim(label); + } + return `${spacingPrefix}${color.dim(prefix)}${ + isItem || selectableGroups ? `${color.dim(S_CHECKBOX_INACTIVE)} ` : '' + }${color.dim(label)}`; + }; + + return new GroupMultiSelectPrompt({ + options: opts.options, + initialValues: opts.initialValues, + required: opts.required ?? true, + cursorAt: opts.cursorAt, + selectableGroups, + validate(selected: Value[]) { + if (this.required && selected.length === 0) + return `Please select at least one option.\n${color.reset( + color.dim( + `Press ${color.gray(color.bgWhite(color.inverse(' space ')))} to select, ${color.gray( + color.bgWhite(color.inverse(' enter ')) + )} to submit` + ) + )}`; + }, + render() { + const title = `${color.gray(S_BAR)}\n${symbol(this.state)} ${opts.message}\n`; + + switch (this.state) { + case 'submit': { + return `${title}${color.gray(S_BAR)} ${this.options + .filter(({ value }) => this.value.includes(value)) + .map((option) => opt(option, 'submitted')) + .join(color.dim(', '))}`; + } + case 'cancel': { + const label = this.options + .filter(({ value }) => this.value.includes(value)) + .map((option) => opt(option, 'cancelled')) + .join(color.dim(', ')); + return `${title}${color.gray(S_BAR)} ${ + label.trim() ? `${label}\n${color.gray(S_BAR)}` : '' + }`; + } + case 'error': { + const footer = this.error + .split('\n') + .map((ln, i) => + i === 0 ? `${color.yellow(S_BAR_END)} ${color.yellow(ln)}` : ` ${ln}` + ) + .join('\n'); + return `${title}${color.yellow(S_BAR)} ${this.options + .map((option, i, options) => { + const selected = + this.value.includes(option.value) || + (option.group === true && this.isGroupSelected(`${option.value}`)); + const active = i === this.cursor; + const groupActive = + !active && + typeof option.group === 'string' && + this.options[this.cursor]!.value === option.group; + if (groupActive) { + return opt(option, selected ? 'group-active-selected' : 'group-active', options); + } + if (active && selected) { + return opt(option, 'active-selected', options); + } + if (selected) { + return opt(option, 'selected', options); + } + return opt(option, active ? 'active' : 'inactive', options); + }) + .join(`\n${color.yellow(S_BAR)} `)}\n${footer}\n`; + } + default: { + return `${title}${color.cyan(S_BAR)} ${this.options + .map((option, i, options) => { + const selected = + this.value.includes(option.value) || + (option.group === true && this.isGroupSelected(`${option.value}`)); + const active = i === this.cursor; + const groupActive = + !active && + typeof option.group === 'string' && + this.options[this.cursor]!.value === option.group; + if (groupActive) { + return opt(option, selected ? 'group-active-selected' : 'group-active', options); + } + if (active && selected) { + return opt(option, 'active-selected', options); + } + if (selected) { + return opt(option, 'selected', options); + } + return opt(option, active ? 'active' : 'inactive', options); + }) + .join(`\n${color.cyan(S_BAR)} `)}\n${color.cyan(S_BAR_END)}\n`; + } + } + } + }).prompt() as Promise; +}; + +const strip = (str: string) => str.replace(ansiRegex(), ''); +function buildBox(message = '', title = '', dimmed = true) { + const lines = `\n${message}\n`.split('\n'); + const titleLen = strip(title).length; + const len = + Math.max( + lines.reduce((sum, ln) => { + ln = strip(ln); + return ln.length > sum ? ln.length : sum; + }, 0), + titleLen + ) + 2; + const msg = lines + .map( + (ln) => + `${color.gray(S_BAR)} ${dimmed ? color.dim(ln) : ln}${' '.repeat(len - strip(ln).length)}${color.gray(S_BAR)}` + ) + .join('\n'); + process.stdout.write( + `${color.gray(S_BAR)}\n${color.green(S_STEP_SUBMIT)} ${color.reset(title)} ${color.gray( + S_BAR_H.repeat(Math.max(len - titleLen - 1, 1)) + S_CORNER_TOP_RIGHT + )}\n${msg}\n${color.gray(S_CONNECT_LEFT + S_BAR_H.repeat(len + 2) + S_CORNER_BOTTOM_RIGHT)}\n` + ); +} + +export const note = (message = '', title = ''): void => buildBox(message, title, true); +export const box = (message = '', title = ''): void => buildBox(message, title, false); +export const taskLog = (title: string) => { + const BAR = color.dim(S_BAR); + const ACTIVE = color.green(S_STEP_SUBMIT); + const SUCCESS = color.green(S_SUCCESS); + const ERROR = color.red(S_ERROR); + + // heading + process.stdout.write(`${BAR}\n`); + process.stdout.write(`${ACTIVE} ${title}\n`); + + let output = ''; + let frame = ''; + + // clears previous output + const clear = (eraseTitle = false): void => { + if (!frame) return; + const terminalWidth = process.stdout.columns; + const frameHeight = frame.split('\n').reduce((height, line) => { + // accounts for line wraps + height += Math.ceil(line.length / terminalWidth); + return height; + }, 0); + const lines = frameHeight + (eraseTitle ? 1 : 0); + + process.stdout.write(cursor.up(lines)); + process.stdout.write(erase.down()); + }; + + // logs the output + const print = (limit = 0): void => { + const lines = output.split('\n').slice(-limit); + // reset frame + frame = ''; + for (const line of lines) { + frame += `${BAR} ${line}\n`; + } + process.stdout.write(color.dim(frame)); + }; + + return { + set text(data: string) { + clear(); + output += data; + // half the height of the terminal + const frameHeight = Math.ceil(process.stdout.rows / 2); + print(frameHeight); + }, + fail(message: string): void { + clear(true); + process.stdout.write(`${ERROR} ${message}\n`); + print(); // log the output on failure + }, + success(message: string): void { + clear(true); + process.stdout.write(`${SUCCESS} ${message}\n`); + } + }; +}; + +export const cancel = (message = ''): void => { + process.stdout.write(`${color.gray(S_BAR_END)} ${color.red(message)}\n\n`); +}; + +export const intro = (title = ''): void => { + process.stdout.write(`${color.gray(S_BAR_START)} ${title}\n`); +}; + +export const outro = (message = ''): void => { + process.stdout.write(`${color.gray(S_BAR)}\n${color.gray(S_BAR_END)} ${message}\n\n`); +}; + +export type LogMessageOptions = { + symbol?: string; +}; +export const log = { + message: (message = '', { symbol = color.gray(S_BAR) }: LogMessageOptions = {}): void => { + const parts = [color.gray(S_BAR)]; + if (message) { + const [firstLine, ...lines] = message.split('\n'); + parts.push(`${symbol} ${firstLine}`, ...lines.map((ln) => `${color.gray(S_BAR)} ${ln}`)); + } + process.stdout.write(`${parts.join('\n')}\n`); + }, + info: (message: string): void => { + log.message(message, { symbol: color.blue(S_INFO) }); + }, + success: (message: string): void => { + log.message(message, { symbol: color.green(S_SUCCESS) }); + }, + step: (message: string): void => { + log.message(message, { symbol: color.green(S_STEP_SUBMIT) }); + }, + warn: (message: string): void => { + log.message(message, { symbol: color.yellow(S_WARN) }); + }, + /** alias for `log.warn()`. */ + warning: (message: string): void => { + log.warn(message); + }, + error: (message: string): void => { + log.message(message, { symbol: color.red(S_ERROR) }); + } +}; + +export const spinner = (): { + start: (msg?: string) => void; + stop: (msg?: string, code?: number) => void; + message: (msg?: string) => void; +} => { + const frames = unicode ? ['◒', '◐', '◓', '◑'] : ['•', 'o', 'O', '0']; + const delay = unicode ? 80 : 120; + + let unblock: () => void; + let loop: NodeJS.Timeout; + let isSpinnerActive: boolean = false; + let _message: string = ''; + + const handleExit = (code: number) => { + const msg = code > 1 ? 'Something went wrong' : 'Canceled'; + if (isSpinnerActive) stop(msg, code); + }; + + const errorEventHandler = () => { + handleExit(2); + }; + const signalEventHandler = () => { + handleExit(1); + }; + + const registerHooks = () => { + // Reference: https://nodejs.org/api/process.html#event-uncaughtexception + process.on('uncaughtExceptionMonitor', errorEventHandler); + // Reference: https://nodejs.org/api/process.html#event-unhandledrejection + process.on('unhandledRejection', errorEventHandler); + // Reference Signal Events: https://nodejs.org/api/process.html#signal-events + process.on('SIGINT', signalEventHandler); + process.on('SIGTERM', signalEventHandler); + process.on('exit', handleExit); + }; + + const clearHooks = () => { + process.removeListener('uncaughtExceptionMonitor', errorEventHandler); + process.removeListener('unhandledRejection', errorEventHandler); + process.removeListener('SIGINT', signalEventHandler); + process.removeListener('SIGTERM', signalEventHandler); + process.removeListener('exit', handleExit); + }; + + const start = (msg: string = ''): void => { + isSpinnerActive = true; + unblock = block(); + _message = msg.replace(/\.+$/, ''); + process.stdout.write(`${color.gray(S_BAR)}\n`); + let frameIndex = 0; + let dotsTimer = 0; + registerHooks(); + loop = setInterval(() => { + const frame = color.magenta(frames[frameIndex]); + const loadingDots = '.'.repeat(Math.floor(dotsTimer)).slice(0, 3); + process.stdout.write(cursor.move(-999, 0)); + process.stdout.write(erase.down(1)); + process.stdout.write(`${frame} ${_message}${loadingDots}`); + frameIndex = frameIndex + 1 < frames.length ? frameIndex + 1 : 0; + dotsTimer = dotsTimer < frames.length ? dotsTimer + 0.125 : 0; + }, delay); + }; + + const stop = (msg: string = '', code: number = 0): void => { + _message = msg ?? _message; + isSpinnerActive = false; + clearInterval(loop); + const step = + code === 0 + ? color.green(S_STEP_SUBMIT) + : code === 1 + ? color.red(S_STEP_CANCEL) + : color.red(S_STEP_ERROR); + process.stdout.write(cursor.move(-999, 0)); + process.stdout.write(erase.down(1)); + process.stdout.write(`${step} ${_message}\n`); + clearHooks(); + unblock(); + }; + + const message = (msg: string = ''): void => { + _message = msg ?? _message; + }; + + return { + start, + stop, + message + }; +}; + +// Adapted from https://github.com/chalk/ansi-regex +// @see LICENSE +function ansiRegex() { + const pattern = [ + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', + '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))' + ].join('|'); + + return new RegExp(pattern, 'g'); +} + +export type PromptGroupAwaitedReturn = { + [P in keyof T]: Exclude, symbol>; +}; + +export interface PromptGroupOptions { + /** + * Control how the group can be canceled + * if one of the prompts is canceled. + */ + onCancel?: (opts: { results: Prettify>> }) => void; +} + +type Prettify = { + [P in keyof T]: T[P]; +} & {}; + +export type PromptGroup = { + [P in keyof T]: (opts: { + results: Prettify>>>; + }) => void | Promise; +}; + +/** + * Define a group of prompts to be displayed + * and return a results of objects within the group + */ +export const group = async ( + prompts: PromptGroup, + opts?: PromptGroupOptions +): Promise>> => { + const results = {} as any; + const promptNames = Object.keys(prompts); + + for (const name of promptNames) { + const prompt = prompts[name as keyof T]; + const result = await prompt({ results })?.catch((e) => { + throw e; + }); + + // Pass the results to the onCancel function + // so the user can decide what to do with the results + // TODO: Switch to callback within core to avoid isCancel Fn + if (typeof opts?.onCancel === 'function' && isCancel(result)) { + results[name] = 'canceled'; + opts.onCancel({ results }); + continue; + } + + results[name] = result; + } + + return results; +}; + +export type Task = { + /** + * Task title + */ + title: string; + /** + * Task function + */ + task: (message: (string: string) => void) => string | Promise | void | Promise; + + /** + * If enabled === false the task will be skipped + */ + enabled?: boolean; +}; + +/** + * Define a group of tasks to be executed + */ +export const tasks = async (tasks: Task[]): Promise => { + for (const task of tasks) { + if (task.enabled === false) continue; + + const s = spinner(); + s.start(task.title); + const result = await task.task(s.message); + s.stop(result || task.title); + } +}; diff --git a/packages/clack-prompts/package.json b/packages/clack-prompts/package.json new file mode 100644 index 00000000..733d8445 --- /dev/null +++ b/packages/clack-prompts/package.json @@ -0,0 +1,34 @@ +{ + "name": "@sveltejs/clack-prompts", + "private": true, + "version": "0.9.1", + "type": "module", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/sveltejs/cli/tree/main/packages/clack-prompts" + }, + "bugs": "https://github.com/sveltejs/cli/issues", + "scripts": { + "check": "tsc", + "format": "pnpm lint --write", + "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore" + }, + "files": [ + "dist" + ], + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./package.json": "./package.json" + }, + "devDependencies": { + "@sveltejs/clack-core": "workspace:*", + "is-unicode-supported": "^1.3.0", + "picocolors": "^1.1.1", + "sisteransi": "^1.0.5" + } +} diff --git a/packages/clack-prompts/tsconfig.json b/packages/clack-prompts/tsconfig.json new file mode 100644 index 00000000..a1fcf6c9 --- /dev/null +++ b/packages/clack-prompts/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "checkJs": false, + "isolatedDeclarations": true, + "declaration": true + } +} diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index d0670c89..37b47a20 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -4,7 +4,7 @@ import process from 'node:process'; import pc from 'picocolors'; import * as v from 'valibot'; import * as pkg from 'empathic/package'; -import * as p from '@clack/prompts'; +import * as p from '@sveltejs/clack-prompts'; import { Command } from 'commander'; import { officialAddons, @@ -202,7 +202,7 @@ export const add = new Command('add') common.runCommand(async () => { const selectedAddonIds = selectedAddons.map(({ id }) => id); const { nextSteps } = await runAddCommand(options, selectedAddonIds); - if (nextSteps) p.note(nextSteps, 'Next steps', { format: (line) => line }); + if (nextSteps) p.box(nextSteps, 'Next steps'); }); }); @@ -459,7 +459,7 @@ export async function runAddCommand( .map(({ name, message }) => pc.yellow(`${name} (${message})`)) .join('\n- '); - p.note(`- ${message}`, 'Preconditions not met', { format: (line) => line }); + p.note(`- ${message}`, 'Preconditions not met'); const force = await p.confirm({ message: 'Preconditions failed. Do you wish to continue?', diff --git a/packages/cli/commands/create.ts b/packages/cli/commands/create.ts index 5d259c31..e8b848e2 100644 --- a/packages/cli/commands/create.ts +++ b/packages/cli/commands/create.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import process from 'node:process'; import * as v from 'valibot'; import { Command, Option } from 'commander'; -import * as p from '@clack/prompts'; +import * as p from '@sveltejs/clack-prompts'; import pc from 'picocolors'; import { create as createKit, @@ -93,8 +93,8 @@ export const create = new Command('create') `Stuck? Visit us at ${pc.cyan('https://svelte.dev/chat')}` ]; - p.note(steps.join('\n'), 'Project next steps', { format: (line) => line }); - if (addOnNextSteps) p.note(addOnNextSteps, 'Add-on next steps', { format: (line) => line }); + p.box(steps.join('\n'), 'Project next steps'); + if (addOnNextSteps) p.box(addOnNextSteps, 'Add-on next steps'); }); }); diff --git a/packages/cli/lib/install.ts b/packages/cli/lib/install.ts index 958a8ee4..900bf5be 100644 --- a/packages/cli/lib/install.ts +++ b/packages/cli/lib/install.ts @@ -9,7 +9,7 @@ import type { AddonWithoutExplicitArgs } from '@sveltejs/cli-core'; import pc from 'picocolors'; -import * as p from '@clack/prompts'; +import * as p from '@sveltejs/clack-prompts'; import { exec, NonZeroExitError } from 'tinyexec'; import { resolveCommand } from 'package-manager-detector'; import { TESTING } from '../utils/env.ts'; diff --git a/packages/cli/package.json b/packages/cli/package.json index 01dba37d..4ecb6908 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -30,8 +30,8 @@ } }, "devDependencies": { - "@clack/prompts": "^1.0.0-alpha.0", "@sveltejs/addons": "workspace:*", + "@sveltejs/clack-prompts": "workspace:*", "@sveltejs/cli-core": "workspace:*", "@sveltejs/create": "workspace:*", "@types/degit": "^2.8.6", diff --git a/packages/cli/utils/common.ts b/packages/cli/utils/common.ts index b2282f97..935024bf 100644 --- a/packages/cli/utils/common.ts +++ b/packages/cli/utils/common.ts @@ -1,6 +1,6 @@ import pc from 'picocolors'; import pkg from '../package.json' with { type: 'json' }; -import * as p from '@clack/prompts'; +import * as p from '@sveltejs/clack-prompts'; import type { Argument, HelpConfiguration, Option } from 'commander'; import { UnsupportedError } from './errors.ts'; import process from 'node:process'; diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index f53e4878..90829424 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -4,7 +4,7 @@ import process from 'node:process'; import * as find from 'empathic/find'; import { exec } from 'tinyexec'; import { Option } from 'commander'; -import * as p from '@clack/prompts'; +import * as p from '@sveltejs/clack-prompts'; import { AGENTS, COMMANDS, @@ -46,12 +46,7 @@ export async function packageManagerPrompt(cwd: string): Promise { - const task = p.taskLog({ - title: `Installing dependencies with ${agent}...`, - limit: Math.ceil(process.stdout.rows / 2), - spacing: 0, - retainLog: true - }); + const task = p.taskLog(`Installing dependencies with ${agent}...`); try { const { command, args } = constructCommand(COMMANDS[agent].install, [])!; @@ -61,17 +56,17 @@ export async function installDependencies(agent: AgentName, cwd: string): Promis }); proc.process?.stdout?.on('data', (data) => { - task.message(data.toString(), { raw: true }); + task.text = data; }); proc.process?.stderr?.on('data', (data) => { - task.message(data.toString(), { raw: true }); + task.text = data; }); await proc; task.success('Successfully installed dependencies'); } catch { - task.error('Failed to install dependencies'); + task.fail('Failed to install dependencies'); p.cancel('Operation failed.'); process.exit(2); } diff --git a/packages/core/index.ts b/packages/core/index.ts index e22448cb..e68a90e8 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -1,5 +1,5 @@ export { defineAddon, defineAddonOptions } from './addon/config.ts'; -export { log } from '@clack/prompts'; +export { log } from '@sveltejs/clack-prompts'; export { default as colors } from 'picocolors'; export { default as dedent } from 'dedent'; export * as utils from './utils.ts'; diff --git a/packages/core/package.json b/packages/core/package.json index 59ba0aec..41232984 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -42,8 +42,8 @@ } }, "devDependencies": { - "@clack/prompts": "^1.0.0-alpha.0", "@sveltejs/acorn-typescript": "^1.0.1", + "@sveltejs/clack-prompts": "workspace:*", "@types/estree": "^1.0.6", "acorn": "^8.14.0", "decircular": "^1.0.0", diff --git a/packages/migrate/package.json b/packages/migrate/package.json index 3a4c1ee9..65ede312 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -27,7 +27,7 @@ "svelte-migrate": "./bin.js" }, "dependencies": { - "@clack/prompts": "^1.0.0-alpha.0", + "@clack/prompts": "^0.9.1", "import-meta-resolve": "^4.1.0", "magic-string": "^0.30.17", "package-manager-detector": "^0.2.11", diff --git a/packages/migrate/utils.js b/packages/migrate/utils.js index cd401068..4fd00665 100644 --- a/packages/migrate/utils.js +++ b/packages/migrate/utils.js @@ -440,7 +440,5 @@ export function migration_succeeded(next_steps) { messages.push(`${i + 1}: ${step}`); }); - p.note(messages.join('\n'), 'Recommended next steps:', { - format: (line) => pc.white(line) - }); + p.note(messages.join('\n'), 'Recommended next steps:'); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a119bb8..7ad25f51 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -91,14 +91,41 @@ importers: specifier: workspace:* version: link:../core + packages/clack-core: + devDependencies: + picocolors: + specifier: ^1.1.1 + version: 1.1.1 + sisteransi: + specifier: ^1.0.5 + version: 1.0.5 + wrap-ansi: + specifier: ^8.1.0 + version: 8.1.0 + + packages/clack-prompts: + devDependencies: + '@sveltejs/clack-core': + specifier: workspace:* + version: link:../clack-core + is-unicode-supported: + specifier: ^1.3.0 + version: 1.3.0 + picocolors: + specifier: ^1.1.1 + version: 1.1.1 + sisteransi: + specifier: ^1.0.5 + version: 1.0.5 + packages/cli: devDependencies: - '@clack/prompts': - specifier: ^1.0.0-alpha.0 - version: 1.0.0-alpha.0 '@sveltejs/addons': specifier: workspace:* version: link:../addons + '@sveltejs/clack-prompts': + specifier: workspace:* + version: link:../clack-prompts '@sveltejs/cli-core': specifier: workspace:* version: link:../core @@ -144,12 +171,12 @@ importers: packages/core: devDependencies: - '@clack/prompts': - specifier: ^1.0.0-alpha.0 - version: 1.0.0-alpha.0 '@sveltejs/acorn-typescript': specifier: ^1.0.1 version: 1.0.5(acorn@8.14.1) + '@sveltejs/clack-prompts': + specifier: workspace:* + version: link:../clack-prompts '@types/estree': specifier: ^1.0.6 version: 1.0.7 @@ -211,8 +238,8 @@ importers: packages/migrate: dependencies: '@clack/prompts': - specifier: ^1.0.0-alpha.0 - version: 1.0.0-alpha.0 + specifier: ^0.9.1 + version: 0.9.1 import-meta-resolve: specifier: ^4.1.0 version: 4.1.0 @@ -322,11 +349,11 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} - '@clack/core@1.0.0-alpha.0': - resolution: {integrity: sha512-Cp/bPW/pMUCkJ7Lr8VFixvFrlnJ4tQPDHqfTNQ51z50qwX1fSIAstQLfel2NquVHqbfjyrUkBsal8OJRBPJVjw==} + '@clack/core@0.4.1': + resolution: {integrity: sha512-Pxhij4UXg8KSr7rPek6Zowm+5M22rbd2g1nfojHJkxp5YkFqiZ2+YLEM/XGVIzvGOcM0nqjIFxrpDwWRZYWYjA==} - '@clack/prompts@1.0.0-alpha.0': - resolution: {integrity: sha512-Aem7r4U2A4jdOh0PIv51Ugi+4vDgzJjGVMnuPUNVVHDGhFHEO//u6F/JY6NsZQFtXrd7ZmfePSiipikr/e5wWg==} + '@clack/prompts@0.9.1': + resolution: {integrity: sha512-JIpyaboYZeWYlyP0H+OoPPxd6nqueG/CmN6ixBiNFsIDHREevjIf0n0Ohh5gr5C8pEDknzgvz+pIJ8dMhzWIeg==} '@emnapi/core@1.4.0': resolution: {integrity: sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==} @@ -1552,6 +1579,10 @@ packages: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -2467,14 +2498,14 @@ snapshots: human-id: 4.1.1 prettier: 2.8.8 - '@clack/core@1.0.0-alpha.0': + '@clack/core@0.4.1': dependencies: picocolors: 1.1.1 sisteransi: 1.0.5 - '@clack/prompts@1.0.0-alpha.0': + '@clack/prompts@0.9.1': dependencies: - '@clack/core': 1.0.0-alpha.0 + '@clack/core': 0.4.1 picocolors: 1.1.1 sisteransi: 1.0.5 @@ -3608,6 +3639,8 @@ snapshots: dependencies: better-path-resolve: 1.0.0 + is-unicode-supported@1.3.0: {} + is-windows@1.0.2: {} isexe@2.0.0: {} diff --git a/rolldown.config.js b/rolldown.config.js index a9eb3aa7..3ffbb1da 100644 --- a/rolldown.config.js +++ b/rolldown.config.js @@ -118,7 +118,13 @@ function getConfig(project) { } /** @type {RolldownOptions[]} */ -export default [getConfig('create'), getConfig('core'), getConfig('cli')]; +export default [ + getConfig('clack-core'), + getConfig('clack-prompts'), + getConfig('create'), + getConfig('core'), + getConfig('cli') +]; /** * @param {PackageJson} pkg From 324f2eab125ec418b3ed5717fdda8b73b160b3bd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 19:05:00 +0200 Subject: [PATCH 30/38] Version Packages (#566) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/chilly-clocks-run.md | 5 ----- packages/cli/CHANGELOG.md | 6 ++++++ packages/cli/package.json | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 .changeset/chilly-clocks-run.md diff --git a/.changeset/chilly-clocks-run.md b/.changeset/chilly-clocks-run.md deleted file mode 100644 index 0ff0f71b..00000000 --- a/.changeset/chilly-clocks-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -fix: directory selection placeholder value was taken as folder path diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 3eb90e77..d7d663bc 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,11 @@ # sv +## 0.8.5 +### Patch Changes + + +- fix: directory selection placeholder value was taken as folder path ([#564](https://github.com/sveltejs/cli/pull/564)) + ## 0.8.4 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 4ecb6908..3ad66004 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "sv", - "version": "0.8.4", + "version": "0.8.5", "type": "module", "description": "A CLI for creating and updating SvelteKit projects", "license": "MIT", From 80381b12699f44a6cd13b1f95ad945173cb50dbd Mon Sep 17 00:00:00 2001 From: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 18 May 2025 01:38:43 -0400 Subject: [PATCH 31/38] fix: account for Node `current` releases with even majors when resolving `@types/node` version (#565) * fix node types version resolver * changeset * fix * format --- .changeset/dull-pens-wash.md | 5 +++++ packages/addons/common.ts | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 .changeset/dull-pens-wash.md diff --git a/.changeset/dull-pens-wash.md b/.changeset/dull-pens-wash.md new file mode 100644 index 00000000..7ba8f156 --- /dev/null +++ b/.changeset/dull-pens-wash.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix: account for Node `current` releases with even majors when resolving `@types/node` version diff --git a/packages/addons/common.ts b/packages/addons/common.ts index 90fb9eba..b03d9d5e 100644 --- a/packages/addons/common.ts +++ b/packages/addons/common.ts @@ -85,13 +85,19 @@ export function addToDemoPage(content: string, path: string): string { */ export function getNodeTypesVersion(): string { const nodeVersion = process.versions.node; + const isDenoOrBun = Boolean(process.versions.deno ?? process.versions.bun); const [major] = nodeVersion.split('.'); - const isLTS = Number(major) % 2 === 0; + const majorNum = Number(major); + const isEvenMajor = majorNum % 2 === 0; + const isLTS = !!process.release.lts || (isDenoOrBun && isEvenMajor); if (isLTS) { return `^${major}`; } - const previousLTSMajor = Number(major) - 1; + // It's possible for an even major number to _temporarily_ not + // be an `LTS` release (meaning `process.release.lts` is `undefined`) during it's `Current` stage. + // In those cases, we'll decrement the major by 2. + const previousLTSMajor = isEvenMajor ? majorNum - 2 : majorNum - 1; return `^${previousLTSMajor}`; } From 365e29606131dcb96b15204d0f2a572c60c6bd16 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 18 May 2025 07:44:18 +0200 Subject: [PATCH 32/38] Version Packages (#567) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/dull-pens-wash.md | 5 ----- packages/cli/CHANGELOG.md | 6 ++++++ packages/cli/package.json | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 .changeset/dull-pens-wash.md diff --git a/.changeset/dull-pens-wash.md b/.changeset/dull-pens-wash.md deleted file mode 100644 index 7ba8f156..00000000 --- a/.changeset/dull-pens-wash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -fix: account for Node `current` releases with even majors when resolving `@types/node` version diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index d7d663bc..b8f280e0 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,11 @@ # sv +## 0.8.6 +### Patch Changes + + +- fix: account for Node `current` releases with even majors when resolving `@types/node` version ([#565](https://github.com/sveltejs/cli/pull/565)) + ## 0.8.5 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 3ad66004..9ab11ba9 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "sv", - "version": "0.8.5", + "version": "0.8.6", "type": "module", "description": "A CLI for creating and updating SvelteKit projects", "license": "MIT", From 6665b500f157d62f36c09f0f941b3b5603e156b4 Mon Sep 17 00:00:00 2001 From: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 23 May 2025 08:56:53 -0400 Subject: [PATCH 33/38] fix: add `kit` check in `drizzle` add-on (#574) * fix setups * fix drizzle setup * update changeset * only execute the setups of pre-selected add-ons, if specified --- .changeset/new-bats-dress.md | 5 +++++ packages/addons/drizzle/index.ts | 7 +++++-- packages/cli/commands/add/index.ts | 3 ++- 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 .changeset/new-bats-dress.md diff --git a/.changeset/new-bats-dress.md b/.changeset/new-bats-dress.md new file mode 100644 index 00000000..046f214b --- /dev/null +++ b/.changeset/new-bats-dress.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix: add null check for `kit` in the `drizzle` add-on's setup diff --git a/packages/addons/drizzle/index.ts b/packages/addons/drizzle/index.ts index 681ffc7c..80219517 100644 --- a/packages/addons/drizzle/index.ts +++ b/packages/addons/drizzle/index.ts @@ -73,14 +73,17 @@ export default defineAddon({ options, setup: ({ kit, unsupported, cwd, typescript }) => { const ext = typescript ? 'ts' : 'js'; - if (!kit) unsupported('Requires SvelteKit'); + if (!kit) { + return unsupported('Requires SvelteKit'); + } - const baseDBPath = path.resolve(kit!.libDirectory, 'server', 'db'); + const baseDBPath = path.resolve(kit.libDirectory, 'server', 'db'); const paths = { 'drizzle config': path.relative(cwd, path.resolve(cwd, `drizzle.config.${ext}`)), 'database schema': path.relative(cwd, path.resolve(baseDBPath, `schema.${ext}`)), database: path.relative(cwd, path.resolve(baseDBPath, `index.${ext}`)) }; + for (const [fileType, filePath] of Object.entries(paths)) { if (fs.existsSync(filePath)) { unsupported(`Preexisting ${fileType} file at '${filePath}'`); diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index 37b47a20..abd074a3 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -387,7 +387,8 @@ export async function runAddCommand( // prepare official addons let workspace = await createWorkspace({ cwd: options.cwd }); - const addonSetupResults = setupAddons(officialAddons, workspace); + const setups = selectedAddons.length ? selectedAddons.map(({ addon }) => addon) : officialAddons; + const addonSetupResults = setupAddons(setups, workspace); // prompt which addons to apply if (selectedAddons.length === 0) { From bebc34ef9d3853a4c13dbad9ee906b6fde17a69f Mon Sep 17 00:00:00 2001 From: BridgerB <6395506+BridgerB@users.noreply.github.com> Date: Fri, 23 May 2025 10:38:50 -0600 Subject: [PATCH 34/38] fix: removed unused import in `drizzle` schema to fix lint (#571) * removed unused import to fix lint * remove text from other db providers as well * changeset --------- Co-authored-by: Manuel Serret --- .changeset/clear-laws-dress.md | 5 +++++ packages/addons/drizzle/index.ts | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 .changeset/clear-laws-dress.md diff --git a/.changeset/clear-laws-dress.md b/.changeset/clear-laws-dress.md new file mode 100644 index 00000000..b20bc452 --- /dev/null +++ b/.changeset/clear-laws-dress.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix: removed unused import in `drizzle` schema to fix lint diff --git a/packages/addons/drizzle/index.ts b/packages/addons/drizzle/index.ts index 80219517..dc3dfeae 100644 --- a/packages/addons/drizzle/index.ts +++ b/packages/addons/drizzle/index.ts @@ -228,7 +228,6 @@ export default defineAddon({ if (options.database === 'sqlite') { imports.addNamed(ast, 'drizzle-orm/sqlite-core', { sqliteTable: 'sqliteTable', - text: 'text', integer: 'integer' }); @@ -241,7 +240,6 @@ export default defineAddon({ imports.addNamed(ast, 'drizzle-orm/mysql-core', { mysqlTable: 'mysqlTable', serial: 'serial', - text: 'text', int: 'int' }); @@ -254,7 +252,6 @@ export default defineAddon({ imports.addNamed(ast, 'drizzle-orm/pg-core', { pgTable: 'pgTable', serial: 'serial', - text: 'text', integer: 'integer' }); From adfea6b186444f49d19a7034338aa674922bc66d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 23 May 2025 18:39:51 +0200 Subject: [PATCH 35/38] Version Packages (#575) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/clear-laws-dress.md | 5 ----- .changeset/new-bats-dress.md | 5 ----- packages/cli/CHANGELOG.md | 9 +++++++++ packages/cli/package.json | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) delete mode 100644 .changeset/clear-laws-dress.md delete mode 100644 .changeset/new-bats-dress.md diff --git a/.changeset/clear-laws-dress.md b/.changeset/clear-laws-dress.md deleted file mode 100644 index b20bc452..00000000 --- a/.changeset/clear-laws-dress.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -fix: removed unused import in `drizzle` schema to fix lint diff --git a/.changeset/new-bats-dress.md b/.changeset/new-bats-dress.md deleted file mode 100644 index 046f214b..00000000 --- a/.changeset/new-bats-dress.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -fix: add null check for `kit` in the `drizzle` add-on's setup diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index b8f280e0..a0d05ef8 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,14 @@ # sv +## 0.8.7 +### Patch Changes + + +- fix: removed unused import in `drizzle` schema to fix lint ([#571](https://github.com/sveltejs/cli/pull/571)) + + +- fix: add null check for `kit` in the `drizzle` add-on's setup ([#574](https://github.com/sveltejs/cli/pull/574)) + ## 0.8.6 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 9ab11ba9..f123df10 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "sv", - "version": "0.8.6", + "version": "0.8.7", "type": "module", "description": "A CLI for creating and updating SvelteKit projects", "license": "MIT", From 17799ccefc86a0348b4cc38535ed215a107071c7 Mon Sep 17 00:00:00 2001 From: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 5 Jun 2025 12:34:51 -0400 Subject: [PATCH 36/38] chore: remove `tar-fs` (#577) * remove tar-fs * fix storybook test * lint * stop touching my config --- packages/addons/_tests/storybook/test.ts | 6 +- packages/addons/storybook/index.ts | 8 +- packages/cli/commands/add/fetch-packages.ts | 21 +-- packages/cli/package.json | 2 - pnpm-lock.yaml | 152 -------------------- 5 files changed, 22 insertions(+), 167 deletions(-) diff --git a/packages/addons/_tests/storybook/test.ts b/packages/addons/_tests/storybook/test.ts index 5a7e76b8..8e796638 100644 --- a/packages/addons/_tests/storybook/test.ts +++ b/packages/addons/_tests/storybook/test.ts @@ -2,8 +2,10 @@ import process from 'node:process'; import { expect } from '@playwright/test'; import { setupTest } from '../_setup/suite.ts'; import storybook from '../../storybook/index.ts'; +import eslint from '../../eslint/index.ts'; -const { test, variants, prepareServer } = setupTest({ storybook }); +// we're including the `eslint` add-on to prevent `storybook` from modifying this repo's `eslint.config.js` +const { test, variants, prepareServer } = setupTest({ storybook, eslint }); let port = 6006; @@ -11,7 +13,7 @@ test.for(variants)( 'storybook loaded - %s', { concurrent: !process.env.CI }, async (variant, { page, ...ctx }) => { - const cwd = await ctx.run(variant, { storybook: {} }); + const cwd = await ctx.run(variant, { storybook: {}, eslint: {} }); const { close } = await prepareServer({ cwd, diff --git a/packages/addons/storybook/index.ts b/packages/addons/storybook/index.ts index ad35e16d..dd9a782f 100644 --- a/packages/addons/storybook/index.ts +++ b/packages/addons/storybook/index.ts @@ -1,3 +1,4 @@ +import process from 'node:process'; import { defineAddon } from '@sveltejs/cli-core'; import { getNodeTypesVersion } from '../common.ts'; @@ -11,7 +12,12 @@ export default defineAddon({ runsAfter('eslint'); }, run: async ({ sv }) => { - await sv.execute(['storybook@latest', 'init', '--skip-install', '--no-dev'], 'inherit'); + const args = ['storybook@latest', 'init', '--skip-install', '--no-dev']; + + // skips the onboarding prompt during tests + if (process.env.NODE_ENV?.toLowerCase() === 'test') args.push('--yes'); + + await sv.execute(args, 'inherit'); sv.devDependency(`@types/node`, getNodeTypesVersion()); } }); diff --git a/packages/cli/commands/add/fetch-packages.ts b/packages/cli/commands/add/fetch-packages.ts index 5bc86bb5..35e8144a 100644 --- a/packages/cli/commands/add/fetch-packages.ts +++ b/packages/cli/commands/add/fetch-packages.ts @@ -3,7 +3,8 @@ import path from 'node:path'; import { createGunzip } from 'node:zlib'; import { fileURLToPath } from 'node:url'; import { pipeline } from 'node:stream/promises'; -import { extract } from 'tar-fs'; +// TODO: replace tar-fs +// import { extract } from 'tar-fs'; import type { AddonWithoutExplicitArgs } from '@sveltejs/cli-core'; // path to the `node_modules` directory of `sv` @@ -65,15 +66,15 @@ export async function downloadPackage(options: DownloadOptions): Promise { - // file paths from the tarball will always have a `package/` prefix, - // so we'll need to replace it with the name of the package - header.name = header.name.replace('package', pkg.name); - return header; - } - }) + createGunzip() + // extract(NODE_MODULES, { + // map: (header) => { + // // file paths from the tarball will always have a `package/` prefix, + // // so we'll need to replace it with the name of the package + // header.name = header.name.replace('package', pkg.name); + // return header; + // } + // }) ); const { default: details } = await import(pkg.name); diff --git a/packages/cli/package.json b/packages/cli/package.json index f123df10..a973ca4c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -36,14 +36,12 @@ "@sveltejs/create": "workspace:*", "@types/degit": "^2.8.6", "@types/ps-tree": "^1.1.6", - "@types/tar-fs": "^2.0.4", "commander": "^13.1.0", "degit": "^2.8.4", "empathic": "^1.0.0", "package-manager-detector": "^0.2.11", "picocolors": "^1.1.1", "ps-tree": "^1.2.0", - "tar-fs": "^3.0.8", "tinyexec": "^0.3.2", "valibot": "^0.41.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ad25f51..5be56988 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -138,9 +138,6 @@ importers: '@types/ps-tree': specifier: ^1.1.6 version: 1.1.6 - '@types/tar-fs': - specifier: ^2.0.4 - version: 2.0.4 commander: specifier: ^13.1.0 version: 13.1.0 @@ -159,9 +156,6 @@ importers: ps-tree: specifier: ^1.2.0 version: 1.2.0 - tar-fs: - specifier: ^3.0.8 - version: 3.0.8 tinyexec: specifier: ^0.3.2 version: 0.3.2 @@ -909,12 +903,6 @@ packages: '@types/semver@7.7.0': resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} - '@types/tar-fs@2.0.4': - resolution: {integrity: sha512-ipPec0CjTmVDWE+QKr9cTmIIoTl7dFG/yARCM5MqK8i6CNLIG1P8x4kwDsOQY1ChZOZjH0wO9nvfgBvWl4R3kA==} - - '@types/tar-stream@3.1.3': - resolution: {integrity: sha512-Zbnx4wpkWBMBSu5CytMbrT5ZpMiF55qgM+EpHzR4yIDu7mv52cej8hTkOc6K+LzpkOAbxwn/m7j3iO+/l42YkQ==} - '@typescript-eslint/eslint-plugin@8.29.0': resolution: {integrity: sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1057,42 +1045,9 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - b4a@1.6.7: - resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - bare-events@2.5.4: - resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} - - bare-fs@4.1.2: - resolution: {integrity: sha512-8wSeOia5B7LwD4+h465y73KOdj5QHsbbuoUfPBi+pXgFJIPuG7SsiOdJuijWMyfid49eD+WivpfY7KT8gbAzBA==} - engines: {bare: '>=1.16.0'} - peerDependencies: - bare-buffer: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - - bare-os@3.6.1: - resolution: {integrity: sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==} - engines: {bare: '>=1.14.0'} - - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - - bare-stream@2.6.5: - resolution: {integrity: sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==} - peerDependencies: - bare-buffer: '*' - bare-events: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - bare-events: - optional: true - better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} @@ -1260,9 +1215,6 @@ packages: resolution: {integrity: sha512-qtKgI1Mv8rTacvpaTkh28HM2Lbf+IOjXb7rhpt/42kZxRm8TBb/IVlo5iL2ztT19kc/EHAFN0fZ641avlXAgdg==} engines: {node: '>=16'} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - enhanced-resolve@5.18.1: resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} engines: {node: '>=10.13.0'} @@ -1397,9 +1349,6 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -1720,9 +1669,6 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -1901,9 +1847,6 @@ packages: engines: {node: '>= 0.10'} hasBin: true - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2019,9 +1962,6 @@ packages: stream-combiner@0.0.4: resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} - streamx@2.22.0: - resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2080,19 +2020,10 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - tar-fs@3.0.8: - resolution: {integrity: sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==} - - tar-stream@3.1.7: - resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} - term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} - text-decoder@1.2.3: - resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} - thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -2321,9 +2252,6 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} @@ -2931,15 +2859,6 @@ snapshots: '@types/semver@7.7.0': {} - '@types/tar-fs@2.0.4': - dependencies: - '@types/node': 22.14.0 - '@types/tar-stream': 3.1.3 - - '@types/tar-stream@3.1.3': - dependencies: - '@types/node': 22.14.0 - '@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.24.0)(typescript@5.8.3))(eslint@9.24.0)(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -3113,35 +3032,8 @@ snapshots: axobject-query@4.1.0: {} - b4a@1.6.7: {} - balanced-match@1.0.2: {} - bare-events@2.5.4: - optional: true - - bare-fs@4.1.2: - dependencies: - bare-events: 2.5.4 - bare-path: 3.0.0 - bare-stream: 2.6.5(bare-events@2.5.4) - optional: true - - bare-os@3.6.1: - optional: true - - bare-path@3.0.0: - dependencies: - bare-os: 3.6.1 - optional: true - - bare-stream@2.6.5(bare-events@2.5.4): - dependencies: - streamx: 2.22.0 - optionalDependencies: - bare-events: 2.5.4 - optional: true - better-path-resolve@1.0.0: dependencies: is-windows: 1.0.2 @@ -3275,10 +3167,6 @@ snapshots: empathic@1.0.0: {} - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - enhanced-resolve@5.18.1: dependencies: graceful-fs: 4.2.11 @@ -3471,8 +3359,6 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-fifo@1.3.2: {} - fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3752,10 +3638,6 @@ snapshots: object-assign@4.1.1: {} - once@1.4.0: - dependencies: - wrappy: 1.0.2 - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -3909,11 +3791,6 @@ snapshots: dependencies: event-stream: 3.3.4 - pump@3.0.2: - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - punycode@2.3.1: {} quansync@0.2.10: {} @@ -4045,13 +3922,6 @@ snapshots: dependencies: duplexer: 0.1.2 - streamx@2.22.0: - dependencies: - fast-fifo: 1.3.2 - text-decoder: 1.2.3 - optionalDependencies: - bare-events: 2.5.4 - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -4142,28 +4012,8 @@ snapshots: tapable@2.2.1: {} - tar-fs@3.0.8: - dependencies: - pump: 3.0.2 - tar-stream: 3.1.7 - optionalDependencies: - bare-fs: 4.1.2 - bare-path: 3.0.0 - transitivePeerDependencies: - - bare-buffer - - tar-stream@3.1.7: - dependencies: - b4a: 1.6.7 - fast-fifo: 1.3.2 - streamx: 2.22.0 - term-size@2.2.1: {} - text-decoder@1.2.3: - dependencies: - b4a: 1.6.7 - thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -4370,8 +4220,6 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 - wrappy@1.0.2: {} - yaml@1.10.2: {} yocto-queue@0.1.0: {} From f3e2410cd6a630d91235bfdfd6ccbd32c612fc61 Mon Sep 17 00:00:00 2001 From: Manuel <30698007+manuel3108@users.noreply.github.com> Date: Sun, 8 Jun 2025 22:54:05 +0200 Subject: [PATCH 37/38] fix(vitest): `mount(...)` not available (#584) --- .changeset/cuddly-rings-travel.md | 5 +++++ packages/addons/vitest-addon/index.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/cuddly-rings-travel.md diff --git a/.changeset/cuddly-rings-travel.md b/.changeset/cuddly-rings-travel.md new file mode 100644 index 00000000..36c12289 --- /dev/null +++ b/.changeset/cuddly-rings-travel.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +fix(vitest): `mount(...)` not available diff --git a/packages/addons/vitest-addon/index.ts b/packages/addons/vitest-addon/index.ts index 59819bb3..b68c1d75 100644 --- a/packages/addons/vitest-addon/index.ts +++ b/packages/addons/vitest-addon/index.ts @@ -10,7 +10,7 @@ export default defineAddon({ run: ({ sv, typescript, kit }) => { const ext = typescript ? 'ts' : 'js'; - sv.devDependency('vitest', '^3.0.0'); + sv.devDependency('vitest', '3.1.4'); sv.devDependency('@testing-library/svelte', '^5.2.4'); sv.devDependency('@testing-library/jest-dom', '^6.6.3'); sv.devDependency('jsdom', '^26.0.0'); From 052201b60af285f7e386a011dfe916bee6462350 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 8 Jun 2025 16:54:50 -0400 Subject: [PATCH 38/38] Version Packages (#585) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/cuddly-rings-travel.md | 5 ----- packages/cli/CHANGELOG.md | 6 ++++++ packages/cli/package.json | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 .changeset/cuddly-rings-travel.md diff --git a/.changeset/cuddly-rings-travel.md b/.changeset/cuddly-rings-travel.md deleted file mode 100644 index 36c12289..00000000 --- a/.changeset/cuddly-rings-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'sv': patch ---- - -fix(vitest): `mount(...)` not available diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index a0d05ef8..d72f8a03 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,11 @@ # sv +## 0.8.8 +### Patch Changes + + +- fix(vitest): `mount(...)` not available ([#584](https://github.com/sveltejs/cli/pull/584)) + ## 0.8.7 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index a973ca4c..00b10f95 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "sv", - "version": "0.8.7", + "version": "0.8.8", "type": "module", "description": "A CLI for creating and updating SvelteKit projects", "license": "MIT",