From bed48a144d10a9986869955a4337ead7457256d6 Mon Sep 17 00:00:00 2001 From: Sila Setthakan-anan Date: Thu, 17 Oct 2024 02:21:25 +0700 Subject: [PATCH 01/56] docs: typo in `chain` example (#270) Co-authored-by: sila-strike --- docs/curry/chain.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/curry/chain.mdx b/docs/curry/chain.mdx index 8be9cf1b9..2fc0c8fdb 100644 --- a/docs/curry/chain.mdx +++ b/docs/curry/chain.mdx @@ -38,7 +38,7 @@ const gods: Deity[] = [ { rank: 9, name: 'Loki' }, ] -const getName = (god: Deity) => item.name +const getName = (god: Deity) => god.name const upperCase = (text: string) => text.toUpperCase() as Uppercase const getUpperName = _.chain(getName, upperCase) From a88fa1b0d2014b991830753400b9d1705ca0cd29 Mon Sep 17 00:00:00 2001 From: Shan Shaji Date: Sat, 19 Oct 2024 01:16:37 +0530 Subject: [PATCH 02/56] feat(types): allow readonly array in `omit` function (#272) --- src/object/omit.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object/omit.ts b/src/object/omit.ts index 175115c8b..ed8de03ce 100644 --- a/src/object/omit.ts +++ b/src/object/omit.ts @@ -13,7 +13,7 @@ */ export function omit( obj: T, - keys: TKeys[], + keys: readonly TKeys[], ): Omit { if (!obj) { return {} as Omit From 6a06ec37ec7ddc12978bb0dee8f0ff9a8524357f Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 21 Oct 2024 13:04:48 -0400 Subject: [PATCH 03/56] chore: center the language links --- README-pt_br.md | 6 +++--- README.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README-pt_br.md b/README-pt_br.md index 069cbbb23..7f3dede33 100644 --- a/README-pt_br.md +++ b/README-pt_br.md @@ -10,11 +10,11 @@ Estilo de Código: Biome.js Discussões no GitHub Gitter.im +

+ English | Português +

-  -[English](./README.md) | Português - **Diga adeus ao peso do Lodash. Pare de reinventar a roda.** Radashi (pronunciado /ruh-DAH-shee/) é uma biblioteca de utilitários para TypeScript, repleta de funções leves, legíveis, performáticas e robustas. diff --git a/README.md b/README.md index 4f3f43a9e..68a9a3150 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ Code Style: Biome.js GitHub Discussions Gitter.im +

+ English | Português +

-  -English | [Português](./README-pt_br.md) - **Ditch the bloat of Lodash. Stop reinventing the wheel.** From 6a15c962c7cb911d35ad60aec7bacbfc1aec172f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 16:10:05 -0400 Subject: [PATCH 04/56] chore(deps): lock file maintenance (#278) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 862 ++++++++++++------------- scripts/benchmarks/pnpm-lock.yaml | 56 +- scripts/browser-support/pnpm-lock.yaml | 42 +- scripts/bundle-impact/pnpm-lock.yaml | 16 +- scripts/docs/pnpm-lock.yaml | 16 +- scripts/format/pnpm-lock.yaml | 16 +- scripts/functions/pnpm-lock.yaml | 24 +- scripts/lint/pnpm-lock.yaml | 16 +- scripts/radashi-db/pnpm-lock.yaml | 56 +- scripts/release-notes/pnpm-lock.yaml | 42 +- scripts/versions/pnpm-lock.yaml | 10 +- 11 files changed, 574 insertions(+), 582 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b3bac961b..70108467d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,19 +10,19 @@ importers: devDependencies: '@biomejs/biome': specifier: ^1.8.3 - version: 1.9.3 + version: 1.9.4 '@radashi-org/biome-config': specifier: link:scripts/biome-config version: link:scripts/biome-config '@types/node': specifier: ^22.7.5 - version: 22.7.5 + version: 22.7.7 '@vitest/coverage-v8': specifier: 2.0.5 - version: 2.0.5(vitest@2.1.1(@types/node@22.7.5)) + version: 2.0.5(vitest@2.1.1(@types/node@22.7.7)) cspell: specifier: ^8.13.3 - version: 8.14.4 + version: 8.15.4 prettier: specifier: ^3.3.2 version: 3.3.3 @@ -37,13 +37,13 @@ importers: version: 0.1.4 tsup: specifier: ^8.1.0 - version: 8.3.0(postcss@8.4.47)(typescript@5.6.2)(yaml@2.5.1) + version: 8.3.0(postcss@8.4.47)(typescript@5.6.3)(yaml@2.6.0) typescript: specifier: ^5.5.2 - version: 5.6.2 + version: 5.6.3 vitest: specifier: 2.1.1 - version: 2.1.1(@types/node@22.7.5) + version: 2.1.1(@types/node@22.7.7) packages: @@ -59,271 +59,271 @@ packages: resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} engines: {node: '>=6.9.0'} - '@babel/parser@7.25.7': - resolution: {integrity: sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==} + '@babel/parser@7.25.8': + resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/types@7.25.7': - resolution: {integrity: sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==} + '@babel/types@7.25.8': + resolution: {integrity: sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@biomejs/biome@1.9.3': - resolution: {integrity: sha512-POjAPz0APAmX33WOQFGQrwLvlu7WLV4CFJMlB12b6ZSg+2q6fYu9kZwLCOA+x83zXfcPd1RpuWOKJW0GbBwLIQ==} + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@1.9.3': - resolution: {integrity: sha512-QZzD2XrjJDUyIZK+aR2i5DDxCJfdwiYbUKu9GzkCUJpL78uSelAHAPy7m0GuPMVtF/Uo+OKv97W3P9nuWZangQ==} + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@1.9.3': - resolution: {integrity: sha512-vSCoIBJE0BN3SWDFuAY/tRavpUtNoqiceJ5PrU3xDfsLcm/U6N93JSM0M9OAiC/X7mPPfejtr6Yc9vSgWlEgVw==} + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@1.9.3': - resolution: {integrity: sha512-VBzyhaqqqwP3bAkkBrhVq50i3Uj9+RWuj+pYmXrMDgjS5+SKYGE56BwNw4l8hR3SmYbLSbEo15GcV043CDSk+Q==} + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-arm64@1.9.3': - resolution: {integrity: sha512-vJkAimD2+sVviNTbaWOGqEBy31cW0ZB52KtpVIbkuma7PlfII3tsLhFa+cwbRAcRBkobBBhqZ06hXoZAN8NODQ==} + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-x64-musl@1.9.3': - resolution: {integrity: sha512-TJmnOG2+NOGM72mlczEsNki9UT+XAsMFAOo8J0me/N47EJ/vkLXxf481evfHLlxMejTY6IN8SdRSiPVLv6AHlA==} + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-linux-x64@1.9.3': - resolution: {integrity: sha512-x220V4c+romd26Mu1ptU+EudMXVS4xmzKxPVb9mgnfYlN4Yx9vD5NZraSx/onJnd3Gh/y8iPUdU5CDZJKg9COA==} + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-win32-arm64@1.9.3': - resolution: {integrity: sha512-lg/yZis2HdQGsycUvHWSzo9kOvnGgvtrYRgoCEwPBwwAL8/6crOp3+f47tPwI/LI1dZrhSji7PNsGKGHbwyAhw==} + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@1.9.3': - resolution: {integrity: sha512-cQMy2zanBkVLpmmxXdK6YePzmZx0s5Z7KEnwmrW54rcXK3myCNbQa09SwGZ8i/8sLw0H9F3X7K4rxVNGU8/D4Q==} + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] - '@cspell/cspell-bundled-dicts@8.14.4': - resolution: {integrity: sha512-JHZOpCJzN6fPBapBOvoeMxZbr0ZA11ZAkwcqM4w0lKoacbi6TwK8GIYf66hHvwLmMeav75TNXWE6aPTvBLMMqA==} + '@cspell/cspell-bundled-dicts@8.15.4': + resolution: {integrity: sha512-t5b2JwGeUmzmjl319mCuaeKGxTvmzLLRmrpdHr+ZZGRO4nf7L48Lbe9A6uwNUvsZe0cXohiNXsrrsuzRVXswVA==} engines: {node: '>=18'} - '@cspell/cspell-json-reporter@8.14.4': - resolution: {integrity: sha512-gJ6tQbGCNLyHS2iIimMg77as5MMAFv3sxU7W6tjLlZp8htiNZS7fS976g24WbT/hscsTT9Dd0sNHkpo8K3nvVw==} + '@cspell/cspell-json-reporter@8.15.4': + resolution: {integrity: sha512-solraYhZG4l++NeVCOtpc8DMvwHc46TmJt8DQbgvKtk6wOjTEcFrwKfA6Ei9YKbvyebJlpWMenO3goOll0loYg==} engines: {node: '>=18'} - '@cspell/cspell-pipe@8.14.4': - resolution: {integrity: sha512-CLLdouqfrQ4rqdQdPu0Oo+HHCU/oLYoEsK1nNPb28cZTFxnn0cuSPKB6AMPBJmMwdfJ6fMD0BCKNbEe1UNLHcw==} + '@cspell/cspell-pipe@8.15.4': + resolution: {integrity: sha512-WfCmZVFC6mX6vYlf02hWwelcSBTbDQgc5YqY+1miuMk+OHSUAHSACjZId6/a4IAID94xScvFfj7jgrdejUVvIQ==} engines: {node: '>=18'} - '@cspell/cspell-resolver@8.14.4': - resolution: {integrity: sha512-s3uZyymJ04yn8+zlTp7Pt1WRSlAel6XVo+iZRxls3LSvIP819KK64DoyjCD2Uon0Vg9P/K7aAPt8GcxDcnJtgA==} + '@cspell/cspell-resolver@8.15.4': + resolution: {integrity: sha512-Zr428o+uUTqywrdKyjluJVnDPVAJEqZ1chQLKIrHggUah1cgs5aQ7rZ+0Rv5euYMlC2idZnP7IL6TDaIib80oA==} engines: {node: '>=18'} - '@cspell/cspell-service-bus@8.14.4': - resolution: {integrity: sha512-i3UG+ep63akNsDXZrtGgICNF3MLBHtvKe/VOIH6+L+NYaAaVHqqQvOY9MdUwt1HXh8ElzfwfoRp36wc5aAvt6g==} + '@cspell/cspell-service-bus@8.15.4': + resolution: {integrity: sha512-pXYofnV/V9Y3LZdfFGbmhdxPX/ABjiD3wFjGHt5YhIU9hjVVuvjFlgY7pH2AvRjs4F8xKXv1ReWl44BJOL9gLA==} engines: {node: '>=18'} - '@cspell/cspell-types@8.14.4': - resolution: {integrity: sha512-VXwikqdHgjOVperVVCn2DOe8W3rPIswwZtMHfRYnagpzZo/TOntIjkXPJSfTtl/cFyx5DnCBsDH8ytKGlMeHkw==} + '@cspell/cspell-types@8.15.4': + resolution: {integrity: sha512-1hDtgYDQVW11zgtrr12EmGW45Deoi7IjZOhzPFLb+3WkhZ46ggWdbrRalWwBolQPDDo6+B2Q6WXz5hdND+Tpwg==} engines: {node: '>=18'} - '@cspell/dict-ada@4.0.2': - resolution: {integrity: sha512-0kENOWQeHjUlfyId/aCM/mKXtkEgV0Zu2RhUXCBr4hHo9F9vph+Uu8Ww2b0i5a4ZixoIkudGA+eJvyxrG1jUpA==} + '@cspell/dict-ada@4.0.5': + resolution: {integrity: sha512-6/RtZ/a+lhFVmrx/B7bfP7rzC4yjEYe8o74EybXcvu4Oue6J4Ey2WSYj96iuodloj1LWrkNCQyX5h4Pmcj0Iag==} - '@cspell/dict-aws@4.0.4': - resolution: {integrity: sha512-6AWI/Kkf+RcX/J81VX8+GKLeTgHWEr/OMhGk3dHQzWK66RaqDJCGDqi7494ghZKcBB7dGa3U5jcKw2FZHL/u3w==} + '@cspell/dict-aws@4.0.7': + resolution: {integrity: sha512-PoaPpa2NXtSkhGIMIKhsJUXB6UbtTt6Ao3x9JdU9kn7fRZkwD4RjHDGqulucIOz7KeEX/dNRafap6oK9xHe4RA==} - '@cspell/dict-bash@4.1.5': - resolution: {integrity: sha512-YGim/h7E2U5HCCb2ckNufT6/yyWygt9nSZ5C7qw6oOD3bygbObqD1+rlPor1JW+YyO+3GwTIHE70uKEEU6VZYw==} + '@cspell/dict-bash@4.1.8': + resolution: {integrity: sha512-I2CM2pTNthQwW069lKcrVxchJGMVQBzru2ygsHCwgidXRnJL/NTjAPOFTxN58Jc1bf7THWghfEDyKX/oyfc0yg==} - '@cspell/dict-companies@3.1.4': - resolution: {integrity: sha512-y9e0amzEK36EiiKx3VAA+SHQJPpf2Qv5cCt5eTUSggpTkiFkCh6gRKQ97rVlrKh5GJrqinDwYIJtTsxuh2vy2Q==} + '@cspell/dict-companies@3.1.7': + resolution: {integrity: sha512-ncVs/efuAkP1/tLDhWbXukBjgZ5xOUfe03neHMWsE8zvXXc5+Lw6TX5jaJXZLOoES/f4j4AhRE20jsPCF5pm+A==} - '@cspell/dict-cpp@5.1.19': - resolution: {integrity: sha512-i/odUPNFLdqWisOktu6c4qjUR4k+P9Al2RCri3Wso9EFblp53xt/5jIUdGMdDDVQGqX7s/KLtdqNxNKqP3/d+w==} + '@cspell/dict-cpp@5.1.22': + resolution: {integrity: sha512-g1/8P5/Q+xnIc8Js4UtBg3XOhcFrFlFbG3UWVtyEx49YTf0r9eyDtDt1qMMDBZT91pyCwLcAEbwS+4i5PIfNZw==} - '@cspell/dict-cryptocurrencies@5.0.0': - resolution: {integrity: sha512-Z4ARIw5+bvmShL+4ZrhDzGhnc9znaAGHOEMaB/GURdS/jdoreEDY34wdN0NtdLHDO5KO7GduZnZyqGdRoiSmYA==} + '@cspell/dict-cryptocurrencies@5.0.3': + resolution: {integrity: sha512-bl5q+Mk+T3xOZ12+FG37dB30GDxStza49Rmoax95n37MTLksk9wBo1ICOlPJ6PnDUSyeuv4SIVKgRKMKkJJglA==} - '@cspell/dict-csharp@4.0.2': - resolution: {integrity: sha512-1JMofhLK+4p4KairF75D3A924m5ERMgd1GvzhwK2geuYgd2ZKuGW72gvXpIV7aGf52E3Uu1kDXxxGAiZ5uVG7g==} + '@cspell/dict-csharp@4.0.5': + resolution: {integrity: sha512-c/sFnNgtRwRJxtC3JHKkyOm+U3/sUrltFeNwml9VsxKBHVmvlg4tk4ar58PdpW9/zTlGUkWi2i85//DN1EsUCA==} - '@cspell/dict-css@4.0.13': - resolution: {integrity: sha512-WfOQkqlAJTo8eIQeztaH0N0P+iF5hsJVKFuhy4jmARPISy8Efcv8QXk2/IVbmjJH0/ZV7dKRdnY5JFVXuVz37g==} + '@cspell/dict-css@4.0.16': + resolution: {integrity: sha512-70qu7L9z/JR6QLyJPk38fNTKitlIHnfunx0wjpWQUQ8/jGADIhMCrz6hInBjqPNdtGpYm8d1dNFyF8taEkOgrQ==} - '@cspell/dict-dart@2.2.1': - resolution: {integrity: sha512-yriKm7QkoPx3JPSSOcw6iX9gOb2N50bOo/wqWviqPYbhpMRh9Xiv6dkUy3+ot+21GuShZazO8X6U5+Vw67XEwg==} + '@cspell/dict-dart@2.2.4': + resolution: {integrity: sha512-of/cVuUIZZK/+iqefGln8G3bVpfyN6ZtH+LyLkHMoR5tEj+2vtilGNk9ngwyR8L4lEqbKuzSkOxgfVjsXf5PsQ==} - '@cspell/dict-data-science@2.0.1': - resolution: {integrity: sha512-xeutkzK0eBe+LFXOFU2kJeAYO6IuFUc1g7iRLr7HeCmlC4rsdGclwGHh61KmttL3+YHQytYStxaRBdGAXWC8Lw==} + '@cspell/dict-data-science@2.0.5': + resolution: {integrity: sha512-nNSILXmhSJox9/QoXICPQgm8q5PbiSQP4afpbkBqPi/u/b3K9MbNH5HvOOa6230gxcGdbZ9Argl2hY/U8siBlg==} - '@cspell/dict-django@4.1.0': - resolution: {integrity: sha512-bKJ4gPyrf+1c78Z0Oc4trEB9MuhcB+Yg+uTTWsvhY6O2ncFYbB/LbEZfqhfmmuK/XJJixXfI1laF2zicyf+l0w==} + '@cspell/dict-django@4.1.3': + resolution: {integrity: sha512-yBspeL3roJlO0a1vKKNaWABURuHdHZ9b1L8d3AukX0AsBy9snSggc8xCavPmSzNfeMDXbH+1lgQiYBd3IW03fg==} - '@cspell/dict-docker@1.1.7': - resolution: {integrity: sha512-XlXHAr822euV36GGsl2J1CkBIVg3fZ6879ZOg5dxTIssuhUOCiV2BuzKZmt6aIFmcdPmR14+9i9Xq+3zuxeX0A==} + '@cspell/dict-docker@1.1.11': + resolution: {integrity: sha512-s0Yhb16/R+UT1y727ekbR/itWQF3Qz275DR1ahOa66wYtPjHUXmhM3B/LT3aPaX+hD6AWmK23v57SuyfYHUjsw==} - '@cspell/dict-dotnet@5.0.5': - resolution: {integrity: sha512-gjg0L97ee146wX47dnA698cHm85e7EOpf9mVrJD8DmEaqoo/k1oPy2g7c7LgKxK9XnqwoXxhLNnngPrwXOoEtQ==} + '@cspell/dict-dotnet@5.0.8': + resolution: {integrity: sha512-MD8CmMgMEdJAIPl2Py3iqrx3B708MbCIXAuOeZ0Mzzb8YmLmiisY7QEYSZPg08D7xuwARycP0Ki+bb0GAkFSqg==} - '@cspell/dict-elixir@4.0.3': - resolution: {integrity: sha512-g+uKLWvOp9IEZvrIvBPTr/oaO6619uH/wyqypqvwpmnmpjcfi8+/hqZH8YNKt15oviK8k4CkINIqNhyndG9d9Q==} + '@cspell/dict-elixir@4.0.6': + resolution: {integrity: sha512-TfqSTxMHZ2jhiqnXlVKM0bUADtCvwKQv2XZL/DI0rx3doG8mEMS8SGPOmiyyGkHpR/pGOq18AFH3BEm4lViHIw==} - '@cspell/dict-en-common-misspellings@2.0.4': - resolution: {integrity: sha512-lvOiRjV/FG4pAGZL3PN2GCVHSTCE92cwhfLGGkOsQtxSmef6WCHfHwp9auafkBlX0yFQSKDfq6/TlpQbjbJBtQ==} + '@cspell/dict-en-common-misspellings@2.0.7': + resolution: {integrity: sha512-qNFo3G4wyabcwnM+hDrMYKN9vNVg/k9QkhqSlSst6pULjdvPyPs1mqz1689xO/v9t8e6sR4IKc3CgUXDMTYOpA==} '@cspell/dict-en-gb@1.1.33': resolution: {integrity: sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==} - '@cspell/dict-en_us@4.3.23': - resolution: {integrity: sha512-l0SoEQBsi3zDSl3OuL4/apBkxjuj4hLIg/oy6+gZ7LWh03rKdF6VNtSZNXWAmMY+pmb1cGA3ouleTiJIglbsIg==} + '@cspell/dict-en_us@4.3.26': + resolution: {integrity: sha512-hDbHYJsi3UgU1J++B0WLiYhWQdsmve3CH53FIaMRAdhrWOHcuw7h1dYkQXHFEP5lOjaq53KUHp/oh5su6VkIZg==} - '@cspell/dict-filetypes@3.0.4': - resolution: {integrity: sha512-IBi8eIVdykoGgIv5wQhOURi5lmCNJq0we6DvqKoPQJHthXbgsuO1qrHSiUVydMiQl/XvcnUWTMeAlVUlUClnVg==} + '@cspell/dict-filetypes@3.0.7': + resolution: {integrity: sha512-/DN0Ujp9/EXvpTcgih9JmBaE8n+G0wtsspyNdvHT5luRfpfol1xm/CIQb6xloCXCiLkWX+EMPeLSiVIZq+24dA==} - '@cspell/dict-flutter@1.0.0': - resolution: {integrity: sha512-W7k1VIc4KeV8BjEBxpA3cqpzbDWjfb7oXkEb0LecBCBp5Z7kcfnjT1YVotTx/U9PGyAOBhDaEdgZACVGNQhayw==} + '@cspell/dict-flutter@1.0.3': + resolution: {integrity: sha512-52C9aUEU22ptpgYh6gQyIdA4MP6NPwzbEqndfgPh3Sra191/kgs7CVqXiO1qbtZa9gnYHUoVApkoxRE7mrXHfg==} - '@cspell/dict-fonts@4.0.0': - resolution: {integrity: sha512-t9V4GeN/m517UZn63kZPUYP3OQg5f0OBLSd3Md5CU3eH1IFogSvTzHHnz4Wqqbv8NNRiBZ3HfdY/pqREZ6br3Q==} + '@cspell/dict-fonts@4.0.3': + resolution: {integrity: sha512-sPd17kV5qgYXLteuHFPn5mbp/oCHKgitNfsZLFC3W2fWEgZlhg4hK+UGig3KzrYhhvQ8wBnmZrAQm0TFKCKzsA==} - '@cspell/dict-fsharp@1.0.1': - resolution: {integrity: sha512-23xyPcD+j+NnqOjRHgW3IU7Li912SX9wmeefcY0QxukbAxJ/vAN4rBpjSwwYZeQPAn3fxdfdNZs03fg+UM+4yQ==} + '@cspell/dict-fsharp@1.0.4': + resolution: {integrity: sha512-G5wk0o1qyHUNi9nVgdE1h5wl5ylq7pcBjX8vhjHcO4XBq20D5eMoXjwqMo/+szKAqzJ+WV3BgAL50akLKrT9Rw==} - '@cspell/dict-fullstack@3.2.0': - resolution: {integrity: sha512-sIGQwU6G3rLTo+nx0GKyirR5dQSFeTIzFTOrURw51ISf+jKG9a3OmvsVtc2OANfvEAOLOC9Wfd8WYhmsO8KRDQ==} + '@cspell/dict-fullstack@3.2.3': + resolution: {integrity: sha512-62PbndIyQPH11mAv0PyiyT0vbwD0AXEocPpHlCHzfb5v9SspzCCbzQ/LIBiFmyRa+q5LMW35CnSVu6OXdT+LKg==} - '@cspell/dict-gaming-terms@1.0.5': - resolution: {integrity: sha512-C3riccZDD3d9caJQQs1+MPfrUrQ+0KHdlj9iUR1QD92FgTOF6UxoBpvHUUZ9YSezslcmpFQK4xQQ5FUGS7uWfw==} + '@cspell/dict-gaming-terms@1.0.8': + resolution: {integrity: sha512-7OL0zTl93WFWhhtpXFrtm9uZXItC3ncAs8d0iQDMMFVNU1rBr6raBNxJskxE5wx2Ant12fgI66ZGVagXfN+yfA==} - '@cspell/dict-git@3.0.0': - resolution: {integrity: sha512-simGS/lIiXbEaqJu9E2VPoYW1OTC2xrwPPXNXFMa2uo/50av56qOuaxDrZ5eH1LidFXwoc8HROCHYeKoNrDLSw==} + '@cspell/dict-git@3.0.3': + resolution: {integrity: sha512-LSxB+psZ0qoj83GkyjeEH/ZViyVsGEF/A6BAo8Nqc0w0HjD2qX/QR4sfA6JHUgQ3Yi/ccxdK7xNIo67L2ScW5A==} - '@cspell/dict-golang@6.0.13': - resolution: {integrity: sha512-uBUWi+AjFpluB6qF0rsC1gGyooqXeKPUdWHSmSXW/DCnS5PBSjRW6VWWp8efc1Fanob0QJxiZiYlc4U7oxuG6Q==} + '@cspell/dict-golang@6.0.16': + resolution: {integrity: sha512-hZOBlgcguv2Hdc93n2zjdAQm1j3grsN9T9WhPnQ1wh2vUDoCLEujg+6gWhjcLb8ECOcwZTWgNyQLWeOxEsAj/w==} - '@cspell/dict-google@1.0.1': - resolution: {integrity: sha512-dQr4M3n95uOhtloNSgB9tYYGXGGEGEykkFyRtfcp5pFuEecYUa0BSgtlGKx9RXVtJtKgR+yFT/a5uQSlt8WjqQ==} + '@cspell/dict-google@1.0.4': + resolution: {integrity: sha512-JThUT9eiguCja1mHHLwYESgxkhk17Gv7P3b1S7ZJzXw86QyVHPrbpVoMpozHk0C9o+Ym764B7gZGKmw9uMGduQ==} - '@cspell/dict-haskell@4.0.1': - resolution: {integrity: sha512-uRrl65mGrOmwT7NxspB4xKXFUenNC7IikmpRZW8Uzqbqcu7ZRCUfstuVH7T1rmjRgRkjcIjE4PC11luDou4wEQ==} + '@cspell/dict-haskell@4.0.4': + resolution: {integrity: sha512-EwQsedEEnND/vY6tqRfg9y7tsnZdxNqOxLXSXTsFA6JRhUlr8Qs88iUUAfsUzWc4nNmmzQH2UbtT25ooG9x4nA==} - '@cspell/dict-html-symbol-entities@4.0.0': - resolution: {integrity: sha512-HGRu+48ErJjoweR5IbcixxETRewrBb0uxQBd6xFGcxbEYCX8CnQFTAmKI5xNaIt2PKaZiJH3ijodGSqbKdsxhw==} + '@cspell/dict-html-symbol-entities@4.0.3': + resolution: {integrity: sha512-aABXX7dMLNFdSE8aY844X4+hvfK7977sOWgZXo4MTGAmOzR8524fjbJPswIBK7GaD3+SgFZ2yP2o0CFvXDGF+A==} - '@cspell/dict-html@4.0.6': - resolution: {integrity: sha512-cLWHfuOhE4wqwC12up6Doxo2u1xxVhX1A8zriR4CUD+osFQzUIcBK1ykNXppga+rt1WyypaJdTU2eV6OpzYrgQ==} + '@cspell/dict-html@4.0.9': + resolution: {integrity: sha512-BNp7w3m910K4qIVyOBOZxHuFNbVojUY6ES8Y8r7YjYgJkm2lCuQoVwwhPjurnomJ7BPmZTb+3LLJ58XIkgF7JQ==} - '@cspell/dict-java@5.0.7': - resolution: {integrity: sha512-ejQ9iJXYIq7R09BScU2y5OUGrSqwcD+J5mHFOKbduuQ5s/Eh/duz45KOzykeMLI6KHPVxhBKpUPBWIsfewECpQ==} + '@cspell/dict-java@5.0.10': + resolution: {integrity: sha512-pVNcOnmoGiNL8GSVq4WbX/Vs2FGS0Nej+1aEeGuUY9CU14X8yAVCG+oih5ZoLt1jaR8YfR8byUF8wdp4qG4XIw==} - '@cspell/dict-julia@1.0.1': - resolution: {integrity: sha512-4JsCLCRhhLMLiaHpmR7zHFjj1qOauzDI5ZzCNQS31TUMfsOo26jAKDfo0jljFAKgw5M2fEG7sKr8IlPpQAYrmQ==} + '@cspell/dict-julia@1.0.4': + resolution: {integrity: sha512-bFVgNX35MD3kZRbXbJVzdnN7OuEqmQXGpdOi9jzB40TSgBTlJWA4nxeAKV4CPCZxNRUGnLH0p05T/AD7Aom9/w==} - '@cspell/dict-k8s@1.0.6': - resolution: {integrity: sha512-srhVDtwrd799uxMpsPOQqeDJY+gEocgZpoK06EFrb4GRYGhv7lXo9Fb+xQMyQytzOW9dw4DNOEck++nacDuymg==} + '@cspell/dict-k8s@1.0.9': + resolution: {integrity: sha512-Q7GELSQIzo+BERl2ya/nBEnZeQC+zJP19SN1pI6gqDYraM51uYJacbbcWLYYO2Y+5joDjNt/sd/lJtLaQwoSlA==} - '@cspell/dict-latex@4.0.0': - resolution: {integrity: sha512-LPY4y6D5oI7D3d+5JMJHK/wxYTQa2lJMSNxps2JtuF8hbAnBQb3igoWEjEbIbRRH1XBM0X8dQqemnjQNCiAtxQ==} + '@cspell/dict-latex@4.0.3': + resolution: {integrity: sha512-2KXBt9fSpymYHxHfvhUpjUFyzrmN4c4P8mwIzweLyvqntBT3k0YGZJSriOdjfUjwSygrfEwiuPI1EMrvgrOMJw==} - '@cspell/dict-lorem-ipsum@4.0.0': - resolution: {integrity: sha512-1l3yjfNvMzZPibW8A7mQU4kTozwVZVw0AvFEdy+NcqtbxH+TvbSkNMqROOFWrkD2PjnKG0+Ea0tHI2Pi6Gchnw==} + '@cspell/dict-lorem-ipsum@4.0.3': + resolution: {integrity: sha512-WFpDi/PDYHXft6p0eCXuYnn7mzMEQLVeqpO+wHSUd+kz5ADusZ4cpslAA4wUZJstF1/1kMCQCZM6HLZic9bT8A==} - '@cspell/dict-lua@4.0.3': - resolution: {integrity: sha512-lDHKjsrrbqPaea13+G9s0rtXjMO06gPXPYRjRYawbNmo4E/e3XFfVzeci3OQDQNDmf2cPOwt9Ef5lu2lDmwfJg==} + '@cspell/dict-lua@4.0.6': + resolution: {integrity: sha512-Jwvh1jmAd9b+SP9e1GkS2ACbqKKRo9E1f9GdjF/ijmooZuHU0hPyqvnhZzUAxO1egbnNjxS/J2T6iUtjAUK2KQ==} - '@cspell/dict-makefile@1.0.0': - resolution: {integrity: sha512-3W9tHPcSbJa6s0bcqWo6VisEDTSN5zOtDbnPabF7rbyjRpNo0uHXHRJQF8gAbFzoTzBBhgkTmrfSiuyQm7vBUQ==} + '@cspell/dict-makefile@1.0.3': + resolution: {integrity: sha512-R3U0DSpvTs6qdqfyBATnePj9Q/pypkje0Nj26mQJ8TOBQutCRAJbr2ZFAeDjgRx5EAJU/+8txiyVF97fbVRViw==} - '@cspell/dict-monkeyc@1.0.6': - resolution: {integrity: sha512-oO8ZDu/FtZ55aq9Mb67HtaCnsLn59xvhO/t2mLLTHAp667hJFxpp7bCtr2zOrR1NELzFXmKln/2lw/PvxMSvrA==} + '@cspell/dict-monkeyc@1.0.9': + resolution: {integrity: sha512-Jvf6g5xlB4+za3ThvenYKREXTEgzx5gMUSzrAxIiPleVG4hmRb/GBSoSjtkGaibN3XxGx5x809gSTYCA/IHCpA==} - '@cspell/dict-node@5.0.1': - resolution: {integrity: sha512-lax/jGz9h3Dv83v8LHa5G0bf6wm8YVRMzbjJPG/9rp7cAGPtdrga+XANFq+B7bY5+jiSA3zvj10LUFCFjnnCCg==} + '@cspell/dict-node@5.0.4': + resolution: {integrity: sha512-Hz5hiuOvZTd7Cp1IBqUZ7/ChwJeQpD5BJuwCaDn4mPNq4iMcQ1iWBYMThvNVqCEDgKv63X52nT8RAWacss98qg==} - '@cspell/dict-npm@5.1.5': - resolution: {integrity: sha512-oAOGWuJYU3DlO+cAsStKMWN8YEkBue25cRC9EwdiL5Z84nchU20UIoYrLfIQejMlZca+1GyrNeyxRAgn4KiivA==} + '@cspell/dict-npm@5.1.8': + resolution: {integrity: sha512-AJELYXeB4fQdIoNfmuaQxB1Hli3cX6XPsQCjfBxlu0QYXhrjB/IrCLLQAjWIywDqJiWyGUFTz4DqaANm8C/r9Q==} - '@cspell/dict-php@4.0.10': - resolution: {integrity: sha512-NfTZdp6kcZDF1PvgQ6cY0zE4FUO5rSwNmBH/iwCBuaLfJAFQ97rgjxo+D2bic4CFwNjyHutnHPtjJBRANO5XQw==} + '@cspell/dict-php@4.0.13': + resolution: {integrity: sha512-P6sREMZkhElzz/HhXAjahnICYIqB/HSGp1EhZh+Y6IhvC15AzgtDP8B8VYCIsQof6rPF1SQrFwunxOv8H1e2eg==} - '@cspell/dict-powershell@5.0.10': - resolution: {integrity: sha512-U4H0zm94sNK+YP7jSFb7xb160XLf2dKIPVt5sOYctKlEyR9M16sP8FHbyWV2Yp1YtxXugoNdeCm2vwGEDAd8sg==} + '@cspell/dict-powershell@5.0.13': + resolution: {integrity: sha512-0qdj0XZIPmb77nRTynKidRJKTU0Fl+10jyLbAhFTuBWKMypVY06EaYFnwhsgsws/7nNX8MTEQuewbl9bWFAbsg==} - '@cspell/dict-public-licenses@2.0.8': - resolution: {integrity: sha512-Sup+tFS7cDV0fgpoKtUqEZ6+fA/H+XUgBiqQ/Fbs6vUE3WCjJHOIVsP+udHuyMH7iBfJ4UFYOYeORcY4EaKdMg==} + '@cspell/dict-public-licenses@2.0.11': + resolution: {integrity: sha512-rR5KjRUSnVKdfs5G+gJ4oIvQvm8+NJ6cHWY2N+GE69/FSGWDOPHxulCzeGnQU/c6WWZMSimG9o49i9r//lUQyA==} - '@cspell/dict-python@4.2.8': - resolution: {integrity: sha512-4y5dynLiajvowhB3PqlcwJ2C4okK1y2Hombec1+TGcV9sUBfo8FYNw6VRFUUrpsxO+Ut/3ncIifdZS5/zAWi5w==} + '@cspell/dict-python@4.2.12': + resolution: {integrity: sha512-U25eOFu+RE0aEcF2AsxZmq3Lic7y9zspJ9SzjrC0mfJz+yr3YmSCw4E0blMD3mZoNcf7H/vMshuKIY5AY36U+Q==} - '@cspell/dict-r@2.0.1': - resolution: {integrity: sha512-KCmKaeYMLm2Ip79mlYPc8p+B2uzwBp4KMkzeLd5E6jUlCL93Y5Nvq68wV5fRLDRTf7N1LvofkVFWfDcednFOgA==} + '@cspell/dict-r@2.0.4': + resolution: {integrity: sha512-cBpRsE/U0d9BRhiNRMLMH1PpWgw+N+1A2jumgt1if9nBGmQw4MUpg2u9I0xlFVhstTIdzXiLXMxP45cABuiUeQ==} - '@cspell/dict-ruby@5.0.4': - resolution: {integrity: sha512-URw0jScj5pv8sKCVLNnde11qVCQR442rUpSd12u46Swl+5qBaSdnOUoCWQk419kd9/dpC6bB/3l4kOSY2fdYHw==} + '@cspell/dict-ruby@5.0.7': + resolution: {integrity: sha512-4/d0hcoPzi5Alk0FmcyqlzFW9lQnZh9j07MJzPcyVO62nYJJAGKaPZL2o4qHeCS/od/ctJC5AHRdoUm0ktsw6Q==} - '@cspell/dict-rust@4.0.6': - resolution: {integrity: sha512-Buzy9PfLbdRPibSth8CV1D8ZsYqybo26yNIlAN+8ehU0pSBss0Jv4aleL4vKQ3FjouXeAC27rtEsLd7yaMZTog==} + '@cspell/dict-rust@4.0.9': + resolution: {integrity: sha512-Dhr6TIZsMV92xcikKIWei6p/qswS4M+gTkivpWwz4/1oaVk2nRrxJmCdRoVkJlZkkAc17rjxrS12mpnJZI0iWw==} - '@cspell/dict-scala@5.0.3': - resolution: {integrity: sha512-4yGb4AInT99rqprxVNT9TYb1YSpq58Owzq7zi3ZS5T0u899Y4VsxsBiOgHnQ/4W+ygi+sp+oqef8w8nABR2lkg==} + '@cspell/dict-scala@5.0.6': + resolution: {integrity: sha512-tl0YWAfjUVb4LyyE4JIMVE8DlLzb1ecHRmIWc4eT6nkyDqQgHKzdHsnusxFEFMVLIQomgSg0Zz6hJ5S1E4W4ww==} - '@cspell/dict-software-terms@4.1.7': - resolution: {integrity: sha512-+fFTALseXszDN8/khonF1DpTcYzwyNqYxhATLakr7CUPtUCO1fCH4lidMtBN4UtPVpE6tbjc5D8tj51PJxEOcw==} + '@cspell/dict-software-terms@4.1.11': + resolution: {integrity: sha512-77CTHxWFTVw6tVoMN8WBMrlNW2F2FbgATwD/6vcOuiyrJUmh8klN5ZK3m+yyK3ZzsnaW2Bduoc0fw2Ckcm/riQ==} - '@cspell/dict-sql@2.1.5': - resolution: {integrity: sha512-FmxanytHXss7GAWAXmgaxl3icTCW7YxlimyOSPNfm+njqeUDjw3kEv4mFNDDObBJv8Ec5AWCbUDkWIpkE3IpKg==} + '@cspell/dict-sql@2.1.8': + resolution: {integrity: sha512-dJRE4JV1qmXTbbGm6WIcg1knmR6K5RXnQxF4XHs5HA3LAjc/zf77F95i5LC+guOGppVF6Hdl66S2UyxT+SAF3A==} - '@cspell/dict-svelte@1.0.2': - resolution: {integrity: sha512-rPJmnn/GsDs0btNvrRBciOhngKV98yZ9SHmg8qI6HLS8hZKvcXc0LMsf9LLuMK1TmS2+WQFAan6qeqg6bBxL2Q==} + '@cspell/dict-svelte@1.0.5': + resolution: {integrity: sha512-sseHlcXOqWE4Ner9sg8KsjxwSJ2yssoJNqFHR9liWVbDV+m7kBiUtn2EB690TihzVsEmDr/0Yxrbb5Bniz70mA==} - '@cspell/dict-swift@2.0.1': - resolution: {integrity: sha512-gxrCMUOndOk7xZFmXNtkCEeroZRnS2VbeaIPiymGRHj5H+qfTAzAKxtv7jJbVA3YYvEzWcVE2oKDP4wcbhIERw==} + '@cspell/dict-swift@2.0.4': + resolution: {integrity: sha512-CsFF0IFAbRtYNg0yZcdaYbADF5F3DsM8C4wHnZefQy8YcHP/qjAF/GdGfBFBLx+XSthYuBlo2b2XQVdz3cJZBw==} - '@cspell/dict-terraform@1.0.2': - resolution: {integrity: sha512-UZdJwWIpib2Rx02w6vtXTU3z+M/VMZU0F1dhSL3Ab9otQsFntT8U1CX7wBSqQCLg8bJiCfnUyVvMK3UBm3SR8A==} + '@cspell/dict-terraform@1.0.5': + resolution: {integrity: sha512-qH3epPB2d6d5w1l4hR2OsnN8qDQ4P0z6oDB7+YiNH+BoECXv4Z38MIV1H8cxIzD2wkzkt2JTcFYaVW72MDZAlg==} - '@cspell/dict-typescript@3.1.6': - resolution: {integrity: sha512-1beC6O4P/j23VuxX+i0+F7XqPVc3hhiAzGJHEKqnWf5cWAXQtg0xz3xQJ5MvYx2a7iLaSa+lu7+05vG9UHyu9Q==} + '@cspell/dict-typescript@3.1.10': + resolution: {integrity: sha512-7Zek3w4Rh3ZYyhihJ34FdnUBwP3OmRldnEq3hZ+FgQ0PyYZjXv5ztEViRBBxXjiFx1nHozr6pLi74TxToD8xsg==} - '@cspell/dict-vue@3.0.0': - resolution: {integrity: sha512-niiEMPWPV9IeRBRzZ0TBZmNnkK3olkOPYxC1Ny2AX4TGlYRajcW0WUtoSHmvvjZNfWLSg2L6ruiBeuPSbjnG6A==} + '@cspell/dict-vue@3.0.3': + resolution: {integrity: sha512-akmYbrgAGumqk1xXALtDJcEcOMYBYMnkjpmGzH13Ozhq1mkPF4VgllFQlm1xYde+BUKNnzMgPEzxrL2qZllgYA==} - '@cspell/dynamic-import@8.14.4': - resolution: {integrity: sha512-GjKsBJvPXp4dYRqsMn7n1zpnKbnpfJnlKLOVeoFBh8fi4n06G50xYr+G25CWX1WT3WFaALAavvVICEUPrVsuqg==} + '@cspell/dynamic-import@8.15.4': + resolution: {integrity: sha512-tr0F6EYN6qtniNvt1Uib+PgYQHeo4dQHXE2Optap+hYTOoQ2VoQ+SwBVjZ+Q2bmSAB0fmOyf0AvgsUtnWIpavw==} engines: {node: '>=18.0'} - '@cspell/filetypes@8.14.4': - resolution: {integrity: sha512-qd68dD7xTA4Mnf/wjIKYz2SkiTBshIM+yszOUtLa06YJm0aocoNQ25FHXyYEQYm9NQXCYnRWWA02sFMGs8Sv/w==} + '@cspell/filetypes@8.15.4': + resolution: {integrity: sha512-sNl6jr3ym/4151EY76qlI/00HHsiLZBqW7Vb1tqCzsgSg3EpL30ddjr74So6Sg2PN26Yf09hvxGTJzXn1R4aYw==} engines: {node: '>=18'} - '@cspell/strong-weak-map@8.14.4': - resolution: {integrity: sha512-Uyfck64TfVU24wAP3BLGQ5EsAfzIZiLfN90NhttpEM7GlOBmbGrEJd4hNOwfpYsE/TT80eGWQVPRTLr5SDbXFA==} + '@cspell/strong-weak-map@8.15.4': + resolution: {integrity: sha512-m5DeQksbhJFqcSYF8Q0Af/WXmXCMAJocCUShkzOXK+uZNXnvhBZN7VyQ9hL+GRzX8JTPEPdVcz2lFyVE5p+LzQ==} engines: {node: '>=18'} - '@cspell/url@8.14.4': - resolution: {integrity: sha512-htHhNF8WrM/NfaLSWuTYw0NqVgFRVHYSyHlRT3i/Yv5xvErld8Gw7C6ldm+0TLjoGlUe6X1VV72JSir7+yLp/Q==} + '@cspell/url@8.15.4': + resolution: {integrity: sha512-K2oZu/oLQPs5suRpLS8uu04O3YMUioSlEU1D66fRoOxzI5NzLt7i7yMg3HQHjChGa09N5bzqmrVdhmQrRZXwGg==} engines: {node: '>=18.0'} '@esbuild/aix-ppc64@0.21.5': @@ -733,8 +733,8 @@ packages: '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - '@types/node@22.7.5': - resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} '@vitest/coverage-v8@2.0.5': resolution: {integrity: sha512-qeFcySCg5FLO2bHHSa0tAZAOnAUbp4L6/A5JDuj9+bt53JREl8hpLjLHEWF0e/gWc8INVpJaqA7+Ene2rclpZg==} @@ -759,8 +759,8 @@ packages: '@vitest/pretty-format@2.1.1': resolution: {integrity: sha512-SjxPFOtuINDUW8/UkElJYQSFtnWX7tMksSGW0vfjxMneFqxVr8YJ979QpMbDW7g+BIiq88RAGDjf7en6rvLPPQ==} - '@vitest/pretty-format@2.1.2': - resolution: {integrity: sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==} + '@vitest/pretty-format@2.1.3': + resolution: {integrity: sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==} '@vitest/runner@2.1.1': resolution: {integrity: sha512-uTPuY6PWOYitIkLPidaY5L3t0JJITdGTSwBtwMjKzo5O6RCOEncz9PUN+0pDidX8kTHYjO0EwUIvhlGpnGpxmA==} @@ -886,42 +886,42 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - cspell-config-lib@8.14.4: - resolution: {integrity: sha512-cnUeJfniTiebqCaQmIUnbSrPrTH7xzKRQjJDHAEV0WYnOG2MhRXI13OzytdFdhkVBdStmgTzTCJKE7x+kmU2NA==} + cspell-config-lib@8.15.4: + resolution: {integrity: sha512-vUgikQTRkRMTdkZqSs7F2cTdPpX61cTjr/9L/VCkXkbW38ObCr4650ioiF1Wq3zDF3Gy2bc4ECTpD2PZUXX5SA==} engines: {node: '>=18'} - cspell-dictionary@8.14.4: - resolution: {integrity: sha512-pZvQHxpAW5fZAnt3ZKKy3s7M+3CX2t8tCS3uJrpEHIynlCawpG0fPF78rVE5o+g0dON36Lguc/BUuSN4IWKLmQ==} + cspell-dictionary@8.15.4: + resolution: {integrity: sha512-8+p/l9Saac7qyCbqtELneDoT7CwHu9gYmnI8uXMu34/lPGjhVhy10ZeI0+t1djaO2YyASK400YFKq5uP/5KulA==} engines: {node: '>=18'} - cspell-gitignore@8.14.4: - resolution: {integrity: sha512-RwfQEW5hD7CpYwS7m3b0ONG0nTLKP6bL2tvMdl7qtaYkL7ztGdsBTtLD1pmwqUsCbiN5RuaOxhYOYeRcpFRIkQ==} + cspell-gitignore@8.15.4: + resolution: {integrity: sha512-9n5PpQ8gEf8YcvEtoZGZ2Ma6wnqSFkD2GrmyjISy39DfIX/jNLN7GX2wJm6OD2P4FjXer95ypmIb/JWTlfmbTw==} engines: {node: '>=18'} hasBin: true - cspell-glob@8.14.4: - resolution: {integrity: sha512-C/xTS5nujMRMuguibq92qMVP767mtxrur7DcVolCvpzcivm1RB5NtIN0OctQxTyMbnmKeQv1t4epRKQ9A8vWRg==} + cspell-glob@8.15.4: + resolution: {integrity: sha512-TTfRRHRAN+PN9drIz4MAEgKKYnPThBOlPMdFddyuisvU33Do1sPAnqkkOjTEFdi3jAA5KwnSva68SVH6IzzMBQ==} engines: {node: '>=18'} - cspell-grammar@8.14.4: - resolution: {integrity: sha512-yaSKAAJDiamsw3FChbw4HXb2RvTQrDsLelh1+T4MavarOIcAxXrqAJ8ysqm++g+S/ooJz2YO8YWIyzJKxcMf8g==} + cspell-grammar@8.15.4: + resolution: {integrity: sha512-MKiKyYi05mRtXOxPoTv3Ksi0GwYLiK84Uq0C+5PaMrnIjXeed0bsddSFXCT+7ywFJc7PdjhTtz0M/9WWK3UgbA==} engines: {node: '>=18'} hasBin: true - cspell-io@8.14.4: - resolution: {integrity: sha512-o6OTWRyx/Az+PFhr1B0wMAwqG070hFC9g73Fkxd8+rHX0rfRS69QZH7LgSmZytqbZIMxCTDGdsLl33MFGWCbZQ==} + cspell-io@8.15.4: + resolution: {integrity: sha512-rXIEREPTFV9dwwg4EKfvzqlCNOvT6910AYED5YrSt8Y68usRJ9lbqdx0BrDndVCd33bp1o+9JBfHuRiFIQC81g==} engines: {node: '>=18'} - cspell-lib@8.14.4: - resolution: {integrity: sha512-qdkUkKtm+nmgpA4jQbmQTuepDfjHBDWvs3zDuEwVIVFq/h8gnXrRr75gJ3RYdTy+vOOqHPoLLqgxyqkUUrUGXA==} + cspell-lib@8.15.4: + resolution: {integrity: sha512-iLp/625fvCyFFxSyZYLMgqHIKcrhN4hT7Hw5+ySa38Bp/OfA81ANqWHpsDQ0bGsALTRn/DHBpQYj4xCW/aN9tw==} engines: {node: '>=18'} - cspell-trie-lib@8.14.4: - resolution: {integrity: sha512-zu8EJ33CH+FA5lwTRGqS//Q6phO0qtgEmODMR1KPlD7WlrfTFMb3bWFsLo/tiv5hjpsn7CM6dYDAAgBOSkoyhQ==} + cspell-trie-lib@8.15.4: + resolution: {integrity: sha512-sg9klsNHyrfos0Boiio+qy5d6fI9cCNjBqFYrNxvpKpwZ4gEzDzjgEKdZY1C76RD2KoBQ8I1NF5YcGc0+hhhCw==} engines: {node: '>=18'} - cspell@8.14.4: - resolution: {integrity: sha512-R5Awb3i/RKaVVcZzFt8dkN3M6VnifIEDYBcbzbmYjZ/Eq+ASF+QTmI0E9WPhMEcFM1nd7YOyXnETo560yRdoKw==} + cspell@8.15.4: + resolution: {integrity: sha512-hUOxcwmNWuHzVeGHyN5v/T9MkyCE5gi0mvatxsM794B2wOuR1ZORgjZH62P2HY1uBkXe/x5C6ITWrSyh0WgAcg==} engines: {node: '>=18'} hasBin: true @@ -987,8 +987,8 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - fdir@6.4.0: - resolution: {integrity: sha512-3oB133prH1o4j/L5lLW7uOCF1PlD+/It2L0eL/iAqWMB91RBbqTewABqxhj0ibBd90EEmWZq7ntIWzVaWcXTGQ==} + fdir@6.4.2: + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -1027,9 +1027,6 @@ packages: resolution: {integrity: sha512-47Frx13aZh01afHJTB3zTtKIlFI6vWY+MYCN9Qpew6i52rfKjnhCF/l1YlC8UmEMvvntZZ6z4PiCcmyuedR2aQ==} engines: {node: '>=18'} - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - get-stdin@9.0.0: resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} engines: {node: '>=12'} @@ -1146,14 +1143,14 @@ packages: lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - loupe@3.1.1: - resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - magic-string@0.30.11: - resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} @@ -1241,8 +1238,8 @@ packages: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} - picocolors@1.1.0: - resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -1418,8 +1415,8 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@0.3.0: - resolution: {integrity: sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==} + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} tinyglobby@0.2.9: resolution: {integrity: sha512-8or1+BGEdk1Zkkw2ii16qSS7uVrQJPre5A9o/XkWPATkk23FZh/15BKFxPnlTy6vkljZxLqYCzzBMj30ZrSvjw==} @@ -1459,8 +1456,8 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - tslib@2.7.0: - resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} tsup@8.3.0: resolution: {integrity: sha512-ALscEeyS03IomcuNdFdc0YWGVIkwH1Ws7nfTbAPuoILvEV2hpGQAY72LIOjglGo4ShWpZfpBqP/jpQVCzqYQag==} @@ -1481,8 +1478,8 @@ packages: typescript: optional: true - typescript@5.6.2: - resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true @@ -1494,8 +1491,8 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.4.8: - resolution: {integrity: sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==} + vite@5.4.9: + resolution: {integrity: sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -1584,8 +1581,8 @@ packages: resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} engines: {node: '>=12'} - yaml@2.5.1: - resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} + yaml@2.6.0: + resolution: {integrity: sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==} engines: {node: '>= 14'} hasBin: true @@ -1600,11 +1597,11 @@ snapshots: '@babel/helper-validator-identifier@7.25.7': {} - '@babel/parser@7.25.7': + '@babel/parser@7.25.8': dependencies: - '@babel/types': 7.25.7 + '@babel/types': 7.25.8 - '@babel/types@7.25.7': + '@babel/types@7.25.8': dependencies: '@babel/helper-string-parser': 7.25.7 '@babel/helper-validator-identifier': 7.25.7 @@ -1612,230 +1609,230 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@biomejs/biome@1.9.3': + '@biomejs/biome@1.9.4': optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.9.3 - '@biomejs/cli-darwin-x64': 1.9.3 - '@biomejs/cli-linux-arm64': 1.9.3 - '@biomejs/cli-linux-arm64-musl': 1.9.3 - '@biomejs/cli-linux-x64': 1.9.3 - '@biomejs/cli-linux-x64-musl': 1.9.3 - '@biomejs/cli-win32-arm64': 1.9.3 - '@biomejs/cli-win32-x64': 1.9.3 + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 - '@biomejs/cli-darwin-arm64@1.9.3': + '@biomejs/cli-darwin-arm64@1.9.4': optional: true - '@biomejs/cli-darwin-x64@1.9.3': + '@biomejs/cli-darwin-x64@1.9.4': optional: true - '@biomejs/cli-linux-arm64-musl@1.9.3': + '@biomejs/cli-linux-arm64-musl@1.9.4': optional: true - '@biomejs/cli-linux-arm64@1.9.3': + '@biomejs/cli-linux-arm64@1.9.4': optional: true - '@biomejs/cli-linux-x64-musl@1.9.3': + '@biomejs/cli-linux-x64-musl@1.9.4': optional: true - '@biomejs/cli-linux-x64@1.9.3': + '@biomejs/cli-linux-x64@1.9.4': optional: true - '@biomejs/cli-win32-arm64@1.9.3': + '@biomejs/cli-win32-arm64@1.9.4': optional: true - '@biomejs/cli-win32-x64@1.9.3': + '@biomejs/cli-win32-x64@1.9.4': optional: true - '@cspell/cspell-bundled-dicts@8.14.4': + '@cspell/cspell-bundled-dicts@8.15.4': dependencies: - '@cspell/dict-ada': 4.0.2 - '@cspell/dict-aws': 4.0.4 - '@cspell/dict-bash': 4.1.5 - '@cspell/dict-companies': 3.1.4 - '@cspell/dict-cpp': 5.1.19 - '@cspell/dict-cryptocurrencies': 5.0.0 - '@cspell/dict-csharp': 4.0.2 - '@cspell/dict-css': 4.0.13 - '@cspell/dict-dart': 2.2.1 - '@cspell/dict-django': 4.1.0 - '@cspell/dict-docker': 1.1.7 - '@cspell/dict-dotnet': 5.0.5 - '@cspell/dict-elixir': 4.0.3 - '@cspell/dict-en-common-misspellings': 2.0.4 + '@cspell/dict-ada': 4.0.5 + '@cspell/dict-aws': 4.0.7 + '@cspell/dict-bash': 4.1.8 + '@cspell/dict-companies': 3.1.7 + '@cspell/dict-cpp': 5.1.22 + '@cspell/dict-cryptocurrencies': 5.0.3 + '@cspell/dict-csharp': 4.0.5 + '@cspell/dict-css': 4.0.16 + '@cspell/dict-dart': 2.2.4 + '@cspell/dict-django': 4.1.3 + '@cspell/dict-docker': 1.1.11 + '@cspell/dict-dotnet': 5.0.8 + '@cspell/dict-elixir': 4.0.6 + '@cspell/dict-en-common-misspellings': 2.0.7 '@cspell/dict-en-gb': 1.1.33 - '@cspell/dict-en_us': 4.3.23 - '@cspell/dict-filetypes': 3.0.4 - '@cspell/dict-flutter': 1.0.0 - '@cspell/dict-fonts': 4.0.0 - '@cspell/dict-fsharp': 1.0.1 - '@cspell/dict-fullstack': 3.2.0 - '@cspell/dict-gaming-terms': 1.0.5 - '@cspell/dict-git': 3.0.0 - '@cspell/dict-golang': 6.0.13 - '@cspell/dict-google': 1.0.1 - '@cspell/dict-haskell': 4.0.1 - '@cspell/dict-html': 4.0.6 - '@cspell/dict-html-symbol-entities': 4.0.0 - '@cspell/dict-java': 5.0.7 - '@cspell/dict-julia': 1.0.1 - '@cspell/dict-k8s': 1.0.6 - '@cspell/dict-latex': 4.0.0 - '@cspell/dict-lorem-ipsum': 4.0.0 - '@cspell/dict-lua': 4.0.3 - '@cspell/dict-makefile': 1.0.0 - '@cspell/dict-monkeyc': 1.0.6 - '@cspell/dict-node': 5.0.1 - '@cspell/dict-npm': 5.1.5 - '@cspell/dict-php': 4.0.10 - '@cspell/dict-powershell': 5.0.10 - '@cspell/dict-public-licenses': 2.0.8 - '@cspell/dict-python': 4.2.8 - '@cspell/dict-r': 2.0.1 - '@cspell/dict-ruby': 5.0.4 - '@cspell/dict-rust': 4.0.6 - '@cspell/dict-scala': 5.0.3 - '@cspell/dict-software-terms': 4.1.7 - '@cspell/dict-sql': 2.1.5 - '@cspell/dict-svelte': 1.0.2 - '@cspell/dict-swift': 2.0.1 - '@cspell/dict-terraform': 1.0.2 - '@cspell/dict-typescript': 3.1.6 - '@cspell/dict-vue': 3.0.0 - - '@cspell/cspell-json-reporter@8.14.4': - dependencies: - '@cspell/cspell-types': 8.14.4 - - '@cspell/cspell-pipe@8.14.4': {} - - '@cspell/cspell-resolver@8.14.4': + '@cspell/dict-en_us': 4.3.26 + '@cspell/dict-filetypes': 3.0.7 + '@cspell/dict-flutter': 1.0.3 + '@cspell/dict-fonts': 4.0.3 + '@cspell/dict-fsharp': 1.0.4 + '@cspell/dict-fullstack': 3.2.3 + '@cspell/dict-gaming-terms': 1.0.8 + '@cspell/dict-git': 3.0.3 + '@cspell/dict-golang': 6.0.16 + '@cspell/dict-google': 1.0.4 + '@cspell/dict-haskell': 4.0.4 + '@cspell/dict-html': 4.0.9 + '@cspell/dict-html-symbol-entities': 4.0.3 + '@cspell/dict-java': 5.0.10 + '@cspell/dict-julia': 1.0.4 + '@cspell/dict-k8s': 1.0.9 + '@cspell/dict-latex': 4.0.3 + '@cspell/dict-lorem-ipsum': 4.0.3 + '@cspell/dict-lua': 4.0.6 + '@cspell/dict-makefile': 1.0.3 + '@cspell/dict-monkeyc': 1.0.9 + '@cspell/dict-node': 5.0.4 + '@cspell/dict-npm': 5.1.8 + '@cspell/dict-php': 4.0.13 + '@cspell/dict-powershell': 5.0.13 + '@cspell/dict-public-licenses': 2.0.11 + '@cspell/dict-python': 4.2.12 + '@cspell/dict-r': 2.0.4 + '@cspell/dict-ruby': 5.0.7 + '@cspell/dict-rust': 4.0.9 + '@cspell/dict-scala': 5.0.6 + '@cspell/dict-software-terms': 4.1.11 + '@cspell/dict-sql': 2.1.8 + '@cspell/dict-svelte': 1.0.5 + '@cspell/dict-swift': 2.0.4 + '@cspell/dict-terraform': 1.0.5 + '@cspell/dict-typescript': 3.1.10 + '@cspell/dict-vue': 3.0.3 + + '@cspell/cspell-json-reporter@8.15.4': + dependencies: + '@cspell/cspell-types': 8.15.4 + + '@cspell/cspell-pipe@8.15.4': {} + + '@cspell/cspell-resolver@8.15.4': dependencies: global-directory: 4.0.1 - '@cspell/cspell-service-bus@8.14.4': {} + '@cspell/cspell-service-bus@8.15.4': {} - '@cspell/cspell-types@8.14.4': {} + '@cspell/cspell-types@8.15.4': {} - '@cspell/dict-ada@4.0.2': {} + '@cspell/dict-ada@4.0.5': {} - '@cspell/dict-aws@4.0.4': {} + '@cspell/dict-aws@4.0.7': {} - '@cspell/dict-bash@4.1.5': {} + '@cspell/dict-bash@4.1.8': {} - '@cspell/dict-companies@3.1.4': {} + '@cspell/dict-companies@3.1.7': {} - '@cspell/dict-cpp@5.1.19': {} + '@cspell/dict-cpp@5.1.22': {} - '@cspell/dict-cryptocurrencies@5.0.0': {} + '@cspell/dict-cryptocurrencies@5.0.3': {} - '@cspell/dict-csharp@4.0.2': {} + '@cspell/dict-csharp@4.0.5': {} - '@cspell/dict-css@4.0.13': {} + '@cspell/dict-css@4.0.16': {} - '@cspell/dict-dart@2.2.1': {} + '@cspell/dict-dart@2.2.4': {} - '@cspell/dict-data-science@2.0.1': {} + '@cspell/dict-data-science@2.0.5': {} - '@cspell/dict-django@4.1.0': {} + '@cspell/dict-django@4.1.3': {} - '@cspell/dict-docker@1.1.7': {} + '@cspell/dict-docker@1.1.11': {} - '@cspell/dict-dotnet@5.0.5': {} + '@cspell/dict-dotnet@5.0.8': {} - '@cspell/dict-elixir@4.0.3': {} + '@cspell/dict-elixir@4.0.6': {} - '@cspell/dict-en-common-misspellings@2.0.4': {} + '@cspell/dict-en-common-misspellings@2.0.7': {} '@cspell/dict-en-gb@1.1.33': {} - '@cspell/dict-en_us@4.3.23': {} + '@cspell/dict-en_us@4.3.26': {} - '@cspell/dict-filetypes@3.0.4': {} + '@cspell/dict-filetypes@3.0.7': {} - '@cspell/dict-flutter@1.0.0': {} + '@cspell/dict-flutter@1.0.3': {} - '@cspell/dict-fonts@4.0.0': {} + '@cspell/dict-fonts@4.0.3': {} - '@cspell/dict-fsharp@1.0.1': {} + '@cspell/dict-fsharp@1.0.4': {} - '@cspell/dict-fullstack@3.2.0': {} + '@cspell/dict-fullstack@3.2.3': {} - '@cspell/dict-gaming-terms@1.0.5': {} + '@cspell/dict-gaming-terms@1.0.8': {} - '@cspell/dict-git@3.0.0': {} + '@cspell/dict-git@3.0.3': {} - '@cspell/dict-golang@6.0.13': {} + '@cspell/dict-golang@6.0.16': {} - '@cspell/dict-google@1.0.1': {} + '@cspell/dict-google@1.0.4': {} - '@cspell/dict-haskell@4.0.1': {} + '@cspell/dict-haskell@4.0.4': {} - '@cspell/dict-html-symbol-entities@4.0.0': {} + '@cspell/dict-html-symbol-entities@4.0.3': {} - '@cspell/dict-html@4.0.6': {} + '@cspell/dict-html@4.0.9': {} - '@cspell/dict-java@5.0.7': {} + '@cspell/dict-java@5.0.10': {} - '@cspell/dict-julia@1.0.1': {} + '@cspell/dict-julia@1.0.4': {} - '@cspell/dict-k8s@1.0.6': {} + '@cspell/dict-k8s@1.0.9': {} - '@cspell/dict-latex@4.0.0': {} + '@cspell/dict-latex@4.0.3': {} - '@cspell/dict-lorem-ipsum@4.0.0': {} + '@cspell/dict-lorem-ipsum@4.0.3': {} - '@cspell/dict-lua@4.0.3': {} + '@cspell/dict-lua@4.0.6': {} - '@cspell/dict-makefile@1.0.0': {} + '@cspell/dict-makefile@1.0.3': {} - '@cspell/dict-monkeyc@1.0.6': {} + '@cspell/dict-monkeyc@1.0.9': {} - '@cspell/dict-node@5.0.1': {} + '@cspell/dict-node@5.0.4': {} - '@cspell/dict-npm@5.1.5': {} + '@cspell/dict-npm@5.1.8': {} - '@cspell/dict-php@4.0.10': {} + '@cspell/dict-php@4.0.13': {} - '@cspell/dict-powershell@5.0.10': {} + '@cspell/dict-powershell@5.0.13': {} - '@cspell/dict-public-licenses@2.0.8': {} + '@cspell/dict-public-licenses@2.0.11': {} - '@cspell/dict-python@4.2.8': + '@cspell/dict-python@4.2.12': dependencies: - '@cspell/dict-data-science': 2.0.1 + '@cspell/dict-data-science': 2.0.5 - '@cspell/dict-r@2.0.1': {} + '@cspell/dict-r@2.0.4': {} - '@cspell/dict-ruby@5.0.4': {} + '@cspell/dict-ruby@5.0.7': {} - '@cspell/dict-rust@4.0.6': {} + '@cspell/dict-rust@4.0.9': {} - '@cspell/dict-scala@5.0.3': {} + '@cspell/dict-scala@5.0.6': {} - '@cspell/dict-software-terms@4.1.7': {} + '@cspell/dict-software-terms@4.1.11': {} - '@cspell/dict-sql@2.1.5': {} + '@cspell/dict-sql@2.1.8': {} - '@cspell/dict-svelte@1.0.2': {} + '@cspell/dict-svelte@1.0.5': {} - '@cspell/dict-swift@2.0.1': {} + '@cspell/dict-swift@2.0.4': {} - '@cspell/dict-terraform@1.0.2': {} + '@cspell/dict-terraform@1.0.5': {} - '@cspell/dict-typescript@3.1.6': {} + '@cspell/dict-typescript@3.1.10': {} - '@cspell/dict-vue@3.0.0': {} + '@cspell/dict-vue@3.0.3': {} - '@cspell/dynamic-import@8.14.4': + '@cspell/dynamic-import@8.15.4': dependencies: import-meta-resolve: 4.1.0 - '@cspell/filetypes@8.14.4': {} + '@cspell/filetypes@8.15.4': {} - '@cspell/strong-weak-map@8.14.4': {} + '@cspell/strong-weak-map@8.15.4': {} - '@cspell/url@8.14.4': {} + '@cspell/url@8.15.4': {} '@esbuild/aix-ppc64@0.21.5': optional: true @@ -2071,11 +2068,11 @@ snapshots: '@types/estree@1.0.6': {} - '@types/node@22.7.5': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 - '@vitest/coverage-v8@2.0.5(vitest@2.1.1(@types/node@22.7.5))': + '@vitest/coverage-v8@2.0.5(vitest@2.1.1(@types/node@22.7.7))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -2084,12 +2081,12 @@ snapshots: istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 - magic-string: 0.30.11 + magic-string: 0.30.12 magicast: 0.3.5 std-env: 3.7.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.1.1(@types/node@22.7.5) + vitest: 2.1.1(@types/node@22.7.7) transitivePeerDependencies: - supports-color @@ -2100,19 +2097,19 @@ snapshots: chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(vite@5.4.8(@types/node@22.7.5))': + '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(vite@5.4.9(@types/node@22.7.7))': dependencies: '@vitest/spy': 2.1.1 estree-walker: 3.0.3 - magic-string: 0.30.11 + magic-string: 0.30.12 optionalDependencies: - vite: 5.4.8(@types/node@22.7.5) + vite: 5.4.9(@types/node@22.7.7) '@vitest/pretty-format@2.1.1': dependencies: tinyrainbow: 1.2.0 - '@vitest/pretty-format@2.1.2': + '@vitest/pretty-format@2.1.3': dependencies: tinyrainbow: 1.2.0 @@ -2124,7 +2121,7 @@ snapshots: '@vitest/snapshot@2.1.1': dependencies: '@vitest/pretty-format': 2.1.1 - magic-string: 0.30.11 + magic-string: 0.30.12 pathe: 1.1.2 '@vitest/spy@2.1.1': @@ -2134,7 +2131,7 @@ snapshots: '@vitest/utils@2.1.1': dependencies: '@vitest/pretty-format': 2.1.1 - loupe: 3.1.1 + loupe: 3.1.2 tinyrainbow: 1.2.0 ansi-regex@5.0.1: {} @@ -2184,7 +2181,7 @@ snapshots: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.1 + loupe: 3.1.2 pathval: 2.0.0 chalk-template@1.1.0: @@ -2240,59 +2237,59 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - cspell-config-lib@8.14.4: + cspell-config-lib@8.15.4: dependencies: - '@cspell/cspell-types': 8.14.4 + '@cspell/cspell-types': 8.15.4 comment-json: 4.2.5 - yaml: 2.5.1 + yaml: 2.6.0 - cspell-dictionary@8.14.4: + cspell-dictionary@8.15.4: dependencies: - '@cspell/cspell-pipe': 8.14.4 - '@cspell/cspell-types': 8.14.4 - cspell-trie-lib: 8.14.4 + '@cspell/cspell-pipe': 8.15.4 + '@cspell/cspell-types': 8.15.4 + cspell-trie-lib: 8.15.4 fast-equals: 5.0.1 - cspell-gitignore@8.14.4: + cspell-gitignore@8.15.4: dependencies: - '@cspell/url': 8.14.4 - cspell-glob: 8.14.4 - cspell-io: 8.14.4 + '@cspell/url': 8.15.4 + cspell-glob: 8.15.4 + cspell-io: 8.15.4 find-up-simple: 1.0.0 - cspell-glob@8.14.4: + cspell-glob@8.15.4: dependencies: - '@cspell/url': 8.14.4 + '@cspell/url': 8.15.4 micromatch: 4.0.8 - cspell-grammar@8.14.4: + cspell-grammar@8.15.4: dependencies: - '@cspell/cspell-pipe': 8.14.4 - '@cspell/cspell-types': 8.14.4 + '@cspell/cspell-pipe': 8.15.4 + '@cspell/cspell-types': 8.15.4 - cspell-io@8.14.4: + cspell-io@8.15.4: dependencies: - '@cspell/cspell-service-bus': 8.14.4 - '@cspell/url': 8.14.4 + '@cspell/cspell-service-bus': 8.15.4 + '@cspell/url': 8.15.4 - cspell-lib@8.14.4: + cspell-lib@8.15.4: dependencies: - '@cspell/cspell-bundled-dicts': 8.14.4 - '@cspell/cspell-pipe': 8.14.4 - '@cspell/cspell-resolver': 8.14.4 - '@cspell/cspell-types': 8.14.4 - '@cspell/dynamic-import': 8.14.4 - '@cspell/filetypes': 8.14.4 - '@cspell/strong-weak-map': 8.14.4 - '@cspell/url': 8.14.4 + '@cspell/cspell-bundled-dicts': 8.15.4 + '@cspell/cspell-pipe': 8.15.4 + '@cspell/cspell-resolver': 8.15.4 + '@cspell/cspell-types': 8.15.4 + '@cspell/dynamic-import': 8.15.4 + '@cspell/filetypes': 8.15.4 + '@cspell/strong-weak-map': 8.15.4 + '@cspell/url': 8.15.4 clear-module: 4.1.2 comment-json: 4.2.5 - cspell-config-lib: 8.14.4 - cspell-dictionary: 8.14.4 - cspell-glob: 8.14.4 - cspell-grammar: 8.14.4 - cspell-io: 8.14.4 - cspell-trie-lib: 8.14.4 + cspell-config-lib: 8.15.4 + cspell-dictionary: 8.15.4 + cspell-glob: 8.15.4 + cspell-grammar: 8.15.4 + cspell-io: 8.15.4 + cspell-trie-lib: 8.15.4 env-paths: 3.0.0 fast-equals: 5.0.1 gensequence: 7.0.0 @@ -2302,33 +2299,32 @@ snapshots: vscode-uri: 3.0.8 xdg-basedir: 5.1.0 - cspell-trie-lib@8.14.4: + cspell-trie-lib@8.15.4: dependencies: - '@cspell/cspell-pipe': 8.14.4 - '@cspell/cspell-types': 8.14.4 + '@cspell/cspell-pipe': 8.15.4 + '@cspell/cspell-types': 8.15.4 gensequence: 7.0.0 - cspell@8.14.4: + cspell@8.15.4: dependencies: - '@cspell/cspell-json-reporter': 8.14.4 - '@cspell/cspell-pipe': 8.14.4 - '@cspell/cspell-types': 8.14.4 - '@cspell/dynamic-import': 8.14.4 - '@cspell/url': 8.14.4 + '@cspell/cspell-json-reporter': 8.15.4 + '@cspell/cspell-pipe': 8.15.4 + '@cspell/cspell-types': 8.15.4 + '@cspell/dynamic-import': 8.15.4 + '@cspell/url': 8.15.4 chalk: 5.3.0 chalk-template: 1.1.0 commander: 12.1.0 - cspell-dictionary: 8.14.4 - cspell-gitignore: 8.14.4 - cspell-glob: 8.14.4 - cspell-io: 8.14.4 - cspell-lib: 8.14.4 - fast-glob: 3.3.2 + cspell-dictionary: 8.15.4 + cspell-gitignore: 8.15.4 + cspell-glob: 8.15.4 + cspell-io: 8.15.4 + cspell-lib: 8.15.4 fast-json-stable-stringify: 2.1.0 file-entry-cache: 9.1.0 get-stdin: 9.0.0 semver: 7.6.3 - strip-ansi: 7.1.0 + tinyglobby: 0.2.9 debug@4.3.7: dependencies: @@ -2431,7 +2427,7 @@ snapshots: dependencies: reusify: 1.0.4 - fdir@6.4.0(picomatch@4.0.2): + fdir@6.4.2(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 @@ -2462,8 +2458,6 @@ snapshots: gensequence@7.0.0: {} - get-func-name@2.0.2: {} - get-stdin@9.0.0: {} get-stream@6.0.1: {} @@ -2563,20 +2557,18 @@ snapshots: lodash.sortby@4.7.0: {} - loupe@3.1.1: - dependencies: - get-func-name: 2.0.2 + loupe@3.1.2: {} lru-cache@10.4.3: {} - magic-string@0.30.11: + magic-string@0.30.12: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 magicast@0.3.5: dependencies: - '@babel/parser': 7.25.7 - '@babel/types': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 source-map-js: 1.2.1 make-dir@4.0.0: @@ -2645,7 +2637,7 @@ snapshots: pathval@2.0.0: {} - picocolors@1.1.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -2653,17 +2645,17 @@ snapshots: pirates@4.0.6: {} - postcss-load-config@6.0.1(postcss@8.4.47)(yaml@2.5.1): + postcss-load-config@6.0.1(postcss@8.4.47)(yaml@2.6.0): dependencies: lilconfig: 3.1.2 optionalDependencies: postcss: 8.4.47 - yaml: 2.5.1 + yaml: 2.6.0 postcss@8.4.47: dependencies: nanoid: 3.3.7 - picocolors: 1.1.0 + picocolors: 1.1.1 source-map-js: 1.2.1 prettier-plugin-pkg@0.18.1(prettier@3.3.3): @@ -2734,7 +2726,7 @@ snapshots: sh-syntax@0.4.2: dependencies: - tslib: 2.7.0 + tslib: 2.8.0 shebang-command@2.0.0: dependencies: @@ -2810,11 +2802,11 @@ snapshots: tinybench@2.9.0: {} - tinyexec@0.3.0: {} + tinyexec@0.3.1: {} tinyglobby@0.2.9: dependencies: - fdir: 6.4.0(picomatch@4.0.2) + fdir: 6.4.2(picomatch@4.0.2) picomatch: 4.0.2 tinypool@1.0.1: {} @@ -2839,9 +2831,9 @@ snapshots: ts-interface-checker@0.1.13: {} - tslib@2.7.0: {} + tslib@2.8.0: {} - tsup@8.3.0(postcss@8.4.47)(typescript@5.6.2)(yaml@2.5.1): + tsup@8.3.0(postcss@8.4.47)(typescript@5.6.3)(yaml@2.6.0): dependencies: bundle-require: 5.0.0(esbuild@0.23.1) cac: 6.7.14 @@ -2851,8 +2843,8 @@ snapshots: esbuild: 0.23.1 execa: 5.1.1 joycon: 3.1.1 - picocolors: 1.1.0 - postcss-load-config: 6.0.1(postcss@8.4.47)(yaml@2.5.1) + picocolors: 1.1.1 + postcss-load-config: 6.0.1(postcss@8.4.47)(yaml@2.6.0) resolve-from: 5.0.0 rollup: 4.24.0 source-map: 0.8.0-beta.0 @@ -2861,23 +2853,23 @@ snapshots: tree-kill: 1.2.2 optionalDependencies: postcss: 8.4.47 - typescript: 5.6.2 + typescript: 5.6.3 transitivePeerDependencies: - jiti - supports-color - tsx - yaml - typescript@5.6.2: {} + typescript@5.6.3: {} undici-types@6.19.8: {} - vite-node@2.1.1(@types/node@22.7.5): + vite-node@2.1.1(@types/node@22.7.7): dependencies: cac: 6.7.14 debug: 4.3.7 pathe: 1.1.2 - vite: 5.4.8(@types/node@22.7.5) + vite: 5.4.9(@types/node@22.7.7) transitivePeerDependencies: - '@types/node' - less @@ -2889,38 +2881,38 @@ snapshots: - supports-color - terser - vite@5.4.8(@types/node@22.7.5): + vite@5.4.9(@types/node@22.7.7): dependencies: esbuild: 0.21.5 postcss: 8.4.47 rollup: 4.24.0 optionalDependencies: - '@types/node': 22.7.5 + '@types/node': 22.7.7 fsevents: 2.3.3 - vitest@2.1.1(@types/node@22.7.5): + vitest@2.1.1(@types/node@22.7.7): dependencies: '@vitest/expect': 2.1.1 - '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(vite@5.4.8(@types/node@22.7.5)) - '@vitest/pretty-format': 2.1.2 + '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(vite@5.4.9(@types/node@22.7.7)) + '@vitest/pretty-format': 2.1.3 '@vitest/runner': 2.1.1 '@vitest/snapshot': 2.1.1 '@vitest/spy': 2.1.1 '@vitest/utils': 2.1.1 chai: 5.1.1 debug: 4.3.7 - magic-string: 0.30.11 + magic-string: 0.30.12 pathe: 1.1.2 std-env: 3.7.0 tinybench: 2.9.0 - tinyexec: 0.3.0 + tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.8(@types/node@22.7.5) - vite-node: 2.1.1(@types/node@22.7.5) + vite: 5.4.9(@types/node@22.7.7) + vite-node: 2.1.1(@types/node@22.7.7) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.7.5 + '@types/node': 22.7.7 transitivePeerDependencies: - less - lightningcss @@ -2967,4 +2959,4 @@ snapshots: xdg-basedir@5.1.0: {} - yaml@2.5.1: {} + yaml@2.6.0: {} diff --git a/scripts/benchmarks/pnpm-lock.yaml b/scripts/benchmarks/pnpm-lock.yaml index 8df7c2a8e..5b20f7d02 100644 --- a/scripts/benchmarks/pnpm-lock.yaml +++ b/scripts/benchmarks/pnpm-lock.yaml @@ -10,13 +10,13 @@ importers: dependencies: '@babel/parser': specifier: ^7.25.3 - version: 7.25.7 + version: 7.25.8 '@babel/traverse': specifier: ^7.25.3 version: 7.25.7 '@babel/types': specifier: ^7.25.2 - version: 7.25.7 + version: 7.25.8 '@octokit/rest': specifier: ^21.0.1 version: 21.0.2 @@ -25,13 +25,13 @@ importers: version: 7.20.6 '@types/node': specifier: ^22.2.0 - version: 22.7.4 + version: 22.7.7 esbuild: specifier: ^0.23.0 version: 0.23.1 execa: specifier: ^9.3.0 - version: 9.4.0 + version: 9.4.1 fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -73,8 +73,8 @@ packages: resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.25.7': - resolution: {integrity: sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==} + '@babel/parser@7.25.8': + resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} engines: {node: '>=6.0.0'} hasBin: true @@ -86,8 +86,8 @@ packages: resolution: {integrity: sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==} engines: {node: '>=6.9.0'} - '@babel/types@7.25.7': - resolution: {integrity: sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==} + '@babel/types@7.25.8': + resolution: {integrity: sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==} engines: {node: '>=6.9.0'} '@esbuild/aix-ppc64@0.23.1': @@ -329,8 +329,8 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} - '@types/node@22.7.4': - resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} @@ -384,8 +384,8 @@ packages: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} - execa@9.4.0: - resolution: {integrity: sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==} + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} engines: {node: ^18.19.0 || >=20.5.0} fast-glob@3.3.2: @@ -505,8 +505,8 @@ packages: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} - picocolors@1.1.0: - resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -589,11 +589,11 @@ snapshots: '@babel/code-frame@7.25.7': dependencies: '@babel/highlight': 7.25.7 - picocolors: 1.1.0 + picocolors: 1.1.1 '@babel/generator@7.25.7': dependencies: - '@babel/types': 7.25.7 + '@babel/types': 7.25.8 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.0.2 @@ -607,31 +607,31 @@ snapshots: '@babel/helper-validator-identifier': 7.25.7 chalk: 2.4.2 js-tokens: 4.0.0 - picocolors: 1.1.0 + picocolors: 1.1.1 - '@babel/parser@7.25.7': + '@babel/parser@7.25.8': dependencies: - '@babel/types': 7.25.7 + '@babel/types': 7.25.8 '@babel/template@7.25.7': dependencies: '@babel/code-frame': 7.25.7 - '@babel/parser': 7.25.7 - '@babel/types': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 '@babel/traverse@7.25.7': dependencies: '@babel/code-frame': 7.25.7 '@babel/generator': 7.25.7 - '@babel/parser': 7.25.7 + '@babel/parser': 7.25.8 '@babel/template': 7.25.7 - '@babel/types': 7.25.7 + '@babel/types': 7.25.8 debug: 4.3.7 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.25.7': + '@babel/types@7.25.8': dependencies: '@babel/helper-string-parser': 7.25.7 '@babel/helper-validator-identifier': 7.25.7 @@ -812,9 +812,9 @@ snapshots: '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.25.7 + '@babel/types': 7.25.8 - '@types/node@22.7.4': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 @@ -887,7 +887,7 @@ snapshots: escape-string-regexp@1.0.5: {} - execa@9.4.0: + execa@9.4.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.3 @@ -992,7 +992,7 @@ snapshots: path-key@4.0.0: {} - picocolors@1.1.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} diff --git a/scripts/browser-support/pnpm-lock.yaml b/scripts/browser-support/pnpm-lock.yaml index 39424e127..e6cb55179 100644 --- a/scripts/browser-support/pnpm-lock.yaml +++ b/scripts/browser-support/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@types/node': specifier: ^22.4.0 - version: 22.7.4 + version: 22.7.7 browserslist-generator: specifier: ^2.1.0 version: 2.3.0 @@ -202,11 +202,11 @@ packages: resolution: {integrity: sha512-o41riCGPiOEStayoikBCAqwa6igbv9L9rP+k5UCfQ24EJD/wGrdDs/KTNwkHG5JzDK3T60D5dMkWkLKEPy8gjA==} engines: {node: '>=12'} - '@mdn/browser-compat-data@5.6.4': - resolution: {integrity: sha512-bOOF4GGzn0exmvNHpSWmTfOXB9beTpIFCm2KPY2UVoCdn1YVfr8heuHr1C++BYI9Tun8REgi5TNVdKbBs249CA==} + '@mdn/browser-compat-data@5.6.8': + resolution: {integrity: sha512-ueuvAVqVaPF+bEclXAH/P+qfUJ2IMJDaeUS+j8HC/maWTdV5tcm2eTvlGdXRLiq0rJAZk0Zy22i51rzW0B2izQ==} - '@types/node@22.7.4': - resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} '@types/object-path@0.11.4': resolution: {integrity: sha512-4tgJ1Z3elF/tOMpA8JLVuR9spt9Ynsf7+JjqsQ2IqtiPJtcLoHoXcT6qU4E10cPFqyXX5HDm9QwIzZhBSkLxsw==} @@ -226,8 +226,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - caniuse-lite@1.0.30001667: - resolution: {integrity: sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==} + caniuse-lite@1.0.30001669: + resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} @@ -237,8 +237,8 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - electron-to-chromium@1.5.32: - resolution: {integrity: sha512-M+7ph0VGBQqqpTT2YrabjNKSQ2fEl9PVx6AK3N558gDH9NO8O6XN9SXXFWRo9u9PbEg/bWq+tjXQr+eXmxubCw==} + electron-to-chromium@1.5.41: + resolution: {integrity: sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==} esbuild@0.23.1: resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} @@ -282,8 +282,8 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - picocolors@1.1.0: - resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -431,9 +431,9 @@ snapshots: '@esm2cjs/strip-final-newline@3.0.1-cjs.0': {} - '@mdn/browser-compat-data@5.6.4': {} + '@mdn/browser-compat-data@5.6.8': {} - '@types/node@22.7.4': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 @@ -445,12 +445,12 @@ snapshots: browserslist-generator@2.3.0: dependencies: - '@mdn/browser-compat-data': 5.6.4 + '@mdn/browser-compat-data': 5.6.8 '@types/object-path': 0.11.4 '@types/semver': 7.5.8 '@types/ua-parser-js': 0.7.39 browserslist: 4.24.0 - caniuse-lite: 1.0.30001667 + caniuse-lite: 1.0.30001669 isbot: 3.8.0 object-path: 0.11.8 semver: 7.6.3 @@ -458,12 +458,12 @@ snapshots: browserslist@4.24.0: dependencies: - caniuse-lite: 1.0.30001667 - electron-to-chromium: 1.5.32 + caniuse-lite: 1.0.30001669 + electron-to-chromium: 1.5.41 node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.0) - caniuse-lite@1.0.30001667: {} + caniuse-lite@1.0.30001669: {} cross-spawn@7.0.3: dependencies: @@ -473,7 +473,7 @@ snapshots: dequal@2.0.3: {} - electron-to-chromium@1.5.32: {} + electron-to-chromium@1.5.41: {} esbuild@0.23.1: optionalDependencies: @@ -525,7 +525,7 @@ snapshots: path-key@3.1.1: {} - picocolors@1.1.0: {} + picocolors@1.1.1: {} resolve-pkg-maps@1.0.0: {} @@ -554,7 +554,7 @@ snapshots: dependencies: browserslist: 4.24.0 escalade: 3.2.0 - picocolors: 1.1.0 + picocolors: 1.1.1 which@2.0.2: dependencies: diff --git a/scripts/bundle-impact/pnpm-lock.yaml b/scripts/bundle-impact/pnpm-lock.yaml index c40f2af5d..7060fe4f7 100644 --- a/scripts/bundle-impact/pnpm-lock.yaml +++ b/scripts/bundle-impact/pnpm-lock.yaml @@ -13,13 +13,13 @@ importers: version: 21.0.2 '@types/node': specifier: ^22.4.0 - version: 22.7.4 + version: 22.7.7 esbuild: specifier: ^0.23.0 version: 0.23.1 execa: specifier: ^9.3.0 - version: 9.4.0 + version: 9.4.1 radashi: specifier: link:../../src version: link:../../src @@ -232,8 +232,8 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@types/node@22.7.4': - resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} before-after-hook@3.0.2: resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} @@ -247,8 +247,8 @@ packages: engines: {node: '>=18'} hasBin: true - execa@9.4.0: - resolution: {integrity: sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==} + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} engines: {node: ^18.19.0 || >=20.5.0} figures@6.1.0: @@ -488,7 +488,7 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@types/node@22.7.4': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 @@ -527,7 +527,7 @@ snapshots: '@esbuild/win32-ia32': 0.23.1 '@esbuild/win32-x64': 0.23.1 - execa@9.4.0: + execa@9.4.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.3 diff --git a/scripts/docs/pnpm-lock.yaml b/scripts/docs/pnpm-lock.yaml index fd1534696..70aa96525 100644 --- a/scripts/docs/pnpm-lock.yaml +++ b/scripts/docs/pnpm-lock.yaml @@ -10,10 +10,10 @@ importers: dependencies: '@types/node': specifier: ^22.3.0 - version: 22.7.4 + version: 22.7.7 execa: specifier: ^9.3.1 - version: 9.4.0 + version: 9.4.1 git-cliff: specifier: 2.4.0 version: 2.4.0 @@ -183,8 +183,8 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@types/node@22.7.4': - resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} @@ -199,8 +199,8 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - execa@9.4.0: - resolution: {integrity: sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==} + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} engines: {node: ^18.19.0 || >=20.5.0} figures@6.1.0: @@ -450,7 +450,7 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@types/node@22.7.4': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 @@ -499,7 +499,7 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - execa@9.4.0: + execa@9.4.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.3 diff --git a/scripts/format/pnpm-lock.yaml b/scripts/format/pnpm-lock.yaml index 93ca61e01..723ac8078 100644 --- a/scripts/format/pnpm-lock.yaml +++ b/scripts/format/pnpm-lock.yaml @@ -10,10 +10,10 @@ importers: dependencies: '@types/node': specifier: ^22.4.0 - version: 22.7.4 + version: 22.7.7 execa: specifier: ^9.3.1 - version: 9.4.0 + version: 9.4.1 fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -186,8 +186,8 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@types/node@22.7.4': - resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -202,8 +202,8 @@ packages: engines: {node: '>=18'} hasBin: true - execa@9.4.0: - resolution: {integrity: sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==} + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} engines: {node: ^18.19.0 || >=20.5.0} fast-glob@3.3.2: @@ -444,7 +444,7 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@types/node@22.7.4': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 @@ -485,7 +485,7 @@ snapshots: '@esbuild/win32-ia32': 0.23.1 '@esbuild/win32-x64': 0.23.1 - execa@9.4.0: + execa@9.4.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.3 diff --git a/scripts/functions/pnpm-lock.yaml b/scripts/functions/pnpm-lock.yaml index b29fb5d4b..b115cb3ff 100644 --- a/scripts/functions/pnpm-lock.yaml +++ b/scripts/functions/pnpm-lock.yaml @@ -16,10 +16,10 @@ importers: version: 14.1.2 '@types/node': specifier: ^22.2.0 - version: 22.7.4 + version: 22.7.7 execa: specifier: ^9.3.0 - version: 9.4.0 + version: 9.4.1 fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -43,7 +43,7 @@ importers: version: 1.5.3 yaml: specifier: ^2.5.0 - version: 2.5.1 + version: 2.6.0 packages: @@ -271,8 +271,8 @@ packages: '@types/mdurl@2.0.0': resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - '@types/node@22.7.4': - resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -297,8 +297,8 @@ packages: engines: {node: '>=18'} hasBin: true - execa@9.4.0: - resolution: {integrity: sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==} + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} engines: {node: ^18.19.0 || >=20.5.0} fast-glob@3.3.2: @@ -471,8 +471,8 @@ packages: engines: {node: '>= 8'} hasBin: true - yaml@2.5.1: - resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} + yaml@2.6.0: + resolution: {integrity: sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==} engines: {node: '>= 14'} hasBin: true @@ -640,7 +640,7 @@ snapshots: '@types/mdurl@2.0.0': {} - '@types/node@22.7.4': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 @@ -687,7 +687,7 @@ snapshots: '@esbuild/win32-ia32': 0.23.1 '@esbuild/win32-x64': 0.23.1 - execa@9.4.0: + execa@9.4.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.3 @@ -844,6 +844,6 @@ snapshots: dependencies: isexe: 2.0.0 - yaml@2.5.1: {} + yaml@2.6.0: {} yoctocolors@2.1.1: {} diff --git a/scripts/lint/pnpm-lock.yaml b/scripts/lint/pnpm-lock.yaml index 1d844b2eb..35268c7d1 100644 --- a/scripts/lint/pnpm-lock.yaml +++ b/scripts/lint/pnpm-lock.yaml @@ -10,10 +10,10 @@ importers: dependencies: '@types/node': specifier: ^22.4.0 - version: 22.7.4 + version: 22.7.7 execa: specifier: ^9.3.1 - version: 9.4.0 + version: 9.4.1 fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -195,8 +195,8 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@types/node@22.7.4': - resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -211,8 +211,8 @@ packages: engines: {node: '>=18'} hasBin: true - execa@9.4.0: - resolution: {integrity: sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==} + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} engines: {node: ^18.19.0 || >=20.5.0} fast-glob@3.3.2: @@ -465,7 +465,7 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@types/node@22.7.4': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 @@ -506,7 +506,7 @@ snapshots: '@esbuild/win32-ia32': 0.23.1 '@esbuild/win32-x64': 0.23.1 - execa@9.4.0: + execa@9.4.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.3 diff --git a/scripts/radashi-db/pnpm-lock.yaml b/scripts/radashi-db/pnpm-lock.yaml index 86ef2a83e..d51358960 100644 --- a/scripts/radashi-db/pnpm-lock.yaml +++ b/scripts/radashi-db/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@supabase/supabase-js': specifier: ^2.45.0 - version: 2.45.4 + version: 2.45.6 algoliasearch: specifier: ^4.24.0 version: 4.24.0 @@ -62,30 +62,30 @@ packages: '@algolia/transporter@4.24.0': resolution: {integrity: sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==} - '@supabase/auth-js@2.65.0': - resolution: {integrity: sha512-+wboHfZufAE2Y612OsKeVP4rVOeGZzzMLD/Ac3HrTQkkY4qXNjI6Af9gtmxwccE5nFvTiF114FEbIQ1hRq5uUw==} + '@supabase/auth-js@2.65.1': + resolution: {integrity: sha512-IA7i2Xq2SWNCNMKxwmPlHafBQda0qtnFr8QnyyBr+KaSxoXXqEzFCnQ1dGTy6bsZjVBgXu++o3qrDypTspaAPw==} - '@supabase/functions-js@2.4.1': - resolution: {integrity: sha512-8sZ2ibwHlf+WkHDUZJUXqqmPvWQ3UHN0W30behOJngVh/qHHekhJLCFbh0AjkE9/FqqXtf9eoVvmYgfCLk5tNA==} + '@supabase/functions-js@2.4.3': + resolution: {integrity: sha512-sOLXy+mWRyu4LLv1onYydq+10mNRQ4rzqQxNhbrKLTLTcdcmS9hbWif0bGz/NavmiQfPs4ZcmQJp4WqOXlR4AQ==} '@supabase/node-fetch@2.6.15': resolution: {integrity: sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==} engines: {node: 4.x || >=6.0.0} - '@supabase/postgrest-js@1.16.1': - resolution: {integrity: sha512-EOSEZFm5pPuCPGCmLF1VOCS78DfkSz600PBuvBND/IZmMciJ1pmsS3ss6TkB6UkuvTybYiBh7gKOYyxoEO3USA==} + '@supabase/postgrest-js@1.16.3': + resolution: {integrity: sha512-HI6dsbW68AKlOPofUjDTaosiDBCtW4XAm0D18pPwxoW3zKOE2Ru13Z69Wuys9fd6iTpfDViNco5sgrtnP0666A==} - '@supabase/realtime-js@2.10.2': - resolution: {integrity: sha512-qyCQaNg90HmJstsvr2aJNxK2zgoKh9ZZA8oqb7UT2LCh3mj9zpa3Iwu167AuyNxsxrUE8eEJ2yH6wLCij4EApA==} + '@supabase/realtime-js@2.10.7': + resolution: {integrity: sha512-OLI0hiSAqQSqRpGMTUwoIWo51eUivSYlaNBgxsXZE7PSoWh12wPRdVt0psUMaUzEonSB85K21wGc7W5jHnT6uA==} - '@supabase/storage-js@2.7.0': - resolution: {integrity: sha512-iZenEdO6Mx9iTR6T7wC7sk6KKsoDPLq8rdu5VRy7+JiT1i8fnqfcOr6mfF2Eaqky9VQzhP8zZKQYjzozB65Rig==} + '@supabase/storage-js@2.7.1': + resolution: {integrity: sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==} - '@supabase/supabase-js@2.45.4': - resolution: {integrity: sha512-E5p8/zOLaQ3a462MZnmnz03CrduA5ySH9hZyL03Y+QZLIOO4/Gs8Rdy4ZCKDHsN7x0xdanVEWWFN3pJFQr9/hg==} + '@supabase/supabase-js@2.45.6': + resolution: {integrity: sha512-qVXSSUhhIqdFnF2VUGgeecPvw1cDW6+avcTbRgur4LaGnzrJCbM3Rx7g81/SSZjjeqYOtmHuKWhiHzV/EN8Ktw==} - '@types/node@22.7.4': - resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} '@types/phoenix@1.6.5': resolution: {integrity: sha512-xegpDuR+z0UqG9fwHqNoy3rI7JDlvaPh2TY47Fl80oq6g+hXT+c/LEuE43X48clZ6lOfANl5WrPur9fYO1RJ/w==} @@ -198,11 +198,11 @@ snapshots: '@algolia/logger-common': 4.24.0 '@algolia/requester-common': 4.24.0 - '@supabase/auth-js@2.65.0': + '@supabase/auth-js@2.65.1': dependencies: '@supabase/node-fetch': 2.6.15 - '@supabase/functions-js@2.4.1': + '@supabase/functions-js@2.4.3': dependencies: '@supabase/node-fetch': 2.6.15 @@ -210,11 +210,11 @@ snapshots: dependencies: whatwg-url: 5.0.0 - '@supabase/postgrest-js@1.16.1': + '@supabase/postgrest-js@1.16.3': dependencies: '@supabase/node-fetch': 2.6.15 - '@supabase/realtime-js@2.10.2': + '@supabase/realtime-js@2.10.7': dependencies: '@supabase/node-fetch': 2.6.15 '@types/phoenix': 1.6.5 @@ -224,23 +224,23 @@ snapshots: - bufferutil - utf-8-validate - '@supabase/storage-js@2.7.0': + '@supabase/storage-js@2.7.1': dependencies: '@supabase/node-fetch': 2.6.15 - '@supabase/supabase-js@2.45.4': + '@supabase/supabase-js@2.45.6': dependencies: - '@supabase/auth-js': 2.65.0 - '@supabase/functions-js': 2.4.1 + '@supabase/auth-js': 2.65.1 + '@supabase/functions-js': 2.4.3 '@supabase/node-fetch': 2.6.15 - '@supabase/postgrest-js': 1.16.1 - '@supabase/realtime-js': 2.10.2 - '@supabase/storage-js': 2.7.0 + '@supabase/postgrest-js': 1.16.3 + '@supabase/realtime-js': 2.10.7 + '@supabase/storage-js': 2.7.1 transitivePeerDependencies: - bufferutil - utf-8-validate - '@types/node@22.7.4': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 @@ -248,7 +248,7 @@ snapshots: '@types/ws@8.5.12': dependencies: - '@types/node': 22.7.4 + '@types/node': 22.7.7 algoliasearch@4.24.0: dependencies: diff --git a/scripts/release-notes/pnpm-lock.yaml b/scripts/release-notes/pnpm-lock.yaml index 5174832ea..12214cd30 100644 --- a/scripts/release-notes/pnpm-lock.yaml +++ b/scripts/release-notes/pnpm-lock.yaml @@ -13,10 +13,10 @@ importers: version: 0.25.2 '@types/node': specifier: ^22.1.0 - version: 22.7.4 + version: 22.7.7 execa: specifier: ^9.3.0 - version: 9.4.0 + version: 9.4.1 mri: specifier: ^1.2.0 version: 1.2.0 @@ -237,8 +237,8 @@ packages: '@octokit/openapi-webhooks-types@8.3.0': resolution: {integrity: sha512-vKLsoR4xQxg4Z+6rU/F65ItTUz/EXbD+j/d4mlq2GW8TsA4Tc8Kdma2JTAAJ5hrKWUQzkR/Esn2fjsqiVRYaQg==} - '@octokit/plugin-paginate-graphql@5.2.3': - resolution: {integrity: sha512-EzFueuXVU3VHv5FwEXbdznn9EmyF0vA5LGDX6a8fJ9YJAlDgdYHRKJMO4Ghl2PPPJBxIPMDUJMnlUHqcvP7AnQ==} + '@octokit/plugin-paginate-graphql@5.2.4': + resolution: {integrity: sha512-pLZES1jWaOynXKHOqdnwZ5ULeVR6tVVCMm+AUbp0htdcyXDU95WbkYdU4R2ej1wKj5Tu94Mee2Ne0PjPO9cCyA==} engines: {node: '>= 18'} peerDependencies: '@octokit/core': '>=6' @@ -299,11 +299,11 @@ packages: '@types/node-fetch@2.6.11': resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} - '@types/node@18.19.54': - resolution: {integrity: sha512-+BRgt0G5gYjTvdLac9sIeE0iZcJxi4Jc4PV5EUzqi+88jmQLr+fRZdv2tCTV7IHKSGxM6SaLoOXQWWUiLUItMw==} + '@types/node@18.19.57': + resolution: {integrity: sha512-I2ioBd/IPrYDMv9UNR5NlPElOZ68QB7yY5V2EsLtSrTO0LM0PnCEFF9biLWHf5k+sIy4ohueCV9t4gk1AEdlVA==} - '@types/node@22.7.4': - resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} @@ -343,8 +343,8 @@ packages: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} - execa@9.4.0: - resolution: {integrity: sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==} + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} engines: {node: ^18.19.0 || >=20.5.0} figures@6.1.0: @@ -354,8 +354,8 @@ packages: form-data-encoder@1.7.2: resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} formdata-node@4.4.1: @@ -517,7 +517,7 @@ snapshots: '@anthropic-ai/sdk@0.25.2': dependencies: - '@types/node': 18.19.54 + '@types/node': 18.19.57 '@types/node-fetch': 2.6.11 abort-controller: 3.0.0 agentkeepalive: 4.5.0 @@ -695,7 +695,7 @@ snapshots: '@octokit/openapi-webhooks-types@8.3.0': {} - '@octokit/plugin-paginate-graphql@5.2.3(@octokit/core@6.1.2)': + '@octokit/plugin-paginate-graphql@5.2.4(@octokit/core@6.1.2)': dependencies: '@octokit/core': 6.1.2 @@ -753,14 +753,14 @@ snapshots: '@types/node-fetch@2.6.11': dependencies: - '@types/node': 22.7.4 - form-data: 4.0.0 + '@types/node': 22.7.7 + form-data: 4.0.1 - '@types/node@18.19.54': + '@types/node@18.19.57': dependencies: undici-types: 5.26.5 - '@types/node@22.7.4': + '@types/node@22.7.7': dependencies: undici-types: 6.19.8 @@ -819,7 +819,7 @@ snapshots: event-target-shim@5.0.1: {} - execa@9.4.0: + execa@9.4.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.3 @@ -840,7 +840,7 @@ snapshots: form-data-encoder@1.7.2: {} - form-data@4.0.0: + form-data@4.0.1: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -905,7 +905,7 @@ snapshots: '@octokit/app': 15.1.0 '@octokit/core': 6.1.2 '@octokit/oauth-app': 7.1.3 - '@octokit/plugin-paginate-graphql': 5.2.3(@octokit/core@6.1.2) + '@octokit/plugin-paginate-graphql': 5.2.4(@octokit/core@6.1.2) '@octokit/plugin-paginate-rest': 11.3.5(@octokit/core@6.1.2) '@octokit/plugin-rest-endpoint-methods': 13.2.6(@octokit/core@6.1.2) '@octokit/plugin-retry': 7.1.2(@octokit/core@6.1.2) diff --git a/scripts/versions/pnpm-lock.yaml b/scripts/versions/pnpm-lock.yaml index f35c9aa63..42c1fdc55 100644 --- a/scripts/versions/pnpm-lock.yaml +++ b/scripts/versions/pnpm-lock.yaml @@ -16,7 +16,7 @@ importers: version: 21.0.2 execa: specifier: ^9.3.0 - version: 9.4.0 + version: 9.4.1 fast-glob: specifier: ^3.3.2 version: 3.3.2 @@ -272,8 +272,8 @@ packages: engines: {node: '>=18'} hasBin: true - execa@9.4.0: - resolution: {integrity: sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==} + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} engines: {node: ^18.19.0 || >=20.5.0} fast-glob@3.3.2: @@ -657,7 +657,7 @@ snapshots: '@esbuild/win32-ia32': 0.23.1 '@esbuild/win32-x64': 0.23.1 - execa@9.4.0: + execa@9.4.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 cross-spawn: 7.0.3 @@ -724,7 +724,7 @@ snapshots: git-cliff@2.4.0: dependencies: - execa: 9.4.0 + execa: 9.4.1 optionalDependencies: git-cliff-darwin-arm64: 2.4.0 git-cliff-darwin-x64: 2.4.0 From b640c2c25da12826e5891bf97934a1d14629799d Mon Sep 17 00:00:00 2001 From: Marlon Passos Date: Fri, 1 Nov 2024 17:55:58 -0300 Subject: [PATCH 05/56] docs: fix runtime errors in docs examples for playground (#247) Co-authored-by: Alec Larson <1925840+aleclarson@users.noreply.github.com> --- docs/array/list.mdx | 2 +- docs/async/defer.mdx | 63 ++++++++++++++++++++++++++------ docs/async/guard.mdx | 53 ++++++++++++++++++++++++--- docs/async/map.mdx | 11 ++++-- docs/async/reduce.mdx | 9 ++++- docs/async/retry.mdx | 19 ++++++++-- docs/async/tryit.mdx | 11 +++++- docs/async/withResolvers.mdx | 4 +- docs/curry/debounce.mdx | 20 ++++++---- docs/curry/once.mdx | 2 +- docs/curry/throttle.mdx | 6 +-- docs/function/castComparator.mdx | 2 +- docs/number/clamp.mdx | 15 +++++--- docs/typed/isResultErr.mdx | 4 +- docs/typed/isResultOk.mdx | 4 +- 15 files changed, 175 insertions(+), 50 deletions(-) diff --git a/docs/array/list.mdx b/docs/array/list.mdx index b91df2e95..70f791044 100644 --- a/docs/array/list.mdx +++ b/docs/array/list.mdx @@ -21,7 +21,7 @@ _.list(0, 3, 'y') // [y, y, y, y] _.list(0, 3, () => 'y') // [y, y, y, y] _.list(0, 3, i => i) // [0, 1, 2, 3] _.list(0, 3, i => `y${i}`) // [y0, y1, y2, y3] -_.list(0, 3, obj) // [obj, obj, obj, obj] +_.list(0, 3, {}) // [{}, {}, {}, {}] _.list(0, 6, i => i, 2) // [0, 2, 4, 6] ``` diff --git a/docs/async/defer.mdx b/docs/async/defer.mdx index 5fde5385e..cfe15a059 100644 --- a/docs/async/defer.mdx +++ b/docs/async/defer.mdx @@ -1,27 +1,35 @@ --- title: defer -description: Run an async function with deferred functions +description: Defer work until an async function completes since: 12.1.0 --- ### Usage -The `_.defer` functions lets you run an async function, registering functions as you go -that should be deferred until the async function completes, and then executed. This is -really useful in scripts where failure up to or after a specific point will require some -cleanup. It's a bit like a `finally` block. +The `defer` function allows you to run an async function while registering cleanup functions that will execute after it completes. This is useful when you need to clean up resources regardless of whether the main function succeeds or fails, similar to a `finally` block. -A hat tip to Swift's `defer` for the inspiration. +The function passed to `defer` receives a `register` function as its argument. Use this to register cleanup work that should run after the main function finishes. -The function passed to `_.defer` is called with a single `register` function argument that -can be used to register the work you want to be called when the function completes. If your function throws an error and then a registered cleanup function throws -and error it is ignored by default. The register -function supports an optional second `options` argument that lets you configure a rethrow -strategy so that error in the cleanup function is rethrown. +By default, if a cleanup function throws an error after the main function has thrown an error, the cleanup error will be ignored. You can customize this behavior by passing `{ rethrow: true }` to the `register` function to have it rethrow cleanup errors instead. + +#### Clean up temporary files ```ts import * as _ from 'radashi' +// Placeholder functions +const createBuildDir = async () => { + console.log('Creating build directory...') + await _.sleep(100) + console.log('Build directory created.') + return 'build' +} +const build = async () => { + console.log('Building project...') + await _.sleep(100) + console.log('Project built.') +} + await _.defer(async cleanup => { const buildDir = await createBuildDir() @@ -29,13 +37,44 @@ await _.defer(async cleanup => { await build() }) +``` + +#### Clean up resources in an API + +```ts +// Placeholder API +const api = { + org: { + create: async () => ({ id: 1 }), + delete: async () => { + console.log('Deleting organization...') + await _.sleep(100) + console.log('Deleted organization.') + }, + }, + user: { + create: async () => ({ id: 2 }), + delete: async () => { + console.log('Deleting user...') + await _.sleep(100) + console.log('Deleted user.') + }, + }, +} + +// Placeholder test function +const executeTest = async () => { + console.log('Executing test...') + await _.sleep(100) + console.log('Test complete.') +} await _.defer(async register => { const org = await api.org.create() register(async () => api.org.delete(org.id), { rethrow: true }) const user = await api.user.create() - register(async () => api.users.delete(user.id), { rethrow: true }) + register(async () => api.user.delete(user.id), { rethrow: true }) await executeTest(org, user) }) diff --git a/docs/async/guard.mdx b/docs/async/guard.mdx index 0015a4869..1bc5e27de 100644 --- a/docs/async/guard.mdx +++ b/docs/async/guard.mdx @@ -1,20 +1,61 @@ --- title: guard -description: Have a function return undefined if it errors out +description: Make an async function return undefined if it rejects since: 12.1.0 --- ### Usage -This lets you set a default value if an async function errors out. +The `guard` function allows you to make an async function return `undefined` if it rejects. This is useful when you want to handle errors in a functional way, such as returning a default value. ```ts -const users = (await guard(fetchUsers)) ?? [] +import * as _ from 'radashi' + +const example = async () => { + throw new Error() +} + +const result = (await _.guard(example)) ?? [] +// [] ``` -You can choose to guard only specific errors too +#### Guard only specific errors + +The 2nd argument to `guard` is an error predicate. If provided, the function will only return `undefined` if the error matches the predicate. ```ts -const isInvalidUserError = (err: any) => err.code === 'INVALID_ID' -const user = (await guard(fetchUser, isInvalidUserError)) ?? DEFAULT_USER +import * as _ from 'radashi' + +const DEFAULT_USER = { name: 'John Doe' } + +async function fetchUser(id: string) { + if (id === 'unknown') throw new Error('User does not exist') + if (id === 'oops') throw new ReferenceError() + return { name: 'Jim Jimmy' } +} + +const isPlainError = (err: any) => err.name === 'Error' + +const userA = + (await _.guard(() => fetchUser('unknown'), isPlainError)) ?? DEFAULT_USER +// { name: "John Doe"} + +// This one will reject. +const userB = await _.guard(() => fetchUser('oops'), isPlainError).catch(e => e) +// [object ReferenceError] +``` + +#### Synchronous guards + +The `guard` function also works with synchronous functions. + +```ts +import * as _ from 'radashi' + +function example() { + throw new Error() +} + +const result = _.guard(example) ?? [] +// [] ``` diff --git a/docs/async/map.mdx b/docs/async/map.mdx index 6444f46e3..c6e57bddd 100644 --- a/docs/async/map.mdx +++ b/docs/async/map.mdx @@ -6,14 +6,17 @@ since: 12.1.0 ### Usage -A map that handles callback functions that return a promise. +The `map` function is like `Array.prototype.map`, but it works with async functions. Only one item is processed at a time. ```ts -import * as _ from 'radashi' - const userIds = [1, 2, 3, 4] +const api = { + users: { + find: async (id: number) => id < 3, + }, +} const users = await _.map(userIds, async userId => { return await api.users.find(userId) -}) +}) // [true, true, false, false] ``` diff --git a/docs/async/reduce.mdx b/docs/async/reduce.mdx index 493eb6440..e2cbab5e4 100644 --- a/docs/async/reduce.mdx +++ b/docs/async/reduce.mdx @@ -12,6 +12,13 @@ A reduce that handles callback functions that return a promise. import * as _ from 'radashi' const userIds = [1, 2, 3, 4] +const api = { + users: { + async find(id: number) { + return { name: `person ${id}` } + }, + }, +} const users = await _.reduce( userIds, @@ -23,5 +30,5 @@ const users = await _.reduce( } }, {}, -) +) // { 1: { name: 'person 1' }, 2: { name: 'person 2' }, 3: { name: 'person 3' }, 4: { name: 'person 4' } } ``` diff --git a/docs/async/retry.mdx b/docs/async/retry.mdx index 95a272f7c..0659e4bfd 100644 --- a/docs/async/retry.mdx +++ b/docs/async/retry.mdx @@ -15,10 +15,21 @@ The `backoff` option is like delay but uses a function to sleep -- makes for eas ```ts import * as _ from 'radashi' -await _.retry({}, api.users.list) -await _.retry({ times: 10 }, api.users.list) -await _.retry({ times: 2, delay: 1000 }, api.users.list) +const api = { + users: { + async list() { + if (Math.random() < 0.5) { + throw new Error('Random error') + } + return [] + }, + }, +} + +await _.retry({}, api.users.list) // try 3 times before failing +await _.retry({ times: 10 }, api.users.list) // try 10 times before failing +await _.retry({ times: 2, delay: 1000 }, api.users.list) // try 2 times with 1 second delay // exponential backoff -await _.retry({ backoff: i => 10 ** i }, api.users.list) +await _.retry({ backoff: i => 10 ** i }, api.users.list) // try 3 times with 10, 100, 1000 ms delay ``` diff --git a/docs/async/tryit.mdx b/docs/async/tryit.mdx index 1aa68aeb9..d2e5043c5 100644 --- a/docs/async/tryit.mdx +++ b/docs/async/tryit.mdx @@ -13,7 +13,16 @@ The `tryit` function let's you wrap a function to convert it to an error-first f ```ts import * as _ from 'radashi' -const [err, user] = await _.tryit(api.users.find)(userId) +const api = { + users: { + find: async (id: number) => id < 3 ? { id, name: 'Alice' } : throw new Error('Not found'), + }, +} +const userIdA = 1 +const userIdB = 3 + +const [err, user] = await _.tryit(api.users.find)(userId) // [null, { id: 1, name: 'Alice' }] +const [err, user] = await _.tryit(api.users.find)(userIdB) // [Error('Not found'), undefined] ``` ### Currying diff --git a/docs/async/withResolvers.mdx b/docs/async/withResolvers.mdx index 84718a2f1..67fb90e6a 100644 --- a/docs/async/withResolvers.mdx +++ b/docs/async/withResolvers.mdx @@ -11,7 +11,9 @@ Creates a new promise and returns the resolve and reject functions along with th The ponyfill for https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers ```ts -const { resolve, reject, promise } = withResolvers() +import * as _ from 'radashi' + +const { resolve, reject, promise } = _.withResolvers() resolve(42) ``` diff --git a/docs/curry/debounce.mdx b/docs/curry/debounce.mdx index db2ef7882..f731ec4f4 100644 --- a/docs/curry/debounce.mdx +++ b/docs/curry/debounce.mdx @@ -13,14 +13,18 @@ If called again during this waiting period, it resets the timer. Your source fun ```ts import * as _ from 'radashi' -// Send a search request to the API server when the user stops typing -// for at least 100ms. -input.addEventListener( - 'change', - _.debounce({ delay: 100 }, (event: InputEvent) => { - api.movies.search(event.target.value) - }), -) +const processData = (data: string) => { + console.log(`Processing data: "${data}"...`) +} +const debouncedProcessData = _.debounce({ delay: 100 }, processData) + +debouncedProcessData('data1') // Never logs +debouncedProcessData('data2') // Never logs +debouncedProcessData('data3') // Processing data: "data3"... + +setTimeout(() => { + debouncedProcessData('data4') // Processing data: "data4"... (200ms later) +}, 200) ``` ## Options diff --git a/docs/curry/once.mdx b/docs/curry/once.mdx index 59a34eb52..536a748d3 100644 --- a/docs/curry/once.mdx +++ b/docs/curry/once.mdx @@ -11,7 +11,7 @@ Create a wrapper around a given function such that it executes at most once. Sub ```ts import * as _ from 'radashi' -const fn = once(() => Math.random()) +const fn = _.once(() => Math.random()) fn() // 0.5 fn() // 0.5 ``` diff --git a/docs/curry/throttle.mdx b/docs/curry/throttle.mdx index 19fd83af3..e8670a535 100644 --- a/docs/curry/throttle.mdx +++ b/docs/curry/throttle.mdx @@ -21,17 +21,17 @@ The returned throttled function also includes these methods: - `trigger(...args): void`: To invoke the wrapped function without waiting for the next interval ```typescript -import { throttle } from 'radashi' +import * as _ from 'radashi' // Throttle a scroll event handler const handleScroll = () => { console.log('Scroll position:', window.scrollY) } -const throttledScroll = throttle({ interval: 200 }, handleScroll) +const throttledScroll = _.throttle({ interval: 200 }, handleScroll) window.addEventListener('scroll', throttledScroll) // Throttle an API call -const throttledFetch = throttle( +const throttledFetch = _.throttle( { interval: 5000, trailing: true }, async () => { const response = await fetch('https://api.example.com/data') diff --git a/docs/function/castComparator.mdx b/docs/function/castComparator.mdx index 6c230dd5e..eeb43e811 100644 --- a/docs/function/castComparator.mdx +++ b/docs/function/castComparator.mdx @@ -14,7 +14,7 @@ The first argument of `castComparator` is called the `mapping`. This can be eith - **Property Name**: If `mapping` is a property name, it maps the input values to a property of the input values with a comparable value. ```ts -import * as _ from 'radash' +import * as _ from 'radashi' const users = [ { id: 1, firstName: 'Alice', lastName: 'Smith' }, diff --git a/docs/number/clamp.mdx b/docs/number/clamp.mdx index 18278c562..adfb23083 100644 --- a/docs/number/clamp.mdx +++ b/docs/number/clamp.mdx @@ -19,10 +19,15 @@ range. ```ts import * as _ from 'radashi' -_.clamp(5, 1, 10) // returns 5 -_.clamp(0, 1, 10) // returns 1 -_.clamp(15, 1, 10) // returns 10 +_.clamp(5, 1, 10) // 5 +_.clamp(0, 1, 10) // 1 +_.clamp(15, 1, 10) // 10 +``` + +#### Invalid ranges -// Invalid range -_.clamp(1, 10, 1) // throws +If the minimum is greater than the maximum, an error is thrown. + +```ts +_.clamp(1, 10, 1) // throws Error ``` diff --git a/docs/typed/isResultErr.mdx b/docs/typed/isResultErr.mdx index ac1b27639..97c917a64 100644 --- a/docs/typed/isResultErr.mdx +++ b/docs/typed/isResultErr.mdx @@ -9,9 +9,11 @@ since: 12.2.0 Check if a value is both a `Result` tuple and an `Err` result. ```ts +import * as _ from 'radashi' + declare const value: unknown -if (isResultErr(value)) { +if (_.isResultErr(value)) { value // <-- now an Err type value[0] // <-- This is the error! } diff --git a/docs/typed/isResultOk.mdx b/docs/typed/isResultOk.mdx index f8e90cc97..88c420b05 100644 --- a/docs/typed/isResultOk.mdx +++ b/docs/typed/isResultOk.mdx @@ -9,9 +9,11 @@ since: 12.2.0 Check if a value is both a `Result` tuple and an `Ok` result. ```ts +import * as _ from 'radashi' + declare const value: unknown -if (isResultOk(value)) { +if (_.isResultOk(value)) { value // <-- now an Ok type value[1] // <-- This is the resulting value! } From 04c798f3f8b80026dc118cf212d699f3dc29014a Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Fri, 1 Nov 2024 17:05:22 -0400 Subject: [PATCH 06/56] chore: release v12.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 93f0229cc..0d0625c30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "radashi", - "version": "12.1.0", + "version": "12.2.0", "type": "module", "description": "The modern, community-first TypeScript toolkit with all of the fast, readable, and minimal utility functions you need. Type-safe, dependency-free, tree-shakeable, fully tested.", "repository": { From caa03e8d80d0201c564eec9137140907f5580fb0 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:19:15 -0500 Subject: [PATCH 07/56] chore: add vitest config to cspell ignore --- cspell.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/cspell.yaml b/cspell.yaml index ebb42c7a6..4502a1f81 100644 --- a/cspell.yaml +++ b/cspell.yaml @@ -5,6 +5,7 @@ ignorePaths: - '**/tsconfig.json' - '**/pnpm-lock.yaml' - '**/dist' + - 'vitest.config.ts' - 'coverage' - 'cliff.toml' - 'README-pt_br.md' From 29b8cf46fbb2563d570bea38646bab38a0ce1ca2 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:19:41 -0500 Subject: [PATCH 08/56] chore: exclude src/*.ts modules from coverage --- vitest.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/vitest.config.ts b/vitest.config.ts index 4e9039ec1..511f696b9 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -13,6 +13,7 @@ export default defineConfig(env => ({ coverage: { thresholds: { 100: true }, include: ['src/**'], + exclude: ['src/*.ts'], }, setupFiles: env.mode === 'benchmark' ? ['benchmarks/globals.ts'] : [], typecheck: { From 6db39586bf45acd91d4429dcd31c9a1a680302ee Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:15:37 -0500 Subject: [PATCH 09/56] chore: set exactOptionalPropertyTypes to true --- src/async/AggregateError.ts | 2 +- tests/tsconfig.json | 1 + tsconfig.json | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/async/AggregateError.ts b/src/async/AggregateError.ts index 0b3f183b7..26305e799 100644 --- a/src/async/AggregateError.ts +++ b/src/async/AggregateError.ts @@ -22,7 +22,7 @@ const AggregateErrorOrPolyfill: AggregateErrorConstructor = const name = errors.find(e => e.name)?.name ?? '' this.name = `AggregateError(${name}...)` this.message = `AggregateError with ${errors.length} errors` - this.stack = errors.find(e => e.stack)?.stack ?? this.stack + this.stack = errors.find(e => e.stack)?.stack ?? this.stack! this.errors = errors } } as unknown as AggregateErrorConstructor))() diff --git a/tests/tsconfig.json b/tests/tsconfig.json index 948ea9088..c93259ed9 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "exactOptionalPropertyTypes": true, "allowImportingTsExtensions": true, "emitDeclarationOnly": true, "declaration": true, diff --git a/tsconfig.json b/tsconfig.json index 4d1bb0eb8..129c0470c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "include": ["src/**/*.ts"], "compilerOptions": { "allowImportingTsExtensions": true, + "exactOptionalPropertyTypes": true, "moduleResolution": "node", "outDir": "./dist/tmp", "noEmitOnError": true, From 19042a71d5409f6ff6c9fdcf4c639bec4adba48c Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:16:27 -0500 Subject: [PATCH 10/56] chore: format --- scripts/radashi-db/supabase.types.ts | 94 ++++++++++++++-------------- tests/typed/isEqual.test.ts | 25 +++++--- vitest.config.ts | 2 +- 3 files changed, 63 insertions(+), 58 deletions(-) diff --git a/scripts/radashi-db/supabase.types.ts b/scripts/radashi-db/supabase.types.ts index 76c6ff39a..990a12b51 100644 --- a/scripts/radashi-db/supabase.types.ts +++ b/scripts/radashi-db/supabase.types.ts @@ -44,21 +44,21 @@ export type Database = { name: string notes: string | null rename: string | null - status: Database["public"]["Enums"]["ParityStatus"] | null + status: Database['public']['Enums']['ParityStatus'] | null weekly_downloads_num: number } Insert: { name: string notes?: string | null rename?: string | null - status?: Database["public"]["Enums"]["ParityStatus"] | null + status?: Database['public']['Enums']['ParityStatus'] | null weekly_downloads_num: number } Update: { name?: string notes?: string | null rename?: string | null - status?: Database["public"]["Enums"]["ParityStatus"] | null + status?: Database['public']['Enums']['ParityStatus'] | null weekly_downloads_num?: number } Relationships: [] @@ -130,7 +130,7 @@ export type Database = { pr_author: Json | null pr_number: number ref: string | null - status: Database["public"]["Enums"]["pr_status"] + status: Database['public']['Enums']['pr_status'] } Insert: { approval_rating: number @@ -147,7 +147,7 @@ export type Database = { pr_author?: Json | null pr_number: number ref?: string | null - status: Database["public"]["Enums"]["pr_status"] + status: Database['public']['Enums']['pr_status'] } Update: { approval_rating?: number @@ -164,7 +164,7 @@ export type Database = { pr_author?: Json | null pr_number?: number ref?: string | null - status?: Database["public"]["Enums"]["pr_status"] + status?: Database['public']['Enums']['pr_status'] } Relationships: [] } @@ -175,16 +175,16 @@ export type Database = { Functions: { http: { Args: { - request: Database["public"]["CompositeTypes"]["http_request"] + request: Database['public']['CompositeTypes']['http_request'] } - Returns: Database["public"]["CompositeTypes"]["http_response"] + Returns: Database['public']['CompositeTypes']['http_response'] } http_delete: | { Args: { uri: string } - Returns: Database["public"]["CompositeTypes"]["http_response"] + Returns: Database['public']['CompositeTypes']['http_response'] } | { Args: { @@ -192,34 +192,34 @@ export type Database = { content: string content_type: string } - Returns: Database["public"]["CompositeTypes"]["http_response"] + Returns: Database['public']['CompositeTypes']['http_response'] } http_get: | { Args: { uri: string } - Returns: Database["public"]["CompositeTypes"]["http_response"] + Returns: Database['public']['CompositeTypes']['http_response'] } | { Args: { uri: string data: Json } - Returns: Database["public"]["CompositeTypes"]["http_response"] + Returns: Database['public']['CompositeTypes']['http_response'] } http_head: { Args: { uri: string } - Returns: Database["public"]["CompositeTypes"]["http_response"] + Returns: Database['public']['CompositeTypes']['http_response'] } http_header: { Args: { field: string value: string } - Returns: Database["public"]["CompositeTypes"]["http_header"] + Returns: Database['public']['CompositeTypes']['http_header'] } http_list_curlopt: { Args: Record @@ -234,7 +234,7 @@ export type Database = { content: string content_type: string } - Returns: Database["public"]["CompositeTypes"]["http_response"] + Returns: Database['public']['CompositeTypes']['http_response'] } http_post: | { @@ -243,14 +243,14 @@ export type Database = { content: string content_type: string } - Returns: Database["public"]["CompositeTypes"]["http_response"] + Returns: Database['public']['CompositeTypes']['http_response'] } | { Args: { uri: string data: Json } - Returns: Database["public"]["CompositeTypes"]["http_response"] + Returns: Database['public']['CompositeTypes']['http_response'] } http_put: { Args: { @@ -258,7 +258,7 @@ export type Database = { content: string content_type: string } - Returns: Database["public"]["CompositeTypes"]["http_response"] + Returns: Database['public']['CompositeTypes']['http_response'] } http_reset_curlopt: { Args: Record @@ -292,8 +292,8 @@ export type Database = { } } Enums: { - ParityStatus: "no" | "yes" | "100" | "soon" - pr_status: "draft" | "open" | "closed" | "merged" + ParityStatus: 'no' | 'yes' | '100' | 'soon' + pr_status: 'draft' | 'open' | 'closed' | 'merged' } CompositeTypes: { http_header: { @@ -303,41 +303,41 @@ export type Database = { http_request: { method: unknown | null uri: string | null - headers: Database["public"]["CompositeTypes"]["http_header"][] | null + headers: Database['public']['CompositeTypes']['http_header'][] | null content_type: string | null content: string | null } http_response: { status: number | null content_type: string | null - headers: Database["public"]["CompositeTypes"]["http_header"][] | null + headers: Database['public']['CompositeTypes']['http_header'][] | null content: string | null } } } } -type PublicSchema = Database[Extract] +type PublicSchema = Database[Extract] export type Tables< PublicTableNameOrOptions extends - | keyof (PublicSchema["Tables"] & PublicSchema["Views"]) + | keyof (PublicSchema['Tables'] & PublicSchema['Views']) | { schema: keyof Database }, TableName extends PublicTableNameOrOptions extends { schema: keyof Database } - ? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] & - Database[PublicTableNameOrOptions["schema"]]["Views"]) + ? keyof (Database[PublicTableNameOrOptions['schema']]['Tables'] & + Database[PublicTableNameOrOptions['schema']]['Views']) : never = never, > = PublicTableNameOrOptions extends { schema: keyof Database } - ? (Database[PublicTableNameOrOptions["schema"]]["Tables"] & - Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends { + ? (Database[PublicTableNameOrOptions['schema']]['Tables'] & + Database[PublicTableNameOrOptions['schema']]['Views'])[TableName] extends { Row: infer R } ? R : never - : PublicTableNameOrOptions extends keyof (PublicSchema["Tables"] & - PublicSchema["Views"]) - ? (PublicSchema["Tables"] & - PublicSchema["Views"])[PublicTableNameOrOptions] extends { + : PublicTableNameOrOptions extends keyof (PublicSchema['Tables'] & + PublicSchema['Views']) + ? (PublicSchema['Tables'] & + PublicSchema['Views'])[PublicTableNameOrOptions] extends { Row: infer R } ? R @@ -346,19 +346,19 @@ export type Tables< export type TablesInsert< PublicTableNameOrOptions extends - | keyof PublicSchema["Tables"] + | keyof PublicSchema['Tables'] | { schema: keyof Database }, TableName extends PublicTableNameOrOptions extends { schema: keyof Database } - ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] + ? keyof Database[PublicTableNameOrOptions['schema']]['Tables'] : never = never, > = PublicTableNameOrOptions extends { schema: keyof Database } - ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { + ? Database[PublicTableNameOrOptions['schema']]['Tables'][TableName] extends { Insert: infer I } ? I : never - : PublicTableNameOrOptions extends keyof PublicSchema["Tables"] - ? PublicSchema["Tables"][PublicTableNameOrOptions] extends { + : PublicTableNameOrOptions extends keyof PublicSchema['Tables'] + ? PublicSchema['Tables'][PublicTableNameOrOptions] extends { Insert: infer I } ? I @@ -367,19 +367,19 @@ export type TablesInsert< export type TablesUpdate< PublicTableNameOrOptions extends - | keyof PublicSchema["Tables"] + | keyof PublicSchema['Tables'] | { schema: keyof Database }, TableName extends PublicTableNameOrOptions extends { schema: keyof Database } - ? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"] + ? keyof Database[PublicTableNameOrOptions['schema']]['Tables'] : never = never, > = PublicTableNameOrOptions extends { schema: keyof Database } - ? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends { + ? Database[PublicTableNameOrOptions['schema']]['Tables'][TableName] extends { Update: infer U } ? U : never - : PublicTableNameOrOptions extends keyof PublicSchema["Tables"] - ? PublicSchema["Tables"][PublicTableNameOrOptions] extends { + : PublicTableNameOrOptions extends keyof PublicSchema['Tables'] + ? PublicSchema['Tables'][PublicTableNameOrOptions] extends { Update: infer U } ? U @@ -388,13 +388,13 @@ export type TablesUpdate< export type Enums< PublicEnumNameOrOptions extends - | keyof PublicSchema["Enums"] + | keyof PublicSchema['Enums'] | { schema: keyof Database }, EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database } - ? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"] + ? keyof Database[PublicEnumNameOrOptions['schema']]['Enums'] : never = never, > = PublicEnumNameOrOptions extends { schema: keyof Database } - ? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName] - : PublicEnumNameOrOptions extends keyof PublicSchema["Enums"] - ? PublicSchema["Enums"][PublicEnumNameOrOptions] + ? Database[PublicEnumNameOrOptions['schema']]['Enums'][EnumName] + : PublicEnumNameOrOptions extends keyof PublicSchema['Enums'] + ? PublicSchema['Enums'][PublicEnumNameOrOptions] : never diff --git a/tests/typed/isEqual.test.ts b/tests/typed/isEqual.test.ts index 3a64d7ad4..3d19b6845 100644 --- a/tests/typed/isEqual.test.ts +++ b/tests/typed/isEqual.test.ts @@ -46,16 +46,21 @@ describe('isEqual', () => { expect( _.isEqual([complex, complex], [{ ...complex }, { ...complex }]), ).toBeTruthy() - expect(_.isEqual(new Map([ - [1, "one"], - [2, "two"], - [3, "three"], - ]), new Map([ - [3, "three"], - [2, "two"], - [1, "one"], - ]))).toBeTruthy(); - expect(_.isEqual(new Set([1,2,3]), new Set([3,2,1]))).toBeTruthy() + expect( + _.isEqual( + new Map([ + [1, 'one'], + [2, 'two'], + [3, 'three'], + ]), + new Map([ + [3, 'three'], + [2, 'two'], + [1, 'one'], + ]), + ), + ).toBeTruthy() + expect(_.isEqual(new Set([1, 2, 3]), new Set([3, 2, 1]))).toBeTruthy() }) test('returns false for non-equal things', () => { expect(_.isEqual(0, 1)).toBeFalsy() diff --git a/vitest.config.ts b/vitest.config.ts index 511f696b9..d987e6c4d 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -19,7 +19,7 @@ export default defineConfig(env => ({ typecheck: { include: ['tests/**/*.test-d.ts'], enabled: true, - tsconfig: "tests/tsconfig.json" + tsconfig: 'tests/tsconfig.json', }, }, resolve: { From a9f9a60e8d76f05e8e6c36862c2ff631656669c3 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 12:13:09 -0500 Subject: [PATCH 11/56] chore: use --provenance when publishing --- scripts/versions/src/publishVersion.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/versions/src/publishVersion.ts b/scripts/versions/src/publishVersion.ts index 086080c2f..091b9cbc6 100644 --- a/scripts/versions/src/publishVersion.ts +++ b/scripts/versions/src/publishVersion.ts @@ -26,6 +26,12 @@ export async function publishVersion(args: { deployKey?: string nightlyDeployKey?: string }) { + if (!process.env.CI) { + throw new Error( + 'publishVersion must be run in CI, due to provenance requirements', + ) + } + // Determine the last stable version const { stdout: stableVersion } = await execa('npm', [ 'view', @@ -204,7 +210,7 @@ export async function publishVersion(args: { stdio: 'inherit', }) - const npmPublishArgs = ['publish', '--ignore-scripts'] + const npmPublishArgs = ['publish', '--provenance', '--ignore-scripts'] // Use radashi@next for pre-release major versions and radashi@beta // for pre-release minor/patch versions. From 5a14cdd6d10b1a9a2bf13e2c7b89d83225801089 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 12:23:29 -0500 Subject: [PATCH 12/56] ci: require explicit --latest flag for stable release --- scripts/versions/ci-publish.ts | 17 ++++++++++++----- scripts/versions/src/publishVersion.ts | 4 +++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/scripts/versions/ci-publish.ts b/scripts/versions/ci-publish.ts index 3d4dd8a34..feb8590ac 100644 --- a/scripts/versions/ci-publish.ts +++ b/scripts/versions/ci-publish.ts @@ -1,5 +1,5 @@ import mri from 'mri' -import { publishVersion } from './src/publishVersion' +import { publishVersion, VALID_TAGS } from './src/publishVersion' main() @@ -25,17 +25,24 @@ function parseArgs() { const argv = mri(process.argv.slice(2), { boolean: ['no-push'], - string: ['tag'], + string: ['tag', 'latest'], }) - if (argv.tag && argv.tag !== 'beta' && argv.tag !== 'next') { - console.error('Error: --tag must be beta or next') + if (argv.latest && argv.tag) { + console.error('Error: --latest and --tag cannot be specified together') + process.exit(1) + } + + if (!argv.latest && !VALID_TAGS.includes(argv.tag)) { + console.error( + `Error: --tag must be one of [${VALID_TAGS.join(', ')}] or --latest must be specified instead`, + ) process.exit(1) } return { push: !argv['no-push'], - tag: argv.tag as 'beta' | 'next', + tag: argv.tag as (typeof VALID_TAGS)[number], gitCliffToken, npmToken, radashiBotToken, diff --git a/scripts/versions/src/publishVersion.ts b/scripts/versions/src/publishVersion.ts index 091b9cbc6..df8612cc7 100644 --- a/scripts/versions/src/publishVersion.ts +++ b/scripts/versions/src/publishVersion.ts @@ -13,12 +13,14 @@ import { trackVersion } from './trackVersion' // This is the commit that Radashi's changelog is based on. const changelogBaseSha = '2be4acf455ebec86e846854dbab57bd0bfbbceb7' +export const VALID_TAGS = ['beta', 'next'] as const + export async function publishVersion(args: { /** * Use "beta" for pre-release minor/patch versions and "next" for * pre-release major versions. */ - tag?: 'beta' | 'next' + tag?: (typeof VALID_TAGS)[number] push: boolean gitCliffToken?: string npmToken?: string From 160ddbadaf45842e72715448d9fa0cc9e4541a70 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:12:31 -0500 Subject: [PATCH 13/56] chore: add publish-latest workflow --- .github/workflows/publish-latest.yml | 79 ++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 .github/workflows/publish-latest.yml diff --git a/.github/workflows/publish-latest.yml b/.github/workflows/publish-latest.yml new file mode 100644 index 000000000..49a979751 --- /dev/null +++ b/.github/workflows/publish-latest.yml @@ -0,0 +1,79 @@ +name: Publish radashi@latest + +on: + workflow_dispatch: + +jobs: + test: + name: Test + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18.x, 20.x, 22.x] + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: pnpm + - run: pnpm install + - run: pnpm test + - if: ${{ matrix.node-version == '22.x' }} + name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4.0.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + + validate: + name: Validate + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + registry-url: 'https://registry.npmjs.org' + node-version: '22.x' + cache: pnpm + - run: pnpm install + - name: Lint + run: pnpm lint + - name: Check Build + run: pnpm build + + publish-latest: + name: Publish Latest + needs: [test, validate] + runs-on: ubuntu-latest + continue-on-error: true + permissions: + id-token: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + registry-url: 'https://registry.npmjs.org' + node-version: '22.x' + cache: pnpm + - run: pnpm install + - run: pnpm build + + - name: Install script dependencies + run: | + pnpm install -C scripts/versions + pnpm install -C scripts/radashi-db + + - name: Publish + env: + GIT_CLIFF_PAT: ${{ secrets.GIT_CLIFF_PAT }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + RADASHI_BOT_TOKEN: ${{ secrets.RADASHI_BOT_TOKEN }} + SUPABASE_KEY: ${{ secrets.SUPABASE_KEY }} + DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} + run: | + ./scripts/versions/node_modules/.bin/tsx ./scripts/versions/ci-publish.ts --latest From e6d61fc1c71bfa7631b48ab0d0f1578f95da4401 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:15:19 -0500 Subject: [PATCH 14/56] ci: exit publishVersion if next version equals latest version --- scripts/versions/src/publishVersion.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/versions/src/publishVersion.ts b/scripts/versions/src/publishVersion.ts index df8612cc7..e6ad17caf 100644 --- a/scripts/versions/src/publishVersion.ts +++ b/scripts/versions/src/publishVersion.ts @@ -50,6 +50,11 @@ export async function publishVersion(args: { env: { GITHUB_TOKEN: args.gitCliffToken }, }).then(r => r.stdout.replace(/^v/, '')) + if (stableVersion === newVersion) { + log('🚫 No version bump detected') + process.exit(1) + } + const newMajorVersion = newVersion.split('.')[0] if (args.tag) { From 7f7799d265ec020de5dad52ff4db8f52dd2429d5 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:24:39 -0500 Subject: [PATCH 15/56] chore: force provenance in npmrc --- .npmrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.npmrc b/.npmrc index 581701ceb..136f095b8 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ -package-manager-strict=false \ No newline at end of file +package-manager-strict=false +provenance=true \ No newline at end of file From c7ff08b2df44f41d2b2b73d9dbc6cbecd210ae58 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:25:37 -0500 Subject: [PATCH 16/56] chore: remove "prepublishOnly" and "release" scripts These were intended for non-CI releases, which are now forbidden. --- package.json | 2 -- scripts/release.sh | 10 ---------- 2 files changed, 12 deletions(-) delete mode 100644 scripts/release.sh diff --git a/package.json b/package.json index 0d0625c30..3d5f3eef2 100644 --- a/package.json +++ b/package.json @@ -39,8 +39,6 @@ "format": "bash ./scripts/format.sh", "lint": "bash ./scripts/lint.sh", "move-function": "bash ./scripts/move-function.sh", - "prepublishOnly": "tsc && biome check --fix && pnpm -s build", - "release": "bash ./scripts/release.sh", "test": "vitest run --coverage", "test-branch": "bash ./scripts/test-branch.sh", "test-single": "bash ./scripts/test-single.sh", diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100644 index ccdc85138..000000000 --- a/scripts/release.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash -set -e - -if [ ! -d "scripts/versions/node_modules" ]; then - echo "Node modules not found. Installing dependencies..." - pnpm install -C scripts/versions - pnpm install -C scripts/radashi-db -fi - -pnpm -s scripts/versions/node_modules/.bin/tsx scripts/versions/ci-publish.ts "$@" From 28c6efcf8b19227573c4f9a325ef47303c314827 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:56:36 -0500 Subject: [PATCH 17/56] test: add type tests for `group` --- tests/array/group.test-d.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/array/group.test-d.ts diff --git a/tests/array/group.test-d.ts b/tests/array/group.test-d.ts new file mode 100644 index 000000000..411609dc3 --- /dev/null +++ b/tests/array/group.test-d.ts @@ -0,0 +1,15 @@ +import * as _ from 'radashi' + +test('group', () => { + const groups = _.group([1, 1.2, 1.3, 2], Math.floor) + + // Note: This *should* be number[][] since we use + // exactOptionalPropertyTypes, but TypeScript has an outstanding + // issue: https://github.com/microsoft/TypeScript/issues/46969 + expectTypeOf(Object.values(groups)).toEqualTypeOf<(number[] | undefined)[]>() + + expectTypeOf(groups[1]).toEqualTypeOf() + if (1 in groups) { + expectTypeOf(groups[1]).toEqualTypeOf() + } +}) From 8fe71d82bdd67ec94c80d2d0c3318b1e62a58edb Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:00:58 -0500 Subject: [PATCH 18/56] fix(types): improve signature of `shake` (#293) --- src/object/shake.ts | 18 +++++++++++--- tests/object/shake.test-d.ts | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 tests/object/shake.test-d.ts diff --git a/src/object/shake.ts b/src/object/shake.ts index b3026b103..66dcde26b 100644 --- a/src/object/shake.ts +++ b/src/object/shake.ts @@ -2,6 +2,8 @@ * Removes (shakes out) undefined entries from an object. Optional * second argument shakes out values by custom evaluation. * + * Note that non-enumerable keys are never shaken out. + * * @see https://radashi.js.org/reference/object/shake * @example * ```ts @@ -13,13 +15,23 @@ */ export function shake( obj: T, - filter: (value: T[keyof T]) => boolean = value => value === undefined, +): { + [K in keyof T]: Exclude +} + +export function shake( + obj: T, + filter: ((value: unknown) => boolean) | undefined, +): T + +export function shake( + obj: T, + filter: (value: unknown) => boolean = value => value === undefined, ): T { if (!obj) { return {} as T } - const keys = Object.keys(obj) as (keyof T)[] - return keys.reduce((acc, key) => { + return (Object.keys(obj) as (keyof T)[]).reduce((acc, key) => { if (!filter(obj[key])) { acc[key] = obj[key] } diff --git a/tests/object/shake.test-d.ts b/tests/object/shake.test-d.ts new file mode 100644 index 000000000..88cea4ef2 --- /dev/null +++ b/tests/object/shake.test-d.ts @@ -0,0 +1,46 @@ +import { shake } from 'radashi' + +describe('shake', () => { + test('object with possibly undefined values', () => { + // Undefined values are removed. + const result = shake({} as { a: string | undefined }) + expectTypeOf(result).toEqualTypeOf<{ a: string }>() + }) + + test('object with optional properties', () => { + // Optional properties must not be affected, because we don't know + // whether they exist on the object at runtime. + const result = shake({} as { a?: string }) + expectTypeOf(result).toEqualTypeOf<{ a?: string }>() + + // When using exactOptionalPropertyTypes, optional properties + // *will* have their undefined values removed, but their + // optionality still won't be affected. + const result2 = shake({} as { a?: string | undefined }, undefined) + expectTypeOf(result2).toEqualTypeOf<{ a?: string }>() + }) + + test('Record type', () => { + // Undefined values are removed. + const result = shake({} as Record) + expectTypeOf(result).toEqualTypeOf>() + + // Allows any property key. Preserves null values. + const result2 = shake({} as Record) + expectTypeOf(result2).toEqualTypeOf>() + }) + + test('with filter function', () => { + // We cannot assume *anything* about the return type when a filter + // function is used. You can use type assertions to “fix” the + // return type in this case. + const result = shake({} as { a: string | undefined }, value => { + // We cannot assume *anything* about the value parameter, + // since “object assignability” is not strict in TypeScript. + expectTypeOf(value).toEqualTypeOf() + + return value === undefined + }) + expectTypeOf(result).toEqualTypeOf<{ a: string | undefined }>() + }) +}) From 2ade9bec805c3612e5bb08c7edd025af51a2dad5 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:12:26 -0500 Subject: [PATCH 19/56] fix(types): `mapValues` index signature handling (#297) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …and optional properties handling. --- src/object/mapValues.ts | 41 ++++++-------------------------- tests/object/mapValues.test-d.ts | 29 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 34 deletions(-) create mode 100644 tests/object/mapValues.test-d.ts diff --git a/src/object/mapValues.ts b/src/object/mapValues.ts index 5d2d81989..179ab630e 100644 --- a/src/object/mapValues.ts +++ b/src/object/mapValues.ts @@ -10,42 +10,15 @@ * ``` * @version 12.1.0 */ -export function mapValues< - TValue, - TKey extends string | number | symbol, - TNewValue, ->( - obj: { [K in TKey]: TValue }, - mapFunc: (value: TValue, key: TKey) => TNewValue, -): { [K in TKey]: TNewValue } - -// This overload exists to support cases where `obj` is a partial -// object whose values are never undefined when the key is also -// defined. For example: -// { [key: string]?: number } versus { [key: string]: number | undefined } -export function mapValues< - TValue, - TKey extends string | number | symbol, - TNewValue, ->( - obj: { [K in TKey]?: TValue }, - mapFunc: (value: TValue, key: TKey) => TNewValue, -): { [K in TKey]?: TNewValue } - -export function mapValues< - TValue, - TKey extends string | number | symbol, - TNewValue, ->( - obj: { [K in TKey]?: TValue }, - mapFunc: (value: TValue, key: TKey) => TNewValue, -): Record { - const keys = Object.keys(obj) as TKey[] - return keys.reduce( +export function mapValues( + obj: T, + mapFunc: (value: Required[keyof T], key: keyof T) => U, +): { [K in keyof T]: U } { + return (Object.keys(obj) as (keyof T)[]).reduce( (acc, key) => { - acc[key] = mapFunc(obj[key]!, key) + acc[key] = mapFunc(obj[key], key) return acc }, - {} as Record, + {} as { [K in keyof T]: U }, ) } diff --git a/tests/object/mapValues.test-d.ts b/tests/object/mapValues.test-d.ts new file mode 100644 index 000000000..ca94b4c37 --- /dev/null +++ b/tests/object/mapValues.test-d.ts @@ -0,0 +1,29 @@ +import { mapValues } from 'radashi' + +describe('mapValues', () => { + test('Record types', () => { + const object = mapValues({} as Record, x => x.toFixed(2)) + expectTypeOf(object).toEqualTypeOf>() + }) + + test('index signature types', () => { + const object = mapValues({} as { [key: string]: number }, x => x.toFixed(2)) + expectTypeOf(object).toEqualTypeOf<{ [key: string]: string }>() + }) + + test('literal types', () => { + const object = mapValues({} as { a: number }, x => x.toFixed(2)) + expectTypeOf(object).toEqualTypeOf<{ a: string }>() + }) + + test('optional types', () => { + const object = mapValues({} as { a?: number }, x => { + // Due to exactOptionalPropertyTypes, the type-checker knows + // that `x` will never be undefined, because `mapValues` can + // only process keys that are present. + expectTypeOf(x).toEqualTypeOf() + return x.toFixed(2) + }) + expectTypeOf(object).toEqualTypeOf<{ a?: string }>() + }) +}) From 2c685979897fab26eac2a66fa676b0e01ab6349b Mon Sep 17 00:00:00 2001 From: Alexander Harding Date: Thu, 7 Nov 2024 15:21:47 -0600 Subject: [PATCH 20/56] fix(types): let `zipToObject` receive readonly arrays (#294) Co-authored-by: Alec Larson <1925840+aleclarson@users.noreply.github.com> Co-authored-by: Marlon Passos --- src/array/zipToObject.ts | 4 ++-- tests/array/zipToObject.test-d.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 tests/array/zipToObject.test-d.ts diff --git a/src/array/zipToObject.ts b/src/array/zipToObject.ts index 964045111..bf82c4737 100644 --- a/src/array/zipToObject.ts +++ b/src/array/zipToObject.ts @@ -19,8 +19,8 @@ import { isArray, isFunction } from 'radashi' * @version 12.1.0 */ export function zipToObject( - keys: K[], - values: V | ((key: K, idx: number) => V) | V[], + keys: readonly K[], + values: V | ((key: K, idx: number) => V) | readonly V[], ): Record { if (!keys || !keys.length) { return {} as Record diff --git a/tests/array/zipToObject.test-d.ts b/tests/array/zipToObject.test-d.ts new file mode 100644 index 000000000..45b859ce5 --- /dev/null +++ b/tests/array/zipToObject.test-d.ts @@ -0,0 +1,31 @@ +import * as _ from 'radashi' + +describe('zipToObject', () => { + test('mutable arrays with loose types', () => { + const names = ['ra', 'zeus', 'loki'] + const followers = [1000000, 500000, 250000] + expectTypeOf(_.zipToObject(names, followers)).toEqualTypeOf< + Record + >() + }) + + test('readonly arrays with string literals', () => { + const names = ['ra', 'zeus', 'loki'] as const + const cultures = ['egypt', 'greek', 'norse'] as const + + expectTypeOf(_.zipToObject(names, cultures)).toEqualTypeOf< + Record<'ra' | 'zeus' | 'loki', 'egypt' | 'greek' | 'norse'> + >() + }) + + test('inline array and single value', () => { + // Note how the value type is widened to `number`. + const result = _.zipToObject(['a', 'b'], 1) + expectTypeOf(result).toEqualTypeOf>() + }) + + test('empty array', () => { + const result = _.zipToObject([], 1) + expectTypeOf(result).toEqualTypeOf>() + }) +}) From 0e0ff04fb23283e323206689a31109589bb712ed Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:32:24 -0500 Subject: [PATCH 21/56] ci: checkout with deploy key when publishing --- .github/workflows/publish-beta.yml | 1 + .github/workflows/publish-latest.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/publish-beta.yml b/.github/workflows/publish-beta.yml index 84c3512b9..734e2b419 100644 --- a/.github/workflows/publish-beta.yml +++ b/.github/workflows/publish-beta.yml @@ -53,6 +53,7 @@ jobs: steps: - uses: actions/checkout@v4 with: + ssh-key: ${{ secrets.DEPLOY_KEY }} fetch-depth: 0 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 diff --git a/.github/workflows/publish-latest.yml b/.github/workflows/publish-latest.yml index 49a979751..db143a077 100644 --- a/.github/workflows/publish-latest.yml +++ b/.github/workflows/publish-latest.yml @@ -53,6 +53,7 @@ jobs: steps: - uses: actions/checkout@v4 with: + ssh-key: ${{ secrets.DEPLOY_KEY }} fetch-depth: 0 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 From ca03e8aa8c76987420c6a73c76a40e1ee302d8de Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sat, 9 Nov 2024 10:22:36 -0500 Subject: [PATCH 22/56] ci: fix deploy key by using ssh url This also reverts 0e0ff04fb23283e323206689a31109589bb712ed. --- .github/workflows/publish-beta.yml | 1 - .github/workflows/publish-latest.yml | 1 - scripts/versions/ci-publish.ts | 6 ++++++ scripts/versions/src/publishVersion.ts | 15 +++++++++++---- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-beta.yml b/.github/workflows/publish-beta.yml index 734e2b419..84c3512b9 100644 --- a/.github/workflows/publish-beta.yml +++ b/.github/workflows/publish-beta.yml @@ -53,7 +53,6 @@ jobs: steps: - uses: actions/checkout@v4 with: - ssh-key: ${{ secrets.DEPLOY_KEY }} fetch-depth: 0 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 diff --git a/.github/workflows/publish-latest.yml b/.github/workflows/publish-latest.yml index db143a077..49a979751 100644 --- a/.github/workflows/publish-latest.yml +++ b/.github/workflows/publish-latest.yml @@ -53,7 +53,6 @@ jobs: steps: - uses: actions/checkout@v4 with: - ssh-key: ${{ secrets.DEPLOY_KEY }} fetch-depth: 0 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 diff --git a/scripts/versions/ci-publish.ts b/scripts/versions/ci-publish.ts index feb8590ac..a7844cb62 100644 --- a/scripts/versions/ci-publish.ts +++ b/scripts/versions/ci-publish.ts @@ -51,6 +51,12 @@ function parseArgs() { } } +/** + * This ensures that the environment variables are set and returns the + * values as a typed object. To ensure sensitive variables are not + * accessible to untrusted code, the environment variables are cleared + * after they are read. + */ function verifyEnvVars>( vars: T, ): { diff --git a/scripts/versions/src/publishVersion.ts b/scripts/versions/src/publishVersion.ts index e6ad17caf..c0704ba12 100644 --- a/scripts/versions/src/publishVersion.ts +++ b/scripts/versions/src/publishVersion.ts @@ -151,6 +151,13 @@ export async function publishVersion(args: { if (args.push) { if (args.deployKey) { await installDeployKey(args.deployKey) + // The origin must use SSH for the deploy key to work. + await execa('git', [ + 'remote', + 'set-url', + 'origin', + 'git@github.com:radashi-org/radashi.git', + ]) } log('Pushing to origin') await execa('git', ['push'], { stdio: 'inherit' }) @@ -185,11 +192,11 @@ export async function publishVersion(args: { ], { reject: false }, ) - } - // Use the nightly deploy key if we're pushing a nightly tag. - if (args.tag && args.nightlyDeployKey) { - await installDeployKey(args.nightlyDeployKey) + // Use the nightly deploy key if we're pushing a nightly tag. + if (args.nightlyDeployKey) { + await installDeployKey(args.nightlyDeployKey) + } } log(`Pushing new tag ${exactTag}`) From 5682f01d660b92e2d2039f23700c4448ba62d467 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sat, 9 Nov 2024 10:40:31 -0500 Subject: [PATCH 23/56] chore: use separate changelog for `next` tag --- scripts/versions/src/publishVersion.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/versions/src/publishVersion.ts b/scripts/versions/src/publishVersion.ts index c0704ba12..a7f77b073 100644 --- a/scripts/versions/src/publishVersion.ts +++ b/scripts/versions/src/publishVersion.ts @@ -116,9 +116,11 @@ export async function publishVersion(args: { } } + const changelogFile = `CHANGELOG${args.tag === 'next' ? '-next' : ''}.md` + // Generate Changelog log(`Generating changelog from ${changelogBaseSha.slice(0, 7)} to HEAD`) - const gitCliffArgs = [`${changelogBaseSha}..HEAD`, '-o', 'CHANGELOG.md'] + const gitCliffArgs = [`${changelogBaseSha}..HEAD`, '-o', changelogFile] if (!args.tag) { gitCliffArgs.push('--tag', `v${newVersion}`) } @@ -127,15 +129,15 @@ export async function publishVersion(args: { }) // Check if CHANGELOG.md has changed - await execa('git', ['status', '--porcelain', 'CHANGELOG.md']).then(status => { + await execa('git', ['status', '--porcelain', changelogFile]).then(status => { if (!status.stdout.trim()) { - log('No changes detected in CHANGELOG.md') + log('No changes detected in %s', changelogFile) process.exit(1) } }) // Commit files - const committedFiles = ['CHANGELOG.md'] + const committedFiles = [changelogFile] if (!args.tag) { // Only commit the changed version in package.json if it's a // stable version being published. From 5c9d0223cd5035a10671a87a724fddbcce4999b7 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sat, 9 Nov 2024 11:51:13 -0500 Subject: [PATCH 24/56] ci: fix provenance in publish-beta --- .github/workflows/publish-beta.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish-beta.yml b/.github/workflows/publish-beta.yml index 84c3512b9..be82c5050 100644 --- a/.github/workflows/publish-beta.yml +++ b/.github/workflows/publish-beta.yml @@ -50,6 +50,8 @@ jobs: needs: [test, validate] runs-on: ubuntu-latest continue-on-error: true + permissions: + id-token: write steps: - uses: actions/checkout@v4 with: From e5e8292f053337013d1faadddcde67bcec9255a2 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sat, 9 Nov 2024 12:51:06 -0500 Subject: [PATCH 25/56] chore: add release notes for PRs to edit --- .github/next-major.md | 7 +++++++ .github/next-minor.md | 11 +++++++++++ .github/pull_request_template.md | 1 + 3 files changed, 19 insertions(+) create mode 100644 .github/next-major.md create mode 100644 .github/next-minor.md diff --git a/.github/next-major.md b/.github/next-major.md new file mode 100644 index 000000000..5e9e194fd --- /dev/null +++ b/.github/next-major.md @@ -0,0 +1,7 @@ +If you open a PR that contains a breaking change, add it to this file. + +The `####` headline should be short and descriptive of the breaking change. In the body of the section, include a link to the PR. You don't need to include a description of the change itself, as we will extract that from the PR description. + +## Breaking Changes + +#### diff --git a/.github/next-minor.md b/.github/next-minor.md new file mode 100644 index 000000000..2b8355528 --- /dev/null +++ b/.github/next-minor.md @@ -0,0 +1,11 @@ +If you open a PR that introduces a new function, add it to the "New Functions" section. If you're extending an existing function, add it to the "New Features" section. + +The `####` headline should be short and descriptive of the new functionality. In the body of the section, include a link to the PR. You don't need to include a description of the change itself, as we will extract that from the documentation. + +## New Functions + +#### + +## New Features + +#### diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 0d28faeb7..0e96e48e5 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -22,6 +22,7 @@ - [ ] Related documentation has been updated, if needed - [ ] Related tests have been added or updated, if needed - [ ] Related benchmarks have been added or updated, if needed +- [ ] Release notes in [next-minor.md](.github/next-minor.md) or [next-major.md](.github/next-major.md) have been added, if needed ## Does this PR introduce a breaking change? From 5cf5895127ef1ba98103d097ee90136eaf8176c4 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sat, 9 Nov 2024 14:37:31 -0500 Subject: [PATCH 26/56] ci: add prerelease-pr workflow --- .github/workflows/prerelease-pr.yml | 34 ++ scripts/common/installDeployKey.ts | 14 + scripts/common/verifyEnvVars.ts | 32 ++ scripts/prerelease/ci-prerelease.ts | 17 + scripts/prerelease/package.json | 15 + scripts/prerelease/pnpm-lock.yaml | 606 +++++++++++++++++++++++++ scripts/prerelease/src/prerelease.ts | 97 ++++ scripts/versions/ci-publish.ts | 63 +-- scripts/versions/src/publishVersion.ts | 52 ++- 9 files changed, 868 insertions(+), 62 deletions(-) create mode 100644 .github/workflows/prerelease-pr.yml create mode 100644 scripts/common/installDeployKey.ts create mode 100644 scripts/common/verifyEnvVars.ts create mode 100644 scripts/prerelease/ci-prerelease.ts create mode 100644 scripts/prerelease/package.json create mode 100644 scripts/prerelease/pnpm-lock.yaml create mode 100644 scripts/prerelease/src/prerelease.ts diff --git a/.github/workflows/prerelease-pr.yml b/.github/workflows/prerelease-pr.yml new file mode 100644 index 000000000..4d14141ce --- /dev/null +++ b/.github/workflows/prerelease-pr.yml @@ -0,0 +1,34 @@ +name: Prerelease PR + +on: + pull_request_target: + types: [labeled] + +jobs: + prerelease: + if: ${{ contains(github.event.pull_request.labels.*.name, 'prerelease') && github.event.pull_request.state == 'open' && github.event.pull_request.draft == false && github.event.pull_request.mergeable_state == 'clean' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + registry-url: 'https://registry.npmjs.org' + node-version: '22.x' + cache: pnpm + + - name: Install script dependencies + run: | + pnpm install -C scripts/prerelease + + - name: Publish + env: + DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_TITLE: ${{ github.event.pull_request.title }} + PR_REPO_URL: ${{ github.event.pull_request.head.repo.clone_url }} + PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} + run: | + ./scripts/prerelease/node_modules/.bin/tsx ./scripts/prerelease/ci-prerelease.ts diff --git a/scripts/common/installDeployKey.ts b/scripts/common/installDeployKey.ts new file mode 100644 index 000000000..141e52c65 --- /dev/null +++ b/scripts/common/installDeployKey.ts @@ -0,0 +1,14 @@ +import fs from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' + +export async function installDeployKey(deployKey: string) { + const sshDir = path.join(os.homedir(), '.ssh') + await fs.mkdir(sshDir, { recursive: true }) + + const keyPath = path.join(sshDir, 'deploy_key') + await fs.writeFile(keyPath, deployKey, { mode: 0o600 }) + + // Set GIT_SSH_COMMAND to use the deploy key + process.env.GIT_SSH_COMMAND = `ssh -i ${keyPath} -o StrictHostKeyChecking=no` +} diff --git a/scripts/common/verifyEnvVars.ts b/scripts/common/verifyEnvVars.ts new file mode 100644 index 000000000..4cf625946 --- /dev/null +++ b/scripts/common/verifyEnvVars.ts @@ -0,0 +1,32 @@ +/** + * This ensures that the environment variables are set and returns the + * values as a typed object. To ensure sensitive variables are not + * accessible to untrusted code, the environment variables are cleared + * after they are read. + */ +export function verifyEnvVars>( + vars: T, +): { + [K in keyof T]: T[K] extends infer Value + ? Value extends string + ? string + : undefined + : undefined +} { + return Object.entries(vars).reduce( + (acc, [alias, envName]) => { + if (!envName) { + return acc + } + const value = process.env[envName] + if (!value) { + console.error(`Error: ${envName} is not set`) + process.exit(1) + } + process.env[envName] = '' + acc[alias] = value + return acc + }, + {} as Record, + ) as any +} diff --git a/scripts/prerelease/ci-prerelease.ts b/scripts/prerelease/ci-prerelease.ts new file mode 100644 index 000000000..608df215f --- /dev/null +++ b/scripts/prerelease/ci-prerelease.ts @@ -0,0 +1,17 @@ +import { verifyEnvVars } from '../common/verifyEnvVars' + +main() + +async function main() { + const args = verifyEnvVars({ + deployKey: 'DEPLOY_KEY', + prNumber: 'PR_NUMBER', + prTitle: 'PR_TITLE', + prRepoUrl: 'PR_REPO_URL', + prHeadRef: 'PR_HEAD_REF', + }) + + const { prerelease } = await import('./src/prerelease') + + await prerelease(args) +} diff --git a/scripts/prerelease/package.json b/scripts/prerelease/package.json new file mode 100644 index 000000000..8b0aec81b --- /dev/null +++ b/scripts/prerelease/package.json @@ -0,0 +1,15 @@ +{ + "type": "module", + "private": true, + "dependencies": { + "@octokit/rest": "^21.0.2", + "execa": "^9.3.0", + "mri": "^1.2.0", + "tsx": "^4.17.0" + }, + "pnpm": { + "overrides": { + "execa": "^9.3.0" + } + } +} diff --git a/scripts/prerelease/pnpm-lock.yaml b/scripts/prerelease/pnpm-lock.yaml new file mode 100644 index 000000000..524136bdc --- /dev/null +++ b/scripts/prerelease/pnpm-lock.yaml @@ -0,0 +1,606 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + execa: ^9.3.0 + +importers: + + .: + dependencies: + '@octokit/rest': + specifier: ^21.0.2 + version: 21.0.2 + execa: + specifier: ^9.3.0 + version: 9.5.1 + mri: + specifier: ^1.2.0 + version: 1.2.0 + tsx: + specifier: ^4.17.0 + version: 4.19.2 + +packages: + + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@octokit/auth-token@5.1.1': + resolution: {integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==} + engines: {node: '>= 18'} + + '@octokit/core@6.1.2': + resolution: {integrity: sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==} + engines: {node: '>= 18'} + + '@octokit/endpoint@10.1.1': + resolution: {integrity: sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==} + engines: {node: '>= 18'} + + '@octokit/graphql@8.1.1': + resolution: {integrity: sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==} + engines: {node: '>= 18'} + + '@octokit/openapi-types@22.2.0': + resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==} + + '@octokit/plugin-paginate-rest@11.3.5': + resolution: {integrity: sha512-cgwIRtKrpwhLoBi0CUNuY83DPGRMaWVjqVI/bGKsLJ4PzyWZNaEmhHroI2xlrVXkk6nFv0IsZpOp+ZWSWUS2AQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-request-log@5.3.1': + resolution: {integrity: sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-rest-endpoint-methods@13.2.6': + resolution: {integrity: sha512-wMsdyHMjSfKjGINkdGKki06VEkgdEldIGstIEyGX0wbYHGByOwN/KiM+hAAlUwAtPkP3gvXtVQA9L3ITdV2tVw==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/request-error@6.1.5': + resolution: {integrity: sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==} + engines: {node: '>= 18'} + + '@octokit/request@9.1.3': + resolution: {integrity: sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==} + engines: {node: '>= 18'} + + '@octokit/rest@21.0.2': + resolution: {integrity: sha512-+CiLisCoyWmYicH25y1cDfCrv41kRSvTq6pPWtRroRJzhsCZWZyCqGyI8foJT5LmScADSwRAnr/xo+eewL04wQ==} + engines: {node: '>= 18'} + + '@octokit/types@13.6.1': + resolution: {integrity: sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==} + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + before-after-hook@3.0.2: + resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} + + cross-spawn@7.0.5: + resolution: {integrity: sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==} + engines: {node: '>= 8'} + + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + engines: {node: '>=18'} + hasBin: true + + execa@9.5.1: + resolution: {integrity: sha512-QY5PPtSonnGwhhHDNI7+3RvY285c7iuJFFB+lU+oEzMY/gEGJ808owqJsrr8Otd1E/x07po1LkUBmdAc5duPAg==} + engines: {node: ^18.19.0 || >=20.5.0} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + + human-signals@8.0.0: + resolution: {integrity: sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==} + engines: {node: '>=18.18.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + pretty-ms@9.1.0: + resolution: {integrity: sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==} + engines: {node: '>=18'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + tsx@4.19.2: + resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==} + engines: {node: '>=18.0.0'} + hasBin: true + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + universal-user-agent@7.0.2: + resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + +snapshots: + + '@esbuild/aix-ppc64@0.23.1': + optional: true + + '@esbuild/android-arm64@0.23.1': + optional: true + + '@esbuild/android-arm@0.23.1': + optional: true + + '@esbuild/android-x64@0.23.1': + optional: true + + '@esbuild/darwin-arm64@0.23.1': + optional: true + + '@esbuild/darwin-x64@0.23.1': + optional: true + + '@esbuild/freebsd-arm64@0.23.1': + optional: true + + '@esbuild/freebsd-x64@0.23.1': + optional: true + + '@esbuild/linux-arm64@0.23.1': + optional: true + + '@esbuild/linux-arm@0.23.1': + optional: true + + '@esbuild/linux-ia32@0.23.1': + optional: true + + '@esbuild/linux-loong64@0.23.1': + optional: true + + '@esbuild/linux-mips64el@0.23.1': + optional: true + + '@esbuild/linux-ppc64@0.23.1': + optional: true + + '@esbuild/linux-riscv64@0.23.1': + optional: true + + '@esbuild/linux-s390x@0.23.1': + optional: true + + '@esbuild/linux-x64@0.23.1': + optional: true + + '@esbuild/netbsd-x64@0.23.1': + optional: true + + '@esbuild/openbsd-arm64@0.23.1': + optional: true + + '@esbuild/openbsd-x64@0.23.1': + optional: true + + '@esbuild/sunos-x64@0.23.1': + optional: true + + '@esbuild/win32-arm64@0.23.1': + optional: true + + '@esbuild/win32-ia32@0.23.1': + optional: true + + '@esbuild/win32-x64@0.23.1': + optional: true + + '@octokit/auth-token@5.1.1': {} + + '@octokit/core@6.1.2': + dependencies: + '@octokit/auth-token': 5.1.1 + '@octokit/graphql': 8.1.1 + '@octokit/request': 9.1.3 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + before-after-hook: 3.0.2 + universal-user-agent: 7.0.2 + + '@octokit/endpoint@10.1.1': + dependencies: + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/graphql@8.1.1': + dependencies: + '@octokit/request': 9.1.3 + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/openapi-types@22.2.0': {} + + '@octokit/plugin-paginate-rest@11.3.5(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/types': 13.6.1 + + '@octokit/plugin-request-log@5.3.1(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + + '@octokit/plugin-rest-endpoint-methods@13.2.6(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/types': 13.6.1 + + '@octokit/request-error@6.1.5': + dependencies: + '@octokit/types': 13.6.1 + + '@octokit/request@9.1.3': + dependencies: + '@octokit/endpoint': 10.1.1 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/rest@21.0.2': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/plugin-paginate-rest': 11.3.5(@octokit/core@6.1.2) + '@octokit/plugin-request-log': 5.3.1(@octokit/core@6.1.2) + '@octokit/plugin-rest-endpoint-methods': 13.2.6(@octokit/core@6.1.2) + + '@octokit/types@13.6.1': + dependencies: + '@octokit/openapi-types': 22.2.0 + + '@sec-ant/readable-stream@0.4.1': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + before-after-hook@3.0.2: {} + + cross-spawn@7.0.5: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + esbuild@0.23.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 + + execa@9.5.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.5 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.1.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.1 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + + fsevents@2.3.3: + optional: true + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + human-signals@8.0.0: {} + + is-plain-obj@4.1.0: {} + + is-stream@4.0.1: {} + + is-unicode-supported@2.1.0: {} + + isexe@2.0.0: {} + + mri@1.2.0: {} + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + parse-ms@4.0.0: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + pretty-ms@9.1.0: + dependencies: + parse-ms: 4.0.0 + + resolve-pkg-maps@1.0.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + strip-final-newline@4.0.0: {} + + tsx@4.19.2: + dependencies: + esbuild: 0.23.1 + get-tsconfig: 4.8.1 + optionalDependencies: + fsevents: 2.3.3 + + unicorn-magic@0.3.0: {} + + universal-user-agent@7.0.2: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + yoctocolors@2.1.1: {} diff --git a/scripts/prerelease/src/prerelease.ts b/scripts/prerelease/src/prerelease.ts new file mode 100644 index 000000000..03a104395 --- /dev/null +++ b/scripts/prerelease/src/prerelease.ts @@ -0,0 +1,97 @@ +import { execa, type Options as ExecaOptions } from 'execa' +import { installDeployKey } from '../../common/installDeployKey' + +export async function prerelease({ + deployKey, + prNumber, + prTitle, + prRepoUrl, + prHeadRef, +}: { + deployKey: string + prNumber: string + prTitle: string + prRepoUrl: string + prHeadRef: string +}) { + let targetBranch = await get('git', ['rev-parse', '--abbrev-ref', 'HEAD']) + + // If targeting the main branch, release from the beta branch instead. + if (targetBranch === 'main') { + targetBranch = 'beta' + + await exec('git', ['checkout', targetBranch]) + } + + // Check if this PR was already merged + const existingCommit = await get('git', [ + 'log', + '--format=%H', + '-1', + '--grep', + `(#${prNumber})$`, + ]) + + if (existingCommit) { + // TODO: filter out the old commit for a new release? + console.error( + `PR #${prNumber} was already merged in commit ${existingCommit}`, + ) + process.exit(0) + } + + const baseCommit = await get('git', ['merge-base', 'HEAD', `pr/${prHeadRef}`]) + + // Get the first commit author from the PR branch + const prAuthor = await get('git', [ + 'log', + '--format=%an\t%ae', + '-1', + baseCommit + '..' + `pr/${prHeadRef}`, + ]) + + // Checkout the PR into the target branch. + await exec('bash', ['scripts/checkout-pr.sh'], { + env: { + PR_REPO_URL: prRepoUrl, + PR_HEAD_REF: prHeadRef, + }, + }) + + // Stage all changes + await exec('git', ['add', '.']) + + // Create commit with PR title and number + await exec('git', [ + 'commit', + '-m', + `${prTitle} (#${prNumber})`, + '--author', + prAuthor, + ]) + + await installDeployKey(deployKey) + + // The origin must use SSH for the deploy key to work. + await execa('git', [ + 'remote', + 'set-url', + 'origin', + 'git@github.com:radashi-org/radashi.git', + ]) + + // Push the commit to the target branch + await exec('git', ['push', 'origin', targetBranch]) +} + +async function get(cmd: string, args: readonly string[]) { + return (await execa(cmd, args)).stdout +} + +function exec(cmd: string, args: readonly string[], opts?: ExecaOptions) { + const quotedArgs = args.map(arg => + arg.includes(' ') ? JSON.stringify(arg) : arg, + ) + console.log(`> ${cmd} ${quotedArgs.join(' ')}`) + return execa(cmd, args, { stdio: 'inherit', ...opts }) +} diff --git a/scripts/versions/ci-publish.ts b/scripts/versions/ci-publish.ts index a7844cb62..14aa44787 100644 --- a/scripts/versions/ci-publish.ts +++ b/scripts/versions/ci-publish.ts @@ -1,14 +1,21 @@ -import mri from 'mri' -import { publishVersion, VALID_TAGS } from './src/publishVersion' +import { verifyEnvVars } from '../common/verifyEnvVars' main() async function main() { - const args = parseArgs() + const args = await parseArgs() + + const { publishVersion, VALID_TAGS } = await import('./src/publishVersion') + + if (args.tag && !VALID_TAGS.includes(args.tag)) { + console.error(`Error: --tag must be one of [${VALID_TAGS.join(', ')}]`) + process.exit(1) + } + await publishVersion(args) } -function parseArgs() { +async function parseArgs() { const { gitCliffToken, npmToken, @@ -16,13 +23,15 @@ function parseArgs() { deployKey, nightlyDeployKey, } = verifyEnvVars({ - gitCliffToken: !!process.env.CI && 'GIT_CLIFF_PAT', - npmToken: !!process.env.CI && 'NPM_TOKEN', + gitCliffToken: 'GIT_CLIFF_PAT', + npmToken: 'NPM_TOKEN', radashiBotToken: 'RADASHI_BOT_TOKEN', deployKey: 'DEPLOY_KEY', nightlyDeployKey: 'NIGHTLY_DEPLOY_KEY', }) + const { default: mri } = await import('mri') + const argv = mri(process.argv.slice(2), { boolean: ['no-push'], string: ['tag', 'latest'], @@ -33,16 +42,11 @@ function parseArgs() { process.exit(1) } - if (!argv.latest && !VALID_TAGS.includes(argv.tag)) { - console.error( - `Error: --tag must be one of [${VALID_TAGS.join(', ')}] or --latest must be specified instead`, - ) - process.exit(1) - } + type ValidTag = typeof import('./src/publishVersion').VALID_TAGS[number] return { push: !argv['no-push'], - tag: argv.tag as (typeof VALID_TAGS)[number], + tag: argv.tag as ValidTag, gitCliffToken, npmToken, radashiBotToken, @@ -50,36 +54,3 @@ function parseArgs() { nightlyDeployKey, } } - -/** - * This ensures that the environment variables are set and returns the - * values as a typed object. To ensure sensitive variables are not - * accessible to untrusted code, the environment variables are cleared - * after they are read. - */ -function verifyEnvVars>( - vars: T, -): { - [K in keyof T]: T[K] extends infer Value - ? Value extends string - ? string - : undefined - : undefined -} { - return Object.entries(vars).reduce( - (acc, [alias, envName]) => { - if (!envName) { - return acc - } - const value = process.env[envName] - if (!value) { - console.error(`Error: ${envName} is not set`) - process.exit(1) - } - process.env[envName] = '' - acc[alias] = value - return acc - }, - {} as Record, - ) as any -} diff --git a/scripts/versions/src/publishVersion.ts b/scripts/versions/src/publishVersion.ts index a7f77b073..c98d77ac8 100644 --- a/scripts/versions/src/publishVersion.ts +++ b/scripts/versions/src/publishVersion.ts @@ -4,9 +4,8 @@ import glob from 'fast-glob' import { green } from 'kleur/colors' import crypto from 'node:crypto' import fs from 'node:fs/promises' -import os from 'node:os' -import path from 'node:path' import { sift } from 'radashi/array/sift.js' +import { installDeployKey } from '../../common/installDeployKey' import { dedent } from './dedent' import { trackVersion } from './trackVersion' @@ -21,6 +20,7 @@ export async function publishVersion(args: { * pre-release major versions. */ tag?: (typeof VALID_TAGS)[number] + patch?: boolean push: boolean gitCliffToken?: string npmToken?: string @@ -55,10 +55,41 @@ export async function publishVersion(args: { process.exit(1) } - const newMajorVersion = newVersion.split('.')[0] + const [newMajorVersion, newMinorVersion] = newVersion.split('.') + + if (args.patch) { + // Get the list of commits that have been added since the last + // stable version. + const commits = await execa('git', [ + 'log', + 'v' + stableVersion + '..HEAD', + '--pretty=format:%h\t%s', + ]).then(r => + r.stdout + .split('\n') + .map(line => line.split('\t') as [commit: string, subject: string]), + ) - if (args.tag) { - const lastMajorVersion = stableVersion.split('.')[0] + // Use the patch branch for patch releases, since we need to + // filter out feature commits. + await execa('git', ['fetch', 'origin', 'patch']) + await execa('git', ['checkout', 'patch']) + + // Apply every commit except feature commits and breaking changes. + for (const [commit, subject] of commits) { + if (/^(feat|[^ ]+!:)/.test(subject)) { + continue + } + try { + await execa('git', ['cherry-pick', commit]) + } catch (error) { + // Log and reset, then continue to the next commit. + console.error(error) + await execa('git', ['cherry-pick', '--abort']) + } + } + } else if (args.tag) { + const [lastMajorVersion] = stableVersion.split('.') if (lastMajorVersion !== newMajorVersion && args.tag === 'beta') { log('🚫 Expected a patch or minor increment for "beta" tag') process.exit(1) @@ -359,14 +390,3 @@ async function getPrNumbers(range: string) { const { stdout: gitLog } = await execa('git', ['log', '--oneline', range]) return sift(gitLog.split('\n').map(line => line.match(/\(#(\d+)\)$/)?.[1])) } - -async function installDeployKey(deployKey: string) { - const sshDir = path.join(os.homedir(), '.ssh') - await fs.mkdir(sshDir, { recursive: true }) - - const keyPath = path.join(sshDir, 'deploy_key') - await fs.writeFile(keyPath, deployKey, { mode: 0o600 }) - - // Set GIT_SSH_COMMAND to use the deploy key - process.env.GIT_SSH_COMMAND = `ssh -i ${keyPath} -o StrictHostKeyChecking=no` -} From 95a14bc43c8cbf54d8ce55e52216cd806d0e34c3 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sat, 9 Nov 2024 15:13:05 -0500 Subject: [PATCH 27/56] ci: rebase onto main before merging PR into prerelease branch --- .github/workflows/prerelease-pr.yml | 2 - scripts/prerelease/src/prerelease.ts | 58 ++++++++++++++++++---------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/.github/workflows/prerelease-pr.yml b/.github/workflows/prerelease-pr.yml index 4d14141ce..13cf624f7 100644 --- a/.github/workflows/prerelease-pr.yml +++ b/.github/workflows/prerelease-pr.yml @@ -10,8 +10,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - with: - fetch-depth: 0 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 with: diff --git a/scripts/prerelease/src/prerelease.ts b/scripts/prerelease/src/prerelease.ts index 03a104395..d580e9943 100644 --- a/scripts/prerelease/src/prerelease.ts +++ b/scripts/prerelease/src/prerelease.ts @@ -22,6 +22,10 @@ export async function prerelease({ await exec('git', ['checkout', targetBranch]) } + // Otherwise, fetch the main branch for rebasing the next branch. + else { + await exec('git', ['fetch', 'origin', 'main']) + } // Check if this PR was already merged const existingCommit = await get('git', [ @@ -40,6 +44,39 @@ export async function prerelease({ process.exit(0) } + // Ensure all patches from main are applied to the target branch. If + // a merge conflict occurs, a manual rebase is required. + await exec('git', ['rebase', '-X', 'ours', 'origin/main']) + + await mergePullRequest({ + prHeadRef, + prRepoUrl, + message: `${prTitle} (#${prNumber})`, + }) + + await installDeployKey(deployKey) + + // The origin must use SSH for the deploy key to work. + await execa('git', [ + 'remote', + 'set-url', + 'origin', + 'git@github.com:radashi-org/radashi.git', + ]) + + // Push the commit to the target branch + await exec('git', ['push', 'origin', targetBranch, '--force']) +} + +async function mergePullRequest({ + prHeadRef, + prRepoUrl, + message, +}: { + prHeadRef: string + prRepoUrl: string + message: string +}) { const baseCommit = await get('git', ['merge-base', 'HEAD', `pr/${prHeadRef}`]) // Get the first commit author from the PR branch @@ -62,26 +99,7 @@ export async function prerelease({ await exec('git', ['add', '.']) // Create commit with PR title and number - await exec('git', [ - 'commit', - '-m', - `${prTitle} (#${prNumber})`, - '--author', - prAuthor, - ]) - - await installDeployKey(deployKey) - - // The origin must use SSH for the deploy key to work. - await execa('git', [ - 'remote', - 'set-url', - 'origin', - 'git@github.com:radashi-org/radashi.git', - ]) - - // Push the commit to the target branch - await exec('git', ['push', 'origin', targetBranch]) + await exec('git', ['commit', '-m', message, '--author', prAuthor]) } async function get(cmd: string, args: readonly string[]) { From b7e0dff956b221f4080bcc101c2487e519a8a061 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sat, 9 Nov 2024 15:17:10 -0500 Subject: [PATCH 28/56] ci: rework publish workflows - Add check-main workflow to be referenced in readme badge - Add publish-patch workflow for automatic patch releases - Change publish-beta to run when beta/next branches are pushed to - Stop uploading to CodeCov from publish-beta workflow (happens in check-main now) - Remove unnecessary test/validate jobs from publish-latest --- .github/workflows/check-main.yml | 41 ++++++++++++++++++++++++ .github/workflows/publish-beta.yml | 13 +++----- .github/workflows/publish-latest.yml | 42 +------------------------ .github/workflows/publish-patch.yml | 43 ++++++++++++++++++++++++++ README.md | 2 +- scripts/versions/src/publishVersion.ts | 38 +++++------------------ 6 files changed, 99 insertions(+), 80 deletions(-) create mode 100644 .github/workflows/check-main.yml create mode 100644 .github/workflows/publish-patch.yml diff --git a/.github/workflows/check-main.yml b/.github/workflows/check-main.yml new file mode 100644 index 000000000..6d27827d9 --- /dev/null +++ b/.github/workflows/check-main.yml @@ -0,0 +1,41 @@ +name: Check main branch + +on: + workflow_dispatch: + push: + branches: [main] + +jobs: + test: + name: Test + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18.x, 20.x, 22.x] + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: pnpm + - run: pnpm install + - run: pnpm test + + validate: + name: Validate + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + registry-url: 'https://registry.npmjs.org' + node-version: '22.x' + cache: pnpm + - run: pnpm install + - name: Lint + run: pnpm lint + - name: Check Build + run: pnpm build diff --git a/.github/workflows/publish-beta.yml b/.github/workflows/publish-beta.yml index be82c5050..828a54a8f 100644 --- a/.github/workflows/publish-beta.yml +++ b/.github/workflows/publish-beta.yml @@ -2,8 +2,10 @@ name: Publish radashi@beta on: workflow_dispatch: - schedule: - - cron: '0 5 * * *' + push: + branches: + - beta + - next jobs: test: @@ -22,11 +24,6 @@ jobs: cache: pnpm - run: pnpm install - run: pnpm test - - if: ${{ matrix.node-version == '22.x' }} - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4.0.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} validate: name: Validate @@ -79,4 +76,4 @@ jobs: DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} NIGHTLY_DEPLOY_KEY: ${{ secrets.NIGHTLY_DEPLOY_KEY }} run: | - ./scripts/versions/node_modules/.bin/tsx ./scripts/versions/ci-publish.ts --tag beta + ./scripts/versions/node_modules/.bin/tsx ./scripts/versions/ci-publish.ts --tag ${{ github.ref_name }} diff --git a/.github/workflows/publish-latest.yml b/.github/workflows/publish-latest.yml index 49a979751..7e7b065c3 100644 --- a/.github/workflows/publish-latest.yml +++ b/.github/workflows/publish-latest.yml @@ -4,50 +4,10 @@ on: workflow_dispatch: jobs: - test: - name: Test - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x, 20.x, 22.x] - steps: - - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: pnpm - - run: pnpm install - - run: pnpm test - - if: ${{ matrix.node-version == '22.x' }} - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4.0.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - - validate: - name: Validate - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 - with: - registry-url: 'https://registry.npmjs.org' - node-version: '22.x' - cache: pnpm - - run: pnpm install - - name: Lint - run: pnpm lint - - name: Check Build - run: pnpm build - publish-latest: + if: ${{ github.ref == 'refs/heads/main' }} name: Publish Latest - needs: [test, validate] runs-on: ubuntu-latest - continue-on-error: true permissions: id-token: write steps: diff --git a/.github/workflows/publish-patch.yml b/.github/workflows/publish-patch.yml new file mode 100644 index 000000000..69ba7baba --- /dev/null +++ b/.github/workflows/publish-patch.yml @@ -0,0 +1,43 @@ +name: Publish patch + +on: + workflow_run: + workflows: ['Check main'] + types: + - completed + +jobs: + publish: + if: ${{ github.event.workflow_run.conclusion == 'success' }} + name: Publish + runs-on: ubuntu-latest + permissions: + id-token: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + registry-url: 'https://registry.npmjs.org' + node-version: '22.x' + cache: pnpm + - run: pnpm install + - run: pnpm build + + - name: Install script dependencies + run: | + pnpm install -C scripts/versions + pnpm install -C scripts/radashi-db + + - name: Publish + env: + GIT_CLIFF_PAT: ${{ secrets.GIT_CLIFF_PAT }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + RADASHI_BOT_TOKEN: ${{ secrets.RADASHI_BOT_TOKEN }} + SUPABASE_KEY: ${{ secrets.SUPABASE_KEY }} + DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} + NIGHTLY_DEPLOY_KEY: ${{ secrets.NIGHTLY_DEPLOY_KEY }} + run: | + ./scripts/versions/node_modules/.bin/tsx ./scripts/versions/ci-publish.ts --patch diff --git a/README.md b/README.md index 68a9a3150..fce24819d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Radashi

License - Build Status + Build Status Codecov Code Style: Biome.js GitHub Discussions diff --git a/scripts/versions/src/publishVersion.ts b/scripts/versions/src/publishVersion.ts index c98d77ac8..3f2b0d2da 100644 --- a/scripts/versions/src/publishVersion.ts +++ b/scripts/versions/src/publishVersion.ts @@ -56,40 +56,18 @@ export async function publishVersion(args: { } const [newMajorVersion, newMinorVersion] = newVersion.split('.') + const [lastMajorVersion, lastMinorVersion] = stableVersion.split('.') if (args.patch) { - // Get the list of commits that have been added since the last - // stable version. - const commits = await execa('git', [ - 'log', - 'v' + stableVersion + '..HEAD', - '--pretty=format:%h\t%s', - ]).then(r => - r.stdout - .split('\n') - .map(line => line.split('\t') as [commit: string, subject: string]), - ) - - // Use the patch branch for patch releases, since we need to - // filter out feature commits. - await execa('git', ['fetch', 'origin', 'patch']) - await execa('git', ['checkout', 'patch']) - - // Apply every commit except feature commits and breaking changes. - for (const [commit, subject] of commits) { - if (/^(feat|[^ ]+!:)/.test(subject)) { - continue - } - try { - await execa('git', ['cherry-pick', commit]) - } catch (error) { - // Log and reset, then continue to the next commit. - console.error(error) - await execa('git', ['cherry-pick', '--abort']) - } + if (lastMajorVersion !== newMajorVersion) { + log('🚫 Breaking change detected. Patch cannot be published.') + process.exit(1) + } + if (lastMinorVersion !== newMinorVersion) { + log('🚫 Feature commit detected. Patch cannot be published.') + process.exit(1) } } else if (args.tag) { - const [lastMajorVersion] = stableVersion.split('.') if (lastMajorVersion !== newMajorVersion && args.tag === 'beta') { log('🚫 Expected a patch or minor increment for "beta" tag') process.exit(1) From 87f524811ae872748537f13ab3b74fe5527dc0c9 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sat, 9 Nov 2024 15:25:20 -0500 Subject: [PATCH 29/56] ci: fix typo in workflow dependency --- .github/workflows/publish-patch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-patch.yml b/.github/workflows/publish-patch.yml index 69ba7baba..6beb58d62 100644 --- a/.github/workflows/publish-patch.yml +++ b/.github/workflows/publish-patch.yml @@ -2,7 +2,7 @@ name: Publish patch on: workflow_run: - workflows: ['Check main'] + workflows: ['Check main branch'] types: - completed From 536a1f78e5e2583429902c4c7aa335853e6e0ad3 Mon Sep 17 00:00:00 2001 From: aleclarson Date: Sat, 9 Nov 2024 20:26:43 +0000 Subject: [PATCH 30/56] chore(release): 12.2.1 --- CHANGELOG.md | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 087352fa6..ac3cdf0fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [radashi@beta] +## [radashi@12.2.1] - 2024-11-09 +### Details +#### Types +- Improve signature of `shake` by [@aleclarson](https://github.com/aleclarson) in [#293](https://github.com/radashi-org/radashi/pull/293) + +- `mapValues` index signature handling by [@aleclarson](https://github.com/aleclarson) in [#297](https://github.com/radashi-org/radashi/pull/297) + +- Let `zipToObject` receive readonly arrays by [@aeharding](https://github.com/aeharding) in [#294](https://github.com/radashi-org/radashi/pull/294) + + +### New Contributors +* [@aeharding](https://github.com/aeharding) made their first contribution in [#294](https://github.com/radashi-org/radashi/pull/294) +## [radashi@12.2.0] - 2024-11-01 ### Details #### Added - Add `isIntString` function by [@aleclarson](https://github.com/aleclarson) in [fa500d3](https://github.com/radashi-org/radashi/commit/fa500d329d7e06062e7a42cbf4ff9ad9dcb89191) @@ -124,6 +136,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **(shuffle)** Use the Fisher-Yates algorithm by [@eumkz](https://github.com/eumkz) in [#76](https://github.com/radashi-org/radashi/pull/76) +- **(merge)** Improved handling of large arrays by [@Minhir](https://github.com/Minhir) in [#240](https://github.com/radashi-org/radashi/pull/240) + #### Types - Let `filterKey` accept `key: keyof any` by [@aleclarson](https://github.com/aleclarson) in [73ac8bb](https://github.com/radashi-org/radashi/commit/73ac8bba9e2a2a39eb3c117cc940cc2b18199834) @@ -148,17 +162,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Align `isPromise` return type with its logic by [@aleclarson](https://github.com/aleclarson) in [#175](https://github.com/radashi-org/radashi/pull/175) - Publicize the `Falsy` type by [@aleclarson](https://github.com/aleclarson) in [736d334](https://github.com/radashi-org/radashi/commit/736d3342f86cf16199d6d50cacd0cec3f51db078) +- Avoid inferring `memo` return type from `key` option by [@aleclarson](https://github.com/aleclarson) in [#231](https://github.com/radashi-org/radashi/pull/231) + +- Allow readonly array in `omit` function by [@shan-shaji](https://github.com/shan-shaji) in [#272](https://github.com/radashi-org/radashi/pull/272) + ### New Contributors +* [@shan-shaji](https://github.com/shan-shaji) made their first contribution in [#272](https://github.com/radashi-org/radashi/pull/272) * [@crishoj](https://github.com/crishoj) made their first contribution in [#128](https://github.com/radashi-org/radashi/pull/128) * [@nnmrts](https://github.com/nnmrts) made their first contribution in [#126](https://github.com/radashi-org/radashi/pull/126) * [@stefaanv](https://github.com/stefaanv) made their first contribution in [#95](https://github.com/radashi-org/radashi/pull/95) * [@eumkz](https://github.com/eumkz) made their first contribution in [#76](https://github.com/radashi-org/radashi/pull/76) * [@cimbraien](https://github.com/cimbraien) made their first contribution in [#58](https://github.com/radashi-org/radashi/pull/58) -* [@shan-shaji](https://github.com/shan-shaji) made their first contribution in [#53](https://github.com/radashi-org/radashi/pull/53) * [@cdreeves](https://github.com/cdreeves) made their first contribution in [#37](https://github.com/radashi-org/radashi/pull/37) * [@localusercamp](https://github.com/localusercamp) made their first contribution in [#33](https://github.com/radashi-org/radashi/pull/33) -[radashi@beta]: https://github.com/radashi-org/radashi/compare/v12.1.0..HEAD +[radashi@12.2.1]: https://github.com/radashi-org/radashi/compare/v12.2.0..v12.2.1 + +[radashi@12.2.0]: https://github.com/radashi-org/radashi/compare/v12.1.0..v12.2.0 From 69a2b0321b379e3e2ee20dd130a0512ff64b12dd Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sat, 9 Nov 2024 15:29:06 -0500 Subject: [PATCH 31/56] ci: only run check-main workflow if src/tests are changed --- .github/workflows/check-main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check-main.yml b/.github/workflows/check-main.yml index 6d27827d9..d15edb570 100644 --- a/.github/workflows/check-main.yml +++ b/.github/workflows/check-main.yml @@ -4,6 +4,7 @@ on: workflow_dispatch: push: branches: [main] + paths: ['src/**', 'tests/**'] jobs: test: From 503cf338752441ab2f3f307d645c606d813d9568 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 10 Nov 2024 08:59:55 -0500 Subject: [PATCH 32/56] chore: use `jsr publish --dry-run` for linting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …instead of using Deno‘s lint command. --- deno.json | 6 ------ scripts/lint/lint.ts | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/deno.json b/deno.json index 85c7c0b77..1928da158 100644 --- a/deno.json +++ b/deno.json @@ -7,11 +7,5 @@ }, "publish": { "include": ["src", "LICENSE.md", "README.md"] - }, - "lint": { - "include": ["src"], - "rules": { - "tags": ["jsr"] - } } } diff --git a/scripts/lint/lint.ts b/scripts/lint/lint.ts index d0eb31e08..3682d18e3 100644 --- a/scripts/lint/lint.ts +++ b/scripts/lint/lint.ts @@ -22,7 +22,7 @@ const lint = (scripts: string[]): Command[] => [ { name: 'jsr', color: 'green', - command: 'dlx deno-bin@1.44.4 lint', + command: 'dlx jsr publish --dry-run --allow-dirty', }, { name: 'tsc', From 309441c506aab81bf21b805b11c944304a25d87f Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 10 Nov 2024 09:00:33 -0500 Subject: [PATCH 33/56] chore: use explicit .ts extension in src/mod.ts --- src/mod.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod.ts b/src/mod.ts index ae241665a..b1ac0dd6e 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -135,4 +135,4 @@ export * from './typed/isTagged.ts' export * from './typed/isWeakMap.ts' export * from './typed/isWeakSet.ts' -export * from './types' +export * from './types.ts' From 1db135be69926dccc6c0c186449abd9018cab38a Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 10 Nov 2024 09:11:29 -0500 Subject: [PATCH 34/56] chore: avoid triple-slash reference directive (#302) --- src/async/AggregateError.ts | 15 +++++++++++++-- tests/async/all.test.ts | 1 - tests/async/parallel.test.ts | 1 - tests/tsconfig.json | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/async/AggregateError.ts b/src/async/AggregateError.ts index 26305e799..4e9ce203b 100644 --- a/src/async/AggregateError.ts +++ b/src/async/AggregateError.ts @@ -1,4 +1,16 @@ -/// +interface AggregateError extends Error { + errors: any[] +} + +interface AggregateErrorConstructor { + new (errors: Iterable, message?: string): AggregateError + (errors: Iterable, message?: string): AggregateError + readonly prototype: AggregateError +} + +declare const globalThis: { + AggregateError?: AggregateErrorConstructor +} /** * The `AggregateError` object represents an error when several errors @@ -13,7 +25,6 @@ */ const AggregateErrorOrPolyfill: AggregateErrorConstructor = /* @__PURE__ */ (() => - // eslint-disable-next-line compat/compat globalThis.AggregateError ?? (class AggregateError extends Error { errors: Error[] diff --git a/tests/async/all.test.ts b/tests/async/all.test.ts index bb5a71764..83b051575 100644 --- a/tests/async/all.test.ts +++ b/tests/async/all.test.ts @@ -1,5 +1,4 @@ import * as _ from 'radashi' -import type { AggregateError } from 'radashi' describe('all', () => { const promise = { diff --git a/tests/async/parallel.test.ts b/tests/async/parallel.test.ts index 602f23855..5cf28d9a2 100644 --- a/tests/async/parallel.test.ts +++ b/tests/async/parallel.test.ts @@ -1,5 +1,4 @@ import * as _ from 'radashi' -import type { AggregateError } from 'radashi' describe('parallel', () => { test('returns all results from all functions', async () => { diff --git a/tests/tsconfig.json b/tests/tsconfig.json index c93259ed9..28005ada9 100644 --- a/tests/tsconfig.json +++ b/tests/tsconfig.json @@ -7,7 +7,7 @@ "moduleResolution": "node", "outDir": "../dist/tmp", "target": "esnext", - "lib": ["es2020"], + "lib": ["es2020", "es2021.promise"], "esModuleInterop": true, "module": "esnext", "skipLibCheck": true, From a2a5da1d9e215fdf73da6860e7b62b24dec81559 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 10 Nov 2024 13:05:50 -0500 Subject: [PATCH 35/56] fix(types): export `PromiseWithResolvers` type (#301) Merged by gomerge CLI. --- src/async/withResolvers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/async/withResolvers.ts b/src/async/withResolvers.ts index 41caf2b26..6c5f576e6 100644 --- a/src/async/withResolvers.ts +++ b/src/async/withResolvers.ts @@ -1,4 +1,4 @@ -interface PromiseWithResolvers { +export interface PromiseWithResolvers { promise: Promise resolve: (value: T | PromiseLike) => void reject: (reason?: any) => void From b95cb73226b9616056197991e3425db4b8adeb46 Mon Sep 17 00:00:00 2001 From: Marlon Passos Date: Sun, 10 Nov 2024 15:05:57 -0300 Subject: [PATCH 36/56] fix(types): improve `isEmpty` signature (#219) Merged by gomerge CLI. --- docs/typed/isEmpty.mdx | 42 ++++++++++++ src/typed/isEmpty.ts | 40 ++++++++++-- tests/typed/isEmpty.test-d.ts | 120 ++++++++++++++++++++++++++++++++++ tests/typed/isEmpty.test.ts | 1 + 4 files changed, 198 insertions(+), 5 deletions(-) create mode 100644 tests/typed/isEmpty.test-d.ts diff --git a/docs/typed/isEmpty.mdx b/docs/typed/isEmpty.mdx index 3f61597d4..e2f04266e 100644 --- a/docs/typed/isEmpty.mdx +++ b/docs/typed/isEmpty.mdx @@ -17,3 +17,45 @@ _.isEmpty('') // => true _.isEmpty('hello') // => false _.isEmpty(['hello']) // => false ``` + +Empty values include: + +- `null` +- `undefined` +- `0` +- empty string +- empty array +- invalid `Date` time +- object with `length` property of `0` +- object with `size` property of `0` +- object with no enumerable keys + +### Type Guards + +In some cases, `isEmpty` acts as a [type guard](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards), which helps TypeScript infer more specific types based on the check. + +Due to TypeScript limitations, object types cannot be narrowed, except for arrays and functions. + +```ts +import * as _ from 'radashi' + +// Example with string +const value1: string = '' +if (_.isEmpty(value1)) { + // TypeScript infers value1 as '' + console.log('Value is an empty string') +} else { + // TypeScript infers value1 as string + console.log('Value is a non-empty string') +} + +// Example with array +const value2: string[] = [] +if (_.isEmpty(value2)) { + // TypeScript infers value2 as never[] + console.log('Value is an empty array') +} else { + // TypeScript infers value2 as string[] + console.log('Value is a non-empty array') +} +``` diff --git a/src/typed/isEmpty.ts b/src/typed/isEmpty.ts index 1fdc9a24f..90b50b7da 100644 --- a/src/typed/isEmpty.ts +++ b/src/typed/isEmpty.ts @@ -2,15 +2,14 @@ import { isDate, isFunction, isNumber, isSymbol } from 'radashi' /** * Return true if the given value is empty. + * This function also uses [Type Guards](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards) to ensure type safety * * Empty values include: * - `null` * - `undefined` * - `0` - * - `NaN` - * - `''` - * - `[]` - * - `{}` + * - empty string + * - empty array * - invalid `Date` time * - object with `length` property of `0` * - object with `size` property of `0` @@ -27,7 +26,9 @@ import { isDate, isFunction, isNumber, isSymbol } from 'radashi' * ``` * @version 12.1.0 */ -export function isEmpty(value: any): boolean { +export function isEmpty(value: T): value is ToEmpty +export function isEmpty(value: unknown): boolean +export function isEmpty(value: unknown): boolean { if (value === true || value === false) { return true } @@ -57,3 +58,32 @@ export function isEmpty(value: any): boolean { const keys = Object.keys(value).length return keys === 0 } + +// biome-ignore lint/complexity/noBannedTypes: +type NeverEmpty = symbol | Function + +/** + * A type that can be narrowed by `isEmpty`. + */ +export type ToEmptyAble = + | NeverEmpty + | boolean + | number + | string + | readonly any[] + | null + | undefined + +/** + * Narrow a type to an empty value. + * + * Due to TypeScript limitations, object types cannot be narrowed, + * except for arrays and functions. + */ +export type ToEmpty = ( + T extends any[] + ? never[] + : Extract +) extends infer U + ? Extract + : never diff --git a/tests/typed/isEmpty.test-d.ts b/tests/typed/isEmpty.test-d.ts new file mode 100644 index 000000000..42a51b4a7 --- /dev/null +++ b/tests/typed/isEmpty.test-d.ts @@ -0,0 +1,120 @@ +import type { ToEmptyAble } from 'radashi' +import * as _ from 'radashi' + +describe('isEmpty type guard', () => { + test('string', () => { + const value = {} as string + + if (_.isEmpty(value)) { + expectTypeOf(value).toEqualTypeOf<''>() + } else { + expectTypeOf(value).toEqualTypeOf() + } + }) + + test('array', () => { + const value = [] as string[] + + if (_.isEmpty(value)) { + expectTypeOf(value).toEqualTypeOf() + } else { + expectTypeOf(value).toEqualTypeOf() + } + }) + + test('readonly array', () => { + const value = [] as readonly string[] + + if (_.isEmpty(value)) { + expectTypeOf(value).toEqualTypeOf() + } else { + expectTypeOf(value).toEqualTypeOf() + } + }) + + test('number', () => { + const value = {} as number + + if (_.isEmpty(value)) { + expectTypeOf(value).toEqualTypeOf<0>() + } else { + expectTypeOf(value).toEqualTypeOf() + } + }) + + test('boolean', () => { + const value = {} as boolean + + if (_.isEmpty(value)) { + expectTypeOf(value).toEqualTypeOf() + } else { + expectTypeOf(value).toEqualTypeOf() + } + }) + + test('kitchen sink', () => { + const value = {} as ToEmptyAble + + if (_.isEmpty(value)) { + expectTypeOf(value).toEqualTypeOf< + 0 | '' | false | readonly never[] | null | undefined + >() + } else { + expectTypeOf(value).toEqualTypeOf< + // biome-ignore lint/complexity/noBannedTypes: + true | number | string | readonly any[] | symbol | Function + >() + } + }) + + /** + * Some types are marked as "never empty", which means `isEmpty` + * will always return false for them. + */ + test('never empty types', () => { + const value = {} as symbol | (() => any) | null | undefined + + if (_.isEmpty(value)) { + expectTypeOf(value).toEqualTypeOf() + } else { + expectTypeOf(value).toEqualTypeOf any)>() + } + }) + + /** + * Object types that are *not* assignable to the `ToEmptyAble` type + * will disable the type guard entirely. This is an unavoidable + * limitation of TypeScript. + */ + test('incompatible types', () => { + const value = {} as Date | null | undefined + + if (_.isEmpty(value)) { + expectTypeOf(value).toEqualTypeOf() + } else { + expectTypeOf(value).toEqualTypeOf() + } + }) + + test('any', () => { + const value = {} as any + + if (_.isEmpty(value)) { + expectTypeOf(value).toEqualTypeOf< + false | '' | 0 | readonly never[] | never[] | null | undefined + >() + } else { + expectTypeOf(value).toEqualTypeOf() + } + }) + + test('unknown', () => { + const value = {} as unknown + + if (_.isEmpty(value)) { + expectTypeOf(value).toEqualTypeOf() + } else { + expectTypeOf(value).toEqualTypeOf() + } + }) +}) diff --git a/tests/typed/isEmpty.test.ts b/tests/typed/isEmpty.test.ts index e20a52915..916f33631 100644 --- a/tests/typed/isEmpty.test.ts +++ b/tests/typed/isEmpty.test.ts @@ -23,6 +23,7 @@ describe('isEmpty', () => { expect(_.isEmpty(new Date())).toBeFalsy() expect(_.isEmpty(new Date('2022-09-01T02:19:55.976Z'))).toBeFalsy() expect(_.isEmpty(22)).toBeFalsy() + expect(_.isEmpty(-22)).toBeFalsy() expect(_.isEmpty(new Person())).toBeFalsy() expect(_.isEmpty({ name: 'x' })).toBeFalsy() expect(_.isEmpty('abc')).toBeFalsy() From 665ba72328b25014e907a7f956eb002086d1994c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Rish=C3=B8j?= Date: Sun, 10 Nov 2024 19:06:05 +0100 Subject: [PATCH 37/56] fix(types): narrow return type of `first` and `last` (#160) Merged by gomerge CLI. --- src/array/first.ts | 14 ++++++++----- src/array/last.ts | 14 ++++++++----- tests/array/first.test-d.ts | 40 +++++++++++++++++++++++++++++++++++++ tests/array/last.test-d.ts | 40 +++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 tests/array/first.test-d.ts create mode 100644 tests/array/last.test-d.ts diff --git a/src/array/first.ts b/src/array/first.ts index ca809d7e6..f70fc71f6 100644 --- a/src/array/first.ts +++ b/src/array/first.ts @@ -12,10 +12,14 @@ * ``` * @version 12.1.0 */ -export function first(array: readonly T[]): T | undefined - -export function first(array: readonly T[], defaultValue: U): T | U - -export function first(array: readonly unknown[], defaultValue?: unknown) { +export function first< + const TArray extends readonly any[], + const TDefault = undefined, +>( + array: TArray, + defaultValue?: TDefault, +): TArray extends readonly [infer TFirst, ...any[]] + ? TFirst + : TArray[number] | TDefault { return array?.length > 0 ? array[0] : defaultValue } diff --git a/src/array/last.ts b/src/array/last.ts index 71810b9a1..7fca7b2af 100644 --- a/src/array/last.ts +++ b/src/array/last.ts @@ -12,10 +12,14 @@ * ``` * @version 12.1.0 */ -export function last(array: readonly T[]): T | undefined - -export function last(array: readonly T[], defaultValue: U): T | U - -export function last(array: readonly unknown[], defaultValue?: unknown) { +export function last< + const TArray extends readonly any[], + const TDefault = undefined, +>( + array: TArray, + defaultValue?: TDefault, +): TArray extends readonly [...any[], infer TLast] + ? TLast + : TArray[number] | TDefault { return array?.length > 0 ? array[array.length - 1] : defaultValue } diff --git a/tests/array/first.test-d.ts b/tests/array/first.test-d.ts new file mode 100644 index 000000000..fd0db3528 --- /dev/null +++ b/tests/array/first.test-d.ts @@ -0,0 +1,40 @@ +import * as _ from 'radashi' + +describe('first', () => { + test('inlined array', () => { + expectTypeOf(_.first([])).toEqualTypeOf() + expectTypeOf(_.first([1, 2, 3])).toEqualTypeOf<1>() + }) + + test('variable with empty array', () => { + const emptyArray = [] as never[] + + expectTypeOf(_.first(emptyArray)).toEqualTypeOf() + }) + + test('variable with mutable array', () => { + const array = [1, 2, 3] + + expectTypeOf(_.first(array)).toEqualTypeOf() + }) + + test('variable with readonly tuple', () => { + const emptyTuple = [] as const + const tuple = [1, 2, 3] as const + + expectTypeOf(_.first(emptyTuple)).toEqualTypeOf() + expectTypeOf(_.first(tuple)).toEqualTypeOf<1>() + }) + + test('with default value', () => { + const emptyArray = [] as never[] + const emptyTuple = [] as const + const array = [1, 2, 3] + const tuple = [1, 2, 3] as const + + expectTypeOf(_.first(emptyArray, false)).toEqualTypeOf() + expectTypeOf(_.first(emptyTuple, false)).toEqualTypeOf() + expectTypeOf(_.first(array, false)).toEqualTypeOf() + expectTypeOf(_.first(tuple, false)).toEqualTypeOf<1>() + }) +}) diff --git a/tests/array/last.test-d.ts b/tests/array/last.test-d.ts new file mode 100644 index 000000000..8578490cf --- /dev/null +++ b/tests/array/last.test-d.ts @@ -0,0 +1,40 @@ +import * as _ from 'radashi' + +describe('last', () => { + test('inlined array', () => { + expectTypeOf(_.last([])).toEqualTypeOf() + expectTypeOf(_.last([1, 2, 3])).toEqualTypeOf<3>() + }) + + test('variable with empty array', () => { + const emptyArray = [] as never[] + + expectTypeOf(_.last(emptyArray)).toEqualTypeOf() + }) + + test('variable with mutable array', () => { + const array = [1, 2, 3] + + expectTypeOf(_.last(array)).toEqualTypeOf() + }) + + test('variable with readonly tuple', () => { + const emptyTuple = [] as const + const tuple = [1, 2, 3] as const + + expectTypeOf(_.last(emptyTuple)).toEqualTypeOf() + expectTypeOf(_.last(tuple)).toEqualTypeOf<3>() + }) + + test('with default value', () => { + const emptyArray = [] as never[] + const emptyTuple = [] as const + const array = [1, 2, 3] + const tuple = [1, 2, 3] as const + + expectTypeOf(_.last(emptyArray, false)).toEqualTypeOf() + expectTypeOf(_.last(emptyTuple, false)).toEqualTypeOf() + expectTypeOf(_.last(array, false)).toEqualTypeOf() + expectTypeOf(_.last(tuple, false)).toEqualTypeOf<3>() + }) +}) From fee290ad08f9fa5413ccde3f06fe5667dd5a5ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Rish=C3=B8j?= Date: Sun, 10 Nov 2024 19:06:12 +0100 Subject: [PATCH 38/56] fix(types): improve `draw` signature for non-empty arrays (#153) Merged by gomerge CLI. --- src/random/draw.ts | 6 ++++-- tests/random/draw.test-d.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/random/draw.test-d.ts diff --git a/src/random/draw.ts b/src/random/draw.ts index 6f2bfa117..ddef019bb 100644 --- a/src/random/draw.ts +++ b/src/random/draw.ts @@ -16,10 +16,12 @@ import { random } from 'radashi' * ``` * @version 12.1.0 */ -export function draw(array: readonly T[]): T | null { +export function draw( + array: T, +): T extends readonly [any, ...any[]] ? T[number] : T[number] | null { const max = array.length if (max === 0) { - return null + return null as any } const index = random(0, max - 1) return array[index] diff --git a/tests/random/draw.test-d.ts b/tests/random/draw.test-d.ts new file mode 100644 index 000000000..af3b4f941 --- /dev/null +++ b/tests/random/draw.test-d.ts @@ -0,0 +1,28 @@ +import * as _ from 'radashi' + +describe('draw', () => { + test('variable with mutable array', () => { + const array = [1, 2, 3] + + expectTypeOf(_.draw(array)).toEqualTypeOf() + }) + + test('variable with empty array', () => { + const emptyArray = [] as never[] + const emptyTuple = [] as const + + expectTypeOf(_.draw(emptyArray)).toEqualTypeOf() + expectTypeOf(_.draw(emptyTuple)).toEqualTypeOf() + }) + + test('variable with tuple', () => { + const tuple = [1, 2, 3] as const + + expectTypeOf(_.draw(tuple)).toEqualTypeOf<1 | 2 | 3>() + }) + + test('inlined array', () => { + expectTypeOf(_.draw([])).toEqualTypeOf() + expectTypeOf(_.draw([1, 2, 3])).toEqualTypeOf<1 | 2 | 3>() + }) +}) From 3b5876826a5717a9e04879275c4956e3b4a3e65a Mon Sep 17 00:00:00 2001 From: aleclarson Date: Sun, 10 Nov 2024 18:07:12 +0000 Subject: [PATCH 39/56] chore(release): 12.2.2 --- CHANGELOG.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac3cdf0fa..747a51def 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [radashi@12.2.2] - 2024-11-10 +### Details +#### Types +- Export `PromiseWithResolvers` type by [@aleclarson](https://github.com/aleclarson) in [#301](https://github.com/radashi-org/radashi/pull/301) + +- Improve `isEmpty` signature by [@MarlonPassos-git](https://github.com/MarlonPassos-git) in [#219](https://github.com/radashi-org/radashi/pull/219) + +- Narrow return type of `first` and `last` by [@crishoj](https://github.com/crishoj) in [#160](https://github.com/radashi-org/radashi/pull/160) + +- Improve `draw` signature for non-empty arrays by [@crishoj](https://github.com/crishoj) in [#153](https://github.com/radashi-org/radashi/pull/153) + + ## [radashi@12.2.1] - 2024-11-09 ### Details #### Types @@ -169,7 +181,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### New Contributors * [@shan-shaji](https://github.com/shan-shaji) made their first contribution in [#272](https://github.com/radashi-org/radashi/pull/272) -* [@crishoj](https://github.com/crishoj) made their first contribution in [#128](https://github.com/radashi-org/radashi/pull/128) * [@nnmrts](https://github.com/nnmrts) made their first contribution in [#126](https://github.com/radashi-org/radashi/pull/126) * [@stefaanv](https://github.com/stefaanv) made their first contribution in [#95](https://github.com/radashi-org/radashi/pull/95) * [@eumkz](https://github.com/eumkz) made their first contribution in [#76](https://github.com/radashi-org/radashi/pull/76) @@ -177,6 +188,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [@cdreeves](https://github.com/cdreeves) made their first contribution in [#37](https://github.com/radashi-org/radashi/pull/37) * [@localusercamp](https://github.com/localusercamp) made their first contribution in [#33](https://github.com/radashi-org/radashi/pull/33) +[radashi@12.2.2]: https://github.com/radashi-org/radashi/compare/v12.2.1..v12.2.2 + [radashi@12.2.1]: https://github.com/radashi-org/radashi/compare/v12.2.0..v12.2.1 [radashi@12.2.0]: https://github.com/radashi-org/radashi/compare/v12.1.0..v12.2.0 From 215f4d95c8641e9458dc612ecd02bd0b5b978b13 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 10 Nov 2024 14:28:05 -0500 Subject: [PATCH 40/56] ci: fetch beta branch in prerelease workflow --- scripts/prerelease/src/prerelease.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/prerelease/src/prerelease.ts b/scripts/prerelease/src/prerelease.ts index d580e9943..0d4642071 100644 --- a/scripts/prerelease/src/prerelease.ts +++ b/scripts/prerelease/src/prerelease.ts @@ -20,6 +20,7 @@ export async function prerelease({ if (targetBranch === 'main') { targetBranch = 'beta' + await exec('git', ['fetch', 'origin', targetBranch]) await exec('git', ['checkout', targetBranch]) } // Otherwise, fetch the main branch for rebasing the next branch. From 7e3fc9ff4ed2a0b9578535d2bb61a8eac5e34c25 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 10 Nov 2024 14:34:29 -0500 Subject: [PATCH 41/56] ci: ignore commits before Radashi fork point --- scripts/prerelease/src/prerelease.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/prerelease/src/prerelease.ts b/scripts/prerelease/src/prerelease.ts index 0d4642071..7d4b078e2 100644 --- a/scripts/prerelease/src/prerelease.ts +++ b/scripts/prerelease/src/prerelease.ts @@ -31,6 +31,7 @@ export async function prerelease({ // Check if this PR was already merged const existingCommit = await get('git', [ 'log', + '2be4acf455ebec86e846854dbab57bd0bfbbceb7..HEAD', '--format=%H', '-1', '--grep', From 61f22eae7adede6019f3f63a4863d30bfa16655d Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 10 Nov 2024 14:38:20 -0500 Subject: [PATCH 42/56] ci: set git user before rebase --- scripts/prerelease/src/prerelease.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/prerelease/src/prerelease.ts b/scripts/prerelease/src/prerelease.ts index 7d4b078e2..734cd6301 100644 --- a/scripts/prerelease/src/prerelease.ts +++ b/scripts/prerelease/src/prerelease.ts @@ -46,6 +46,15 @@ export async function prerelease({ process.exit(0) } + // Set git user (needed by git rebase). + await exec('git', ['config', '--global', 'user.name', 'Radashi Bot']) + await exec('git', [ + 'config', + '--global', + 'user.email', + '175859458+radashi-bot@users.noreply.github.com', + ]) + // Ensure all patches from main are applied to the target branch. If // a merge conflict occurs, a manual rebase is required. await exec('git', ['rebase', '-X', 'ours', 'origin/main']) From 1e0b2669dfd138f379853096c8819b7ccdb17f4b Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 08:59:34 -0500 Subject: [PATCH 43/56] ci: fix rebasing in prerelease-pr workflow --- scripts/prerelease/src/prerelease.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/prerelease/src/prerelease.ts b/scripts/prerelease/src/prerelease.ts index 734cd6301..5144c386c 100644 --- a/scripts/prerelease/src/prerelease.ts +++ b/scripts/prerelease/src/prerelease.ts @@ -57,7 +57,15 @@ export async function prerelease({ // Ensure all patches from main are applied to the target branch. If // a merge conflict occurs, a manual rebase is required. - await exec('git', ['rebase', '-X', 'ours', 'origin/main']) + const mergeBase = await get('git', ['merge-base', 'main', 'HEAD']) + await exec('git', [ + 'rebase', + '--strategy-option', + 'ours', + '--onto', + 'main', + mergeBase, + ]) await mergePullRequest({ prHeadRef, From aeb9c6fab4b5afc2b805066237793fe3d3d28b6f Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 09:00:56 -0500 Subject: [PATCH 44/56] ci: prevent failed prerelease-pr from blocking PR merge --- .github/workflows/prerelease-pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/prerelease-pr.yml b/.github/workflows/prerelease-pr.yml index 13cf624f7..19cfb22c7 100644 --- a/.github/workflows/prerelease-pr.yml +++ b/.github/workflows/prerelease-pr.yml @@ -8,6 +8,7 @@ jobs: prerelease: if: ${{ contains(github.event.pull_request.labels.*.name, 'prerelease') && github.event.pull_request.state == 'open' && github.event.pull_request.draft == false && github.event.pull_request.mergeable_state == 'clean' }} runs-on: ubuntu-latest + continue-on-error: true steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 From 1abfc3a78a56187a3eff7324232d8e3ece958b35 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:56:01 -0500 Subject: [PATCH 45/56] Revert "ci: fix rebasing in prerelease-pr workflow" This reverts commit 1e0b2669dfd138f379853096c8819b7ccdb17f4b. --- scripts/prerelease/src/prerelease.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/scripts/prerelease/src/prerelease.ts b/scripts/prerelease/src/prerelease.ts index 5144c386c..734cd6301 100644 --- a/scripts/prerelease/src/prerelease.ts +++ b/scripts/prerelease/src/prerelease.ts @@ -57,15 +57,7 @@ export async function prerelease({ // Ensure all patches from main are applied to the target branch. If // a merge conflict occurs, a manual rebase is required. - const mergeBase = await get('git', ['merge-base', 'main', 'HEAD']) - await exec('git', [ - 'rebase', - '--strategy-option', - 'ours', - '--onto', - 'main', - mergeBase, - ]) + await exec('git', ['rebase', '-X', 'ours', 'origin/main']) await mergePullRequest({ prHeadRef, From 0bb6b7733540b5f093dbd3ffbb0d816b84f568d1 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:56:15 -0500 Subject: [PATCH 46/56] ci: set fetch-depth=0 in prerelease-pr workflow --- .github/workflows/prerelease-pr.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/prerelease-pr.yml b/.github/workflows/prerelease-pr.yml index 19cfb22c7..e7ab16f57 100644 --- a/.github/workflows/prerelease-pr.yml +++ b/.github/workflows/prerelease-pr.yml @@ -11,6 +11,8 @@ jobs: continue-on-error: true steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 with: From e0c1a4725cdea245e31d1190c4bf3017439fe0c3 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:02:07 -0500 Subject: [PATCH 47/56] ci: fix bug in prerelease script --- scripts/prerelease/src/prerelease.ts | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/scripts/prerelease/src/prerelease.ts b/scripts/prerelease/src/prerelease.ts index 734cd6301..f0597446c 100644 --- a/scripts/prerelease/src/prerelease.ts +++ b/scripts/prerelease/src/prerelease.ts @@ -60,6 +60,7 @@ export async function prerelease({ await exec('git', ['rebase', '-X', 'ours', 'origin/main']) await mergePullRequest({ + targetBranch, prHeadRef, prRepoUrl, message: `${prTitle} (#${prNumber})`, @@ -80,15 +81,30 @@ export async function prerelease({ } async function mergePullRequest({ + targetBranch, prHeadRef, prRepoUrl, message, }: { + targetBranch: string prHeadRef: string prRepoUrl: string message: string }) { - const baseCommit = await get('git', ['merge-base', 'HEAD', `pr/${prHeadRef}`]) + await exec('bash', ['scripts/checkout-pr.sh'], { + env: { + PR_REPO_URL: prRepoUrl, + PR_HEAD_REF: prHeadRef, + }, + }) + + // Get the commit where the PR branch diverged from the target + // branch. + const baseCommit = await get('git', [ + 'merge-base', + targetBranch, + `pr/${prHeadRef}`, + ]) // Get the first commit author from the PR branch const prAuthor = await get('git', [ @@ -98,14 +114,6 @@ async function mergePullRequest({ baseCommit + '..' + `pr/${prHeadRef}`, ]) - // Checkout the PR into the target branch. - await exec('bash', ['scripts/checkout-pr.sh'], { - env: { - PR_REPO_URL: prRepoUrl, - PR_HEAD_REF: prHeadRef, - }, - }) - // Stage all changes await exec('git', ['add', '.']) From 501c96494f493a40d730f1b3f77a0f6d61c68e7b Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:03:21 -0500 Subject: [PATCH 48/56] ci: ignore failed prerelease for PR checks --- .github/workflows/prerelease-pr.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/prerelease-pr.yml b/.github/workflows/prerelease-pr.yml index e7ab16f57..a70456812 100644 --- a/.github/workflows/prerelease-pr.yml +++ b/.github/workflows/prerelease-pr.yml @@ -8,7 +8,6 @@ jobs: prerelease: if: ${{ contains(github.event.pull_request.labels.*.name, 'prerelease') && github.event.pull_request.state == 'open' && github.event.pull_request.draft == false && github.event.pull_request.mergeable_state == 'clean' }} runs-on: ubuntu-latest - continue-on-error: true steps: - uses: actions/checkout@v4 with: @@ -32,4 +31,4 @@ jobs: PR_REPO_URL: ${{ github.event.pull_request.head.repo.clone_url }} PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} run: | - ./scripts/prerelease/node_modules/.bin/tsx ./scripts/prerelease/ci-prerelease.ts + ./scripts/prerelease/node_modules/.bin/tsx ./scripts/prerelease/ci-prerelease.ts || true From a06fa0c1e0d8f92108635bd1e79109315d4de4ca Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:33:01 -0500 Subject: [PATCH 49/56] ci: use continue-on-error so the UI displays failure --- .github/workflows/prerelease-pr.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/prerelease-pr.yml b/.github/workflows/prerelease-pr.yml index a70456812..2748fcbe4 100644 --- a/.github/workflows/prerelease-pr.yml +++ b/.github/workflows/prerelease-pr.yml @@ -23,7 +23,8 @@ jobs: run: | pnpm install -C scripts/prerelease - - name: Publish + - name: Merge PR into target branch + continue-on-error: true env: DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} PR_NUMBER: ${{ github.event.pull_request.number }} @@ -31,4 +32,4 @@ jobs: PR_REPO_URL: ${{ github.event.pull_request.head.repo.clone_url }} PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} run: | - ./scripts/prerelease/node_modules/.bin/tsx ./scripts/prerelease/ci-prerelease.ts || true + ./scripts/prerelease/node_modules/.bin/tsx ./scripts/prerelease/ci-prerelease.ts From abea092efdd50a64e05afb810fedd8e4b8ee25f9 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:58:42 -0500 Subject: [PATCH 50/56] chore: update scripts/checkout-pr.sh --- scripts/checkout-pr.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/checkout-pr.sh b/scripts/checkout-pr.sh index 6985e8228..c9fb5329d 100644 --- a/scripts/checkout-pr.sh +++ b/scripts/checkout-pr.sh @@ -6,9 +6,16 @@ set -x git remote add pr $PR_REPO_URL git fetch pr "$PR_HEAD_REF" -# Import changes from the PR into the current branch without committing BASE_COMMIT=$(git merge-base HEAD "pr/$PR_HEAD_REF") -git cherry-pick -m 1 -n "$BASE_COMMIT..pr/$PR_HEAD_REF" + +# Squash the PR into a single commit +git checkout "pr/$PR_HEAD_REF" +git reset --soft "$BASE_COMMIT" +git commit -m "single commit" +git checkout - + +# Import changes from the PR into the current branch without committing +git cherry-pick -m 1 -n "pr/$PR_HEAD_REF" # List the affected files for debugging purposes git diff --name-status --staged From 63549d7950c2db38419d0bf67a065d13d808846a Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:58:59 -0500 Subject: [PATCH 51/56] ci: fix git author format --- scripts/prerelease/src/prerelease.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/prerelease/src/prerelease.ts b/scripts/prerelease/src/prerelease.ts index f0597446c..37cca8286 100644 --- a/scripts/prerelease/src/prerelease.ts +++ b/scripts/prerelease/src/prerelease.ts @@ -109,7 +109,7 @@ async function mergePullRequest({ // Get the first commit author from the PR branch const prAuthor = await get('git', [ 'log', - '--format=%an\t%ae', + '--format=%an <%ae>', '-1', baseCommit + '..' + `pr/${prHeadRef}`, ]) From 0ef8e44d682eb443540335aed1815ed1322bd161 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:01:59 -0500 Subject: [PATCH 52/56] chore: update scripts/checkout-pr.sh --- scripts/checkout-pr.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/checkout-pr.sh b/scripts/checkout-pr.sh index c9fb5329d..892b1d562 100644 --- a/scripts/checkout-pr.sh +++ b/scripts/checkout-pr.sh @@ -12,10 +12,13 @@ BASE_COMMIT=$(git merge-base HEAD "pr/$PR_HEAD_REF") git checkout "pr/$PR_HEAD_REF" git reset --soft "$BASE_COMMIT" git commit -m "single commit" +SQUASH_COMMIT=$(git rev-parse HEAD) + +# Return to the original branch git checkout - # Import changes from the PR into the current branch without committing -git cherry-pick -m 1 -n "pr/$PR_HEAD_REF" +git cherry-pick -m 1 -n "$SQUASH_COMMIT" # List the affected files for debugging purposes git diff --name-status --staged From d3b6cf4768ebc9758fb3d2eb16fb142f6f3c159a Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:04:56 -0500 Subject: [PATCH 53/56] ci: remove unneeded `git add` command --- scripts/prerelease/src/prerelease.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/prerelease/src/prerelease.ts b/scripts/prerelease/src/prerelease.ts index 37cca8286..2277d1f04 100644 --- a/scripts/prerelease/src/prerelease.ts +++ b/scripts/prerelease/src/prerelease.ts @@ -91,6 +91,9 @@ async function mergePullRequest({ prRepoUrl: string message: string }) { + // Fetch the PR, squash it, merge its changes without committing. + // The changes are left staged. This also creates a "pr" remote, + // which we use in the next steps. await exec('bash', ['scripts/checkout-pr.sh'], { env: { PR_REPO_URL: prRepoUrl, @@ -114,9 +117,6 @@ async function mergePullRequest({ baseCommit + '..' + `pr/${prHeadRef}`, ]) - // Stage all changes - await exec('git', ['add', '.']) - // Create commit with PR title and number await exec('git', ['commit', '-m', message, '--author', prAuthor]) } From f29ef1b8c84067913dd2d1b822b0d9b3149195cc Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:13:15 -0500 Subject: [PATCH 54/56] ci: skip publish-beta if src/** is not affected --- .github/workflows/publish-beta.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-beta.yml b/.github/workflows/publish-beta.yml index 828a54a8f..47adc530c 100644 --- a/.github/workflows/publish-beta.yml +++ b/.github/workflows/publish-beta.yml @@ -3,9 +3,8 @@ name: Publish radashi@beta on: workflow_dispatch: push: - branches: - - beta - - next + branches: [beta, next] + paths: ['src/**'] jobs: test: From ac1de6609750199fa2e70785e10b02b62f012036 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:13:51 -0500 Subject: [PATCH 55/56] chore: stop pushing to beta/next git tag on publish --- scripts/versions/src/publishVersion.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/scripts/versions/src/publishVersion.ts b/scripts/versions/src/publishVersion.ts index 3f2b0d2da..36f0c8c22 100644 --- a/scripts/versions/src/publishVersion.ts +++ b/scripts/versions/src/publishVersion.ts @@ -181,14 +181,6 @@ export async function publishVersion(args: { args.tag === 'next' ? `v${newMajorVersion}-next` : args.tag if (args.push) { - if (preReleaseTag) { - log(`Force-pushing ${preReleaseTag} tag`) - await execa('git', ['tag', preReleaseTag, '-f']) - await execa('git', ['push', 'origin', preReleaseTag, '-f'], { - stdio: 'inherit', - }) - } - // The "nightly" remote is where exact pre-release tags are // pushed, so that they don't clutter the main repo. const remoteName = args.tag ? 'nightly' : 'origin' From e8a7c837d6b93783e8b380bcb27912d4efb16030 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Mon, 11 Nov 2024 17:25:44 -0500 Subject: [PATCH 56/56] chore: fix `git commit` fail --- scripts/checkout-pr.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/checkout-pr.sh b/scripts/checkout-pr.sh index 892b1d562..b1153d015 100644 --- a/scripts/checkout-pr.sh +++ b/scripts/checkout-pr.sh @@ -11,6 +11,8 @@ BASE_COMMIT=$(git merge-base HEAD "pr/$PR_HEAD_REF") # Squash the PR into a single commit git checkout "pr/$PR_HEAD_REF" git reset --soft "$BASE_COMMIT" +git config user.name "Radashi Bot" +git config user.email "175859458+radashi-bot@users.noreply.github.com" git commit -m "single commit" SQUASH_COMMIT=$(git rev-parse HEAD)