diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 28f5bcd..6318658 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/setup-node@v2 with: - node-version: "14" + node-version: "18" - uses: purescript-contrib/setup-purescript@main @@ -41,4 +41,4 @@ jobs: npm run build npm test spago docs --no-search - ./dist/purescript-docs-search build-index + ./dist/purescript-docs-search.cjs build-index diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b612084..f7c3955 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: - uses: actions/setup-node@v2 with: - node-version: "14" + node-version: "18" - uses: purescript-contrib/setup-purescript@main @@ -41,7 +41,7 @@ jobs: with: files: | dist/docs-search-app.js - dist/purescript-docs-search + dist/purescript-docs-search.cjs env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -52,4 +52,4 @@ jobs: run: | mv ci-npmrc.txt .npmrc npm ci - npm publish --non-interactive --access public \ No newline at end of file + npm publish --non-interactive --access public diff --git a/CHANGELOG.md b/CHANGELOG.md index b86c7a3..86cda9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +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). +## [0.0.12 - 2022-08-31] + +Changes: +- Package structure change: `dist/purescript-docs-search.cjs` has been moved to `dist/purescript-docs-search.cjs` due to NodeJS restrictions for `type: module` packages. + +New features: +- Docs for each CLI option +- New `--source-files` option that allows to specify `.purs` sources (see below) + +Bugfixes: +- Include modules with only re-exports in the module list ([#62](https://github.com/purescript/purescript-docs-search/issues/62)) +- Fix `docs.json` parser for some types + ## [0.0.11 - 2021-04-15] Changes: diff --git a/package-lock.json b/package-lock.json index 30f5fe8..4809965 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,1337 @@ { "name": "purescript-docs-search", "version": "0.0.11", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "purescript-docs-search", + "version": "0.0.11", + "license": "BSD-3-Clause", + "dependencies": { + "punycode": "^2.1.1" + }, + "bin": { + "purescript-docs-search": "dist/purescript-docs-search.js" + }, + "devDependencies": { + "esbuild": "^0.11.10", + "glob": "^7.1.6", + "markdown-it": "^12.0.4", + "puppeteer": "^8.0.0", + "spago": "^0.20.9" + } + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true + }, + "node_modules/@npmcli/fs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "dev": true, + "dependencies": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "node_modules/@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/node": { + "version": "14.14.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.39.tgz", + "integrity": "sha512-Qipn7rfTxGEDqZiezH+wxqWYR8vcXq5LRpZrETD19Gs4o8LbklbmqotSUsMU+s5G3PJwMRDfNEYoxrcBwIxOuw==", + "dev": true, + "optional": true + }, + "node_modules/@types/yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", + "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cacache": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.854822", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.854822.tgz", + "integrity": "sha512-xd4D8kHQtB0KtWW0c9xBZD5LVtm9chkMOfs/3Yn01RhT/sFIsVtzTtypfKoFfWBaL+7xCYLxjOLkhwPXaX/Kcg==", + "dev": true + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.11.tgz", + "integrity": "sha512-iq5YdV63vY/nUAFIvY92BXVkYjMbOchnofLKoLKMPZIa4uuIJAJG9WRA+ZRjQBZbrsORUwvZcANeG2d3p46PJQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "dev": true + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", + "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-fetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", + "dev": true, + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/puppeteer": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-8.0.0.tgz", + "integrity": "sha512-D0RzSWlepeWkxPPdK3xhTcefj8rjah1791GE82Pdjsri49sy11ci/JQsAO8K2NRukqvwEtcI+ImP5F4ZiMvtIQ==", + "deprecated": "Version no longer supported. Upgrade to @latest", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "debug": "^4.1.0", + "devtools-protocol": "0.0.854822", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "pkg-dir": "^4.2.0", + "progress": "^2.0.1", + "proxy-from-env": "^1.1.0", + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" + }, + "engines": { + "node": ">=10.18.1" + } + }, + "node_modules/puppeteer/node_modules/ws": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz", + "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "optional": true + }, + "node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", + "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "dev": true, + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/spago": { + "version": "0.20.9", + "resolved": "https://registry.npmjs.org/spago/-/spago-0.20.9.tgz", + "integrity": "sha512-r5TUxnYn9HawlQyMswlhIk24BGFSN2KGbqgZFZrn47GjTpMscU14xkt9CqTWgoSQYsoZieG+3dUtOxUQ7GYD7w==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "make-fetch-happen": "^9.1.0", + "tar": "^6.1.11" + }, + "bin": { + "spago": "spago" + } + }, + "node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tar/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/unbzip2-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + }, "dependencies": { + "@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true + }, + "@npmcli/fs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "dev": true, + "requires": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, "@types/node": { "version": "14.14.39", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.39.tgz", @@ -30,55 +1358,31 @@ "debug": "4" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "agentkeepalive": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", + "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" } }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "requires": { - "safer-buffer": "~2.1.0" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" } }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "balanced-match": { @@ -93,15 +1397,6 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -152,11 +1447,39 @@ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "cacache": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "dev": true, + "requires": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + } + } }, "chownr": { "version": "1.1.4", @@ -164,14 +1487,11 @@ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true }, "concat-map": { "version": "0.0.1", @@ -179,34 +1499,19 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true }, "devtools-protocol": { @@ -215,14 +1520,14 @@ "integrity": "sha512-xd4D8kHQtB0KtWW0c9xBZD5LVtm9chkMOfs/3Yn01RhT/sFIsVtzTtypfKoFfWBaL+7xCYLxjOLkhwPXaX/Kcg==", "dev": true }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, + "optional": true, "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "iconv-lite": "^0.6.2" } }, "end-of-stream": { @@ -240,18 +1545,18 @@ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "dev": true }, + "err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, "esbuild": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.11.tgz", "integrity": "sha512-iq5YdV63vY/nUAFIvY92BXVkYjMbOchnofLKoLKMPZIa4uuIJAJG9WRA+ZRjQBZbrsORUwvZcANeG2d3p46PJQ==", "dev": true }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -264,24 +1569,6 @@ "yauzl": "^2.10.0" } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -291,23 +1578,6 @@ "pend": "~1.2.0" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -315,12 +1585,12 @@ "dev": true }, "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, "requires": { - "minipass": "^2.6.0" + "minipass": "^3.0.0" } }, "fs.realpath": { @@ -338,15 +1608,6 @@ "pump": "^3.0.0" } }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -361,31 +1622,21 @@ "path-is-absolute": "^1.0.0" } }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" } }, "https-proxy-agent": { @@ -398,12 +1649,49 @@ "debug": "4" } }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -420,54 +1708,18 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", "dev": true }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, "linkify-it": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", @@ -477,6 +1729,39 @@ "uc.micro": "^1.0.1" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "dev": true, + "requires": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + } + }, "markdown-it": { "version": "12.3.2", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", @@ -496,21 +1781,6 @@ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", "dev": true }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", - "dev": true - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "dev": true, - "requires": { - "mime-db": "1.47.0" - } - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -521,41 +1791,78 @@ } }, "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", + "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", "dev": true, "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "yallist": "^4.0.0" } }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", "dev": true, "requires": { - "minipass": "^2.9.0" + "minipass": "^3.0.0" } }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "minipass-fetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", "dev": true, "requires": { - "minimist": "^1.2.5" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } + "encoding": "^0.1.12", + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" } }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -568,18 +1875,18 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", "dev": true }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -598,6 +1905,15 @@ "p-try": "^2.0.0" } }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -616,12 +1932,6 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -673,18 +1983,28 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -698,8 +2018,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "puppeteer": { "version": "8.0.0", @@ -721,55 +2040,28 @@ "ws": "^7.2.3" }, "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "ws": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz", "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==", - "dev": true + "dev": true, + "requires": {} } } }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" } }, "safe-buffer": { @@ -782,33 +2074,62 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "optional": true + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true }, + "socks": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", + "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "dev": true, + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, + "socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "dev": true, + "requires": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + } + }, "spago": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/spago/-/spago-0.20.0.tgz", - "integrity": "sha512-B0cvb1g5rjV80ovMT5MuNvUhfcXz0caEa3OPdydvYlvh6/WQZYa0S74or4PUPbRsiwhm9C1FCtfzzEk+yTKaHA==", + "version": "0.20.9", + "resolved": "https://registry.npmjs.org/spago/-/spago-0.20.9.tgz", + "integrity": "sha512-r5TUxnYn9HawlQyMswlhIk24BGFSN2KGbqgZFZrn47GjTpMscU14xkt9CqTWgoSQYsoZieG+3dUtOxUQ7GYD7w==", "dev": true, "requires": { - "request": "^2.88.0", - "tar": "^4.4.8" + "make-fetch-happen": "^9.1.0", + "tar": "^6.1.11" } }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", "dev": true, "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" + "minipass": "^3.1.1" } }, "string_decoder": { @@ -821,18 +2142,25 @@ } }, "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", "dev": true, "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + } } }, "tar-fs": { @@ -879,31 +2207,6 @@ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -932,13 +2235,22 @@ } } }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", "dev": true, "requires": { - "punycode": "^2.1.0" + "imurmurhash": "^0.1.4" } }, "util-deprecate": { @@ -947,23 +2259,6 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -971,9 +2266,9 @@ "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yauzl": { diff --git a/package.json b/package.json index 9408b69..a90d36b 100644 --- a/package.json +++ b/package.json @@ -1,36 +1,37 @@ { "name": "purescript-docs-search", - "version": "0.0.11", + "type": "module", + "version": "0.0.12", "description": "Search frontend for the documentation generated by the PureScript compiler.", "directories": { "test": "test" }, "bin": { - "purescript-docs-search": "dist/purescript-docs-search" + "purescript-docs-search": "dist/purescript-docs-search.cjs" }, "files": [ - "dist/purescript-docs-search", + "dist/purescript-docs-search.cjs", "dist/docs-search-app.js", "README.md", "CHANGELOG.md" ], "scripts": { - "test": "spago docs --no-search && ./dist/purescript-docs-search build-index && spago test && npm run check-version", + "test": "spago docs --no-search && ./dist/purescript-docs-search.cjs build-index && spago test && npm run check-version", "bundle-app": "spago bundle-app --no-build --no-install -m Docs.Search.App --to dist/docs-search-app.js", "esbuild-app": "esbuild dist/docs-search-app.js --target=es2016 --bundle --minify --outfile=dist/docs-search-app.min.js && mv dist/docs-search-app.min.js dist/docs-search-app.js", "build-app": "npm run bundle-app && npm run esbuild-app", - "bundle-main": "spago bundle-app --no-build --no-install -m Docs.Search.Main --to dist/main.js", + "bundle-main": "spago bundle-app --no-build --no-install --platform node -m Docs.Search.Main --to dist/main.js", "esbuild-main": "esbuild dist/main.js --platform=node --bundle --minify --outfile=dist/main.min.js && mv dist/main.min.js dist/main.js", - "add-shebang": "echo \"#!/usr/bin/env node\" > dist/purescript-docs-search && cat dist/main.js >> dist/purescript-docs-search", - "chmod-main": "chmod +x dist/purescript-docs-search", + "add-shebang": "echo \"#!/usr/bin/env node\" > dist/purescript-docs-search.cjs && cat dist/main.js >> dist/purescript-docs-search.cjs", + "chmod-main": "chmod +x dist/purescript-docs-search.cjs", "build-main": "npm run bundle-main && npm run esbuild-main && npm run add-shebang && rm dist/main.js && npm run chmod-main", "build": "spago build && npm run build-app && npm run build-main", "clean": "rm -rf dist", - "check-version": "[ \"$(./dist/purescript-docs-search version)\" = \"$npm_package_version\" ]" + "check-version": "[ \"$(./dist/purescript-docs-search.cjs version)\" = \"$npm_package_version\" ]" }, "repository": { "type": "git", - "url": "git+https://github.com/spacchetti/purescript-docs-search.git" + "url": "git+https://github.com/purescript/purescript-docs-search.git" }, "keywords": [ "purescript" @@ -38,15 +39,17 @@ "author": "Kalnitsky Vladimir ", "license": "BSD-3-Clause", "bugs": { - "url": "https://github.com/spacchetti/purescript-docs-search/issues" + "url": "https://github.com/purescript/purescript-docs-search/issues" + }, + "homepage": "https://github.com/purescript/purescript-docs-search#readme", + "dependencies": { + "punycode": "^2.1.1" }, - "homepage": "https://github.com/spacchetti/purescript-docs-search#readme", - "dependencies": {}, "devDependencies": { "esbuild": "^0.11.10", "glob": "^7.1.6", "markdown-it": "^12.0.4", "puppeteer": "^8.0.0", - "spago": "^0.20.0" + "spago": "^0.20.9" } } diff --git a/packages.dhall b/packages.dhall index d07e1eb..0b0ad5a 100644 --- a/packages.dhall +++ b/packages.dhall @@ -1,8 +1,10 @@ let mkPackage = - https://raw.githubusercontent.com/purescript/package-sets/psc-0.13.2-20190725/src/mkPackage.dhall sha256:0b197efa1d397ace6eb46b243ff2d73a3da5638d8d0ac8473e8e4a8fc528cf57 + https://raw.githubusercontent.com/purescript/package-sets/psc-0.13.2-20190725/src/mkPackage.dhall + sha256:0b197efa1d397ace6eb46b243ff2d73a3da5638d8d0ac8473e8e4a8fc528cf57 let upstream = - https://github.com/purescript/package-sets/releases/download/psc-0.14.0-20210409/packages.dhall sha256:e81c2f2ce790c0e0d79869d22f7a37d16caeb5bd81cfda71d46c58f6199fd33f + https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20220829/packages.dhall + sha256:9ec64ed24ec308770ccdd3d0edb74a814fcfbe34c7df5c28266935f0b5e585d7 let overrides = {=} @@ -33,12 +35,7 @@ let additions = , "web-uievents" ] "https://github.com/purescript-halogen/purescript-halogen.git" - "v6.1.0" - , halogen-css = - mkPackage - [ "halogen" ] - "https://github.com/slamdata/purescript-halogen-css.git" - "v8.0.0" + "v7.0.0" , memoize = mkPackage [ "prelude" @@ -67,8 +64,8 @@ let additions = , "free" , "memoize" ] - "https://github.com/srghma/purescript-optparse.git" - "d49b03fcd35f5be167e9c5c44ab1c17ca0956fb1" + "https://github.com/klntsky/purescript-optparse.git" + "2fe4265b7c6b09744c11190a43ca06777c752473" , exitcodes = mkPackage [ "enums" ] @@ -77,30 +74,42 @@ let additions = , markdown-it = mkPackage [ "prelude", "effect", "options" ] - "https://github.com/nonbili/purescript-markdown-it.git" - "v0.4.0" + "https://github.com/klntsky/purescript-markdown-it.git" + "f3b7654783a83a80d7c09b6caaa7cd40b93ddce1" + , string-parsers = + mkPackage + [ "arrays" + , "assert" + , "bifunctors" + , "console" + , "control" + , "effect" + , "either" + , "enums" + , "foldable-traversable" + , "lists" + , "maybe" + , "minibench" + , "nonempty" + , "partial" + , "prelude" + , "strings" + , "tailrec" + , "transformers" + , "unfoldable" + ] + "https://github.com/purescript-contrib/purescript-string-parsers.git" + "v8.0.0" , html-parser-halogen = mkPackage [ "string-parsers", "halogen" ] "https://github.com/rnons/purescript-html-parser-halogen.git" - "458e492e441fcf69a66911b7b64beea5849e0dad" + "035a51d02ba9f8b70c3ffd9fe31a3f5bed19941c" , markdown-it-halogen = mkPackage [ "markdown-it", "html-parser-halogen" ] "https://github.com/nonbili/purescript-markdown-it-halogen.git" "08c9625015bf04214be14e45230e8ce12f3fa2bf" - , toppokki = - mkPackage - [ "prelude" - , "record" - , "functions" - , "node-http" - , "aff-promise" - , "node-buffer" - , "node-fs-aff" - ] - "https://github.com/justinwoo/purescript-toppokki.git" - "v2.4.0" , search-trie = mkPackage [ "prelude" @@ -126,7 +135,48 @@ let additions = , "transformers" ] "https://github.com/purescript-contrib/purescript-css.git" - "5c1a44ee95c259352a2b4570b060de14130540bc" + "710d6a742beb88299faf08aaeb997ee1e24483ab" + , jest = + mkPackage + [ "aff" + , "aff-promise" + , "effect" + , "prelude" + , "psci-support" + , "foldable-traversable" + ] + "https://github.com/klntsky/purescript-jest.git" + "7feaa5a880fc75002c4eca312993174e7220252b" + , literals = + mkPackage + [ "assert" + , "effect" + , "console" + , "integers" + , "numbers" + , "partial" + , "psci-support" + , "unsafe-coerce" + , "typelevel-prelude" + ] + "https://github.com/jvliwanag/purescript-literals.git" + "ae3ef4e9c1ae7c57ec77bd13906fa60ae8abba4a" + , untagged-union = + mkPackage + [ "assert" + , "console" + , "effect" + , "foreign" + , "foreign-object" + , "literals" + , "maybe" + , "newtype" + , "psci-support" + , "tuples" + , "unsafe-coerce" + ] + "https://github.com/jvliwanag/purescript-untagged-union.git" + "ed8262a966e15e751322c327e2759a9b9c0ef3f3" } in upstream // overrides // additions diff --git a/spago.dhall b/spago.dhall index 3f4faf9..ccf59f6 100644 --- a/spago.dhall +++ b/spago.dhall @@ -15,7 +15,6 @@ , "either" , "exceptions" , "foldable-traversable" - , "foreign" , "foreign-object" , "halogen" , "halogen-css" @@ -34,15 +33,15 @@ , "node-readline" , "optparse" , "ordered-collections" + , "parallel" , "partial" , "prelude" , "profunctor" , "profunctor-lenses" , "search-trie" + , "spec" , "string-parsers" , "strings" - , "test-unit" - , "toppokki" , "transformers" , "tuples" , "unfoldable" diff --git a/src/Docs/Search/App.purs b/src/Docs/Search/App.purs index 6450edb..98f7de9 100644 --- a/src/Docs/Search/App.purs +++ b/src/Docs/Search/App.purs @@ -86,7 +86,7 @@ main = do srio <- runUI resultsComponent unit searchResults void $ H.liftEffect $ subscribe sfio.messages $ \sfm -> do - launchAff_ do + launchAff_ $ void do srio.query (SearchResults.MessageFromSearchField sfm unit) -- We need to read the URI hash only when both components are initialized and @@ -97,8 +97,8 @@ main = do H.liftEffect do listener <- - eventListener \event -> - launchAff_ do + eventListener \_event -> + launchAff_ $ void do sfio.query $ SearchField.ReadURIHash unit addEventListener hashchange listener true (Window.toEventTarget window) @@ -111,8 +111,8 @@ main = do H.liftEffect do listener <- - eventListener \event -> - launchAff_ do + eventListener \_event -> + launchAff_ $ void do sbio.query $ Sidebar.UpdateModuleGrouping unit addEventListener focus listener true (Window.toEventTarget window) @@ -197,7 +197,7 @@ insertVersionInfo = do prefix <- Document.createTextNode " - patched by " doc <#> Text.toNode linkElement <- Document.createElement "a" doc let linkNode = Element.toNode linkElement - Element.setAttribute "href" "https://github.com/spacchetti/purescript-docs-search" linkElement + Element.setAttribute "href" "https://github.com/purescript/purescript-docs-search" linkElement Element.setAttribute "target" "_blank" linkElement linkText <- Document.createTextNode ("docs-search") doc <#> Text.toNode suffix <- Document.createTextNode (" " <> Config.version) doc <#> Text.toNode diff --git a/src/Docs/Search/App/SearchField.purs b/src/Docs/Search/App/SearchField.purs index 42e91cc..708b085 100644 --- a/src/Docs/Search/App/SearchField.purs +++ b/src/Docs/Search/App/SearchField.purs @@ -156,7 +156,7 @@ render state = [ HH.input [ HP.value state.input , HP.placeholder "Search for definitions... (S to focus)" - , HP.id_ "docs-search-query-field" + , HP.id "docs-search-query-field" , HP.type_ HP.InputText , HE.onKeyUp (\event -> case KeyboardEvent.code event of diff --git a/src/Docs/Search/App/SearchResults.purs b/src/Docs/Search/App/SearchResults.purs index 9a58d25..2f9868c 100644 --- a/src/Docs/Search/App/SearchResults.purs +++ b/src/Docs/Search/App/SearchResults.purs @@ -202,9 +202,9 @@ render state@{ mode: Active } = , HH.div_ $ Array.concat $ shownResults <#> renderResult state - , HH.div [ HP.class_ (wrap "load_more"), HP.id_ "load-more" ] + , HH.div [ HP.class_ (wrap "load_more"), HP.id "load-more" ] [ if Array.length shownResults < Array.length state.results - then HH.a [ HP.id_ "load-more-link" + then HH.a [ HP.id "load-more-link" , HE.onClick $ const MoreResultsRequested ] [ HH.text "Show more results" ] else HH.p_ @@ -545,6 +545,9 @@ renderType = case _ of , renderType t2 ] + KindApp t1 t2 -> + HH.span_ [ renderType t1, space, renderType t2 ] + ty@(ForAll _ _ _) -> renderForAll ty @@ -558,6 +561,9 @@ renderType = case _ of ty@REmpty -> renderRow true ty ty@(RCons _ _ _) -> renderRow true ty + Kinded t1 t2 -> + HH.span_ [ renderType t1, space, syntax "::", space, renderType t2 ] + BinaryNoParensType op t1 t2 -> HH.span_ [ renderType t1 diff --git a/src/Docs/Search/App/Sidebar.purs b/src/Docs/Search/App/Sidebar.purs index 35f30b5..3d7c2d5 100644 --- a/src/Docs/Search/App/Sidebar.purs +++ b/src/Docs/Search/App/Sidebar.purs @@ -17,7 +17,6 @@ import Data.Maybe (Maybe(..), isJust, fromMaybe) import Data.Newtype (wrap, unwrap) import Data.Set (Set) import Data.Set as Set -import Data.Symbol (SProxy(..)) import Data.Tuple.Nested (type (/\), (/\)) import Effect (Effect) import Effect.Aff (Aff) @@ -25,6 +24,7 @@ import Halogen as H import Halogen.HTML as HH import Halogen.HTML.Events as HE import Halogen.HTML.Properties as HP +import Type.Proxy (Proxy(..)) import Web.HTML as HTML import Web.HTML.Window as Window import Web.Storage.Storage as Storage @@ -131,7 +131,7 @@ render state@{ groupingMode, moduleNames, localPackageName } = ] [ HH.h3_ [ HH.text $ if groupingMode == DontGroup then "Modules" else "Packages" ] - , HH.input [ HP.id_ "group-modules__input" + , HH.input [ HP.id "group-modules__input" , HP.type_ HP.InputCheckbox , HP.checked (groupingMode == GroupByPackage) , HE.onChecked $ ToggleGrouping <<< isCheckedToGroupingMode @@ -139,7 +139,7 @@ render state@{ groupingMode, moduleNames, localPackageName } = , HH.text " " , HH.label [ HP.for "group-modules__input" - , HP.id_ "group-modules__label" + , HP.id "group-modules__label" ] [ HH.text " GROUP BY PACKAGE" ] @@ -215,4 +215,4 @@ isCheckedToGroupingMode = if _ then GroupByPackage else DontGroup -- Some optics: _groupingMode :: forall a b rest. (a -> b) -> { groupingMode :: a | rest } -> { groupingMode :: b | rest } -_groupingMode = prop (SProxy :: SProxy "groupingMode") +_groupingMode = prop (Proxy :: Proxy "groupingMode") diff --git a/src/Docs/Search/BrowserEngine.js b/src/Docs/Search/BrowserEngine.js index cb9bd47..3e98f4d 100644 --- a/src/Docs/Search/BrowserEngine.js +++ b/src/Docs/Search/BrowserEngine.js @@ -1,6 +1,6 @@ /* global exports */ -exports.loadIndex_ = function (partId) { +export function loadIndex_ (partId) { return function (url) { return function () { return new Promise(function(resolve, reject) { diff --git a/src/Docs/Search/Config.purs b/src/Docs/Search/Config.purs index 2cf7d5e..0cf65ea 100644 --- a/src/Docs/Search/Config.purs +++ b/src/Docs/Search/Config.purs @@ -7,7 +7,7 @@ import Prelude import Data.Newtype (wrap) version :: String -version = "0.0.11" +version = "0.0.12" mkShapeScriptPath :: String -> String mkShapeScriptPath shape = "./index/types/" <> shape <> ".js" diff --git a/src/Docs/Search/IndexBuilder.js b/src/Docs/Search/IndexBuilder.js index 65f01d1..87d5d61 100644 --- a/src/Docs/Search/IndexBuilder.js +++ b/src/Docs/Search/IndexBuilder.js @@ -1,14 +1,13 @@ /* global __dirname require exports */ -var path = require('path'); -var glob = require('glob'); +import globMain from "glob"; -exports.getDirname = function () { +export function getDirname () { return __dirname; }; -exports.glob = function (pattern) { +export function glob (pattern) { return function () { - return glob.sync(pattern); + return globMain.sync(pattern); }; }; diff --git a/src/Docs/Search/IndexBuilder.purs b/src/Docs/Search/IndexBuilder.purs index c03b508..f252835 100644 --- a/src/Docs/Search/IndexBuilder.purs +++ b/src/Docs/Search/IndexBuilder.purs @@ -5,13 +5,14 @@ import Docs.Search.Config as Config import Docs.Search.Declarations (Declarations(..), mkDeclarations) import Docs.Search.DocsJson (DocsJson) import Docs.Search.Extra ((>#>)) +import Docs.Search.Meta (Meta) import Docs.Search.ModuleIndex (PackedModuleIndex, mkPackedModuleIndex) +import Docs.Search.ModuleParser (parseModuleName) import Docs.Search.PackageIndex (PackageInfo, mkPackageInfo) import Docs.Search.Score (mkScores) import Docs.Search.SearchResult (SearchResult) import Docs.Search.TypeIndex (TypeIndex, mkTypeIndex) -import Docs.Search.Types (PackageName, PartId) -import Docs.Search.Meta (Meta) +import Docs.Search.Types (ModuleName, PackageName, PartId) import Prelude @@ -20,6 +21,7 @@ import Data.Argonaut.Decode (decodeJson) import Data.Argonaut.Decode.Error (printJsonDecodeError) import Data.Argonaut.Encode (encodeJson) import Data.Argonaut.Parser (jsonParser) +import Data.Array (concat) import Data.Array as Array import Data.Either (Either(..), either) import Data.Foldable (sum) @@ -38,13 +40,15 @@ import Data.String.Common (replace) as String import Data.String.Pattern (Pattern(..), Replacement(..)) import Data.Traversable (for, for_) import Data.Tuple (Tuple(..), fst) +import Data.Tuple.Nested ((/\)) import Effect (Effect) import Effect.Aff (Aff, launchAff_, parallel, sequential) import Effect.Class (liftEffect) import Effect.Console (log) import Node.Encoding (Encoding(UTF8)) -import Node.FS.Aff (exists, mkdir, readFile, readTextFile, readdir, stat, writeFile, writeTextFile) +import Node.FS.Aff (mkdir, readFile, readTextFile, readdir, stat, writeFile, writeTextFile) import Node.FS.Stats (isDirectory, isFile) +import Node.FS.Sync (exists) import Node.Process as Process import Web.Bower.PackageMeta (PackageMeta(..)) @@ -55,6 +59,7 @@ type Config = , generatedDocs :: String , noPatch :: Boolean , packageName :: PackageName + , sourceFiles :: Array String } @@ -70,8 +75,11 @@ run' cfg = do liftEffect do log "Building the search index..." - docsJsons <- decodeDocsJsons cfg - packageMetas <- decodeBowerJsons cfg + docsJsons /\ moduleNames /\ packageMetas <- sequential $ + (\d h m -> d /\ h /\ m) + <$> parallel (decodeDocsJsons cfg) + <*> parallel (parseModuleHeaders cfg.sourceFiles) + <*> parallel (decodeBowerJsons cfg) let countOfPackages = Array.length packageMetas countOfModules = Array.length docsJsons @@ -88,14 +96,14 @@ run' cfg = do index = mkDeclarations scores docsJsons typeIndex = mkTypeIndex scores docsJsons packageInfo = mkPackageInfo scores packageMetas - moduleIndex = mkPackedModuleIndex index + moduleIndex = mkPackedModuleIndex index moduleNames meta = { localPackageName: cfg.packageName } createDirectories cfg void $ sequential do ignore <$> parallel (writeIndex cfg index) - <*> parallel (writeTypeIndex cfg typeIndex) + <*> parallel (writeTypeIndex typeIndex) <*> parallel (writePackageInfo packageInfo) <*> parallel (writeModuleIndex moduleIndex) <*> parallel (writeMeta meta) @@ -175,6 +183,28 @@ decodeDocsJsons cfg@{ docsFiles } = do pure docsJsons +-- | This function accepts an array of globs pointing to project sources +-- | and returns a list of module names extracted from these files. +-- | Unfortunately, we can't get all module names from `docs.json`s, because +-- | reexport-only modules do not have a single declaration in them, so we can't +-- | count them normally in `mkPackedModuleIndex.extract`, where we only look at +-- | exported declarations. +parseModuleHeaders :: Array String -> Aff (Array ModuleName) +parseModuleHeaders globs = do + files <- getPathsByGlobs globs + + -- we are not checking if the globs match at least one file, because + -- we want to support scenarios where there is no "current project" + + concat <$> for files \filePath -> do + fileContents <- readTextFile UTF8 filePath + case parseModuleName fileContents of + Nothing -> do + liftEffect $ log $ + "Module header decoding failed for " <> filePath <> + ", unable to extract module name" + pure [] + Just res -> pure [res] decodeBowerJsons :: forall rest @@ -209,8 +239,8 @@ decodeBowerJsons { bowerFiles } = do -- | Write type index parts to files. -writeTypeIndex :: Config -> TypeIndex -> Aff Unit -writeTypeIndex { generatedDocs } typeIndex = +writeTypeIndex :: TypeIndex -> Aff Unit +writeTypeIndex typeIndex = for_ entries \(Tuple typeShape results) -> do writeTextFile UTF8 (unwrap Config.typeIndexDirectory <> "/" <> typeShape <> ".js") (mkHeader typeShape <> stringify (encodeJson results)) @@ -264,7 +294,7 @@ getIndex (Declarations trie) = Trie.query prefix trie else -- Entries with path lengths > 1 have been added already. - List.filter (\(Tuple path value) -> List.length path == 1) ( + List.filter (\(Tuple path _value) -> List.length path == 1) ( Trie.query prefix trie ) in @@ -369,7 +399,7 @@ copyAppFile { generatedDocs } = do directoryExists :: String -> Aff Boolean directoryExists path = do - doesExist <- exists path + doesExist <- liftEffect $ exists path case doesExist of false -> pure false true -> isDirectory <$> stat path @@ -377,7 +407,7 @@ directoryExists path = do fileExists :: String -> Aff Boolean fileExists path = do - doesExist <- exists path + doesExist <- liftEffect $ exists path case doesExist of false -> pure false true -> isFile <$> stat path diff --git a/src/Docs/Search/Interactive.purs b/src/Docs/Search/Interactive.purs index 3616b24..892ca0d 100644 --- a/src/Docs/Search/Interactive.purs +++ b/src/Docs/Search/Interactive.purs @@ -6,6 +6,7 @@ import Docs.Search.DocsJson (DataDeclType(..)) import Docs.Search.Engine (mkEngineState, packageInfoToString, Result(..)) import Docs.Search.Engine as Engine import Docs.Search.Extra (stringToList, (>#>)) +import Docs.Search.IndexBuilder (parseModuleHeaders) import Docs.Search.IndexBuilder as IndexBuilder import Docs.Search.ModuleIndex (ModuleResult, mkPackedModuleIndex, unpackModuleIndex) import Docs.Search.NodeEngine (nodeEngine) @@ -19,7 +20,8 @@ import Docs.Search.TypePrinter (keyword, showConstraint, showFunDeps, showType, import Docs.Search.Types (ModuleName, PackageName, PackageInfo, Identifier) import Prelude -import Prim hiding (Type, Constraint) + +import Control.Parallel (parallel, sequential) import Data.Array as Array import Data.Identity (Identity(..)) import Data.List as List @@ -28,17 +30,20 @@ import Data.Newtype (un, unwrap, wrap) import Data.Search.Trie as Trie import Data.String (length) as String import Data.String.Common (split, toLower, trim) as String +import Data.Tuple.Nested ((/\)) import Effect (Effect) import Effect.Aff (launchAff_) import Effect.Class (liftEffect) import Effect.Console (log, clear) as Console import Node.ReadLine (createConsoleInterface, question) +import Prim hiding (Type, Constraint) type Config = { docsFiles :: Array String , bowerFiles :: Array String , packageName :: PackageName + , sourceFiles :: Array String } @@ -48,14 +53,17 @@ run cfg = launchAff_ $ do liftEffect do Console.log "Loading search index..." - docsJsons <- IndexBuilder.decodeDocsJsons cfg - packageMetas <- IndexBuilder.decodeBowerJsons cfg + docsJsons /\ moduleNames /\ packageMetas <- sequential $ + (\d h m -> d /\ h /\ m) + <$> parallel (IndexBuilder.decodeDocsJsons cfg) + <*> parallel (parseModuleHeaders cfg.sourceFiles) + <*> parallel (IndexBuilder.decodeBowerJsons cfg) let scores = mkScores packageMetas index = mkDeclarations scores docsJsons typeIndex = docsJsons >>= resultsWithTypes scores packageIndex = mkPackageIndex $ mkPackageInfo scores packageMetas - moduleIndex = unpackModuleIndex $ mkPackedModuleIndex index + moduleIndex = unpackModuleIndex $ mkPackedModuleIndex index moduleNames engineState = mkEngineState (unwrap index) typeIndex packageIndex moduleIndex scores let countOfDefinitions = Trie.size $ unwrap index diff --git a/src/Docs/Search/Loader.js b/src/Docs/Search/Loader.js index 0dfd479..83dcb57 100644 --- a/src/Docs/Search/Loader.js +++ b/src/Docs/Search/Loader.js @@ -1,6 +1,6 @@ /* global exports */ -exports.loadFromScript = function (globalIdentifier) { +export function loadFromScript (globalIdentifier) { return function (url) { return function () { return new Promise(function (resolve, reject) { diff --git a/src/Docs/Search/Main.purs b/src/Docs/Search/Main.purs index 44cbc67..a6cced4 100644 --- a/src/Docs/Search/Main.purs +++ b/src/Docs/Search/Main.purs @@ -1,19 +1,19 @@ -- | The main module of the CLI interface app. module Docs.Search.Main where -import Prelude - +import Docs.Search.Config as Config import Docs.Search.IndexBuilder as IndexBuilder import Docs.Search.Interactive as Interactive -import Docs.Search.Config as Config import Docs.Search.Types (PackageName(..)) +import Prelude + import Data.Generic.Rep (class Generic) -import Data.Show.Generic (genericShow) import Data.List as List import Data.List.NonEmpty as NonEmpty import Data.Maybe (Maybe, fromMaybe, optional) import Data.Newtype (unwrap) +import Data.Show.Generic (genericShow) import Data.Unfoldable (class Unfoldable) import Effect (Effect) import Effect.Console (log) @@ -28,6 +28,7 @@ main = do let defaultCommands = Search { docsFiles: defaultDocsFiles , bowerFiles: defaultBowerFiles , packageName: Config.defaultPackageName + , sourceFiles: defaultSourceFiles } case fromMaybe defaultCommands args of @@ -35,7 +36,6 @@ main = do Search cfg -> Interactive.run cfg Version -> log Config.version - getArgs :: Effect (Maybe Commands) getArgs = execParser opts where @@ -45,19 +45,16 @@ getArgs = execParser opts <> progDesc "Search frontend for the documentation generated by the PureScript compiler." ) - data Commands = BuildIndex IndexBuilder.Config | Search Interactive.Config | Version - derive instance genericCommands :: Generic Commands _ instance showCommands :: Show Commands where show = genericShow - commands :: Parser (Maybe Commands) commands = optional $ subparser ( command "build-index" @@ -80,39 +77,30 @@ commands = optional $ subparser buildIndex :: Parser Commands buildIndex = ado - docsFiles <- docsFilesOption - bowerFiles <- bowerFilesOption - packageName <- packageNameOption - + sourceFiles <- sourceFilesOption generatedDocs <- strOption ( long "generated-docs" <> metavar "DIR" <> value "./generated-docs/" + <> help "Path to the generated documentation HTML that will be patched. Search app will be injected into each HTML document." ) - noPatch <- flag false true ( long "no-patch" <> help "Do not patch the HTML docs, only build indices" ) - - - in BuildIndex { docsFiles, bowerFiles, generatedDocs, noPatch, packageName } + in BuildIndex { docsFiles, bowerFiles, generatedDocs, noPatch, packageName, sourceFiles } startInteractive :: Parser Commands startInteractive = ado - docsFiles <- docsFilesOption - bowerFiles <- bowerFilesOption - packageName <- packageNameOption - - in Search { docsFiles, bowerFiles, packageName } - + sourceFiles <- sourceFilesOption + in Search { docsFiles, bowerFiles, packageName, sourceFiles } docsFilesOption :: Parser (Array String) docsFilesOption = fromMaybe defaultDocsFiles <$> @@ -121,11 +109,11 @@ docsFilesOption = fromMaybe defaultDocsFiles <$> ( strOption ( long "docs-files" <> metavar "GLOB" + <> help "Glob that captures `docs.json` files that should be used to build the index" ) ) ) - bowerFilesOption :: Parser (Array String) bowerFilesOption = fromMaybe defaultBowerFiles <$> optional @@ -133,31 +121,43 @@ bowerFilesOption = fromMaybe defaultBowerFiles <$> ( strOption ( long "bower-jsons" <> metavar "GLOB" + <> help "Glob that captures `bower.json` files. These files are used to build dependency trees to compute package popularity scores based on how many dependants a package has." ) ) ) - packageNameOption :: Parser PackageName packageNameOption = PackageName <$> strOption ( long "package-name" <> metavar "PACKAGE" <> value (unwrap Config.defaultPackageName) + <> help "Local package name as it should appear in the search results" ) +sourceFilesOption :: Parser (Array String) +sourceFilesOption = fromMaybe defaultSourceFiles <$> + optional + ( some + ( strOption + ( long "source-files" + <> metavar "GLOB" + <> help "Path to project source files, used for more precise module indexing (see #62). Default: src/**/*.purs" + ) + ) + ) defaultDocsFiles :: Array String defaultDocsFiles = [ "output/**/docs.json" ] - defaultBowerFiles :: Array String defaultBowerFiles = [ ".spago/*/*/bower.json", "bower_components/purescript-*/bower.json" ] +defaultSourceFiles :: Array String +defaultSourceFiles = [ "src/**/*.purs" ] many :: forall a f. Unfoldable f => Parser a -> Parser (f a) many x = CA.many x <#> List.toUnfoldable - some :: forall a f. Unfoldable f => Parser a -> Parser (f a) some x = CA.some x <#> NonEmpty.toUnfoldable diff --git a/src/Docs/Search/ModuleIndex.js b/src/Docs/Search/ModuleIndex.js index fd74abc..65d31c4 100644 --- a/src/Docs/Search/ModuleIndex.js +++ b/src/Docs/Search/ModuleIndex.js @@ -1,6 +1,6 @@ /* global exports */ -exports.load = function (url) { +export function load (url) { return function () { return new Promise(function (resolve, reject) { if (typeof window.DocsSearchModuleIndex === 'undefined') { diff --git a/src/Docs/Search/ModuleIndex.purs b/src/Docs/Search/ModuleIndex.purs index f9913c4..157df8d 100644 --- a/src/Docs/Search/ModuleIndex.purs +++ b/src/Docs/Search/ModuleIndex.purs @@ -2,10 +2,10 @@ module Docs.Search.ModuleIndex where import Docs.Search.Config as Config import Docs.Search.Declarations (Declarations(..)) -import Docs.Search.SearchResult (SearchResult(..)) -import Docs.Search.Types (ModuleName, PackageInfo, PackageScore) import Docs.Search.Extra (stringToList) import Docs.Search.Score (Scores, getPackageScore) +import Docs.Search.SearchResult (SearchResult(..)) +import Docs.Search.Types (ModuleName, PackageInfo(..), PackageScore) import Prelude @@ -21,7 +21,7 @@ import Data.Lens.Record (prop) import Data.List (List, (:)) import Data.Map (Map) import Data.Map as Map -import Data.Maybe (fromMaybe) +import Data.Maybe (Maybe(..), fromMaybe) import Data.Newtype (unwrap) import Data.Search.Trie (Trie) import Data.Search.Trie as Trie @@ -30,12 +30,11 @@ import Data.Set as Set import Data.String.CodeUnits (toCharArray) as String import Data.String.Common (split, toLower) as String import Data.String.Pattern (Pattern(..)) -import Data.Symbol (SProxy(..)) import Data.Traversable (foldr, for_) import Data.Tuple.Nested ((/\)) import Effect (Effect) import Effect.Aff (Aff) - +import Type.Proxy (Proxy(..)) -- | Module index that is actually stored in a JS file. type PackedModuleIndex = Map PackageInfo (Set ModuleName) @@ -92,10 +91,15 @@ queryModuleIndex scores { index, modulePackages } query = -- | Constructs a mapping from packages to modules -mkPackedModuleIndex :: Declarations -> PackedModuleIndex -mkPackedModuleIndex (Declarations trie) = +mkPackedModuleIndex :: Declarations -> Array ModuleName -> PackedModuleIndex +mkPackedModuleIndex (Declarations trie) moduleNames = + addLocalPackageModuleNames $ foldr (Map.unionWith Set.union) Map.empty $ extract <$> Trie.values trie where + -- Add modules from src/ that may not contain any definitions, only + -- re-exports + addLocalPackageModuleNames = flip Map.alter LocalPackage $ + Just <<< append (Set.fromFoldable moduleNames) <<< fromMaybe Set.empty extract :: List SearchResult -> Map PackageInfo (Set ModuleName) @@ -116,7 +120,7 @@ foreign import load _modulePackages :: forall a b rest. (a -> b) -> { modulePackages :: a | rest } -> { modulePackages :: b | rest } -_modulePackages = prop (SProxy :: SProxy "modulePackages") +_modulePackages = prop (Proxy :: Proxy "modulePackages") _index :: forall a b rest. (a -> b) -> { index :: a | rest } -> { index :: b | rest } -_index = prop (SProxy :: SProxy "index") +_index = prop (Proxy :: Proxy "index") diff --git a/src/Docs/Search/ModuleParser.purs b/src/Docs/Search/ModuleParser.purs new file mode 100644 index 0000000..0f9e275 --- /dev/null +++ b/src/Docs/Search/ModuleParser.purs @@ -0,0 +1,50 @@ +module Docs.Search.ModuleParser where + +import Prelude + +import Control.Alt ((<|>)) +import Data.Either (hush) +import Data.Foldable (intercalate) +import Data.Maybe (Maybe) +import Data.Newtype (wrap) +import Docs.Search.Types (ModuleName) +import Effect (Effect) +import StringParser (Parser, char, choice, fix, many, manyTill, noneOf, regex, runParser, sepBy, sepBy1, string, try, whiteSpace) + +parseModuleName :: String -> Maybe ModuleName +parseModuleName = map wrap <<< hush <<< runParser do + void $ many whiteSpaceOrComment + moduleHeader + +whiteSpaceOrComment :: Parser Unit +whiteSpaceOrComment = + choice + [ try $ multiLineComment + , try $ singleLineComment + , try $ void whiteSpace + ] + +multiLineComment :: Parser Unit +multiLineComment = do + void $ string "{-" + void $ manyTill (void $ noneOf []) (string "-}") + +singleLineComment :: Parser Unit +singleLineComment = do + void $ string "--" + void $ manyTill (void $ noneOf ['\n']) (char '\n') + +moduleHeader :: Parser String +moduleHeader = do + void $ string "module" + void $ many whiteSpaceOrComment + moduleName + +moduleName :: Parser String +moduleName = sepBy1 moduleNameWord (string ".") <#> intercalate "." + +moduleNameWord :: Parser String +moduleNameWord = do + first <- regex "[A-Z]" + rest <- regex "[A-Za-z0-9]*" + pure $ first <> rest diff --git a/src/Docs/Search/PackageIndex.purs b/src/Docs/Search/PackageIndex.purs index bac5d3e..28ada7e 100644 --- a/src/Docs/Search/PackageIndex.purs +++ b/src/Docs/Search/PackageIndex.purs @@ -56,7 +56,7 @@ mkPackageInfo packageScores pms = , score: getPackageScoreForPackageName packageScores packageName , dependencies: unwrap dependencies <#> - (_.packageName >>> RawPackageName >>> normalizePackageName) + _.packageName >>> RawPackageName >>> normalizePackageName , repository: repository <#> (_.url) } diff --git a/src/Docs/Search/TypeDecoder.purs b/src/Docs/Search/TypeDecoder.purs index c7444cc..ff49e9b 100644 --- a/src/Docs/Search/TypeDecoder.purs +++ b/src/Docs/Search/TypeDecoder.purs @@ -98,6 +98,8 @@ data Type | TypeOp QualifiedName -- | A type application | TypeApp Type Type + -- | Explicit kind application + | KindApp Type Type -- | Forall quantifier | ForAll String (Maybe Type) Type -- | A type withset of type class constraints @@ -110,10 +112,8 @@ data Type | REmpty -- | A non-empty row | RCons Identifier Type Type - {- -- | A type with a kind annotation - | Kinded Type Kind - -} + | Kinded Type Type -- | Binary operator application. During the rebracketing phase of desugaring, -- this data constructor will be removed. | BinaryNoParensType Type Type Type @@ -139,6 +139,9 @@ instance decodeJsonType :: DecodeJson Type where "TypeApp" -> decodeContents (decodeTuple TypeApp (const err)) (Left err) json where err = mkJsonError' "TypeApp" json + "KindApp" -> + decodeContents (decodeTuple KindApp (const err)) (Left err) json + where err = mkJsonError' "KindApp" json "ForAll" -> decodeContents (decodeTriple @@ -163,6 +166,9 @@ instance decodeJsonType :: DecodeJson Type where "RCons" -> decodeContents (decodeTriple RCons (const err)) (Left err) json where err = mkJsonError' "RCons" json + "KindedType" -> + decodeContents (decodeTuple Kinded (const err)) (Left err) json + where err = mkJsonError' "KindedType" json "BinaryNoParensType" -> decodeContents (decodeTriple BinaryNoParensType (const err)) (Left err) json where err = mkJsonError' "BinaryNoParens" json @@ -180,11 +186,13 @@ instance encodeJsonType :: EncodeJson Type where TypeConstructor val -> tagged "TypeConstructor" (encodeJson val) TypeOp val -> tagged "TypeOp" (encodeJson val) TypeApp t1 t2 -> tagged "TypeApp" (encodeTuple t1 t2) + KindApp t1 t2 -> tagged "KindApp" (encodeTuple t1 t2) ForAll str Nothing ty -> tagged "ForAll" (encodeTriple str ty emptySkolemScope) ForAll str (Just k) ty -> tagged "ForAll" (encodeQuadriple str k ty emptySkolemScope) ConstrainedType c t -> tagged "ConstrainedType" (encodeTuple c t) REmpty -> tagged "REmpty" jsonEmptyObject RCons s t1 t2 -> tagged "RCons" (encodeTriple s t1 t2) + Kinded t1 t2 -> tagged "KindedType" (encodeTuple t1 t2) ParensInType t -> tagged "ParensInType" (encodeJson t) TypeWildcard -> tagged "TypeWildcard" jsonEmptyObject BinaryNoParensType t1 t2 t3 -> diff --git a/src/Docs/Search/TypeIndex.js b/src/Docs/Search/TypeIndex.js index ac97073..291d954 100644 --- a/src/Docs/Search/TypeIndex.js +++ b/src/Docs/Search/TypeIndex.js @@ -1,6 +1,6 @@ /* global exports */ -exports.lookup_ = function (shape) { +export function lookup_ (shape) { return function (url) { return function () { return new Promise(function (resolve, reject) { diff --git a/src/Docs/Search/TypePrinter.purs b/src/Docs/Search/TypePrinter.purs index 6b3cfb5..e48d789 100644 --- a/src/Docs/Search/TypePrinter.purs +++ b/src/Docs/Search/TypePrinter.purs @@ -37,6 +37,9 @@ showType = case _ of TypeApp t1 t2 -> showType t1 <> " " <> showType t2 + KindApp t1 t2 -> + showType t1 <> " " <> showType t2 + ty@(ForAll _ _ _) -> showForAll ty @@ -48,6 +51,8 @@ showType = case _ of ty@REmpty -> showRow true ty ty@(RCons _ _ _) -> showRow true ty + Kinded t1 t2 -> showType t1 <> " :: " <> showType t2 + BinaryNoParensType op t1 t2 -> showType t1 <> space <> diff --git a/src/Docs/Search/TypeQuery.purs b/src/Docs/Search/TypeQuery.purs index a102a1b..8abd935 100644 --- a/src/Docs/Search/TypeQuery.purs +++ b/src/Docs/Search/TypeQuery.purs @@ -34,9 +34,9 @@ import Data.Set as Set import Data.String.CodeUnits (fromCharArray) import Data.String.Common (trim) as String import Data.Tuple (Tuple(..), fst, snd) -import Text.Parsing.StringParser (ParseError, Parser, runParser, try) -import Text.Parsing.StringParser.CodePoints (alphaNum, anyLetter, char, eof, lowerCaseChar, skipSpaces, string, upperCaseChar) -import Text.Parsing.StringParser.Combinators (fix, sepBy, sepBy1, sepEndBy, sepEndBy1) +import StringParser (ParseError, Parser, runParser, try) +import StringParser.CodePoints (alphaNum, anyLetter, char, eof, lowerCaseChar, skipSpaces, string, upperCaseChar) +import StringParser.Combinators (fix, sepBy, sepBy1, sepEndBy, sepEndBy1) -- | We need type queries because we don't have a full-featured type parser @@ -236,13 +236,13 @@ unify query type_ = go Nil (List.singleton { q: query, t: type_ }) -- * Names go acc ({ q: QConst qname, t: TypeConstructor (QualifiedName { name }) } : rest) = go (Match qname name : acc) rest - go acc ({ q: QConst qname, t } : rest) = + go acc ({ q: QConst _, t } : rest) = go (TypeMismatch t : acc) rest - go acc ({ q, t: TypeConstructor (QualifiedName { name }) } : rest) = + go acc ({ q, t: TypeConstructor (QualifiedName _) } : rest) = go (QueryMismatch q : acc) rest -- type operators can't appear in type queries: this is always a mismatch - go acc ({ q, t: TypeOp (QualifiedName { name }) } : rest) = + go acc ({ q, t: TypeOp (QualifiedName _) } : rest) = go (QueryMismatch q : acc) rest go acc ({ q, t: t@(BinaryNoParensType _ _ _) } : rest) = go (Mismatch q t : acc) rest @@ -253,7 +253,7 @@ unify query type_ = go Nil (List.singleton { q: query, t: type_ }) (QualifiedName { moduleNameParts: [ "Prim" ] , name: Identifier "Function" })) t1) t2 } : rest) = go acc ({ q: q1, t: t1 } : { q: q2, t: t2 } : rest) - go acc ({ q: q@(QFun q1 q2), t } : rest) = + go acc ({ q: q@(QFun _ _), t } : rest) = go (Mismatch q t : acc) rest -- * Rows @@ -261,7 +261,7 @@ unify query type_ = go Nil (List.singleton { q: query, t: type_ }) , t: TypeApp (TypeConstructor (QualifiedName { moduleNameParts: [ "Prim" ] , name: Identifier "Record" })) row } : rest) = - let { rows, ty } = joinRows row + let { rows } = joinRows row qRowsLength = List.length qRows rowsLength = List.length rows in if rowsLength == qRowsLength then @@ -297,6 +297,12 @@ unify query type_ = go Nil (List.singleton { q: query, t: type_ }) go acc ({ q, t: REmpty } : rest) = go (QueryMismatch q : acc) rest + go acc ({ q, t: Kinded _ _} : rest) = + go (QueryMismatch q : acc) rest + + go acc ({ t: t@(KindApp _ _) } : rest) = + go (TypeMismatch t : acc) rest + -- | Sum various penalties. penalty :: TypeQuery -> Type -> Int @@ -411,6 +417,7 @@ typeSize = go 0 <<< List.singleton go (n + 1) rest go n (TypeOp _ : rest) = go (n + 1) rest + go n (KindApp t1 t2 : res) = go n (t1 : t2 : res) go n (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: [ "Prim" ] , name: Identifier "Function" })) t1) t2 : rest) = @@ -425,6 +432,8 @@ typeSize = go 0 <<< List.singleton go (n + 1) (t1 : t2 : rest) go n (REmpty : rest) = go (n + 1) rest + go n (Kinded t1 t2 : rest) = + go n (t1 : t2 : rest) go n (BinaryNoParensType op t1 t2 : rest) = go (n + 1) (t1 : t2 : rest) go n (ParensInType t : rest) = diff --git a/src/Docs/Search/TypeShape.js b/src/Docs/Search/TypeShape.js index 19ecd86..5aef111 100644 --- a/src/Docs/Search/TypeShape.js +++ b/src/Docs/Search/TypeShape.js @@ -1,6 +1,6 @@ /* global exports */ -exports.hash = function (string) { +export function hash (string) { var hash = Math.floor(Number.MAX_SAFE_INTEGER / 2); if (string.length == 0) { return hash; diff --git a/src/Docs/Search/TypeShape.purs b/src/Docs/Search/TypeShape.purs index 69df8ec..25e1784 100644 --- a/src/Docs/Search/TypeShape.purs +++ b/src/Docs/Search/TypeShape.purs @@ -115,6 +115,9 @@ shapeOfType ty = List.reverse $ go (pure ty) Nil TypeApp child1 child2 -> go (child1 : child2 : rest) (PApp : acc) + KindApp child1 child2 -> + go (child1 : child2 : rest) (PApp : acc) + forallType@(ForAll _ _ _) -> go (foralls.ty : rest) (PForAll (List.length foralls.binders) : acc) where foralls = joinForAlls forallType @@ -136,6 +139,8 @@ shapeOfType ty = List.reverse $ go (pure ty) Nil sorted = List.sortBy (\x y -> compare x.row y.row) joined.rows typesInRow = sorted <#> (_.ty) + Kinded t1 _t2 -> go (t1 : rest) acc + BinaryNoParensType op l r -> go (TypeApp (TypeApp op l) r : rest) acc diff --git a/src/Docs/Search/Types.purs b/src/Docs/Search/Types.purs index 9172edb..5cfa11e 100644 --- a/src/Docs/Search/Types.purs +++ b/src/Docs/Search/Types.purs @@ -31,6 +31,9 @@ derive newtype instance ordModuleName :: Ord ModuleName derive newtype instance decodeJsonModuleName :: DecodeJson ModuleName derive newtype instance encodeJsonModuleName :: EncodeJson ModuleName +instance Show ModuleName where + show = genericShow + -- | Non-normalized package name, e.g. `purescript-prelude` or just `prelude`. newtype RawPackageName = RawPackageName String @@ -55,14 +58,14 @@ data PackageInfo = LocalPackage | Builtin | Package PackageName | UnknownPackage derive instance eqPackageInfo :: Eq PackageInfo derive instance ordPackageInfo :: Ord PackageInfo derive instance genericPackageInfo :: Generic PackageInfo _ -instance showPackageInfo :: Show PackageInfo where - show = genericShow - instance decodeJsonPackageInfo :: DecodeJson PackageInfo where decodeJson = genericDecodeJson instance encodeJsonPackageInfo :: EncodeJson PackageInfo where encodeJson = genericEncodeJson +instance showPackageInfo :: Show PackageInfo where + show = genericShow + newtype PackageScore = PackageScore Int diff --git a/src/Docs/Search/URIHash.js b/src/Docs/Search/URIHash.js index bc61d56..f0c23d4 100644 --- a/src/Docs/Search/URIHash.js +++ b/src/Docs/Search/URIHash.js @@ -1,7 +1,7 @@ /* global exports history */ // https://stackoverflow.com/questions/1397329 -exports.removeHash = function () { +export function removeHash () { var scrollV, scrollH, loc = window.location; if ("pushState" in history) history.pushState("", document.title, loc.pathname + loc.search); diff --git a/src/Docs/Search/URIHash.purs b/src/Docs/Search/URIHash.purs index 9f65f82..40bdcb5 100644 --- a/src/Docs/Search/URIHash.purs +++ b/src/Docs/Search/URIHash.purs @@ -7,7 +7,7 @@ where import Prelude -import Data.Maybe (Maybe(Just), fromMaybe) +import Data.Maybe (fromMaybe) import Data.String.CodeUnits as String import Effect (Effect) import JSURI (decodeURIComponent, encodeURIComponent) @@ -31,7 +31,7 @@ getInput = do location <- Window.location window hash <- Location.hash location pure $ - if String.slice 0 8 hash == Just "#search:" + if String.slice 0 8 hash == "#search:" then fromMaybe "" $ decodeURIComponent $ String.drop 8 hash diff --git a/test/Main.purs b/test/Main.purs index a2cd0b6..01a01d8 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -2,291 +2,28 @@ module Test.Main where import Prelude -import Data.Argonaut.Core (Json) -import Data.Argonaut.Decode (decodeJson) -import Data.Argonaut.Parser (jsonParser) -import Data.Either (Either(..)) -import Data.Maybe (Maybe(..)) -import Docs.Search.TypeDecoder (Constraint(..), FunDep(..), FunDeps(..), QualifiedName(..), Type(..)) -import Docs.Search.Types (Identifier(..)) import Effect (Effect) -import Partial.Unsafe (unsafePartial) +import Effect.Aff (launchAff_) import Test.Declarations as Declarations -import Test.Extra (assertRight) import Test.IndexBuilder as IndexBuilder import Test.ModuleIndex as ModuleIndex +import Test.ModuleParser as ModuleParser +import Test.Spec (Spec) +import Test.Spec.Reporter.Console (consoleReporter) +import Test.Spec.Runner (runSpec) +import Test.TypeJson as TypeJson import Test.TypeQuery as TypeQuery -import Test.UI as UI -import Test.Unit (TestSuite, suite, test) -import Test.Unit.Main (runTest) main :: Effect Unit main = do - runTest mainTest - UI.main + launchAff_ $ runSpec [consoleReporter] mainTest + -- UI.main -mkJson :: String -> Json -mkJson str = - unsafePartial $ case jsonParser str of - Right r -> r - -mainTest :: TestSuite +mainTest :: Spec Unit mainTest = do + ModuleParser.tests TypeQuery.tests + TypeJson.tests IndexBuilder.tests Declarations.tests ModuleIndex.tests - suite "FunDeps decoder" do - test "FunDeps" do - let - funDeps = mkJson """ - [ - [ - [ - "lhs", - "rhs" - ], - [ - "output" - ] - ] - ] - """ - assertRight (decodeJson funDeps) - (FunDeps [ FunDep { lhs: [ "lhs", "rhs" ] - , rhs: [ "output"] - } - ]) - - suite "Constraint decoder" do - test "Constraint" do - let constraint = mkJson """ - { - "constraintAnn": [], - "constraintClass": [ - [ - "Prim" - ], - "Partial" - ], - "constraintArgs": [], - "constraintData": null - } - """ - assertRight (decodeJson constraint) - (Constraint { constraintClass: qualified ["Prim"] "Partial" - , constraintArgs: [] - }) - - suite "Type decoder" do - test "TypeVar" do - let typeVar = mkJson """ - { - "annotation": [], - "tag": "TypeVar", - "contents": "m" - } - """ - - assertRight (decodeJson typeVar) - (TypeVar "m") - - test "TypeApp" do - let typeApp1 = mkJson """ - { - "annotation": [], - "tag": "TypeApp", - "contents": [ - { - "annotation": [], - "tag": "TypeConstructor", - "contents": [ - [ - "Control", - "Monad", - "ST", - "Internal" - ], - "ST" - ] - }, - { - "annotation": [], - "tag": "TypeVar", - "contents": "h" - } - ] - } - """ - - assertRight (decodeJson typeApp1) $ - TypeApp - (TypeConstructor (qualified [ "Control" - , "Monad" - , "ST" - , "Internal" - ] - "ST" - )) - (TypeVar "h") - - test "TypeOp" do - let typeOp = mkJson """ - { - "annotation": [], - "tag": "TypeOp", - "contents": [ - [ - "Data", - "NaturalTransformation" - ], - "~>" - ] - } - """ - assertRight (decodeJson typeOp) $ - TypeOp $ qualified [ "Data", "NaturalTransformation" ] "~>" - - test "BinaryNoParens" do - let binaryNoParens = mkJson """ - { - "annotation": [], - "tag": "BinaryNoParensType", - "contents": [ - { - "annotation": [], - "tag": "TypeOp", - "contents": [ - [ - "Data", - "NaturalTransformation" - ], - "~>" - ] - }, - { - "annotation": [], - "tag": "TypeVar", - "contents": "m" - }, - { - "annotation": [], - "tag": "TypeVar", - "contents": "n" - } - ] - } - """ - - assertRight (decodeJson binaryNoParens) $ - BinaryNoParensType - (TypeOp $ qualified ["Data", "NaturalTransformation"] "~>") - (TypeVar "m") - (TypeVar "n") - - test "ParensInType" do - let parensInType = mkJson """ - { - "annotation": [], - "tag": "ParensInType", - "contents": { - "annotation": [], - "tag": "TypeApp", - "contents": [ - { - "annotation": [], - "tag": "TypeConstructor", - "contents": [ - [ - "Data", - "Maybe" - ], - "Maybe" - ] - }, - { - "annotation": [], - "tag": "TypeConstructor", - "contents": [ - [ - "Prim" - ], - "String" - ] - } - ] - } - } - """ - - assertRight (decodeJson parensInType) $ - ParensInType $ - TypeApp - (TypeConstructor (qualified [ "Data", "Maybe" ] "Maybe")) - (TypeConstructor (qualified [ "Prim" ] "String")) - test "RCons" do - - let rcons = mkJson """ - { - "annotation": [], - "tag": "RCons", - "contents": [ - "tail", - { - "annotation": [], - "tag": "TypeApp", - "contents": [ - { - "annotation": [], - "tag": "TypeConstructor", - "contents": [ - [ - "Data", - "Symbol" - ], - "SProxy" - ] - }, - { - "annotation": [], - "tag": "TypeVar", - "contents": "t" - } - ] - }, - { - "annotation": [], - "tag": "REmpty" - } - ] - } - """ - - assertRight (decodeJson rcons) $ - RCons - (Identifier "tail") - (TypeApp (TypeConstructor $ qualified [ "Data", "Symbol" ] "SProxy") - (TypeVar "t")) - REmpty - - test "ForAll #1" do - let forallJson = mkJson """ - {"annotation":[],"tag":"ForAll","contents":["a",{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"String"]}]},{"annotation":[],"tag":"TypeVar","contents":"a"}]},null]} - """ - assertRight (decodeJson forallJson) $ - ForAll "a" Nothing (TypeApp (TypeApp (TypeConstructor $ qualified ["Prim"] "Function") - (TypeConstructor $ qualified ["Prim"] "String")) - (TypeVar "a")) - - suite "jsons" do - - test "jsons #1" do - let json = mkJson """ -{"annotation":[],"tag":"ForAll","contents":["o",{"annotation":[],"tag":"ForAll","contents":["r",{"annotation":[],"tag":"ForAll","contents":["l",{"annotation":[],"tag":"ConstrainedType","contents":[{"constraintAnn":[],"constraintClass":[["Type","Data","Boolean"],"And"],"constraintArgs":[{"annotation":[],"tag":"TypeVar","contents":"l"},{"annotation":[],"tag":"TypeVar","contents":"r"},{"annotation":[],"tag":"TypeVar","contents":"o"}],"constraintData":null},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"l"}]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"r"}]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"o"}]}]}]}]},null]},null]},null]} - """ - - assertRight (decodeJson json) $ (ForAll "o" Nothing (ForAll "r" Nothing (ForAll "l" Nothing (ConstrainedType (Constraint { constraintArgs: [(TypeVar "l"),(TypeVar "r"),(TypeVar "o")], constraintClass: (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: Identifier "And" }) }) (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: Identifier "Function" })) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: Identifier "BProxy" })) (TypeVar "l"))) (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: Identifier "Function" })) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: Identifier "BProxy" })) (TypeVar "r"))) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: Identifier "BProxy" })) (TypeVar "o")))))))) - - -qualified :: Array String -> String -> QualifiedName -qualified moduleNameParts name = QualifiedName { moduleNameParts, name: Identifier name } diff --git a/test/Test/Declarations.purs b/test/Test/Declarations.purs index 60ea61d..ec9de37 100644 --- a/test/Test/Declarations.purs +++ b/test/Test/Declarations.purs @@ -7,33 +7,32 @@ import Docs.Search.Types (PackageName(..), PackageInfo(..)) import Data.Maybe (Maybe(..)) import Data.Newtype (wrap) +import Test.Spec (Spec, describe, it) +import Test.Spec.Assertions (shouldEqual) -import Test.Unit (TestSuite, suite, test) -import Test.Unit.Assert as Assert - -tests :: TestSuite +tests :: Spec Unit tests = do - suite "Declarations" do - test "extractPackageName" do - Assert.equal Builtin (extractPackageName (wrap "Prim") Nothing) - Assert.equal Builtin (extractPackageName (wrap "Prim.Foo") Nothing) - Assert.equal Builtin (extractPackageName (wrap "Prim.Foo.Bar") Nothing) - Assert.equal UnknownPackage (extractPackageName (wrap "Primitive") Nothing) - Assert.equal (Package $ PackageName "foo") + describe "Declarations" do + it "extractPackageName works correctly" do + Builtin `shouldEqual` (extractPackageName (wrap "Prim") Nothing) + Builtin `shouldEqual` (extractPackageName (wrap "Prim.Foo") Nothing) + Builtin `shouldEqual` (extractPackageName (wrap "Prim.Foo.Bar") Nothing) + UnknownPackage `shouldEqual` (extractPackageName (wrap "Primitive") Nothing) + Package (PackageName "foo") `shouldEqual` (extractPackageName (wrap "Foo") $ Just { start: [] , end: [] , name: ".spago/foo/src/Foo.purs" } ) - Assert.equal (Package $ PackageName "bar") + Package (PackageName "bar") `shouldEqual` (extractPackageName (wrap "Bar") $ Just { start: [] , end: [] , name: "/path/to/somewhere/bower_components/bar/src/Bar.purs" } ) - Assert.equal LocalPackage + LocalPackage `shouldEqual` (extractPackageName (wrap "Bar") $ Just { start: [] , end: [] diff --git a/test/Test/Extra.purs b/test/Test/Extra.purs index 8f0d56f..ae85744 100644 --- a/test/Test/Extra.purs +++ b/test/Test/Extra.purs @@ -4,7 +4,8 @@ import Prelude import Data.Either (Either(..)) import Effect.Aff (Aff) -import Test.Unit.Assert as Assert +import Test.Spec.Assertions (shouldEqual) + assertRight :: forall a b @@ -17,7 +18,7 @@ assertRight -> Aff Unit assertRight eiActual expected = case eiActual of - Left string -> do - Assert.equal (Right expected) eiActual - Right actual -> do - Assert.equal (Right expected) eiActual + Left _ -> do + Right expected `shouldEqual` eiActual + Right _ -> do + Right expected `shouldEqual` eiActual diff --git a/test/Test/IndexBuilder.purs b/test/Test/IndexBuilder.purs index 9c48caf..1215680 100644 --- a/test/Test/IndexBuilder.purs +++ b/test/Test/IndexBuilder.purs @@ -5,16 +5,16 @@ import Prelude import Docs.Search.IndexBuilder (patchHTML) import Data.Tuple (snd) -import Test.Unit (TestSuite, suite, test) -import Test.Unit.Assert as Assert +import Test.Spec (Spec, describe, it) +import Test.Spec.Assertions (shouldEqual, shouldNotSatisfy) -tests :: TestSuite +tests :: Spec Unit tests = do - suite "IndexBuilder" do - suite "patchHTML" do - test "works" do + describe "IndexBuilder" do + describe "patchHTML" do + it "works" do let input = "" - Assert.assertFalse "patchHTML works" (snd (patchHTML input) == input) - test "is idempotent" do + shouldNotSatisfy (snd (patchHTML input)) (eq input) + it "is idempotent" do let input = "" - Assert.equal (snd $ patchHTML $ snd $ patchHTML input) (snd $ patchHTML input) + shouldEqual (snd $ patchHTML $ snd $ patchHTML input) (snd $ patchHTML input) diff --git a/test/Test/ModuleIndex.purs b/test/Test/ModuleIndex.purs index df4a59d..34cb690 100644 --- a/test/Test/ModuleIndex.purs +++ b/test/Test/ModuleIndex.purs @@ -6,20 +6,18 @@ import Prelude import Data.List as List import Data.Newtype (wrap) -import Test.Unit (TestSuite, suite, test) -import Test.Unit.Assert as Assert +import Test.Spec (Spec, describe, it) +import Test.Spec.Assertions (shouldEqual) -tests :: TestSuite +tests :: Spec Unit tests = do - suite "ModuleIndex" do + describe "ModuleIndex" do - test "test #0" do - Assert.equal (extractModuleNameParts $ wrap "Data.Array.ST") ( + it "test #0" do + extractModuleNameParts (wrap "Data.Array.ST") `shouldEqual` List.fromFoldable [ "st", "array.st", "data.array.st" ] - ) - test "test #1" do - Assert.equal (extractModuleNameParts $ wrap "Foo") ( + it "test #1" do + extractModuleNameParts (wrap "Foo") `shouldEqual` List.fromFoldable [ "foo" ] - ) diff --git a/test/Test/ModuleParser.purs b/test/Test/ModuleParser.purs new file mode 100644 index 0000000..6a14405 --- /dev/null +++ b/test/Test/ModuleParser.purs @@ -0,0 +1,61 @@ +module Test.ModuleParser where + +import Docs.Search.IndexBuilder (getPathsByGlobs) +import Docs.Search.ModuleParser (multiLineComment, parseModuleName, singleLineComment) +import Docs.Search.Types (ModuleName(..)) + +import Prelude + +import Data.Array as Array +import Data.Either (Either(..)) +import Data.Foldable (for_) +import Data.Maybe (Maybe(..)) +import Effect.Class (liftEffect) +import Effect.Console as Console +import Effect.Exception (throw) +import Node.Encoding (Encoding(..)) +import Node.FS.Aff (readTextFile) +import StringParser (runParser) +import Test.Spec (Spec, describe, it) +import Test.Spec.Assertions (shouldEqual) + +tests :: Spec Unit +tests = do + describe "ModuleParser" do + it "test #0" do + parseModuleName "module Foo" `shouldEqual` Just (ModuleName "Foo") + it "test #1" do + parseModuleName "module Foo.Bar.B" `shouldEqual` Just (ModuleName "Foo.Bar.B") + it "test #2" do + parseModuleName " module Foo" `shouldEqual` Just (ModuleName "Foo") + it "test #3" do + parseModuleName " {- asdas -} module Foo" `shouldEqual` Just (ModuleName "Foo") + it "test #4" do + parseModuleName "{--}module Foo" `shouldEqual` Just (ModuleName "Foo") + it "test #5" do + parseModuleName "--\nmodule Foo" `shouldEqual` Just (ModuleName "Foo") + it "test #6" do + parseModuleName "--\n-- foo\nmodule Foo" `shouldEqual` Just (ModuleName "Foo") + it "test #7" do + parseModuleName "-- \n -- foo\n {- bar -} --baz\n module Foo" `shouldEqual` Just (ModuleName "Foo") + it "multiline comment #1" do + runParser multiLineComment "{--}" `shouldEqual` Right unit + it "multiline comment #1" do + runParser multiLineComment "{- foo -}" `shouldEqual` Right unit + it "multiline comment #1" do + runParser multiLineComment "{- foo\nbar\nbar\n -}" `shouldEqual` Right unit + it "single line comment #1" do + runParser singleLineComment "-- asd\n" `shouldEqual` Right unit + it "single line comment #1" do + runParser singleLineComment "--\n" `shouldEqual` Right unit + it "Parses every module in .spago/" do + files <- getPathsByGlobs ["./.spago/**/*.purs"] + liftEffect $ Console.log $ "Modules in .spago: " <> show (Array.length files) + for_ files \filePath -> do + fileContents <- readTextFile UTF8 filePath + case parseModuleName fileContents of + Nothing -> do + liftEffect $ throw $ + "Module header decoding failed for " <> filePath <> + ", unable to extract module name" + Just _ -> pure unit diff --git a/test/Test/TypeJson.purs b/test/Test/TypeJson.purs new file mode 100644 index 0000000..98df2a2 --- /dev/null +++ b/test/Test/TypeJson.purs @@ -0,0 +1,300 @@ +module Test.TypeJson + ( tests ) +where + +import Prelude + +import Docs.Search.TypeDecoder (Constraint(..), FunDep(..), FunDeps(..), QualifiedName(..), Type(..)) +import Docs.Search.Types (Identifier(..)) +import Test.Extra (assertRight) +import Test.TypeQuery as TypeQuery + +import Data.Argonaut.Core (Json) +import Data.Argonaut.Decode (decodeJson) +import Data.Argonaut.Parser (jsonParser) +import Data.Either (Either(..)) +import Data.Maybe (Maybe(..)) +import Partial.Unsafe (unsafePartial) +import Test.Spec (Spec, describe, it) + + +tests :: Spec Unit +tests = do + describe "FunDeps decoder" do + it "FunDeps" do + let + funDeps = mkJson """ + [ + [ + [ + "lhs", + "rhs" + ], + [ + "output" + ] + ] + ] + """ + assertRight (decodeJson funDeps) + (FunDeps [ FunDep { lhs: [ "lhs", "rhs" ] + , rhs: [ "output"] + } + ]) + + describe "Constraint decoder" do + it "Constraint" do + let constraint = mkJson """ + { + "constraintAnn": [], + "constraintClass": [ + [ + "Prim" + ], + "Partial" + ], + "constraintArgs": [], + "constraintData": null + } + """ + assertRight (decodeJson constraint) + (Constraint { constraintClass: qualified ["Prim"] "Partial" + , constraintArgs: [] + }) + + describe "Type decoder" do + it "TypeVar" do + let typeVar = mkJson """ + { + "annotation": [], + "tag": "TypeVar", + "contents": "m" + } + """ + + assertRight (decodeJson typeVar) + (TypeVar "m") + + it "TypeApp" do + let typeApp1 = mkJson """ + { + "annotation": [], + "tag": "TypeApp", + "contents": [ + { + "annotation": [], + "tag": "TypeConstructor", + "contents": [ + [ + "Control", + "Monad", + "ST", + "Internal" + ], + "ST" + ] + }, + { + "annotation": [], + "tag": "TypeVar", + "contents": "h" + } + ] + } + """ + + assertRight (decodeJson typeApp1) $ + TypeApp + (TypeConstructor (qualified [ "Control" + , "Monad" + , "ST" + , "Internal" + ] + "ST" + )) + (TypeVar "h") + + it "TypeOp" do + let typeOp = mkJson """ + { + "annotation": [], + "tag": "TypeOp", + "contents": [ + [ + "Data", + "NaturalTransformation" + ], + "~>" + ] + } + """ + assertRight (decodeJson typeOp) $ + TypeOp $ qualified [ "Data", "NaturalTransformation" ] "~>" + + it "BinaryNoParens" do + let binaryNoParens = mkJson """ + { + "annotation": [], + "tag": "BinaryNoParensType", + "contents": [ + { + "annotation": [], + "tag": "TypeOp", + "contents": [ + [ + "Data", + "NaturalTransformation" + ], + "~>" + ] + }, + { + "annotation": [], + "tag": "TypeVar", + "contents": "m" + }, + { + "annotation": [], + "tag": "TypeVar", + "contents": "n" + } + ] + } + """ + + assertRight (decodeJson binaryNoParens) $ + BinaryNoParensType + (TypeOp $ qualified ["Data", "NaturalTransformation"] "~>") + (TypeVar "m") + (TypeVar "n") + + it "ParensInType" do + let parensInType = mkJson """ + { + "annotation": [], + "tag": "ParensInType", + "contents": { + "annotation": [], + "tag": "TypeApp", + "contents": [ + { + "annotation": [], + "tag": "TypeConstructor", + "contents": [ + [ + "Data", + "Maybe" + ], + "Maybe" + ] + }, + { + "annotation": [], + "tag": "TypeConstructor", + "contents": [ + [ + "Prim" + ], + "String" + ] + } + ] + } + } + """ + + assertRight (decodeJson parensInType) $ + ParensInType $ + TypeApp + (TypeConstructor (qualified [ "Data", "Maybe" ] "Maybe")) + (TypeConstructor (qualified [ "Prim" ] "String")) + it "RCons" do + + let rcons = mkJson """ + { + "annotation": [], + "tag": "RCons", + "contents": [ + "tail", + { + "annotation": [], + "tag": "TypeApp", + "contents": [ + { + "annotation": [], + "tag": "TypeConstructor", + "contents": [ + [ + "Data", + "Symbol" + ], + "SProxy" + ] + }, + { + "annotation": [], + "tag": "TypeVar", + "contents": "t" + } + ] + }, + { + "annotation": [], + "tag": "REmpty" + } + ] + } + """ + + assertRight (decodeJson rcons) $ + RCons + (Identifier "tail") + (TypeApp (TypeConstructor $ qualified [ "Data", "Symbol" ] "SProxy") + (TypeVar "t")) + REmpty + + it "ForAll #1" do + let forallJson = mkJson """ + {"annotation":[],"tag":"ForAll","contents":["a",{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"String"]}]},{"annotation":[],"tag":"TypeVar","contents":"a"}]},null]} + """ + assertRight (decodeJson forallJson) $ + ForAll "a" Nothing (TypeApp (TypeApp (TypeConstructor $ qualified ["Prim"] "Function") + (TypeConstructor $ qualified ["Prim"] "String")) + (TypeVar "a")) + + it "KindApp" do + let kindAppJson = mkJson """ + {"annotation":[],"tag":"KindApp","contents":[{"annotation":[],"tag":"REmpty"},{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Type"]}]} + """ + assertRight (decodeJson kindAppJson) $ + KindApp REmpty (TypeConstructor (qualified ["Prim"] "Type")) + it "KindedType" do + let kindedTypeJson = mkJson """ + {"annotation":[],"tag":"KindedType","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Data","Const"],"Const"]},{"annotation":[],"tag":"TypeConstructor","contents":[["Data","Void"],"Void"]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Type"]}]},{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Type"]}]}]} + """ + assertRight (decodeJson kindedTypeJson) $ + Kinded + (TypeApp + (TypeConstructor (qualified ["Data","Const"] "Const")) + (TypeConstructor (qualified ["Data","Void"] "Void"))) + (TypeApp (TypeApp + (TypeConstructor (qualified ["Prim"] "Function")) + (TypeConstructor (qualified ["Prim"] "Type" ))) + (TypeConstructor (qualified ["Prim"] "Type"))) + describe "jsons" do + + it "jsons #1" do + let json = mkJson """ +{"annotation":[],"tag":"ForAll","contents":["o",{"annotation":[],"tag":"ForAll","contents":["r",{"annotation":[],"tag":"ForAll","contents":["l",{"annotation":[],"tag":"ConstrainedType","contents":[{"constraintAnn":[],"constraintClass":[["Type","Data","Boolean"],"And"],"constraintArgs":[{"annotation":[],"tag":"TypeVar","contents":"l"},{"annotation":[],"tag":"TypeVar","contents":"r"},{"annotation":[],"tag":"TypeVar","contents":"o"}],"constraintData":null},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"l"}]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"r"}]}]},{"annotation":[],"tag":"TypeApp","contents":[{"annotation":[],"tag":"TypeConstructor","contents":[["Type","Data","Boolean"],"BProxy"]},{"annotation":[],"tag":"TypeVar","contents":"o"}]}]}]}]},null]},null]},null]} + """ + + assertRight (decodeJson json) $ (ForAll "o" Nothing (ForAll "r" Nothing (ForAll "l" Nothing (ConstrainedType (Constraint { constraintArgs: [(TypeVar "l"),(TypeVar "r"),(TypeVar "o")], constraintClass: (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: Identifier "And" }) }) (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: Identifier "Function" })) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: Identifier "BProxy" })) (TypeVar "l"))) (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: Identifier "Function" })) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: Identifier "BProxy" })) (TypeVar "r"))) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Type","Data","Boolean"], name: Identifier "BProxy" })) (TypeVar "o")))))))) + + +qualified :: Array String -> String -> QualifiedName +qualified = TypeQuery.qname + +mkJson :: String -> Json +mkJson str = + unsafePartial $ case jsonParser str of + Right r -> r diff --git a/test/Test/TypeQuery.purs b/test/Test/TypeQuery.purs index 029ca7c..19cdf4d 100644 --- a/test/Test/TypeQuery.purs +++ b/test/Test/TypeQuery.purs @@ -15,384 +15,535 @@ import Data.List.NonEmpty as NonEmptyList import Data.Set as Set import Data.Tuple (Tuple(..)) import Test.Extra (assertRight) -import Test.Unit (TestSuite, suite, test) -import Test.Unit.Assert as Assert +import Test.Spec (Spec, describe, it) +import Test.Spec.Assertions (shouldEqual, shouldSatisfy) import Data.Maybe (Maybe(..)) - -tests :: TestSuite +tests :: Spec Unit tests = do - suite "TypeQuery parser" do + describe "TypeQuery parser" do - test "test #0" do + it "test #0" do let input = "a" assertRight (parseTypeQuery input) (qVar "a") - test "test #1" do + it "test #1" do let input = "ab" assertRight (parseTypeQuery input) (qVar "ab") - test "test #2" do + it "test #2" do let input = "a b" assertRight (parseTypeQuery input) (QApp (qVar "a") (qVar "b")) - test "test #3" do + it "test #3" do let input = "a b c" assertRight (parseTypeQuery input) (QApp (QApp (qVar "a") (qVar "b")) (qVar "c")) - test "test #4" do + it "test #4" do let input = "a -> b" assertRight (parseTypeQuery input) (QFun (qVar "a") (qVar "b")) - test "test #5" do + it "test #5" do let input = "a -> b c" assertRight (parseTypeQuery input) (QFun (qVar "a") (QApp (qVar "b") (qVar "c"))) - test "test #6" do + it "test #6" do let input = "a b -> c" assertRight (parseTypeQuery input) (QFun (QApp (qVar "a") (qVar "b")) (qVar "c")) - test "test #7" do + it "test #7" do let input = "a b" assertRight (parseTypeQuery input) (QApp (qVar "a") (qVar "b")) - test "test #8" do + it "test #8" do let input = "a (b c)" assertRight (parseTypeQuery input) (QApp (qVar "a") (QApp (qVar "b") (qVar "c"))) - test "test #9" do + it "test #9" do let input = "(a b) (c d)" assertRight (parseTypeQuery input) - (QApp (QApp (qVar "a") (qVar "b")) - (QApp (qVar "c") (qVar "d"))) + ( QApp (QApp (qVar "a") (qVar "b")) + (QApp (qVar "c") (qVar "d")) + ) - test "test #10" do + it "test #10" do let input = "a ( b c )" assertRight (parseTypeQuery input) (QApp (qVar "a") (QApp (qVar "b") (qVar "c"))) - test "test #11" do + it "test #11" do let input = "aaa" assertRight (parseTypeQuery input) (qVar "aaa") - test "test #12" do + it "test #12" do let input = "aaa ( bbb ccc )" assertRight (parseTypeQuery input) (QApp (qVar "aaa") (QApp (qVar "bbb") (qVar "ccc"))) - test "test #13" do + it "test #13" do let input = "(a -> b) -> (c -> d)" - assertRight (parseTypeQuery input) (QFun (QFun (qVar "a") (qVar "b")) - (QFun (qVar "c") (qVar "d"))) + assertRight (parseTypeQuery input) + ( QFun (QFun (qVar "a") (qVar "b")) + (QFun (qVar "c") (qVar "d")) + ) - test "test #14" do + it "test #14" do let input = "a -> b -> c -> d" - assertRight (parseTypeQuery input) (QFun (qVar "a") - (QFun (qVar "b") - (QFun (qVar "c") (qVar "d")))) + assertRight (parseTypeQuery input) + ( QFun (qVar "a") + ( QFun (qVar "b") + (QFun (qVar "c") (qVar "d")) + ) + ) - test "test #15" do + it "test #15" do let input = "a -> b -> c" - assertRight (parseTypeQuery input) (QFun (qVar "a") - (QFun (qVar "b") - (qVar "c"))) + assertRight (parseTypeQuery input) + ( QFun (qVar "a") + ( QFun (qVar "b") + (qVar "c") + ) + ) - test "test #16" do + it "test #16" do let input = "forall a b c. c" - assertRight (parseTypeQuery input) (QForAll (nl "a" ["b", "c"]) (qVar "c")) + assertRight (parseTypeQuery input) (QForAll (nl "a" [ "b", "c" ]) (qVar "c")) - test "test #17" do + it "test #17" do let input = "forall a. Maybe a" assertRight (parseTypeQuery input) (QForAll (nl "a" $ []) (QApp (qConst "Maybe") (qVar "a"))) - test "test #18" do + it "test #18" do let input = "forall m a. Monad m => a -> m a" assertRight (parseTypeQuery input) - (QForAll (nl "m" ["a"]) - (qConstraint "Monad" (l [qVar "m"]) - (QFun (qVar "a") - (QApp (qVar "m") (qVar "a"))))) - - test "test #19" do + ( QForAll (nl "m" [ "a" ]) + ( qConstraint "Monad" (l [ qVar "m" ]) + ( QFun (qVar "a") + (QApp (qVar "m") (qVar "a")) + ) + ) + ) + + it "test #19" do let input = "{ a :: Int }" assertRight (parseTypeQuery input) (QApp (qConst "Record") (QRow (pure (Tuple (Identifier "a") (qConst "Int"))))) - test "test #20" do + it "test #20" do let input = "{a::Int}" assertRight (parseTypeQuery input) (QApp (qConst "Record") (QRow (pure (Tuple (Identifier "a") (qConst "Int"))))) - test "test #21" do + it "test #21" do let input = "Int" assertRight (parseTypeQuery input) (qConst "Int") - test "test #22" do + it "test #22" do let input = "a->b" assertRight (parseTypeQuery input) (QFun (qVar "a") (qVar "b")) - test "test #23" do + it "test #23" do let input = "forall m a. MonadRec m => Process m a -> m a" - assertRight (parseTypeQuery input) (QForAll (nl "m" ("a" : Nil)) - (qConstraint "MonadRec" (l [qVar "m"]) - (QFun (QApp (QApp (qConst "Process") - (qVar "m")) (qVar "a")) - (QApp (qVar "m") (qVar "a"))))) - - test "test #24" do + assertRight (parseTypeQuery input) + ( QForAll (nl "m" ("a" : Nil)) + ( qConstraint "MonadRec" (l [ qVar "m" ]) + ( QFun + ( QApp + ( QApp (qConst "Process") + (qVar "m") + ) + (qVar "a") + ) + (QApp (qVar "m") (qVar "a")) + ) + ) + ) + + it "test #24" do let input = "forall t f a. Foldable1 t => Apply f => f" - assertRight (parseTypeQuery input) (QForAll (nl "t" ["f", "a"]) - (qConstraint "Foldable1" (l [qVar "t"]) - (qConstraint "Apply" (l [qVar "f"]) (qVar "f")))) + assertRight (parseTypeQuery input) + ( QForAll (nl "t" [ "f", "a" ]) + ( qConstraint "Foldable1" (l [ qVar "t" ]) + (qConstraint "Apply" (l [ qVar "f" ]) (qVar "f")) + ) + ) - test "test #25" do + it "test #25" do let input = "forall m a.MonadRec m=>Process m a->m a" - assertRight (parseTypeQuery input) ((QForAll (nl "m" ("a" : Nil)) - (qConstraint "MonadRec" (l [qVar "m"]) - (QFun (QApp (QApp (qConst "Process") - (qVar "m")) (qVar "a")) - (QApp (qVar "m") (qVar "a")))))) - - test "test #26" do + assertRight (parseTypeQuery input) + ( ( QForAll (nl "m" ("a" : Nil)) + ( qConstraint "MonadRec" (l [ qVar "m" ]) + ( QFun + ( QApp + ( QApp (qConst "Process") + (qVar "m") + ) + (qVar "a") + ) + (QApp (qVar "m") (qVar "a")) + ) + ) + ) + ) + + it "test #26" do let input = "m a -> (a -> m b) -> m b" assertRight (parseTypeQuery input) (QFun (QApp (qVar "m") (qVar "a")) (QFun (QFun (qVar "a") (QApp (qVar "m") (qVar "b"))) (QApp (qVar "m") (qVar "b")))) - test "test #27" do + it "test #27" do let input = "forall f a. Alternative f => Lazy (f (List a)) => f a -> f (List a)" - assertRight (parseTypeQuery input) ((QForAll (nl "f" ["a"])) - (qConstraint "Alternative" (l [qVar "f"]) - (qConstraint "Lazy" (l [QApp (qVar "f") - (QApp (qConst "List") (qVar "a"))]) - (QFun (QApp (qVar "f") (qVar "a")) - (QApp (qVar "f") - (QApp (qConst "List") (qVar "a"))))))) - - test "test #28" do + assertRight (parseTypeQuery input) + ( (QForAll (nl "f" [ "a" ])) + ( qConstraint "Alternative" (l [ qVar "f" ]) + ( qConstraint "Lazy" + ( l + [ QApp (qVar "f") + (QApp (qConst "List") (qVar "a")) + ] + ) + ( QFun (QApp (qVar "f") (qVar "a")) + ( QApp (qVar "f") + (QApp (qConst "List") (qVar "a")) + ) + ) + ) + ) + ) + + it "test #28" do let input = "forall f a. Alternative f => Lazy(f (List a))=>f a -> f (List a)" - assertRight (parseTypeQuery input) ((QForAll (nl "f" ["a"])) - (qConstraint "Alternative" (l [qVar "f"]) - (qConstraint "Lazy" (l [QApp (qVar "f") - (QApp (qConst "List") (qVar "a"))]) - (QFun (QApp (qVar "f") (qVar "a")) - (QApp (qVar "f") - (QApp (qConst "List") (qVar "a"))))))) - - test "test #29" do + assertRight (parseTypeQuery input) + ( (QForAll (nl "f" [ "a" ])) + ( qConstraint "Alternative" (l [ qVar "f" ]) + ( qConstraint "Lazy" + ( l + [ QApp (qVar "f") + (QApp (qConst "List") (qVar "a")) + ] + ) + ( QFun (QApp (qVar "f") (qVar "a")) + ( QApp (qVar "f") + (QApp (qConst "List") (qVar "a")) + ) + ) + ) + ) + ) + + it "test #29" do let input = "{a::Int,b::Int}" assertRight (parseTypeQuery input) - (QApp (qConst "Record") (QRow (List.fromFoldable - [ Tuple (Identifier "a") (qConst "Int") - , Tuple (Identifier "b") (qConst "Int")]))) - - test "test #30" do + ( QApp (qConst "Record") + ( QRow + ( List.fromFoldable + [ Tuple (Identifier "a") (qConst "Int") + , Tuple (Identifier "b") (qConst "Int") + ] + ) + ) + ) + + it "test #30" do let input = "{record''' :: Int}" assertRight (parseTypeQuery input) - (QApp (qConst "Record") (QRow (List.fromFoldable [ Tuple (Identifier "record'''") (qConst "Int")]))) + (QApp (qConst "Record") (QRow (List.fromFoldable [ Tuple (Identifier "record'''") (qConst "Int") ]))) - test "test #31" do + it "test #31" do let input = "(row''' :: Int)" assertRight (parseTypeQuery input) - (QRow (List.fromFoldable [ Tuple (Identifier "row'''") (qConst "Int")])) + (QRow (List.fromFoldable [ Tuple (Identifier "row'''") (qConst "Int") ])) - test "test #32" do + it "test #32" do let input = "(row1 :: Int, row2 :: (),row3::(row4::{}))" assertRight (parseTypeQuery input) - (QRow (l [ Tuple (Identifier "row1") (qConst "Int") - , Tuple (Identifier "row2") (QRow Nil) - , Tuple (Identifier "row3") (QRow (l [ Tuple (Identifier "row4") (QApp (qConst "Record") (QRow Nil)) ])) ])) - - test "test #33" do + ( QRow + ( l + [ Tuple (Identifier "row1") (qConst "Int") + , Tuple (Identifier "row2") (QRow Nil) + , Tuple (Identifier "row3") (QRow (l [ Tuple (Identifier "row4") (QApp (qConst "Record") (QRow Nil)) ])) + ] + ) + ) + + it "test #33" do let input = "Foldable1 t => Apply f => t (f a) -> f Unit" assertRight (parseTypeQuery input) (qConstraint "Foldable1" ((qVar "t") : Nil) (qConstraint "Apply" ((qVar "f") : Nil) (QFun (QApp (qVar "t") (QApp (qVar "f") (qVar "a"))) (QApp (qVar "f") (qConst "Unit"))))) - test "test #34" do + it "test #34" do let input = "Foldable1 t => Apply f => t (f a) -> f a" assertRight (parseTypeQuery input) (qConstraint "Foldable1" ((qVar "t") : Nil) (qConstraint "Apply" ((qVar "f") : Nil) (QFun (QApp (qVar "t") (QApp (qVar "f") (qVar "a"))) (QApp (qVar "f") (qVar "a"))))) - test "test #35" do + it "test #35" do let input = "Generic a rep => GenericEq rep => a -> a -> Boolean" assertRight (parseTypeQuery input) - (qConstraint "Generic" ((qVar "a") : (qVar "rep") : Nil) - (qConstraint "GenericEq" ((qVar "rep") : Nil) - (QFun (qVar "a") (QFun (qVar "a") (qConst "Boolean"))))) + ( qConstraint "Generic" ((qVar "a") : (qVar "rep") : Nil) + ( qConstraint "GenericEq" ((qVar "rep") : Nil) + (QFun (qVar "a") (QFun (qVar "a") (qConst "Boolean"))) + ) + ) - suite "polish notation" do + describe "polish notation" do - test "test #1" do + it "test #1" do let input = "(a -> b) -> (b -> ((a -> b) -> c))" assertRight (shapeOfTypeQuery <$> parseTypeQuery input) - (l [ PForAll 3, PFun, PFun, PVar, PVar, PFun, PVar, PFun, PFun - , PVar, PVar, PVar ]) - - test "test #2" do + ( l + [ PForAll 3 + , PFun + , PFun + , PVar + , PVar + , PFun + , PVar + , PFun + , PFun + , PVar + , PVar + , PVar + ] + ) + + it "test #2" do let input = "forall a. (a -> b) -> (b -> ((a -> b) -> c))" assertRight (shapeOfTypeQuery <$> parseTypeQuery input) - (l [ PForAll 3, PFun, PFun, PVar, PVar, PFun, PVar, PFun, PFun - , PVar, PVar, PVar ]) - - test "test #3" do + ( l + [ PForAll 3 + , PFun + , PFun + , PVar + , PVar + , PFun + , PVar + , PFun + , PFun + , PVar + , PVar + , PVar + ] + ) + + it "test #3" do let input = "forall a. (a -> b) -> (b -> ((a -> b) -> c))" assertRight (shapeOfTypeQuery <$> parseTypeQuery input) - (l [ PForAll 3, PFun, PFun, PVar, PVar, PFun, PVar, PFun, PFun - , PVar, PVar, PVar ]) - - test "test #4" do + ( l + [ PForAll 3 + , PFun + , PFun + , PVar + , PVar + , PFun + , PVar + , PFun + , PFun + , PVar + , PVar + , PVar + ] + ) + + it "test #4" do let input = "forall a. (forall h. ST h (STArray h a)) -> Array a" assertRight (shapeOfTypeQuery <$> parseTypeQuery input) - (l [ PForAll 1, PFun, PForAll 1, PApp, PApp, PVar, PVar, PApp, PApp, PVar, PVar, PVar, PApp, PVar, PVar ]) - - suite "type shapes" do - test "test #1" do - let query = "Generic a rep => GenericEq rep => a -> a -> Boolean" - c1 = constr (qname [""] "Generic") [TypeVar "a", TypeVar "rep"] - c2 = constr (qname [""] "GenericEq") [TypeVar "rep"] - - fun t1 t2 = - TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"] - , name: Identifier "Function" })) t1) t2 - type_ = - ForAll "a" Nothing $ - ForAll "rep" Nothing $ - ConstrainedType c1 - (ConstrainedType c2 - (fun (TypeVar "a") (fun (TypeVar "b") - (TypeConstructor $ qname ["Prim", "Boolean"] "Boolean")))) - shape = shapeOfTypeQuery <$> parseTypeQuery query - Assert.equal (pure $ shapeOfType type_) shape - - suite "free variable counting" do - - test "test #1" do + (l [ PForAll 1, PFun, PForAll 1, PApp, PApp, PVar, PVar, PApp, PApp, PVar, PVar, PVar, PApp, PVar, PVar ]) + + describe "type shapes" do + it "test #1" do + let + query = "Generic a rep => GenericEq rep => a -> a -> Boolean" + c1 = constr (qname [ "" ] "Generic") [ TypeVar "a", TypeVar "rep" ] + c2 = constr (qname [ "" ] "GenericEq") [ TypeVar "rep" ] + + fun t1 t2 = + TypeApp + ( TypeApp + ( TypeConstructor + ( QualifiedName + { moduleNameParts: [ "Prim" ] + , name: Identifier "Function" + } + ) + ) + t1 + ) + t2 + type_ = + ForAll "a" Nothing + $ ForAll "rep" Nothing + $ + ConstrainedType c1 + ( ConstrainedType c2 + ( fun (TypeVar "a") + ( fun (TypeVar "b") + (TypeConstructor $ qname [ "Prim", "Boolean" ] "Boolean") + ) + ) + ) + shape = shapeOfTypeQuery <$> parseTypeQuery query + pure (shapeOfType type_) `shouldEqual` shape + + describe "free variable counting" do + + it "test #1" do let input = "forall a. (a -> b) -> (b -> ((a -> b) -> c))" assertRight (countFreeVars <$> parseTypeQuery input) 2 - test "test #2" do + it "test #2" do -- `b` is not bound on the left, `a` is not bound on the right let input = "(forall a. (a -> b)) -> forall b. (b -> a)" assertRight (countFreeVars <$> parseTypeQuery input) 2 - test "test #3" do + it "test #3" do let input = "a -> forall a. a" assertRight (countFreeVars <$> parseTypeQuery input) 1 - test "test #4" do + it "test #4" do let input = "(forall a. a) -> a" assertRight (countFreeVars <$> parseTypeQuery input) 1 - test "test #5" do + it "test #5" do let input = "forall a. a -> a" assertRight (countFreeVars <$> parseTypeQuery input) 0 - test "test #6" do + it "test #6" do let input = "a -> b -> c" assertRight (countFreeVars <$> parseTypeQuery input) 3 - test "test #7" do + it "test #7" do let input = "forall m a. Monad m => a -> m a" assertRight (countFreeVars <$> parseTypeQuery input) 0 - test "test #8" do + it "test #8" do let input = "Monad m => a -> m a" assertRight (countFreeVars <$> parseTypeQuery input) 2 - test "test #9" do + it "test #9" do let input = "Monad m => a -> a" assertRight (countFreeVars <$> parseTypeQuery input) 2 - test "test #10" do + it "test #10" do let input = "forall a. (forall a. a) a" assertRight (countFreeVars <$> parseTypeQuery input) 0 - test "test #11" do + it "test #11" do let input = "forall a. (forall b. a) a" assertRight (countFreeVars <$> parseTypeQuery input) 0 - test "test #12" do + it "test #12" do let input = "forall a. (forall b. a) a b" assertRight (countFreeVars <$> parseTypeQuery input) 1 - suite "typeVarPenalty" do - - test "#0" do - Assert.equal 0 (typeVarPenalty mempty) - - test "#1" do - Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "b" - , substitute "b" "a" - ]) - - test "#2" do - Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "b" - , substitute "a" "b" - , substitute "a" "b" - ]) - - test "#3" do - Assert.equal 1 (typeVarPenalty $ l [ substitute "a" "b" - , substitute "a" "c" - ]) - - test "#4" do - Assert.equal 1 (typeVarPenalty $ l [ substitute "a" "b" - , substitute "b" "a" - , substitute "b" "c" - ]) - - test "#5" do - Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "b" - , substitute "b" "c" - , substitute "c" "a" - ]) - - test "#6" do - Assert.equal 2 (typeVarPenalty $ l [ substitute "a" "b" - , substitute "a" "c" - , substitute "a" "a" - ]) - - test "#7" do - Assert.equal 2 (typeVarPenalty $ l [ substitute "a" "a" - , substitute "b" "a" - , substitute "c" "a" - ]) - - test "#8" do - Assert.equal 4 (typeVarPenalty $ l [ substitute "a" "a" - , substitute "b" "a" - , substitute "c" "a" - , substitute "a" "b" - , substitute "a" "c" - , substitute "a" "a" - ]) - - test "#9" do - Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "e" - , substitute "b" "d" - , substitute "c" "f" - ]) - - suite "unification" do - test "instantiation #0" do - let mVarQuery = qVar "m" - unitConstQuery = qConst "Unit" - - Assert.assert "instantiation #0" $ - (penalty unitConstQuery unitType < penalty mVarQuery unitType) - - test "generalization #0" do - let query = qVar "m" - t1 = TypeVar "m" - - Assert.assert "qeneralization #0" $ - (penalty query unitType > penalty query t1) - + describe "typeVarPenalty" do + + it "#0" do + 0 `shouldEqual` (typeVarPenalty mempty) + + it "#1" do + 0 `shouldEqual` + ( typeVarPenalty $ l + [ substitute "a" "b" + , substitute "b" "a" + ] + ) + + it "#2" do + 0 `shouldEqual` + ( typeVarPenalty $ l + [ substitute "a" "b" + , substitute "a" "b" + , substitute "a" "b" + ] + ) + + it "#3" do + 1 `shouldEqual` + ( typeVarPenalty $ l + [ substitute "a" "b" + , substitute "a" "c" + ] + ) + + it "#4" do + 1 `shouldEqual` + ( typeVarPenalty $ l + [ substitute "a" "b" + , substitute "b" "a" + , substitute "b" "c" + ] + ) + + it "#5" do + 0 `shouldEqual` + ( typeVarPenalty $ l + [ substitute "a" "b" + , substitute "b" "c" + , substitute "c" "a" + ] + ) + + it "#6" do + 2 `shouldEqual` + ( typeVarPenalty $ l + [ substitute "a" "b" + , substitute "a" "c" + , substitute "a" "a" + ] + ) + + it "#7" do + 2 `shouldEqual` + ( typeVarPenalty $ l + [ substitute "a" "a" + , substitute "b" "a" + , substitute "c" "a" + ] + ) + + it "#8" do + 4 `shouldEqual` + ( typeVarPenalty $ l + [ substitute "a" "a" + , substitute "b" "a" + , substitute "c" "a" + , substitute "a" "b" + , substitute "a" "c" + , substitute "a" "a" + ] + ) + + it "#9" do + 0 `shouldEqual` + ( typeVarPenalty $ l + [ substitute "a" "e" + , substitute "b" "d" + , substitute "c" "f" + ] + ) + + describe "unification" do + it "instantiation #0" do + let + mVarQuery = qVar "m" + unitConstQuery = qConst "Unit" + + shouldSatisfy + (penalty unitConstQuery unitType) + (_ < penalty mVarQuery unitType) + + it "generalization #0" do + let + query = qVar "m" + t1 = TypeVar "m" + + shouldSatisfy + (penalty query unitType) + (_ > penalty query t1) l :: forall f. Foldable f => (forall a. f a -> List a) l = List.fromFoldable nl :: forall t - . Foldable t + . Foldable t => Functor t => String -> t String @@ -400,9 +551,12 @@ nl nl x rst = NonEmptyList.cons' (Identifier x) $ List.fromFoldable (rst <#> Identifier) unitType :: Type -unitType = TypeConstructor (QualifiedName { moduleNameParts: [] - , name: Identifier "Unit" - }) +unitType = TypeConstructor + ( QualifiedName + { moduleNameParts: [] + , name: Identifier "Unit" + } + ) countFreeVars :: TypeQuery -> Int countFreeVars = getFreeVariables >>> Set.size diff --git a/test/Test/UI.purs b/test/Test/UI.purs index b290c9d..f677ede 100644 --- a/test/Test/UI.purs +++ b/test/Test/UI.purs @@ -1,67 +1,68 @@ module Test.UI where -import Prelude +-- import Prelude -import Data.Array as Array -import Data.Foldable (for_) -import Data.Newtype (unwrap) -import Effect (Effect) -import Effect.Aff (Aff, launchAff_) -import Effect.Class (liftEffect) -import Effect.Console as Console -import Foreign (Foreign) -import Foreign as Foreign -import Node.FS.Sync (realpath) -import Test.Unit.Assert as Assert -import Toppokki as T +-- import Data.Array as Array +-- import Data.Foldable (for_) +-- import Data.Newtype (unwrap) +-- import Effect (Effect) +-- import Effect.Aff (Aff, launchAff_) +-- import Effect.Class (liftEffect) +-- import Effect.Console as Console +-- import Foreign (Foreign) +-- import Foreign as Foreign +-- import Node.FS.Sync (realpath) +-- import Test.Spec.Assertions (shouldSatisfy) +-- -- import Toppokki as T +-- -- import Playwright as P +-- main :: Effect Unit +-- main = launchAff_ do +-- pure unit +-- path <- liftEffect $ realpath "." -main :: Effect Unit -main = launchAff_ do - path <- liftEffect $ realpath "." +-- let indexHTML = T.URL $ "file://" <> path <> "/generated-docs/html/index.html" +-- prim = T.URL $ "file://" <> path <> "/generated-docs/html/Prim.html" +-- docsSearch = T.URL $ "file://" <> path <> "/generated-docs/html/Docs.Search.App.html" - let indexHTML = T.URL $ "file://" <> path <> "/generated-docs/html/index.html" - prim = T.URL $ "file://" <> path <> "/generated-docs/html/Prim.html" - docsSearch = T.URL $ "file://" <> path <> "/generated-docs/html/Docs.Search.App.html" +-- for_ [ indexHTML, prim, docsSearch ] \url -> do +-- withPage url \page -> do +-- void $ T.pageWaitForSelector (T.Selector "#group-modules__label") { timeout: 10000 } page +-- log $ "has module grouping: " <> unwrap url - for_ [ indexHTML, prim, docsSearch ] \url -> do - withPage url \page -> do - void $ T.pageWaitForSelector (T.Selector "#group-modules__label") { timeout: 10000 } page - log $ "has module grouping: " <> unwrap url +-- withPage url \page -> do +-- T.keyboardPress (T.KeyboardKey "s") {} page +-- void $ T.keyboardType "slice" {} page +-- T.keyboardPress (T.KeyboardKey "Enter") {} page +-- void $ T.pageWaitForSelector (T.Selector ".result__actions__item") { timeout: 10000 } page +-- log $ "has working search field: " <> unwrap url - withPage url \page -> do - T.keyboardPress (T.KeyboardKey "s") {} page - void $ T.keyboardType "slice" {} page - T.keyboardPress (T.KeyboardKey "Enter") {} page - void $ T.pageWaitForSelector (T.Selector ".result__actions__item") { timeout: 10000 } page - log $ "has working search field: " <> unwrap url +-- withPage url \page -> do +-- T.keyboardPress (T.KeyboardKey "s") {} page +-- void $ T.keyboardType "a -> b" {} page +-- T.keyboardPress (T.KeyboardKey "Enter") {} page +-- void $ T.pageWaitForSelector (T.Selector ".result__actions__item") { timeout: 10000 } page +-- arr <- readStringArray <$> T.unsafeEvaluateStringFunction getResultTitlesCode page +-- arr `shouldSatisfy` (Array.elem "unsafeCoerce") +-- log $ "is able to find unsafeCoerce by type: " <> unwrap url - withPage url \page -> do - T.keyboardPress (T.KeyboardKey "s") {} page - void $ T.keyboardType "a -> b" {} page - T.keyboardPress (T.KeyboardKey "Enter") {} page - void $ T.pageWaitForSelector (T.Selector ".result__actions__item") { timeout: 10000 } page - arr <- readStringArray <$> T.unsafeEvaluateStringFunction getResultTitlesCode page - Assert.assert "resulting array contains unsafeCoerce" (Array.elem "unsafeCoerce" arr) - log $ "is able to find unsafeCoerce by type: " <> unwrap url +-- withPage (T.URL $ unwrap url <> "#search:unsafeCoerce") \page -> do +-- void $ T.pageWaitForSelector (T.Selector ".result__actions__item") { timeout: 10000 } page +-- arr <- readStringArray <$> T.unsafeEvaluateStringFunction getResultTitlesCode page +-- arr `shouldSatisfy` (Array.elem "unsafeCoerce") +-- log $ "can read URI hash: " <> unwrap url - withPage (T.URL $ unwrap url <> "#search:unsafeCoerce") \page -> do - void $ T.pageWaitForSelector (T.Selector ".result__actions__item") { timeout: 10000 } page - arr <- readStringArray <$> T.unsafeEvaluateStringFunction getResultTitlesCode page - Assert.assert "resulting array contains unsafeCoerce" (Array.elem "unsafeCoerce" arr) - log $ "can read URI hash: " <> unwrap url +-- where +-- log = liftEffect <<< Console.log +-- getResultTitlesCode = "[].map.call(document.querySelectorAll('.result__title'), el => el.textContent)" +-- readStringArray :: Foreign -> Array String +-- readStringArray = Foreign.unsafeFromForeign - where - log = liftEffect <<< Console.log - getResultTitlesCode = "[].map.call(document.querySelectorAll('.result__title'), el => el.textContent)" - readStringArray :: Foreign -> Array String - readStringArray = Foreign.unsafeFromForeign - -withPage :: forall a. T.URL -> (T.Page -> Aff a) -> Aff Unit -withPage url f = do - browser <- T.launch {} - page <- T.newPage browser - T.goto url page - void $ f page - T.close browser +-- withPage :: forall a. T.URL -> (T.Page -> Aff a) -> Aff Unit +-- withPage url f = do +-- browser <- T.launch {} +-- page <- T.newPage browser +-- T.goto url page +-- void $ f page +-- T.close browser