diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 7148d1f..0cb2226 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,8 +1,8 @@ -name: "CodeQL" +name: 'CodeQL' on: push: - branches: [master, ] + branches: [master] pull_request: # The branches below must be a subset of the branches above branches: [master] @@ -15,42 +15,41 @@ jobs: analyze: name: Analyze runs-on: ubuntu-22.04 - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - # Override language selection by uncommenting this and choosing your languages - # with: - # languages: go, javascript, csharp, python, cpp, java - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + - name: Checkout repository + uses: actions/checkout@v4 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + # Override language selection by uncommenting this and choosing your languages + # with: + # languages: go, javascript, csharp, python, cpp, java + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 5da09c4..c35144d 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -12,12 +12,12 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 - name: Use Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version-file: ".nvmrc" - cache: "pnpm" + node-version-file: '.nvmrc' + cache: 'pnpm' - name: Installing dependencies run: pnpm install - name: Linting diff --git a/.nvmrc b/.nvmrc index 209e3ef..2bd5a0a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20 +22 diff --git a/package.json b/package.json index 702a77e..caf5962 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "url": "https://github.com/webdeveric/utils/issues" }, "homepage": "https://github.com/webdeveric/utils/#readme", - "packageManager": "pnpm@9.13.2+sha512.88c9c3864450350e65a33587ab801acf946d7c814ed1134da4a924f6df5a2120fd36b46aab68f7cd1d413149112d53c7db3a4136624cfd00ff1846a0c6cef48a", + "packageManager": "pnpm@9.14.2+sha512.6e2baf77d06b9362294152c851c4f278ede37ab1eba3a55fda317a4a17b209f4dbb973fb250a77abc463a341fcb1f17f17cfa24091c4eb319cda0d9b84278387", "scripts": { "clean": "rimraf ./dist/", "prebuild": "pnpm clean", @@ -88,7 +88,7 @@ }, "prettier": "@webdeveric/prettier-config", "devDependencies": { - "@types/node": "^20.17.6", + "@types/node": "^22.9.1", "@vitest/coverage-v8": "^2.1.5", "@webdeveric/eslint-config-ts": "^0.11.0", "@webdeveric/prettier-config": "^0.3.0", @@ -102,7 +102,7 @@ "lint-staged": "^15.2.10", "prettier": "^3.3.3", "rimraf": "^6.0.1", - "typescript": "^5.6.3", + "typescript": "^5.7.2", "validate-package-exports": "^0.7.0", "vitest": "^2.1.5" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3080c72..702f908 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,14 +9,14 @@ importers: .: devDependencies: '@types/node': - specifier: ^20.17.6 - version: 20.17.6 + specifier: ^22.9.1 + version: 22.9.1 '@vitest/coverage-v8': specifier: ^2.1.5 - version: 2.1.5(vitest@2.1.5(@types/node@20.17.6)(jsdom@25.0.1)) + version: 2.1.5(vitest@2.1.5(@types/node@22.9.1)(jsdom@25.0.1)) '@webdeveric/eslint-config-ts': specifier: ^0.11.0 - version: 0.11.0(eslint@8.57.1)(typescript@5.6.3) + version: 0.11.0(eslint@8.57.1)(typescript@5.7.2) '@webdeveric/prettier-config': specifier: ^0.3.0 version: 0.3.0(prettier@3.3.3) @@ -31,10 +31,10 @@ importers: version: 9.1.0(eslint@8.57.1) eslint-import-resolver-typescript: specifier: ^3.6.3 - version: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1) + version: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1) eslint-plugin-import: specifier: ^2.31.0 - version: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + version: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) husky: specifier: ^9.1.7 version: 9.1.7 @@ -51,14 +51,14 @@ importers: specifier: ^6.0.1 version: 6.0.1 typescript: - specifier: ^5.6.3 - version: 5.6.3 + specifier: ^5.7.2 + version: 5.7.2 validate-package-exports: specifier: ^0.7.0 version: 0.7.0 vitest: specifier: ^2.1.5 - version: 2.1.5(@types/node@20.17.6)(jsdom@25.0.1) + version: 2.1.5(@types/node@22.9.1)(jsdom@25.0.1) packages: @@ -185,8 +185,8 @@ packages: '@cspell/dict-git@3.0.3': resolution: {integrity: sha512-LSxB+psZ0qoj83GkyjeEH/ZViyVsGEF/A6BAo8Nqc0w0HjD2qX/QR4sfA6JHUgQ3Yi/ccxdK7xNIo67L2ScW5A==} - '@cspell/dict-golang@6.0.16': - resolution: {integrity: sha512-hZOBlgcguv2Hdc93n2zjdAQm1j3grsN9T9WhPnQ1wh2vUDoCLEujg+6gWhjcLb8ECOcwZTWgNyQLWeOxEsAj/w==} + '@cspell/dict-golang@6.0.17': + resolution: {integrity: sha512-uDDLEJ/cHdLiqPw4+5BnmIo2i/TSR+uDvYd6JlBjTmjBKpOCyvUgYRztH7nv5e7virsN5WDiUWah4/ATQGz4Pw==} '@cspell/dict-google@1.0.4': resolution: {integrity: sha512-JThUT9eiguCja1mHHLwYESgxkhk17Gv7P3b1S7ZJzXw86QyVHPrbpVoMpozHk0C9o+Ym764B7gZGKmw9uMGduQ==} @@ -706,8 +706,8 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/node@20.17.6': - resolution: {integrity: sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==} + '@types/node@22.9.1': + resolution: {integrity: sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==} '@typescript-eslint/eslint-plugin@7.18.0': resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} @@ -1619,6 +1619,10 @@ packages: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} + is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} @@ -1649,6 +1653,9 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -1661,6 +1668,10 @@ packages: resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} engines: {node: '>=18'} + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -1668,6 +1679,10 @@ packages: is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} @@ -1691,6 +1706,10 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + is-shared-array-buffer@1.0.3: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} engines: {node: '>= 0.4'} @@ -1711,9 +1730,17 @@ packages: resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -2194,6 +2221,10 @@ packages: resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} + engines: {node: '>= 0.4'} + regexp.prototype.flags@1.5.3: resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} @@ -2456,11 +2487,11 @@ packages: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} - tldts-core@6.1.61: - resolution: {integrity: sha512-In7VffkDWUPgwa+c9picLUxvb0RltVwTkSgMNFgvlGSWveCzGBemBqTsgJCL4EDFWZ6WH0fKTsot6yNhzy3ZzQ==} + tldts-core@6.1.63: + resolution: {integrity: sha512-H1XCt54xY+QPbwhTgmxLkepX0MVHu3USfMmejiCOdkMbRcP22Pn2FVF127r/GWXVDmXTRezyF3Ckvhn4Fs6j7Q==} - tldts@6.1.61: - resolution: {integrity: sha512-rv8LUyez4Ygkopqn+M6OLItAOT9FF3REpPQDkdMx5ix8w4qkuE7Vo2o/vw1nxKQYmJDV8JpAMJQr1b+lTKf0FA==} + tldts@6.1.63: + resolution: {integrity: sha512-YWwhsjyn9sB/1rOkSRYxvkN/wl5LFM1QDv6F2pVR+pb/jFne4EOBxHfkKVWvDIBEAw9iGOwwubHtQTm0WRT5sQ==} hasBin: true to-regex-range@5.0.1: @@ -2508,16 +2539,16 @@ packages: resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.2: - resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + typed-array-byte-offset@1.0.3: + resolution: {integrity: sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==} engines: {node: '>= 0.4'} typed-array-length@1.0.6: resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} engines: {node: '>= 0.4'} - typescript@5.6.3: - resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} engines: {node: '>=14.17'} hasBin: true @@ -2646,6 +2677,14 @@ packages: which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-builtin-type@1.1.4: + resolution: {integrity: sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} @@ -2719,8 +2758,8 @@ packages: engines: {node: '>= 14'} hasBin: true - yaml@2.6.0: - resolution: {integrity: sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==} + yaml@2.6.1: + resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} engines: {node: '>= 14'} hasBin: true @@ -2776,7 +2815,7 @@ snapshots: '@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-golang': 6.0.17 '@cspell/dict-google': 1.0.4 '@cspell/dict-haskell': 4.0.4 '@cspell/dict-html': 4.0.10 @@ -2872,7 +2911,7 @@ snapshots: '@cspell/dict-git@3.0.3': {} - '@cspell/dict-golang@6.0.16': {} + '@cspell/dict-golang@6.0.17': {} '@cspell/dict-google@1.0.4': {} @@ -3331,38 +3370,38 @@ snapshots: '@types/json5@0.0.29': {} - '@types/node@20.17.6': + '@types/node@22.9.1': dependencies: undici-types: 6.19.8 - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.7.2) '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.7.2) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.7.2) '@typescript-eslint/visitor-keys': 7.18.0 eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.4.0(typescript@5.6.3) + ts-api-utils: 1.4.0(typescript@5.7.2) optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.7.2) '@typescript-eslint/visitor-keys': 7.18.0 debug: 4.3.7 eslint: 8.57.1 optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.2 transitivePeerDependencies: - supports-color @@ -3371,21 +3410,21 @@ snapshots: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.7.2)': dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.7.2) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.7.2) debug: 4.3.7 eslint: 8.57.1 - ts-api-utils: 1.4.0(typescript@5.6.3) + ts-api-utils: 1.4.0(typescript@5.7.2) optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.2 transitivePeerDependencies: - supports-color '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.7.2)': dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 @@ -3394,18 +3433,18 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.4.0(typescript@5.6.3) + ts-api-utils: 1.4.0(typescript@5.7.2) optionalDependencies: - typescript: 5.6.3 + typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.7.2)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.7.2) eslint: 8.57.1 transitivePeerDependencies: - supports-color @@ -3418,7 +3457,7 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitest/coverage-v8@2.1.5(vitest@2.1.5(@types/node@20.17.6)(jsdom@25.0.1))': + '@vitest/coverage-v8@2.1.5(vitest@2.1.5(@types/node@22.9.1)(jsdom@25.0.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -3432,7 +3471,7 @@ snapshots: std-env: 3.8.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.1.5(@types/node@20.17.6)(jsdom@25.0.1) + vitest: 2.1.5(@types/node@22.9.1)(jsdom@25.0.1) transitivePeerDependencies: - supports-color @@ -3443,13 +3482,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.5(vite@5.4.11(@types/node@20.17.6))': + '@vitest/mocker@2.1.5(vite@5.4.11(@types/node@22.9.1))': dependencies: '@vitest/spy': 2.1.5 estree-walker: 3.0.3 magic-string: 0.30.13 optionalDependencies: - vite: 5.4.11(@types/node@20.17.6) + vite: 5.4.11(@types/node@22.9.1) '@vitest/pretty-format@2.1.5': dependencies: @@ -3476,13 +3515,13 @@ snapshots: loupe: 3.1.2 tinyrainbow: 1.2.0 - '@webdeveric/eslint-config-ts@0.11.0(eslint@8.57.1)(typescript@5.6.3)': + '@webdeveric/eslint-config-ts@0.11.0(eslint@8.57.1)(typescript@5.7.2)': dependencies: - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.7.2) '@webdeveric/eslint-config': 0.7.0(eslint@8.57.1) eslint: 8.57.1 - typescript: 5.6.3 + typescript: 5.7.2 transitivePeerDependencies: - supports-color @@ -3729,7 +3768,7 @@ snapshots: dependencies: '@cspell/cspell-types': 8.16.0 comment-json: 4.2.5 - yaml: 2.6.0 + yaml: 2.6.1 cspell-dictionary@8.16.0: dependencies: @@ -3955,7 +3994,7 @@ snapshots: string.prototype.trimstart: 1.0.8 typed-array-buffer: 1.0.2 typed-array-byte-length: 1.0.1 - typed-array-byte-offset: 1.0.2 + typed-array-byte-offset: 1.0.3 typed-array-length: 1.0.6 unbox-primitive: 1.0.2 which-typed-array: 1.1.15 @@ -4028,37 +4067,37 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.7.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -4069,7 +4108,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -4081,7 +4120,7 @@ snapshots: string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.7.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -4469,6 +4508,10 @@ snapshots: call-bind: 1.0.7 get-intrinsic: 1.2.4 + is-async-function@2.0.0: + dependencies: + has-tostringtag: 1.0.2 + is-bigint@1.0.4: dependencies: has-bigints: 1.0.2 @@ -4498,6 +4541,10 @@ snapshots: is-extglob@2.1.1: {} + is-finalizationregistry@1.0.2: + dependencies: + call-bind: 1.0.7 + is-fullwidth-code-point@3.0.0: {} is-fullwidth-code-point@4.0.0: {} @@ -4506,12 +4553,18 @@ snapshots: dependencies: get-east-asian-width: 1.3.0 + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 is-lambda@1.0.1: {} + is-map@2.0.3: {} + is-negative-zero@2.0.3: {} is-number-object@1.0.7: @@ -4529,6 +4582,8 @@ snapshots: call-bind: 1.0.7 has-tostringtag: 1.0.2 + is-set@2.0.3: {} + is-shared-array-buffer@1.0.3: dependencies: call-bind: 1.0.7 @@ -4547,10 +4602,17 @@ snapshots: dependencies: which-typed-array: 1.1.15 + is-weakmap@2.0.2: {} + is-weakref@1.0.2: dependencies: call-bind: 1.0.7 + is-weakset@2.0.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + isarray@2.0.5: {} isexe@2.0.0: {} @@ -5071,6 +5133,16 @@ snapshots: json-parse-even-better-errors: 3.0.2 npm-normalize-package-bin: 3.0.1 + reflect.getprototypeof@1.0.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + which-builtin-type: 1.1.4 + regexp.prototype.flags@1.5.3: dependencies: call-bind: 1.0.7 @@ -5357,11 +5429,11 @@ snapshots: tinyspy@3.0.2: {} - tldts-core@6.1.61: {} + tldts-core@6.1.63: {} - tldts@6.1.61: + tldts@6.1.63: dependencies: - tldts-core: 6.1.61 + tldts-core: 6.1.63 to-regex-range@5.0.1: dependencies: @@ -5369,7 +5441,7 @@ snapshots: tough-cookie@5.0.0: dependencies: - tldts: 6.1.61 + tldts: 6.1.63 tr46@5.0.0: dependencies: @@ -5377,9 +5449,9 @@ snapshots: treeverse@3.0.0: {} - ts-api-utils@1.4.0(typescript@5.6.3): + ts-api-utils@1.4.0(typescript@5.7.2): dependencies: - typescript: 5.6.3 + typescript: 5.7.2 tsconfig-paths@3.15.0: dependencies: @@ -5416,7 +5488,7 @@ snapshots: has-proto: 1.0.3 is-typed-array: 1.1.13 - typed-array-byte-offset@1.0.2: + typed-array-byte-offset@1.0.3: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.7 @@ -5424,6 +5496,7 @@ snapshots: gopd: 1.0.1 has-proto: 1.0.3 is-typed-array: 1.1.13 + reflect.getprototypeof: 1.0.6 typed-array-length@1.0.6: dependencies: @@ -5434,7 +5507,7 @@ snapshots: is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 - typescript@5.6.3: {} + typescript@5.7.2: {} unbox-primitive@1.0.2: dependencies: @@ -5475,13 +5548,13 @@ snapshots: - bluebird - supports-color - vite-node@2.1.5(@types/node@20.17.6): + vite-node@2.1.5(@types/node@22.9.1): dependencies: cac: 6.7.14 debug: 4.3.7 es-module-lexer: 1.5.4 pathe: 1.1.2 - vite: 5.4.11(@types/node@20.17.6) + vite: 5.4.11(@types/node@22.9.1) transitivePeerDependencies: - '@types/node' - less @@ -5493,19 +5566,19 @@ snapshots: - supports-color - terser - vite@5.4.11(@types/node@20.17.6): + vite@5.4.11(@types/node@22.9.1): dependencies: esbuild: 0.21.5 postcss: 8.4.49 rollup: 4.27.3 optionalDependencies: - '@types/node': 20.17.6 + '@types/node': 22.9.1 fsevents: 2.3.3 - vitest@2.1.5(@types/node@20.17.6)(jsdom@25.0.1): + vitest@2.1.5(@types/node@22.9.1)(jsdom@25.0.1): dependencies: '@vitest/expect': 2.1.5 - '@vitest/mocker': 2.1.5(vite@5.4.11(@types/node@20.17.6)) + '@vitest/mocker': 2.1.5(vite@5.4.11(@types/node@22.9.1)) '@vitest/pretty-format': 2.1.5 '@vitest/runner': 2.1.5 '@vitest/snapshot': 2.1.5 @@ -5521,11 +5594,11 @@ snapshots: tinyexec: 0.3.1 tinypool: 1.0.2 tinyrainbow: 1.2.0 - vite: 5.4.11(@types/node@20.17.6) - vite-node: 2.1.5(@types/node@20.17.6) + vite: 5.4.11(@types/node@22.9.1) + vite-node: 2.1.5(@types/node@22.9.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 20.17.6 + '@types/node': 22.9.1 jsdom: 25.0.1 transitivePeerDependencies: - less @@ -5569,6 +5642,28 @@ snapshots: is-string: 1.0.7 is-symbol: 1.0.4 + which-builtin-type@1.1.4: + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.2 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 @@ -5629,6 +5724,6 @@ snapshots: yaml@2.5.1: {} - yaml@2.6.0: {} + yaml@2.6.1: {} yocto-queue@0.1.0: {} diff --git a/src/assertion/assertIsObject.ts b/src/assertion/assertIsObject.ts index de9ea15..8900044 100644 --- a/src/assertion/assertIsObject.ts +++ b/src/assertion/assertIsObject.ts @@ -2,13 +2,11 @@ import { isObject } from '../predicate/isObject.js'; import { getError } from './getError.js'; -import type { UnknownRecord } from '../types/records.js'; - -export function assertIsObject( +export function assertIsObject( input: unknown, error: string | Error = 'input is not an object', -): asserts input is T { - if (!isObject(input)) { +): asserts input is object { + if (!isObject(input)) { throw getError(error); } } diff --git a/src/combinations.ts b/src/combinations.ts index 95ae9ce..11c92cf 100644 --- a/src/combinations.ts +++ b/src/combinations.ts @@ -14,9 +14,9 @@ export type CombinationsOutput> = Input extends CombinationsInput ? Type : never; export function* combinations< - Type extends UnknownRecord = UnknownRecord, + Type extends object = object, Input extends CombinationsInput = CombinationsInput, ->(input: Input): Generator> { +>(input: Input): Generator, undefined> { const propertyNames = Object.keys(input); const propertyValues = Object.values(input).map((value) => isObject(value) ? [...combinations(value)] : asArray(value), diff --git a/src/delay.ts b/src/delay.ts index 6304a6e..7ba288a 100644 --- a/src/delay.ts +++ b/src/delay.ts @@ -1,8 +1,7 @@ -import { getType } from './getType.js'; - /** * Delay a specified number of milliseconds before resolving. - * The `ms` value can be between zero and the max delay value for `setTimeout`. + * + * The `ms` value can be between zero and the max delay value for `setTimeout()`, which is `2 ** 31 - 1`. * * {@link https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value} */ @@ -10,14 +9,16 @@ export function delay(milliseconds: number): Promise; export function delay(milliseconds: number, value: T): Promise; -export function delay(milliseconds: number, value?: T): Promise { +export function delay(milliseconds: number, value?: T): Promise { return new Promise((resolve, reject) => { - if (typeof milliseconds !== 'number') { - reject(new TypeError(`milliseconds must be a number. ${getType(milliseconds)} was provided.`)); + const maxDelayMs = 2 ** 31 - 1; + + if (typeof milliseconds !== 'number' || milliseconds < 0 || milliseconds > maxDelayMs) { + reject(new TypeError(`milliseconds must be a number between 0 and ${maxDelayMs}`)); return; } - setTimeout(resolve, Math.max(0, Math.min(milliseconds, 2_147_483_647)), value); + setTimeout(resolve, milliseconds, value); }); } diff --git a/src/normalize.ts b/src/normalize.ts index 6ca00fa..3b5e66d 100644 --- a/src/normalize.ts +++ b/src/normalize.ts @@ -77,22 +77,19 @@ export function normalize { - const innerNormalizers = currentNormalizers[key]; - // If the value is undefined but there is a normalizer record, set value to empty object. - const value = - typeof data[key] === 'undefined' && - isObject>(innerNormalizers) - ? ({} as unknown as CurrentRecord[keyof CurrentRecord]) - : data[key]; - - data[key] = walk(value, innerNormalizers); - - return data; - }, currentRecord); - } + if (isObject(currentNormalizers) && isObject(currentRecord)) { + return getOwnProperties(currentNormalizers).reduce((data, key) => { + const innerNormalizers = currentNormalizers[key]; + // If the value is undefined but there is a normalizer record, set value to empty object. + const value = + typeof data[key] === 'undefined' && isObject(innerNormalizers) + ? ({} as unknown as CurrentRecord[keyof CurrentRecord]) + : data[key]; + + data[key] = walk(value, innerNormalizers); + + return data; + }, currentRecord); } return currentRecord; diff --git a/src/predicate/index.ts b/src/predicate/index.ts index 6b974f3..9df0680 100644 --- a/src/predicate/index.ts +++ b/src/predicate/index.ts @@ -20,6 +20,7 @@ export * from './isNumericString.js'; export * from './isNumericValue.js'; export * from './isNumericValueArray.js'; export * from './isObject.js'; +export * from './isObjectWith.js'; export * from './isOptionalBigInt.js'; export * from './isOptionalBoolean.js'; export * from './isOptionalISODateString.js'; diff --git a/src/predicate/isAsyncIterable.ts b/src/predicate/isAsyncIterable.ts index ef6e1e2..cd13563 100644 --- a/src/predicate/isAsyncIterable.ts +++ b/src/predicate/isAsyncIterable.ts @@ -1,5 +1,5 @@ -import { isObject } from './isObject.js'; +import { isObjectWith } from './isObjectWith.js'; export const isAsyncIterable = (input: unknown): input is AsyncIterable => { - return isObject(input) && typeof input[Symbol.asyncIterator] === 'function'; + return isObjectWith(input, Symbol.asyncIterator) && typeof input[Symbol.asyncIterator] === 'function'; }; diff --git a/src/predicate/isIterable.ts b/src/predicate/isIterable.ts index 3ba3a33..b1ea6e4 100644 --- a/src/predicate/isIterable.ts +++ b/src/predicate/isIterable.ts @@ -1,5 +1,5 @@ -import { isObject } from './isObject.js'; +import { isObjectWith } from './isObjectWith.js'; export const isIterable = (input: unknown): input is Iterable => { - return isObject(input) && typeof input[Symbol.iterator] === 'function'; + return isObjectWith(input, Symbol.iterator) && typeof input[Symbol.iterator] === 'function'; }; diff --git a/src/predicate/isObject.ts b/src/predicate/isObject.ts index 896e731..55c3a7d 100644 --- a/src/predicate/isObject.ts +++ b/src/predicate/isObject.ts @@ -1,4 +1,5 @@ -import type { UnknownRecord } from '../types/records.js'; - -export const isObject = (input: unknown): input is T => +/** + * Determine if `input` is an object and not null or an array. + */ +export const isObject = (input: unknown): input is object => input !== null && typeof input === 'object' && !Array.isArray(input); diff --git a/src/predicate/isObjectWith.ts b/src/predicate/isObjectWith.ts new file mode 100644 index 0000000..e88ce64 --- /dev/null +++ b/src/predicate/isObjectWith.ts @@ -0,0 +1,13 @@ +import { asArray } from '../asArray.js'; + +import { isObject } from './isObject.js'; + +/** + * Determine if `input` is an object and has the provided properties. + */ +export const isObjectWith = ( + input: T, + properties: P | P[], +): input is T & Record => { + return isObject(input) && asArray(properties).every((property) => property in input); +}; diff --git a/src/predicate/isPromiseFulfilledResult.ts b/src/predicate/isPromiseFulfilledResult.ts index 346965a..529b473 100644 --- a/src/predicate/isPromiseFulfilledResult.ts +++ b/src/predicate/isPromiseFulfilledResult.ts @@ -1,5 +1,5 @@ -import { isObject } from './isObject.js'; +import { isObjectWith } from './isObjectWith.js'; export const isPromiseFulfilledResult = (input: unknown): input is PromiseFulfilledResult => { - return isObject(input) && input.status === 'fulfilled'; + return isObjectWith(input, 'status') && input.status === 'fulfilled'; }; diff --git a/src/predicate/isPromiseLike.ts b/src/predicate/isPromiseLike.ts index 3b076f7..63a50a3 100644 --- a/src/predicate/isPromiseLike.ts +++ b/src/predicate/isPromiseLike.ts @@ -1,6 +1,6 @@ import { isFunction } from './isFunction.js'; -import { isObject } from './isObject.js'; +import { isObjectWith } from './isObjectWith.js'; export function isPromiseLike(input: unknown): input is PromiseLike { - return isObject(input) && isFunction(input.then) && input.then.length === 2; + return isObjectWith(input, 'then') && isFunction(input.then) && input.then.length === 2; } diff --git a/src/predicate/isPromiseRejectedResult.ts b/src/predicate/isPromiseRejectedResult.ts index d6e1dd7..4782d72 100644 --- a/src/predicate/isPromiseRejectedResult.ts +++ b/src/predicate/isPromiseRejectedResult.ts @@ -1,5 +1,5 @@ -import { isObject } from './isObject.js'; +import { isObjectWith } from './isObjectWith.js'; export const isPromiseRejectedResult = (input: unknown): input is PromiseRejectedResult => { - return isObject(input) && input.status === 'rejected' && 'reason' in input; + return isObjectWith(input, ['status', 'reason']) && input.status === 'rejected'; }; diff --git a/test/delay.test.ts b/test/delay.test.ts index d22ec7d..78f67f5 100644 --- a/test/delay.test.ts +++ b/test/delay.test.ts @@ -25,5 +25,6 @@ describe('delay()', () => { it('Rejects when provided invalid milliseconds', async () => { await expect(delay('wrong milliseconds value' as unknown as number)).rejects.toThrow(); + await expect(delay(2 ** 32)).rejects.toThrow(); }); }); diff --git a/test/predicate-factory/allOf.test.ts b/test/predicate-factory/allOf.test.ts index 67147d3..23bbc24 100644 --- a/test/predicate-factory/allOf.test.ts +++ b/test/predicate-factory/allOf.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; import { isNumber } from '../../src/predicate/isNumber.js'; -import { isObject } from '../../src/predicate/isObject.js'; +import { isObjectWith } from '../../src/predicate/isObjectWith.js'; import { isString } from '../../src/predicate/isString.js'; import { allOf } from '../../src/predicate-factory/allOf.js'; @@ -13,10 +13,10 @@ describe('allOf()', () => { it('Returns a type predicate function', () => { const fn = allOf( (input): input is { name: string } => { - return isObject(input) && isString(input.name); + return isObjectWith(input, 'name') && isString(input.name); }, (input): input is { age: number } => { - return isObject(input) && isNumber(input.age); + return isObjectWith(input, 'age') && isNumber(input.age); }, ); diff --git a/test/predicate/isObjectWith.test.ts b/test/predicate/isObjectWith.test.ts new file mode 100644 index 0000000..e7320a4 --- /dev/null +++ b/test/predicate/isObjectWith.test.ts @@ -0,0 +1,15 @@ +import { describe, it, expect } from 'vitest'; + +import { isObjectWith } from '../../src/predicate/isObjectWith.js'; + +describe('isObjectWith()', () => { + it('Returns true for valid inputs', () => { + expect(isObjectWith({ property: true }, 'property')).toBeTruthy(); + expect(isObjectWith({ name: 'Test Testerson', age: 100 }, ['name', 'age'])).toBeTruthy(); + }); + + it.each([[], null, false, 'string', Math.PI, Symbol()])('Returns false for invalid inputs', (item) => { + expect(isObjectWith(item, 'property')).toBeFalsy(); + expect(isObjectWith(item, ['property'])).toBeFalsy(); + }); +});