diff --git a/.gitignore b/.gitignore index 0b30243..8db6dbe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,37 +1,2 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# Dependencies -node_modules -.pnp -.pnp.js - -# Local env files -.env -.env.local -.env.development.local -.env.test.local -.env.production.local - -# Testing -coverage - -# Turbo -.turbo - -# Vercel -.vercel - -# Build Outputs -out/ -build -dist - - -# Debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Misc -.DS_Store -*.pem \ No newline at end of file +main.ts +.DS_Store \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 44a73ec..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "eslint.workingDirectories": [ - { - "mode": "auto" - } - ] -} diff --git a/README.md b/README.md index da9d8d5..b1d1389 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,24 @@ # In Flight -![Duckie the Hawk](/img/falcon.png) - -## FROM TURBO SETUP - -This is an official starter Turborepo. - -## Using this example - -Run the following command: - -```sh -npx create-turbo@latest -``` - -## What's inside? +Native Promise based implementations of bluebird utilities. -This Turborepo includes the following packages/apps: - -### Utilities - -This Turborepo has some additional tools already setup for you: - -- [TypeScript](https://www.typescriptlang.org/) for static type checking -- [ESLint](https://eslint.org/) for code linting -- [Prettier](https://prettier.io) for code formatting - -### Build - -To build all apps and packages, run the following command: - -``` -cd my-turborepo -pnpm build -``` - -### Develop - -To develop all apps and packages, run the following command: - -``` -cd my-turborepo -pnpm dev -``` - -### Remote Caching +![Duckie the Hawk](/img/falcon.png) -Turborepo can use a technique known as [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching) to share cache artifacts across machines, enabling you to share build caches with your team and CI/CD pipelines. +## Docs -By default, Turborepo will cache locally. To enable Remote Caching you will need an account with Vercel. If you don't have an account you can [create one](https://vercel.com/signup), then enter the following commands: +### props -``` -cd my-turborepo -npx turbo login -``` +Bluebird equivalent: http://bluebirdjs.com/docs/api/promise.props.html -This will authenticate the Turborepo CLI with your [Vercel account](https://vercel.com/docs/concepts/personal-accounts/overview). +We implement props with `Promise.allSettled` to give the same easy api for resolving a list of promises +as key/value pairs. -Next, you can link your Turborepo to your Remote Cache by running the following command from the root of your Turborepo: +```ts +import duckhawk from "duckhawk"; +const result = await duckhawk.props({ + one: fetch("https://pokeapi.co/api/v2/pokemon/1").then((res) => res.json()), + two: fetch("https://pokeapi.co/api/v2/pokemon/2").then((res) => res.json()), + three: fetch("https://pokeapi.co/api/v2/pokemon/3").then((res) => res.json()), +}); ``` -npx turbo link -``` - -## Useful Links - -Learn more about the power of Turborepo: - -- [Tasks](https://turbo.build/repo/docs/core-concepts/monorepos/running-tasks) -- [Caching](https://turbo.build/repo/docs/core-concepts/caching) -- [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching) -- [Filtering](https://turbo.build/repo/docs/core-concepts/monorepos/filtering) -- [Configuration Options](https://turbo.build/repo/docs/reference/configuration) -- [CLI Usage](https://turbo.build/repo/docs/reference/command-line-reference) diff --git a/deno.json b/deno.json index 1b6b066..c8303ac 100644 --- a/deno.json +++ b/deno.json @@ -1,3 +1,5 @@ { - "workspace": ["./packages/*"] + "imports": { + "@std/expect": "jsr:@std/expect@^1.0.10" + } } diff --git a/deno.lock b/deno.lock index 84cfef3..e48377b 100644 --- a/deno.lock +++ b/deno.lock @@ -1,650 +1,31 @@ { "version": "4", "specifiers": { - "npm:oxlint@~0.14.1": "0.14.1", - "npm:prettier@^3.3.3": "3.4.2", - "npm:prettier@^3.4.2": "3.4.2", - "npm:tsup@^8.3.5": "8.3.5_typescript@5.5.4_esbuild@0.24.0", - "npm:typescript@5.5.4": "5.5.4", - "npm:typescript@^5.7.2": "5.7.2" + "jsr:@std/assert@^1.0.10": "1.0.10", + "jsr:@std/expect@^1.0.10": "1.0.10", + "jsr:@std/internal@^1.0.5": "1.0.5" }, - "npm": { - "@esbuild/aix-ppc64@0.24.0": { - "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==" - }, - "@esbuild/android-arm64@0.24.0": { - "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==" - }, - "@esbuild/android-arm@0.24.0": { - "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==" - }, - "@esbuild/android-x64@0.24.0": { - "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==" - }, - "@esbuild/darwin-arm64@0.24.0": { - "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==" - }, - "@esbuild/darwin-x64@0.24.0": { - "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==" - }, - "@esbuild/freebsd-arm64@0.24.0": { - "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==" - }, - "@esbuild/freebsd-x64@0.24.0": { - "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==" - }, - "@esbuild/linux-arm64@0.24.0": { - "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==" - }, - "@esbuild/linux-arm@0.24.0": { - "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==" - }, - "@esbuild/linux-ia32@0.24.0": { - "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==" - }, - "@esbuild/linux-loong64@0.24.0": { - "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==" - }, - "@esbuild/linux-mips64el@0.24.0": { - "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==" - }, - "@esbuild/linux-ppc64@0.24.0": { - "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==" - }, - "@esbuild/linux-riscv64@0.24.0": { - "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==" - }, - "@esbuild/linux-s390x@0.24.0": { - "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==" - }, - "@esbuild/linux-x64@0.24.0": { - "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==" - }, - "@esbuild/netbsd-x64@0.24.0": { - "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==" - }, - "@esbuild/openbsd-arm64@0.24.0": { - "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==" - }, - "@esbuild/openbsd-x64@0.24.0": { - "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==" - }, - "@esbuild/sunos-x64@0.24.0": { - "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==" - }, - "@esbuild/win32-arm64@0.24.0": { - "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==" - }, - "@esbuild/win32-ia32@0.24.0": { - "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==" - }, - "@esbuild/win32-x64@0.24.0": { - "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==" - }, - "@isaacs/cliui@8.0.2": { - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dependencies": [ - "string-width@5.1.2", - "string-width-cjs@npm:string-width@4.2.3", - "strip-ansi@7.1.0", - "strip-ansi-cjs@npm:strip-ansi@6.0.1", - "wrap-ansi@8.1.0", - "wrap-ansi-cjs@npm:wrap-ansi@7.0.0" - ] - }, - "@jridgewell/gen-mapping@0.3.5": { - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "jsr": { + "@std/assert@1.0.10": { + "integrity": "59b5cbac5bd55459a19045d95cc7c2ff787b4f8527c0dd195078ff6f9481fbb3", "dependencies": [ - "@jridgewell/set-array", - "@jridgewell/sourcemap-codec", - "@jridgewell/trace-mapping" + "jsr:@std/internal" ] }, - "@jridgewell/resolve-uri@3.1.2": { - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" - }, - "@jridgewell/set-array@1.2.1": { - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" - }, - "@jridgewell/sourcemap-codec@1.5.0": { - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "@jridgewell/trace-mapping@0.3.25": { - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "@std/expect@1.0.10": { + "integrity": "7659b640447887cd1735f866962e10e434f12443b13595b149970c806e6f08db", "dependencies": [ - "@jridgewell/resolve-uri", - "@jridgewell/sourcemap-codec" + "jsr:@std/assert", + "jsr:@std/internal" ] }, - "@oxlint/darwin-arm64@0.14.1": { - "integrity": "sha512-P76G8QCHOkLm+8HYk2/5uR4sPnx6uxE5Y8ik8dgCV0XjrNR+/Sg8v2aQ1BmWeEnPGkBXTt1VSECO9BdT1HVeDw==" - }, - "@oxlint/darwin-x64@0.14.1": { - "integrity": "sha512-bFsNkDtiDEhBKsX2DGLGCVhaRSDP2VgnNHOejjVnLK2LURvOglHMrp4NXxxtHArPAfiP6oezja6q8GmsQbcZ4w==" - }, - "@oxlint/linux-arm64-gnu@0.14.1": { - "integrity": "sha512-OWJY1qxJgsaLyQvh97MdpI2Mr8FD90ssGw8o0rG63lWIc3PJESmq9NKU0ZwwUbPbbEpKmwdG3aiZRjh4G1k0cQ==" - }, - "@oxlint/linux-arm64-musl@0.14.1": { - "integrity": "sha512-GPbggyGQV4+5JzpA7l+1liPHkzCDB9ZyPLcHpRtNJJfTQ60JnBww4l3eR7LCukiAor6Sxmlbl+t1OZGjL3zUUA==" - }, - "@oxlint/linux-x64-gnu@0.14.1": { - "integrity": "sha512-4ug2y9fEa2MB4wAFfITkm1oJ2m14YjWQaKxKN9bRazPng2k3wivVAvwc6tKj866HftZxXo3FlOIrE1YP6BxcSw==" - }, - "@oxlint/linux-x64-musl@0.14.1": { - "integrity": "sha512-bsG5ZxFWKml6BQMHbusvNsEU3O0a5BurlrtdXyxlOBZyrWyG6v3pcXM+NX4YT8gaeoK71iCH5I+ymwI9KOwO/w==" - }, - "@oxlint/win32-arm64@0.14.1": { - "integrity": "sha512-Soc3kRTqz++kleXz+Y4IlfiGY+cwXlOiLCVwcRMAnY+TSaP4h2tPXN/cbOypsE7PPq2/kk7JPGUaEKZ/i4G23A==" - }, - "@oxlint/win32-x64@0.14.1": { - "integrity": "sha512-qyjlv5XPxKJ1g9F4ZpNP0m/I2tgHj4lebmyAveaLos3RZWut983WaK3abq4Mr74mIiwfyLA67/m2khG5aXYN2Q==" - }, - "@pkgjs/parseargs@0.11.0": { - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==" - }, - "@rollup/rollup-android-arm-eabi@4.28.1": { - "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==" - }, - "@rollup/rollup-android-arm64@4.28.1": { - "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==" - }, - "@rollup/rollup-darwin-arm64@4.28.1": { - "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==" - }, - "@rollup/rollup-darwin-x64@4.28.1": { - "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==" - }, - "@rollup/rollup-freebsd-arm64@4.28.1": { - "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==" - }, - "@rollup/rollup-freebsd-x64@4.28.1": { - "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==" - }, - "@rollup/rollup-linux-arm-gnueabihf@4.28.1": { - "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==" - }, - "@rollup/rollup-linux-arm-musleabihf@4.28.1": { - "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==" - }, - "@rollup/rollup-linux-arm64-gnu@4.28.1": { - "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==" - }, - "@rollup/rollup-linux-arm64-musl@4.28.1": { - "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==" - }, - "@rollup/rollup-linux-loongarch64-gnu@4.28.1": { - "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==" - }, - "@rollup/rollup-linux-powerpc64le-gnu@4.28.1": { - "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==" - }, - "@rollup/rollup-linux-riscv64-gnu@4.28.1": { - "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==" - }, - "@rollup/rollup-linux-s390x-gnu@4.28.1": { - "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==" - }, - "@rollup/rollup-linux-x64-gnu@4.28.1": { - "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==" - }, - "@rollup/rollup-linux-x64-musl@4.28.1": { - "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==" - }, - "@rollup/rollup-win32-arm64-msvc@4.28.1": { - "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==" - }, - "@rollup/rollup-win32-ia32-msvc@4.28.1": { - "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==" - }, - "@rollup/rollup-win32-x64-msvc@4.28.1": { - "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==" - }, - "@types/estree@1.0.6": { - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" - }, - "ansi-regex@5.0.1": { - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-regex@6.1.0": { - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==" - }, - "ansi-styles@4.3.0": { - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": [ - "color-convert" - ] - }, - "ansi-styles@6.2.1": { - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" - }, - "any-promise@1.3.0": { - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, - "balanced-match@1.0.2": { - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion@2.0.1": { - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": [ - "balanced-match" - ] - }, - "bundle-require@5.0.0_esbuild@0.24.0": { - "integrity": "sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==", - "dependencies": [ - "esbuild", - "load-tsconfig" - ] - }, - "cac@6.7.14": { - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==" - }, - "chokidar@4.0.1": { - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", - "dependencies": [ - "readdirp" - ] - }, - "color-convert@2.0.1": { - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": [ - "color-name" - ] - }, - "color-name@1.1.4": { - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "commander@4.1.1": { - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" - }, - "consola@3.2.3": { - "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==" - }, - "cross-spawn@7.0.6": { - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dependencies": [ - "path-key", - "shebang-command", - "which" - ] - }, - "debug@4.4.0": { - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dependencies": [ - "ms" - ] - }, - "eastasianwidth@0.2.0": { - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "emoji-regex@8.0.0": { - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "emoji-regex@9.2.2": { - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "esbuild@0.24.0": { - "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", - "dependencies": [ - "@esbuild/aix-ppc64", - "@esbuild/android-arm", - "@esbuild/android-arm64", - "@esbuild/android-x64", - "@esbuild/darwin-arm64", - "@esbuild/darwin-x64", - "@esbuild/freebsd-arm64", - "@esbuild/freebsd-x64", - "@esbuild/linux-arm", - "@esbuild/linux-arm64", - "@esbuild/linux-ia32", - "@esbuild/linux-loong64", - "@esbuild/linux-mips64el", - "@esbuild/linux-ppc64", - "@esbuild/linux-riscv64", - "@esbuild/linux-s390x", - "@esbuild/linux-x64", - "@esbuild/netbsd-x64", - "@esbuild/openbsd-arm64", - "@esbuild/openbsd-x64", - "@esbuild/sunos-x64", - "@esbuild/win32-arm64", - "@esbuild/win32-ia32", - "@esbuild/win32-x64" - ] - }, - "fdir@6.4.2_picomatch@4.0.2": { - "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", - "dependencies": [ - "picomatch" - ] - }, - "foreground-child@3.3.0": { - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dependencies": [ - "cross-spawn", - "signal-exit" - ] - }, - "fsevents@2.3.3": { - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==" - }, - "glob@10.4.5": { - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dependencies": [ - "foreground-child", - "jackspeak", - "minimatch", - "minipass", - "package-json-from-dist", - "path-scurry" - ] - }, - "is-fullwidth-code-point@3.0.0": { - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "isexe@2.0.0": { - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "jackspeak@3.4.3": { - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dependencies": [ - "@isaacs/cliui", - "@pkgjs/parseargs" - ] - }, - "joycon@3.1.1": { - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==" - }, - "lilconfig@3.1.3": { - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==" - }, - "lines-and-columns@1.2.4": { - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "load-tsconfig@0.2.5": { - "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==" - }, - "lodash.sortby@4.7.0": { - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" - }, - "lru-cache@10.4.3": { - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" - }, - "minimatch@9.0.5": { - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dependencies": [ - "brace-expansion" - ] - }, - "minipass@7.1.2": { - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==" - }, - "ms@2.1.3": { - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "mz@2.7.0": { - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": [ - "any-promise", - "object-assign", - "thenify-all" - ] - }, - "object-assign@4.1.1": { - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "oxlint@0.14.1": { - "integrity": "sha512-FwcjPfQu806ibSv73Y9tUM8ezUyd811dp3JwEEOC/dIAgd93egRsRNnFauuAq/WuTjIDv73tbr9hB8MziH31Eg==", - "dependencies": [ - "@oxlint/darwin-arm64", - "@oxlint/darwin-x64", - "@oxlint/linux-arm64-gnu", - "@oxlint/linux-arm64-musl", - "@oxlint/linux-x64-gnu", - "@oxlint/linux-x64-musl", - "@oxlint/win32-arm64", - "@oxlint/win32-x64" - ] - }, - "package-json-from-dist@1.0.1": { - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" - }, - "path-key@3.1.1": { - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-scurry@1.11.1": { - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dependencies": [ - "lru-cache", - "minipass" - ] - }, - "picocolors@1.1.1": { - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" - }, - "picomatch@4.0.2": { - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==" - }, - "pirates@4.0.6": { - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==" - }, - "postcss-load-config@6.0.1": { - "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", - "dependencies": [ - "lilconfig" - ] - }, - "prettier@3.4.2": { - "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==" - }, - "punycode@2.3.1": { - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" - }, - "readdirp@4.0.2": { - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==" - }, - "resolve-from@5.0.0": { - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - }, - "rollup@4.28.1": { - "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==", - "dependencies": [ - "@rollup/rollup-android-arm-eabi", - "@rollup/rollup-android-arm64", - "@rollup/rollup-darwin-arm64", - "@rollup/rollup-darwin-x64", - "@rollup/rollup-freebsd-arm64", - "@rollup/rollup-freebsd-x64", - "@rollup/rollup-linux-arm-gnueabihf", - "@rollup/rollup-linux-arm-musleabihf", - "@rollup/rollup-linux-arm64-gnu", - "@rollup/rollup-linux-arm64-musl", - "@rollup/rollup-linux-loongarch64-gnu", - "@rollup/rollup-linux-powerpc64le-gnu", - "@rollup/rollup-linux-riscv64-gnu", - "@rollup/rollup-linux-s390x-gnu", - "@rollup/rollup-linux-x64-gnu", - "@rollup/rollup-linux-x64-musl", - "@rollup/rollup-win32-arm64-msvc", - "@rollup/rollup-win32-ia32-msvc", - "@rollup/rollup-win32-x64-msvc", - "@types/estree", - "fsevents" - ] - }, - "shebang-command@2.0.0": { - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": [ - "shebang-regex" - ] - }, - "shebang-regex@3.0.0": { - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "signal-exit@4.1.0": { - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, - "source-map@0.8.0-beta.0": { - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "dependencies": [ - "whatwg-url" - ] - }, - "string-width@4.2.3": { - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": [ - "emoji-regex@8.0.0", - "is-fullwidth-code-point", - "strip-ansi@6.0.1" - ] - }, - "string-width@5.1.2": { - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": [ - "eastasianwidth", - "emoji-regex@9.2.2", - "strip-ansi@7.1.0" - ] - }, - "strip-ansi@6.0.1": { - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": [ - "ansi-regex@5.0.1" - ] - }, - "strip-ansi@7.1.0": { - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": [ - "ansi-regex@6.1.0" - ] - }, - "sucrase@3.35.0": { - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dependencies": [ - "@jridgewell/gen-mapping", - "commander", - "glob", - "lines-and-columns", - "mz", - "pirates", - "ts-interface-checker" - ] - }, - "thenify-all@1.6.0": { - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dependencies": [ - "thenify" - ] - }, - "thenify@3.3.1": { - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": [ - "any-promise" - ] - }, - "tinyexec@0.3.1": { - "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==" - }, - "tinyglobby@0.2.10_picomatch@4.0.2": { - "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", - "dependencies": [ - "fdir", - "picomatch" - ] - }, - "tr46@1.0.1": { - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "dependencies": [ - "punycode" - ] - }, - "tree-kill@1.2.2": { - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" - }, - "ts-interface-checker@0.1.13": { - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" - }, - "tsup@8.3.5_typescript@5.5.4_esbuild@0.24.0": { - "integrity": "sha512-Tunf6r6m6tnZsG9GYWndg0z8dEV7fD733VBFzFJ5Vcm1FtlXB8xBD/rtrBi2a3YKEV7hHtxiZtW5EAVADoe1pA==", - "dependencies": [ - "bundle-require", - "cac", - "chokidar", - "consola", - "debug", - "esbuild", - "joycon", - "picocolors", - "postcss-load-config", - "resolve-from", - "rollup", - "source-map", - "sucrase", - "tinyexec", - "tinyglobby", - "tree-kill", - "typescript@5.5.4" - ] - }, - "typescript@5.5.4": { - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==" - }, - "typescript@5.7.2": { - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==" - }, - "webidl-conversions@4.0.2": { - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "whatwg-url@7.1.0": { - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dependencies": [ - "lodash.sortby", - "tr46", - "webidl-conversions" - ] - }, - "which@2.0.2": { - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": [ - "isexe" - ] - }, - "wrap-ansi@7.0.0": { - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": [ - "ansi-styles@4.3.0", - "string-width@4.2.3", - "strip-ansi@6.0.1" - ] - }, - "wrap-ansi@8.1.0": { - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": [ - "ansi-styles@6.2.1", - "string-width@5.1.2", - "strip-ansi@7.1.0" - ] + "@std/internal@1.0.5": { + "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" } }, "workspace": { - "packageJson": { - "dependencies": [ - "npm:prettier@^3.3.3", - "npm:typescript@5.5.4" - ] - }, - "members": { - "packages/duckhawk": { - "packageJson": { - "dependencies": [ - "npm:oxlint@~0.14.1", - "npm:prettier@^3.4.2", - "npm:tsup@^8.3.5", - "npm:typescript@^5.7.2" - ] - } - } - } + "dependencies": [ + "jsr:@std/expect@^1.0.10" + ] } } diff --git a/package.json b/package.json deleted file mode 100644 index 5be2be2..0000000 --- a/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "duckhawk-turbo", - "private": true, - "scripts": { - "format": "prettier --write \"**/*.{ts,tsx,md}\"" - }, - "devDependencies": { - "prettier": "^3.3.3", - "typescript": "5.5.4" - } -} diff --git a/packages/duckhawk/package.json b/packages/duckhawk/package.json deleted file mode 100644 index dd5d340..0000000 --- a/packages/duckhawk/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "duckhawk", - "version": "0.1.0", - "main": "./src/index.ts", - "scripts": { - "lint": "oxlint src", - "format": "prettier --write \"**/*.{ts,tsx,md}\"" - }, - "devDependencies": { - "oxlint": "^0.14.1", - "prettier": "^3.4.2" - } -} diff --git a/packages/duckhawk/src/index.ts b/packages/duckhawk/src/index.ts deleted file mode 100644 index 8b13789..0000000 --- a/packages/duckhawk/src/index.ts +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/duckhawk/src/props.ts b/packages/duckhawk/src/props.ts deleted file mode 100644 index d9f70a1..0000000 --- a/packages/duckhawk/src/props.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const props = async < - T extends Record>, - K extends keyof T, ->( - props: Record> -): Promise> => { - const entries = Object.entries(props); - - const results = await Promise.all( - entries.map(async ([key, callback]) => { - const result = await callback; - return [key, result]; - }) - ); - - return Object.fromEntries(results); -}; diff --git a/packages/duckhawk/src/test/props.test.ts b/packages/duckhawk/src/test/props.test.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..6b1b217 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,3 @@ +import { props } from "./props.ts"; + +export default { props }; diff --git a/src/props.ts b/src/props.ts new file mode 100644 index 0000000..818ed24 --- /dev/null +++ b/src/props.ts @@ -0,0 +1,56 @@ +// deno-lint-ignore-file no-explicit-any + +/** + * props implementation with Promise.allSettled. bluebird.props threw on first error + * and cleaned up the promise chain to avoid leaks. We do not do this. + * + * Using Promise natively here means we cannot cleanup the promise chain, so we wait for `allSettled` and + * throw the first error we encounter based on input order after all settle. + * + * @param props - Object of promises to resolve + * @returns Promise that resolves with object of resolved values + * + * @example + * ```ts + * const result = await duckhawk.props({ + * a: Promise.resolve(1), + * b: Promise.resolve(2), + * c: Promise.resolve(3), + * }); + * + * console.log(result); // { a: 1, b: 2, c: 3 } + * ``` + */ +export const props = async < + T extends Record>, + K extends keyof T +>(props: { + [P in K]: T[P]; +}): Promise<{ + [P in K]: Awaited; +}> => { + const entries = Object.entries(props); + + const results = await Promise.allSettled( + entries.map(async ([key, callback]) => { + const result = await callback; + if (result instanceof Error) { + throw result; + } + return [key, result]; + }) + ); + + const firstError = results.find((result) => result.status === "rejected"); + if (firstError) { + throw firstError.reason; + } + + return Object.fromEntries( + results.map((result) => + result.status === "fulfilled" ? result.value : (undefined as never) + ) + ) as { + [P in K]: Awaited; + }; +}; diff --git a/src/test/props.test.ts b/src/test/props.test.ts new file mode 100644 index 0000000..f383586 --- /dev/null +++ b/src/test/props.test.ts @@ -0,0 +1,52 @@ +import { props } from "../props.ts"; +import { expect } from "@std/expect"; +import { delayedReject } from "./utils.ts"; + +Deno.test("props", async () => { + const result = await props({ + a: Promise.resolve(1), + b: Promise.resolve(2), + c: Promise.resolve(3), + }); + expect(result).toEqual({ a: 1, b: 2, c: 3 }); +}); + +Deno.test("props with mixed types", async () => { + const result = await props({ + a: Promise.resolve(1), + b: Promise.resolve("hi"), + c: Promise.resolve({ foo: "bar" }), + }); + expect(result).toEqual({ a: 1, b: "hi", c: { foo: "bar" } }); +}); + +Deno.test("props with mixed types and async", async () => { + const result = await props({ + a: Promise.resolve(1), + b: Promise.resolve("hi"), + // deno-lint-ignore require-await + c: (async () => ({ foo: "bar" }))(), + }); + expect(result).toEqual({ a: 1, b: "hi", c: { foo: "bar" } }); +}); + +Deno.test("props with some failing", () => { + expect( + props({ + a: Promise.resolve(1), + b: Promise.reject(new Error("fail")), + }) + ).rejects.toThrow("fail"); +}); + +Deno.test("props throws first given and rejected", async () => { + const firstError = new Error("first"); + const secondError = new Error("second"); + + await expect( + props({ + a: delayedReject(firstError, 20), + b: delayedReject(secondError, 10), + }) + ).rejects.toEqual(firstError); +}); diff --git a/src/test/utils.ts b/src/test/utils.ts new file mode 100644 index 0000000..0c456d7 --- /dev/null +++ b/src/test/utils.ts @@ -0,0 +1,19 @@ +/** + * Creates a promise that resolves with the given value after specified delay + * @param {*} value - The value to resolve with + * @param {number} delay - Time to wait before resolving (ms) + * @returns {Promise<*>} Promise that resolves after delay + */ +export function delayedResolve(value: T, delay: number) { + return new Promise((resolve) => setTimeout(() => resolve(value), delay)); +} + +/** + * Creates a promise that rejects with the given error after specified delay + * @param {Error|string} error - Error to reject with + * @param {number} delay - Time to wait before rejecting (ms) + * @returns {Promise} Promise that rejects after delay + */ +export function delayedReject(error: Error, delay: number) { + return new Promise((_, reject) => setTimeout(() => reject(error), delay)); +}