git.iko.soy/rowtype-yoga/purescript-docs-search
on master help sign in
51 files changed+3971−1240
since splitsnapshots
unifiedsplit
.github/workflows/build.yml+44 .github/workflows/release.yml+55 .travis.yml−51 CHANGELOG.md+29 README.md+4−4 ci-npmrc.txt+4 package-lock.json+2285 package.json+23−20 packages.dhall+114−26 release.sh+24 spago.dhall+53−41 src/Docs/Search/App.purs+41−33 src/Docs/Search/App/SearchField.purs+11−10 src/Docs/Search/App/SearchResults.purs+18−22 src/Docs/Search/App/Sidebar.purs+62−25 src/Docs/Search/BrowserEngine.js+1−1 src/Docs/Search/BrowserEngine.purs−3 src/Docs/Search/Config.purs+1−1 src/Docs/Search/Declarations.purs+31−6 src/Docs/Search/DocsJson.purs+15−10 src/Docs/Search/IndexBuilder.js+4−5 src/Docs/Search/IndexBuilder.purs+48−15 src/Docs/Search/Interactive.purs+41−8 src/Docs/Search/Loader.js+1−1 src/Docs/Search/Loader.purs+2−1 src/Docs/Search/Main.purs+26−26 src/Docs/Search/ModuleIndex.js+1−1 src/Docs/Search/ModuleIndex.purs+17−13 src/Docs/Search/ModuleParser.purs+50 src/Docs/Search/PackageIndex.purs+4−3 src/Docs/Search/Score.purs+1−1 src/Docs/Search/SearchResult.purs+7−6 src/Docs/Search/TypeDecoder.purs+36−70 src/Docs/Search/TypeIndex.js+1−1 src/Docs/Search/TypeIndex.purs+4−5 src/Docs/Search/TypePrinter.purs+10−14 src/Docs/Search/TypeQuery.purs+20−11 src/Docs/Search/TypeShape.js+1−1 src/Docs/Search/TypeShape.purs+7−2 src/Docs/Search/Types.purs+9−6 src/Docs/Search/URIHash.js+1−1 src/Docs/Search/URIHash.purs+3−3 test/Main.purs+14−526 test/Test/Declarations.purs+12−13 test/Test/Extra.purs+6−5 test/Test/IndexBuilder.purs+9−9 test/Test/ModuleIndex.purs+8−10 test/Test/ModuleParser.purs+61 test/Test/TypeJson.purs+300 test/Test/TypeQuery.purs+384−230 test/Test/UI.purs+68
.github/workflows/build.ymlnew file+44
@@ -0,0 +1,44 @@
1+name: build
2+on:
3+ push:
4+ branches: [master]
5+ pull_request:
6+ branches: [master]
7+jobs:
8+ build:
9+ runs-on: ubuntu-latest
10+ steps:
11+ - uses: actions/checkout@v2
12+
13+ - uses: actions/setup-node@v2
14+ with:
15+ node-version: "18"
16+
17+ - uses: purescript-contrib/setup-purescript@main
18+
19+ - uses: actions/cache@v2
20+ with:
21+ path: ~/.npm
22+ key: ${{ runner.os }}-node-${{ hashFiles('./**/package-lock.json') }}
23+ restore-keys: |
24+ ${{ runner.os }}-node-
25+
26+ - name: Cache PureScript dependencies
27+ uses: actions/cache@v2
28+ with:
29+ key: ${{ runner.os }}-spago-${{ hashFiles('./**/*.dhall') }}
30+ path: |
31+ .spago
32+ output
33+
34+ - name: Install
35+ run: |
36+ npm ci
37+ spago install
38+
39+ - name: Build
40+ run: |
41+ npm run build
42+ npm test
43+ spago docs --no-search
44+ ./dist/purescript-docs-search.cjs build-index
.github/workflows/release.ymlnew file+55
@@ -0,0 +1,55 @@
1+name: release
2+on:
3+ push:
4+ tags:
5+ - 'v*.*.*'
6+jobs:
7+ release:
8+ runs-on: ubuntu-latest
9+ steps:
10+ - uses: actions/checkout@v2
11+
12+ - uses: actions/setup-node@v2
13+ with:
14+ node-version: "18"
15+
16+ - uses: purescript-contrib/setup-purescript@main
17+
18+ - uses: actions/cache@v2
19+ with:
20+ path: ~/.npm
21+ key: ${{ runner.os }}-node-${{ hashFiles('./**/package-lock.json') }}
22+ restore-keys: |
23+ ${{ runner.os }}-node-
24+
25+ - name: Cache PureScript dependencies
26+ uses: actions/cache@v2
27+ with:
28+ key: ${{ runner.os }}-spago-${{ hashFiles('./**/*.dhall') }}
29+ path: |
30+ .spago
31+ output
32+
33+ - name: Build
34+ run: |
35+ npm ci
36+ spago install
37+ npm run build
38+
39+ - name: Release
40+ uses: softprops/action-gh-release@v1
41+ with:
42+ files: |
43+ dist/docs-search-app.js
44+ dist/purescript-docs-search.cjs
45+ env:
46+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
47+
48+ - name: Publish to NPM
49+ shell: bash
50+ env:
51+ NODE_AUTH_TOKEN: ${{ secrets.NPM_API_TOKEN }}
52+ run: |
53+ mv ci-npmrc.txt .npmrc
54+ npm ci
55+ npm publish --non-interactive --access public
.travis.ymldeleted−51
@@ -1,51 +0,0 @@
1−language: node_js
2−dist: trusty
3−sudo: required
4−node_js: stable
5−
6−# Build only master and release tags
7−branches:
8− only:
9− - master
10− - /^v\d+\.\d+\.\d+(\.\d+)?$/
11−
12−env:
13− matrix:
14− - PATH=$HOME/purescript:$PATH
15−
16−install:
17−- export PURS_VERSION=v0.13.3
18−- wget -O $HOME/purescript.tar.gz https://github.com/purescript/purescript/releases/download/$PURS_VERSION/linux64.tar.gz
19−- tar -xvf $HOME/purescript.tar.gz -C $HOME/
20−- chmod a+x $HOME/purescript
21−- npm install -g spago
22−- npm install
23−- spago install
24−
25−script:
26−- npm run build
27−- npm test
28−# Check if it the app is able to build the search index for itself.
29−- spago docs
30−- ./dist/purescript-docs-search build-index
31−
32−deploy:
33− - provider: releases
34− api_key: $API_KEY
35− file:
36− - dist/docs-search-app.js
37− - dist/purescript-docs-search
38− skip_cleanup: true
39− on:
40− tags: true
41− script:
42− - echo 'done'
43− - provider: npm
44− api_token:
45− secure: $NPM_API_TOKEN
46− email: klntsky@gmail.com
47− skip_cleanup: true
48− edge: true
49− on:
50− tags: true
51− branch: master
CHANGELOG.md+29
@@ -5,6 +5,35 @@ All notable changes to this project will be documented in this file.
55The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77
8+## [0.0.12 - 2022-08-31]
9+
10+Changes:
11+- 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.
12+- Improve output for data and newtype constuctors ([#58](https://github.com/purescript/purescript-docs-search/pull/58))
13+
14+New features:
15+- Docs for each CLI option
16+- New `--source-files` option that allows to specify `.purs` sources (see below)
17+
18+Bugfixes:
19+- Include modules with only re-exports in the module list ([#62](https://github.com/purescript/purescript-docs-search/issues/62))
20+- Fix `docs.json` parser for some types
21+
22+## [0.0.11 - 2021-04-15]
23+
24+Changes:
25+- Adapt JSON API for use with PureScript v0.14.
26+
27+## [0.0.10 - 2020-08-11]
28+
29+New features:
30+- Add `--package-name` flag to allow passing local package name.
31+
32+Changes:
33+- Group modules by default.
34+- Add local package modules and `Prim*` modules to the sidebar.
35+- UI tests, using [purescript-toppokki](https://github.com/justinwoo/purescript-toppokki/).
36+
837## [0.0.9 - 2020-07-29]
938
1039New features:
README.md+4−4
@@ -1,8 +1,8 @@
11# purescript-docs-search
22
3−[![Build status](https://travis-ci.org/spacchetti/purescript-docs-search.svg?branch=master)](https://travis-ci.org/spacchetti/purescript-docs-search)
3+[![Build status](https://github.com/purescript/purescript-docs-search/actions/workflows/build.yml/badge.svg)](https://github.com/purescript/purescript-docs-search/actions/workflows/build.yml)
44
5−An app that adds search capabilities to generated documentation for purescript code.
5+An app that adds search capabilities to generated documentation for PureScript code.
66
77It supports nearly-all functionality of [Pursuit](https://github.com/purescript/pursuit), including querying by type.
88
@@ -10,7 +10,7 @@ It supports nearly-all functionality of [Pursuit](https://github.com/purescript/
1010
1111When using [spago](https://github.com/spacchetti/spago), you don't need to install this app manually: run `spago docs` or `spago search`.
1212
13−Otherwise, use [npx](https://github.com/npm/npx): `npx purescript-docs-search`.
13+Otherwise, use NPM (`npm install purescript-docs-search`) or [npx](https://github.com/npm/npx): `npx purescript-docs-search`.
1414
1515## Usage
1616
@@ -45,4 +45,4 @@ npm install
4545npm run build # or build-dev to skip JS compression stage
4646```
4747
48−Use `spago docs --no-search && ./dist/purescript-docs-search build-index` to generate the docs and patch them using the local version of the app.
48+Use `spago docs --no-search && ./dist/purescript-docs-search.cjs build-index` to generate the docs and patch them using the local version of the app.
ci-npmrc.txtnew file+4
@@ -0,0 +1,4 @@
1+//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}
2+registry=https://registry.npmjs.org/
3+always-auth=true
4+
package-lock.jsonnew file+2285
@@ -0,0 +1,2285 @@
1+{
2+ "name": "purescript-docs-search",
3+ "version": "0.0.11",
4+ "lockfileVersion": 2,
5+ "requires": true,
6+ "packages": {
7+ "": {
8+ "name": "purescript-docs-search",
9+ "version": "0.0.11",
10+ "license": "BSD-3-Clause",
11+ "dependencies": {
12+ "punycode": "^2.1.1"
13+ },
14+ "bin": {
15+ "purescript-docs-search": "dist/purescript-docs-search.js"
16+ },
17+ "devDependencies": {
18+ "esbuild": "^0.11.10",
19+ "glob": "^7.1.6",
20+ "markdown-it": "^12.0.4",
21+ "puppeteer": "^8.0.0",
22+ "spago": "^0.20.9"
23+ }
24+ },
25+ "node_modules/@gar/promisify": {
26+ "version": "1.1.3",
27+ "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
28+ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
29+ "dev": true
30+ },
31+ "node_modules/@npmcli/fs": {
32+ "version": "1.1.1",
33+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
34+ "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
35+ "dev": true,
36+ "dependencies": {
37+ "@gar/promisify": "^1.0.1",
38+ "semver": "^7.3.5"
39+ }
40+ },
41+ "node_modules/@npmcli/move-file": {
42+ "version": "1.1.2",
43+ "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
44+ "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
45+ "dev": true,
46+ "dependencies": {
47+ "mkdirp": "^1.0.4",
48+ "rimraf": "^3.0.2"
49+ },
50+ "engines": {
51+ "node": ">=10"
52+ }
53+ },
54+ "node_modules/@tootallnate/once": {
55+ "version": "1.1.2",
56+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
57+ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
58+ "dev": true,
59+ "engines": {
60+ "node": ">= 6"
61+ }
62+ },
63+ "node_modules/@types/node": {
64+ "version": "14.14.39",
65+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.39.tgz",
66+ "integrity": "sha512-Qipn7rfTxGEDqZiezH+wxqWYR8vcXq5LRpZrETD19Gs4o8LbklbmqotSUsMU+s5G3PJwMRDfNEYoxrcBwIxOuw==",
67+ "dev": true,
68+ "optional": true
69+ },
70+ "node_modules/@types/yauzl": {
71+ "version": "2.9.1",
72+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
73+ "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
74+ "dev": true,
75+ "optional": true,
76+ "dependencies": {
77+ "@types/node": "*"
78+ }
79+ },
80+ "node_modules/agent-base": {
81+ "version": "6.0.2",
82+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
83+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
84+ "dev": true,
85+ "dependencies": {
86+ "debug": "4"
87+ },
88+ "engines": {
89+ "node": ">= 6.0.0"
90+ }
91+ },
92+ "node_modules/agentkeepalive": {
93+ "version": "4.2.1",
94+ "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz",
95+ "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==",
96+ "dev": true,
97+ "dependencies": {
98+ "debug": "^4.1.0",
99+ "depd": "^1.1.2",
100+ "humanize-ms": "^1.2.1"
101+ },
102+ "engines": {
103+ "node": ">= 8.0.0"
104+ }
105+ },
106+ "node_modules/aggregate-error": {
107+ "version": "3.1.0",
108+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
109+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
110+ "dev": true,
111+ "dependencies": {
112+ "clean-stack": "^2.0.0",
113+ "indent-string": "^4.0.0"
114+ },
115+ "engines": {
116+ "node": ">=8"
117+ }
118+ },
119+ "node_modules/argparse": {
120+ "version": "2.0.1",
121+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
122+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
123+ "dev": true
124+ },
125+ "node_modules/balanced-match": {
126+ "version": "1.0.0",
127+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
128+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
129+ "dev": true
130+ },
131+ "node_modules/base64-js": {
132+ "version": "1.5.1",
133+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
134+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
135+ "dev": true,
136+ "funding": [
137+ {
138+ "type": "github",
139+ "url": "https://github.com/sponsors/feross"
140+ },
141+ {
142+ "type": "patreon",
143+ "url": "https://www.patreon.com/feross"
144+ },
145+ {
146+ "type": "consulting",
147+ "url": "https://feross.org/support"
148+ }
149+ ]
150+ },
151+ "node_modules/bl": {
152+ "version": "4.1.0",
153+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
154+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
155+ "dev": true,
156+ "dependencies": {
157+ "buffer": "^5.5.0",
158+ "inherits": "^2.0.4",
159+ "readable-stream": "^3.4.0"
160+ }
161+ },
162+ "node_modules/bl/node_modules/buffer": {
163+ "version": "5.7.1",
164+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
165+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
166+ "dev": true,
167+ "funding": [
168+ {
169+ "type": "github",
170+ "url": "https://github.com/sponsors/feross"
171+ },
172+ {
173+ "type": "patreon",
174+ "url": "https://www.patreon.com/feross"
175+ },
176+ {
177+ "type": "consulting",
178+ "url": "https://feross.org/support"
179+ }
180+ ],
181+ "dependencies": {
182+ "base64-js": "^1.3.1",
183+ "ieee754": "^1.1.13"
184+ }
185+ },
186+ "node_modules/bl/node_modules/readable-stream": {
187+ "version": "3.6.0",
188+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
189+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
190+ "dev": true,
191+ "dependencies": {
192+ "inherits": "^2.0.3",
193+ "string_decoder": "^1.1.1",
194+ "util-deprecate": "^1.0.1"
195+ },
196+ "engines": {
197+ "node": ">= 6"
198+ }
199+ },
200+ "node_modules/brace-expansion": {
201+ "version": "1.1.11",
202+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
203+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
204+ "dev": true,
205+ "dependencies": {
206+ "balanced-match": "^1.0.0",
207+ "concat-map": "0.0.1"
208+ }
209+ },
210+ "node_modules/buffer-crc32": {
211+ "version": "0.2.13",
212+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
213+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
214+ "dev": true,
215+ "engines": {
216+ "node": "*"
217+ }
218+ },
219+ "node_modules/cacache": {
220+ "version": "15.3.0",
221+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
222+ "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
223+ "dev": true,
224+ "dependencies": {
225+ "@npmcli/fs": "^1.0.0",
226+ "@npmcli/move-file": "^1.0.1",
227+ "chownr": "^2.0.0",
228+ "fs-minipass": "^2.0.0",
229+ "glob": "^7.1.4",
230+ "infer-owner": "^1.0.4",
231+ "lru-cache": "^6.0.0",
232+ "minipass": "^3.1.1",
233+ "minipass-collect": "^1.0.2",
234+ "minipass-flush": "^1.0.5",
235+ "minipass-pipeline": "^1.2.2",
236+ "mkdirp": "^1.0.3",
237+ "p-map": "^4.0.0",
238+ "promise-inflight": "^1.0.1",
239+ "rimraf": "^3.0.2",
240+ "ssri": "^8.0.1",
241+ "tar": "^6.0.2",
242+ "unique-filename": "^1.1.1"
243+ },
244+ "engines": {
245+ "node": ">= 10"
246+ }
247+ },
248+ "node_modules/cacache/node_modules/chownr": {
249+ "version": "2.0.0",
250+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
251+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
252+ "dev": true,
253+ "engines": {
254+ "node": ">=10"
255+ }
256+ },
257+ "node_modules/chownr": {
258+ "version": "1.1.4",
259+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
260+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
261+ "dev": true
262+ },
263+ "node_modules/clean-stack": {
264+ "version": "2.2.0",
265+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
266+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
267+ "dev": true,
268+ "engines": {
269+ "node": ">=6"
270+ }
271+ },
272+ "node_modules/concat-map": {
273+ "version": "0.0.1",
274+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
275+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
276+ "dev": true
277+ },
278+ "node_modules/debug": {
279+ "version": "4.3.4",
280+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
281+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
282+ "dev": true,
283+ "dependencies": {
284+ "ms": "2.1.2"
285+ },
286+ "engines": {
287+ "node": ">=6.0"
288+ },
289+ "peerDependenciesMeta": {
290+ "supports-color": {
291+ "optional": true
292+ }
293+ }
294+ },
295+ "node_modules/depd": {
296+ "version": "1.1.2",
297+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
298+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
299+ "dev": true,
300+ "engines": {
301+ "node": ">= 0.6"
302+ }
303+ },
304+ "node_modules/devtools-protocol": {
305+ "version": "0.0.854822",
306+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.854822.tgz",
307+ "integrity": "sha512-xd4D8kHQtB0KtWW0c9xBZD5LVtm9chkMOfs/3Yn01RhT/sFIsVtzTtypfKoFfWBaL+7xCYLxjOLkhwPXaX/Kcg==",
308+ "dev": true
309+ },
310+ "node_modules/encoding": {
311+ "version": "0.1.13",
312+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
313+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
314+ "dev": true,
315+ "optional": true,
316+ "dependencies": {
317+ "iconv-lite": "^0.6.2"
318+ }
319+ },
320+ "node_modules/end-of-stream": {
321+ "version": "1.4.4",
322+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
323+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
324+ "dev": true,
325+ "dependencies": {
326+ "once": "^1.4.0"
327+ }
328+ },
329+ "node_modules/entities": {
330+ "version": "2.1.0",
331+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
332+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
333+ "dev": true,
334+ "funding": {
335+ "url": "https://github.com/fb55/entities?sponsor=1"
336+ }
337+ },
338+ "node_modules/err-code": {
339+ "version": "2.0.3",
340+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
341+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
342+ "dev": true
343+ },
344+ "node_modules/esbuild": {
345+ "version": "0.11.11",
346+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.11.tgz",
347+ "integrity": "sha512-iq5YdV63vY/nUAFIvY92BXVkYjMbOchnofLKoLKMPZIa4uuIJAJG9WRA+ZRjQBZbrsORUwvZcANeG2d3p46PJQ==",
348+ "dev": true,
349+ "hasInstallScript": true,
350+ "bin": {
351+ "esbuild": "bin/esbuild"
352+ }
353+ },
354+ "node_modules/extract-zip": {
355+ "version": "2.0.1",
356+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
357+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
358+ "dev": true,
359+ "dependencies": {
360+ "debug": "^4.1.1",
361+ "get-stream": "^5.1.0",
362+ "yauzl": "^2.10.0"
363+ },
364+ "bin": {
365+ "extract-zip": "cli.js"
366+ },
367+ "engines": {
368+ "node": ">= 10.17.0"
369+ },
370+ "optionalDependencies": {
371+ "@types/yauzl": "^2.9.1"
372+ }
373+ },
374+ "node_modules/fd-slicer": {
375+ "version": "1.1.0",
376+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
377+ "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
378+ "dev": true,
379+ "dependencies": {
380+ "pend": "~1.2.0"
381+ }
382+ },
383+ "node_modules/fs-constants": {
384+ "version": "1.0.0",
385+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
386+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
387+ "dev": true
388+ },
389+ "node_modules/fs-minipass": {
390+ "version": "2.1.0",
391+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
392+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
393+ "dev": true,
394+ "dependencies": {
395+ "minipass": "^3.0.0"
396+ },
397+ "engines": {
398+ "node": ">= 8"
399+ }
400+ },
401+ "node_modules/fs.realpath": {
402+ "version": "1.0.0",
403+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
404+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
405+ "dev": true
406+ },
407+ "node_modules/get-stream": {
408+ "version": "5.2.0",
409+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
410+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
411+ "dev": true,
412+ "dependencies": {
413+ "pump": "^3.0.0"
414+ },
415+ "engines": {
416+ "node": ">=8"
417+ },
418+ "funding": {
419+ "url": "https://github.com/sponsors/sindresorhus"
420+ }
421+ },
422+ "node_modules/glob": {
423+ "version": "7.1.6",
424+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
425+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
426+ "dev": true,
427+ "dependencies": {
428+ "fs.realpath": "^1.0.0",
429+ "inflight": "^1.0.4",
430+ "inherits": "2",
431+ "minimatch": "^3.0.4",
432+ "once": "^1.3.0",
433+ "path-is-absolute": "^1.0.0"
434+ },
435+ "engines": {
436+ "node": "*"
437+ },
438+ "funding": {
439+ "url": "https://github.com/sponsors/isaacs"
440+ }
441+ },
442+ "node_modules/http-cache-semantics": {
443+ "version": "4.1.0",
444+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
445+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
446+ "dev": true
447+ },
448+ "node_modules/http-proxy-agent": {
449+ "version": "4.0.1",
450+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
451+ "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
452+ "dev": true,
453+ "dependencies": {
454+ "@tootallnate/once": "1",
455+ "agent-base": "6",
456+ "debug": "4"
457+ },
458+ "engines": {
459+ "node": ">= 6"
460+ }
461+ },
462+ "node_modules/https-proxy-agent": {
463+ "version": "5.0.0",
464+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
465+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
466+ "dev": true,
467+ "dependencies": {
468+ "agent-base": "6",
469+ "debug": "4"
470+ },
471+ "engines": {
472+ "node": ">= 6"
473+ }
474+ },
475+ "node_modules/humanize-ms": {
476+ "version": "1.2.1",
477+ "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
478+ "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
479+ "dev": true,
480+ "dependencies": {
481+ "ms": "^2.0.0"
482+ }
483+ },
484+ "node_modules/iconv-lite": {
485+ "version": "0.6.3",
486+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
487+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
488+ "dev": true,
489+ "optional": true,
490+ "dependencies": {
491+ "safer-buffer": ">= 2.1.2 < 3.0.0"
492+ },
493+ "engines": {
494+ "node": ">=0.10.0"
495+ }
496+ },
497+ "node_modules/ieee754": {
498+ "version": "1.2.1",
499+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
500+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
501+ "dev": true,
502+ "funding": [
503+ {
504+ "type": "github",
505+ "url": "https://github.com/sponsors/feross"
506+ },
507+ {
508+ "type": "patreon",
509+ "url": "https://www.patreon.com/feross"
510+ },
511+ {
512+ "type": "consulting",
513+ "url": "https://feross.org/support"
514+ }
515+ ]
516+ },
517+ "node_modules/imurmurhash": {
518+ "version": "0.1.4",
519+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
520+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
521+ "dev": true,
522+ "engines": {
523+ "node": ">=0.8.19"
524+ }
525+ },
526+ "node_modules/indent-string": {
527+ "version": "4.0.0",
528+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
529+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
530+ "dev": true,
531+ "engines": {
532+ "node": ">=8"
533+ }
534+ },
535+ "node_modules/infer-owner": {
536+ "version": "1.0.4",
537+ "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
538+ "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
539+ "dev": true
540+ },
541+ "node_modules/inflight": {
542+ "version": "1.0.6",
543+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
544+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
545+ "dev": true,
546+ "dependencies": {
547+ "once": "^1.3.0",
548+ "wrappy": "1"
549+ }
550+ },
551+ "node_modules/inherits": {
552+ "version": "2.0.4",
553+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
554+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
555+ "dev": true
556+ },
557+ "node_modules/ip": {
558+ "version": "2.0.0",
559+ "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
560+ "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
561+ "dev": true
562+ },
563+ "node_modules/is-lambda": {
564+ "version": "1.0.1",
565+ "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
566+ "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
567+ "dev": true
568+ },
569+ "node_modules/linkify-it": {
570+ "version": "3.0.3",
571+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
572+ "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
573+ "dev": true,
574+ "dependencies": {
575+ "uc.micro": "^1.0.1"
576+ }
577+ },
578+ "node_modules/lru-cache": {
579+ "version": "6.0.0",
580+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
581+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
582+ "dev": true,
583+ "dependencies": {
584+ "yallist": "^4.0.0"
585+ },
586+ "engines": {
587+ "node": ">=10"
588+ }
589+ },
590+ "node_modules/make-fetch-happen": {
591+ "version": "9.1.0",
592+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
593+ "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
594+ "dev": true,
595+ "dependencies": {
596+ "agentkeepalive": "^4.1.3",
597+ "cacache": "^15.2.0",
598+ "http-cache-semantics": "^4.1.0",
599+ "http-proxy-agent": "^4.0.1",
600+ "https-proxy-agent": "^5.0.0",
601+ "is-lambda": "^1.0.1",
602+ "lru-cache": "^6.0.0",
603+ "minipass": "^3.1.3",
604+ "minipass-collect": "^1.0.2",
605+ "minipass-fetch": "^1.3.2",
606+ "minipass-flush": "^1.0.5",
607+ "minipass-pipeline": "^1.2.4",
608+ "negotiator": "^0.6.2",
609+ "promise-retry": "^2.0.1",
610+ "socks-proxy-agent": "^6.0.0",
611+ "ssri": "^8.0.0"
612+ },
613+ "engines": {
614+ "node": ">= 10"
615+ }
616+ },
617+ "node_modules/markdown-it": {
618+ "version": "12.3.2",
619+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
620+ "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
621+ "dev": true,
622+ "dependencies": {
623+ "argparse": "^2.0.1",
624+ "entities": "~2.1.0",
625+ "linkify-it": "^3.0.1",
626+ "mdurl": "^1.0.1",
627+ "uc.micro": "^1.0.5"
628+ },
629+ "bin": {
630+ "markdown-it": "bin/markdown-it.js"
631+ }
632+ },
633+ "node_modules/mdurl": {
634+ "version": "1.0.1",
635+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
636+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
637+ "dev": true
638+ },
639+ "node_modules/minimatch": {
640+ "version": "3.0.4",
641+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
642+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
643+ "dev": true,
644+ "dependencies": {
645+ "brace-expansion": "^1.1.7"
646+ },
647+ "engines": {
648+ "node": "*"
649+ }
650+ },
651+ "node_modules/minipass": {
652+ "version": "3.3.4",
653+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz",
654+ "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==",
655+ "dev": true,
656+ "dependencies": {
657+ "yallist": "^4.0.0"
658+ },
659+ "engines": {
660+ "node": ">=8"
661+ }
662+ },
663+ "node_modules/minipass-collect": {
664+ "version": "1.0.2",
665+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
666+ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
667+ "dev": true,
668+ "dependencies": {
669+ "minipass": "^3.0.0"
670+ },
671+ "engines": {
672+ "node": ">= 8"
673+ }
674+ },
675+ "node_modules/minipass-fetch": {
676+ "version": "1.4.1",
677+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
678+ "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
679+ "dev": true,
680+ "dependencies": {
681+ "minipass": "^3.1.0",
682+ "minipass-sized": "^1.0.3",
683+ "minizlib": "^2.0.0"
684+ },
685+ "engines": {
686+ "node": ">=8"
687+ },
688+ "optionalDependencies": {
689+ "encoding": "^0.1.12"
690+ }
691+ },
692+ "node_modules/minipass-flush": {
693+ "version": "1.0.5",
694+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
695+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
696+ "dev": true,
697+ "dependencies": {
698+ "minipass": "^3.0.0"
699+ },
700+ "engines": {
701+ "node": ">= 8"
702+ }
703+ },
704+ "node_modules/minipass-pipeline": {
705+ "version": "1.2.4",
706+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
707+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
708+ "dev": true,
709+ "dependencies": {
710+ "minipass": "^3.0.0"
711+ },
712+ "engines": {
713+ "node": ">=8"
714+ }
715+ },
716+ "node_modules/minipass-sized": {
717+ "version": "1.0.3",
718+ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
719+ "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
720+ "dev": true,
721+ "dependencies": {
722+ "minipass": "^3.0.0"
723+ },
724+ "engines": {
725+ "node": ">=8"
726+ }
727+ },
728+ "node_modules/minizlib": {
729+ "version": "2.1.2",
730+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
731+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
732+ "dev": true,
733+ "dependencies": {
734+ "minipass": "^3.0.0",
735+ "yallist": "^4.0.0"
736+ },
737+ "engines": {
738+ "node": ">= 8"
739+ }
740+ },
741+ "node_modules/mkdirp": {
742+ "version": "1.0.4",
743+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
744+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
745+ "dev": true,
746+ "bin": {
747+ "mkdirp": "bin/cmd.js"
748+ },
749+ "engines": {
750+ "node": ">=10"
751+ }
752+ },
753+ "node_modules/mkdirp-classic": {
754+ "version": "0.5.3",
755+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
756+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
757+ "dev": true
758+ },
759+ "node_modules/ms": {
760+ "version": "2.1.2",
761+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
762+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
763+ "dev": true
764+ },
765+ "node_modules/negotiator": {
766+ "version": "0.6.3",
767+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
768+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
769+ "dev": true,
770+ "engines": {
771+ "node": ">= 0.6"
772+ }
773+ },
774+ "node_modules/node-fetch": {
775+ "version": "2.6.1",
776+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
777+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
778+ "dev": true,
779+ "engines": {
780+ "node": "4.x || >=6.0.0"
781+ }
782+ },
783+ "node_modules/once": {
784+ "version": "1.4.0",
785+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
786+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
787+ "dev": true,
788+ "dependencies": {
789+ "wrappy": "1"
790+ }
791+ },
792+ "node_modules/p-limit": {
793+ "version": "2.3.0",
794+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
795+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
796+ "dev": true,
797+ "dependencies": {
798+ "p-try": "^2.0.0"
799+ },
800+ "engines": {
801+ "node": ">=6"
802+ },
803+ "funding": {
804+ "url": "https://github.com/sponsors/sindresorhus"
805+ }
806+ },
807+ "node_modules/p-map": {
808+ "version": "4.0.0",
809+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
810+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
811+ "dev": true,
812+ "dependencies": {
813+ "aggregate-error": "^3.0.0"
814+ },
815+ "engines": {
816+ "node": ">=10"
817+ },
818+ "funding": {
819+ "url": "https://github.com/sponsors/sindresorhus"
820+ }
821+ },
822+ "node_modules/p-try": {
823+ "version": "2.2.0",
824+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
825+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
826+ "dev": true,
827+ "engines": {
828+ "node": ">=6"
829+ }
830+ },
831+ "node_modules/path-is-absolute": {
832+ "version": "1.0.1",
833+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
834+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
835+ "dev": true,
836+ "engines": {
837+ "node": ">=0.10.0"
838+ }
839+ },
840+ "node_modules/pend": {
841+ "version": "1.2.0",
842+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
843+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
844+ "dev": true
845+ },
846+ "node_modules/pkg-dir": {
847+ "version": "4.2.0",
848+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
849+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
850+ "dev": true,
851+ "dependencies": {
852+ "find-up": "^4.0.0"
853+ },
854+ "engines": {
855+ "node": ">=8"
856+ }
857+ },
858+ "node_modules/pkg-dir/node_modules/find-up": {
859+ "version": "4.1.0",
860+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
861+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
862+ "dev": true,
863+ "dependencies": {
864+ "locate-path": "^5.0.0",
865+ "path-exists": "^4.0.0"
866+ },
867+ "engines": {
868+ "node": ">=8"
869+ }
870+ },
871+ "node_modules/pkg-dir/node_modules/locate-path": {
872+ "version": "5.0.0",
873+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
874+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
875+ "dev": true,
876+ "dependencies": {
877+ "p-locate": "^4.1.0"
878+ },
879+ "engines": {
880+ "node": ">=8"
881+ }
882+ },
883+ "node_modules/pkg-dir/node_modules/p-locate": {
884+ "version": "4.1.0",
885+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
886+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
887+ "dev": true,
888+ "dependencies": {
889+ "p-limit": "^2.2.0"
890+ },
891+ "engines": {
892+ "node": ">=8"
893+ }
894+ },
895+ "node_modules/pkg-dir/node_modules/path-exists": {
896+ "version": "4.0.0",
897+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
898+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
899+ "dev": true,
900+ "engines": {
901+ "node": ">=8"
902+ }
903+ },
904+ "node_modules/progress": {
905+ "version": "2.0.3",
906+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
907+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
908+ "dev": true,
909+ "engines": {
910+ "node": ">=0.4.0"
911+ }
912+ },
913+ "node_modules/promise-inflight": {
914+ "version": "1.0.1",
915+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
916+ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
917+ "dev": true
918+ },
919+ "node_modules/promise-retry": {
920+ "version": "2.0.1",
921+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
922+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
923+ "dev": true,
924+ "dependencies": {
925+ "err-code": "^2.0.2",
926+ "retry": "^0.12.0"
927+ },
928+ "engines": {
929+ "node": ">=10"
930+ }
931+ },
932+ "node_modules/proxy-from-env": {
933+ "version": "1.1.0",
934+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
935+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
936+ "dev": true
937+ },
938+ "node_modules/pump": {
939+ "version": "3.0.0",
940+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
941+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
942+ "dev": true,
943+ "dependencies": {
944+ "end-of-stream": "^1.1.0",
945+ "once": "^1.3.1"
946+ }
947+ },
948+ "node_modules/punycode": {
949+ "version": "2.1.1",
950+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
951+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
952+ "engines": {
953+ "node": ">=6"
954+ }
955+ },
956+ "node_modules/puppeteer": {
957+ "version": "8.0.0",
958+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-8.0.0.tgz",
959+ "integrity": "sha512-D0RzSWlepeWkxPPdK3xhTcefj8rjah1791GE82Pdjsri49sy11ci/JQsAO8K2NRukqvwEtcI+ImP5F4ZiMvtIQ==",
960+ "deprecated": "Version no longer supported. Upgrade to @latest",
961+ "dev": true,
962+ "hasInstallScript": true,
963+ "dependencies": {
964+ "debug": "^4.1.0",
965+ "devtools-protocol": "0.0.854822",
966+ "extract-zip": "^2.0.0",
967+ "https-proxy-agent": "^5.0.0",
968+ "node-fetch": "^2.6.1",
969+ "pkg-dir": "^4.2.0",
970+ "progress": "^2.0.1",
971+ "proxy-from-env": "^1.1.0",
972+ "rimraf": "^3.0.2",
973+ "tar-fs": "^2.0.0",
974+ "unbzip2-stream": "^1.3.3",
975+ "ws": "^7.2.3"
976+ },
977+ "engines": {
978+ "node": ">=10.18.1"
979+ }
980+ },
981+ "node_modules/puppeteer/node_modules/ws": {
982+ "version": "7.4.4",
983+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
984+ "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==",
985+ "dev": true,
986+ "engines": {
987+ "node": ">=8.3.0"
988+ },
989+ "peerDependencies": {
990+ "bufferutil": "^4.0.1",
991+ "utf-8-validate": "^5.0.2"
992+ },
993+ "peerDependenciesMeta": {
994+ "bufferutil": {
995+ "optional": true
996+ },
997+ "utf-8-validate": {
998+ "optional": true
999+ }
1000+ }
1001+ },
1002+ "node_modules/retry": {
1003+ "version": "0.12.0",
1004+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
1005+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
1006+ "dev": true,
1007+ "engines": {
1008+ "node": ">= 4"
1009+ }
1010+ },
1011+ "node_modules/rimraf": {
1012+ "version": "3.0.2",
1013+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
1014+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
1015+ "dev": true,
1016+ "dependencies": {
1017+ "glob": "^7.1.3"
1018+ },
1019+ "bin": {
1020+ "rimraf": "bin.js"
1021+ },
1022+ "funding": {
1023+ "url": "https://github.com/sponsors/isaacs"
1024+ }
1025+ },
1026+ "node_modules/safe-buffer": {
1027+ "version": "5.2.1",
1028+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1029+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1030+ "dev": true,
1031+ "funding": [
1032+ {
1033+ "type": "github",
1034+ "url": "https://github.com/sponsors/feross"
1035+ },
1036+ {
1037+ "type": "patreon",
1038+ "url": "https://www.patreon.com/feross"
1039+ },
1040+ {
1041+ "type": "consulting",
1042+ "url": "https://feross.org/support"
1043+ }
1044+ ]
1045+ },
1046+ "node_modules/safer-buffer": {
1047+ "version": "2.1.2",
1048+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1049+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1050+ "dev": true,
1051+ "optional": true
1052+ },
1053+ "node_modules/semver": {
1054+ "version": "7.3.7",
1055+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
1056+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
1057+ "dev": true,
1058+ "dependencies": {
1059+ "lru-cache": "^6.0.0"
1060+ },
1061+ "bin": {
1062+ "semver": "bin/semver.js"
1063+ },
1064+ "engines": {
1065+ "node": ">=10"
1066+ }
1067+ },
1068+ "node_modules/smart-buffer": {
1069+ "version": "4.2.0",
1070+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
1071+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
1072+ "dev": true,
1073+ "engines": {
1074+ "node": ">= 6.0.0",
1075+ "npm": ">= 3.0.0"
1076+ }
1077+ },
1078+ "node_modules/socks": {
1079+ "version": "2.7.0",
1080+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz",
1081+ "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==",
1082+ "dev": true,
1083+ "dependencies": {
1084+ "ip": "^2.0.0",
1085+ "smart-buffer": "^4.2.0"
1086+ },
1087+ "engines": {
1088+ "node": ">= 10.13.0",
1089+ "npm": ">= 3.0.0"
1090+ }
1091+ },
1092+ "node_modules/socks-proxy-agent": {
1093+ "version": "6.2.1",
1094+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
1095+ "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
1096+ "dev": true,
1097+ "dependencies": {
1098+ "agent-base": "^6.0.2",
1099+ "debug": "^4.3.3",
1100+ "socks": "^2.6.2"
1101+ },
1102+ "engines": {
1103+ "node": ">= 10"
1104+ }
1105+ },
1106+ "node_modules/spago": {
1107+ "version": "0.20.9",
1108+ "resolved": "https://registry.npmjs.org/spago/-/spago-0.20.9.tgz",
1109+ "integrity": "sha512-r5TUxnYn9HawlQyMswlhIk24BGFSN2KGbqgZFZrn47GjTpMscU14xkt9CqTWgoSQYsoZieG+3dUtOxUQ7GYD7w==",
1110+ "dev": true,
1111+ "hasInstallScript": true,
1112+ "dependencies": {
1113+ "make-fetch-happen": "^9.1.0",
1114+ "tar": "^6.1.11"
1115+ },
1116+ "bin": {
1117+ "spago": "spago"
1118+ }
1119+ },
1120+ "node_modules/ssri": {
1121+ "version": "8.0.1",
1122+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
1123+ "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
1124+ "dev": true,
1125+ "dependencies": {
1126+ "minipass": "^3.1.1"
1127+ },
1128+ "engines": {
1129+ "node": ">= 8"
1130+ }
1131+ },
1132+ "node_modules/string_decoder": {
1133+ "version": "1.3.0",
1134+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
1135+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
1136+ "dev": true,
1137+ "dependencies": {
1138+ "safe-buffer": "~5.2.0"
1139+ }
1140+ },
1141+ "node_modules/tar": {
1142+ "version": "6.1.11",
1143+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
1144+ "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
1145+ "dev": true,
1146+ "dependencies": {
1147+ "chownr": "^2.0.0",
1148+ "fs-minipass": "^2.0.0",
1149+ "minipass": "^3.0.0",
1150+ "minizlib": "^2.1.1",
1151+ "mkdirp": "^1.0.3",
1152+ "yallist": "^4.0.0"
1153+ },
1154+ "engines": {
1155+ "node": ">= 10"
1156+ }
1157+ },
1158+ "node_modules/tar-fs": {
1159+ "version": "2.1.1",
1160+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
1161+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
1162+ "dev": true,
1163+ "dependencies": {
1164+ "chownr": "^1.1.1",
1165+ "mkdirp-classic": "^0.5.2",
1166+ "pump": "^3.0.0",
1167+ "tar-stream": "^2.1.4"
1168+ }
1169+ },
1170+ "node_modules/tar-stream": {
1171+ "version": "2.2.0",
1172+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
1173+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
1174+ "dev": true,
1175+ "dependencies": {
1176+ "bl": "^4.0.3",
1177+ "end-of-stream": "^1.4.1",
1178+ "fs-constants": "^1.0.0",
1179+ "inherits": "^2.0.3",
1180+ "readable-stream": "^3.1.1"
1181+ },
1182+ "engines": {
1183+ "node": ">=6"
1184+ }
1185+ },
1186+ "node_modules/tar-stream/node_modules/readable-stream": {
1187+ "version": "3.6.0",
1188+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
1189+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
1190+ "dev": true,
1191+ "dependencies": {
1192+ "inherits": "^2.0.3",
1193+ "string_decoder": "^1.1.1",
1194+ "util-deprecate": "^1.0.1"
1195+ },
1196+ "engines": {
1197+ "node": ">= 6"
1198+ }
1199+ },
1200+ "node_modules/tar/node_modules/chownr": {
1201+ "version": "2.0.0",
1202+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
1203+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
1204+ "dev": true,
1205+ "engines": {
1206+ "node": ">=10"
1207+ }
1208+ },
1209+ "node_modules/through": {
1210+ "version": "2.3.8",
1211+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
1212+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
1213+ "dev": true
1214+ },
1215+ "node_modules/uc.micro": {
1216+ "version": "1.0.6",
1217+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
1218+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
1219+ "dev": true
1220+ },
1221+ "node_modules/unbzip2-stream": {
1222+ "version": "1.4.3",
1223+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
1224+ "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
1225+ "dev": true,
1226+ "dependencies": {
1227+ "buffer": "^5.2.1",
1228+ "through": "^2.3.8"
1229+ }
1230+ },
1231+ "node_modules/unbzip2-stream/node_modules/buffer": {
1232+ "version": "5.7.1",
1233+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
1234+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
1235+ "dev": true,
1236+ "funding": [
1237+ {
1238+ "type": "github",
1239+ "url": "https://github.com/sponsors/feross"
1240+ },
1241+ {
1242+ "type": "patreon",
1243+ "url": "https://www.patreon.com/feross"
1244+ },
1245+ {
1246+ "type": "consulting",
1247+ "url": "https://feross.org/support"
1248+ }
1249+ ],
1250+ "dependencies": {
1251+ "base64-js": "^1.3.1",
1252+ "ieee754": "^1.1.13"
1253+ }
1254+ },
1255+ "node_modules/unique-filename": {
1256+ "version": "1.1.1",
1257+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
1258+ "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
1259+ "dev": true,
1260+ "dependencies": {
1261+ "unique-slug": "^2.0.0"
1262+ }
1263+ },
1264+ "node_modules/unique-slug": {
1265+ "version": "2.0.2",
1266+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
1267+ "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
1268+ "dev": true,
1269+ "dependencies": {
1270+ "imurmurhash": "^0.1.4"
1271+ }
1272+ },
1273+ "node_modules/util-deprecate": {
1274+ "version": "1.0.2",
1275+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1276+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
1277+ "dev": true
1278+ },
1279+ "node_modules/wrappy": {
1280+ "version": "1.0.2",
1281+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1282+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1283+ "dev": true
1284+ },
1285+ "node_modules/yallist": {
1286+ "version": "4.0.0",
1287+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
1288+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
1289+ "dev": true
1290+ },
1291+ "node_modules/yauzl": {
1292+ "version": "2.10.0",
1293+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
1294+ "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
1295+ "dev": true,
1296+ "dependencies": {
1297+ "buffer-crc32": "~0.2.3",
1298+ "fd-slicer": "~1.1.0"
1299+ }
1300+ }
1301+ },
1302+ "dependencies": {
1303+ "@gar/promisify": {
1304+ "version": "1.1.3",
1305+ "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
1306+ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
1307+ "dev": true
1308+ },
1309+ "@npmcli/fs": {
1310+ "version": "1.1.1",
1311+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
1312+ "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
1313+ "dev": true,
1314+ "requires": {
1315+ "@gar/promisify": "^1.0.1",
1316+ "semver": "^7.3.5"
1317+ }
1318+ },
1319+ "@npmcli/move-file": {
1320+ "version": "1.1.2",
1321+ "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
1322+ "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
1323+ "dev": true,
1324+ "requires": {
1325+ "mkdirp": "^1.0.4",
1326+ "rimraf": "^3.0.2"
1327+ }
1328+ },
1329+ "@tootallnate/once": {
1330+ "version": "1.1.2",
1331+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
1332+ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
1333+ "dev": true
1334+ },
1335+ "@types/node": {
1336+ "version": "14.14.39",
1337+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.39.tgz",
1338+ "integrity": "sha512-Qipn7rfTxGEDqZiezH+wxqWYR8vcXq5LRpZrETD19Gs4o8LbklbmqotSUsMU+s5G3PJwMRDfNEYoxrcBwIxOuw==",
1339+ "dev": true,
1340+ "optional": true
1341+ },
1342+ "@types/yauzl": {
1343+ "version": "2.9.1",
1344+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
1345+ "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
1346+ "dev": true,
1347+ "optional": true,
1348+ "requires": {
1349+ "@types/node": "*"
1350+ }
1351+ },
1352+ "agent-base": {
1353+ "version": "6.0.2",
1354+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
1355+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
1356+ "dev": true,
1357+ "requires": {
1358+ "debug": "4"
1359+ }
1360+ },
1361+ "agentkeepalive": {
1362+ "version": "4.2.1",
1363+ "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz",
1364+ "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==",
1365+ "dev": true,
1366+ "requires": {
1367+ "debug": "^4.1.0",
1368+ "depd": "^1.1.2",
1369+ "humanize-ms": "^1.2.1"
1370+ }
1371+ },
1372+ "aggregate-error": {
1373+ "version": "3.1.0",
1374+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
1375+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
1376+ "dev": true,
1377+ "requires": {
1378+ "clean-stack": "^2.0.0",
1379+ "indent-string": "^4.0.0"
1380+ }
1381+ },
1382+ "argparse": {
1383+ "version": "2.0.1",
1384+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
1385+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
1386+ "dev": true
1387+ },
1388+ "balanced-match": {
1389+ "version": "1.0.0",
1390+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
1391+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
1392+ "dev": true
1393+ },
1394+ "base64-js": {
1395+ "version": "1.5.1",
1396+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
1397+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
1398+ "dev": true
1399+ },
1400+ "bl": {
1401+ "version": "4.1.0",
1402+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
1403+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
1404+ "dev": true,
1405+ "requires": {
1406+ "buffer": "^5.5.0",
1407+ "inherits": "^2.0.4",
1408+ "readable-stream": "^3.4.0"
1409+ },
1410+ "dependencies": {
1411+ "buffer": {
1412+ "version": "5.7.1",
1413+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
1414+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
1415+ "dev": true,
1416+ "requires": {
1417+ "base64-js": "^1.3.1",
1418+ "ieee754": "^1.1.13"
1419+ }
1420+ },
1421+ "readable-stream": {
1422+ "version": "3.6.0",
1423+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
1424+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
1425+ "dev": true,
1426+ "requires": {
1427+ "inherits": "^2.0.3",
1428+ "string_decoder": "^1.1.1",
1429+ "util-deprecate": "^1.0.1"
1430+ }
1431+ }
1432+ }
1433+ },
1434+ "brace-expansion": {
1435+ "version": "1.1.11",
1436+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
1437+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
1438+ "dev": true,
1439+ "requires": {
1440+ "balanced-match": "^1.0.0",
1441+ "concat-map": "0.0.1"
1442+ }
1443+ },
1444+ "buffer-crc32": {
1445+ "version": "0.2.13",
1446+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
1447+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
1448+ "dev": true
1449+ },
1450+ "cacache": {
1451+ "version": "15.3.0",
1452+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
1453+ "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
1454+ "dev": true,
1455+ "requires": {
1456+ "@npmcli/fs": "^1.0.0",
1457+ "@npmcli/move-file": "^1.0.1",
1458+ "chownr": "^2.0.0",
1459+ "fs-minipass": "^2.0.0",
1460+ "glob": "^7.1.4",
1461+ "infer-owner": "^1.0.4",
1462+ "lru-cache": "^6.0.0",
1463+ "minipass": "^3.1.1",
1464+ "minipass-collect": "^1.0.2",
1465+ "minipass-flush": "^1.0.5",
1466+ "minipass-pipeline": "^1.2.2",
1467+ "mkdirp": "^1.0.3",
1468+ "p-map": "^4.0.0",
1469+ "promise-inflight": "^1.0.1",
1470+ "rimraf": "^3.0.2",
1471+ "ssri": "^8.0.1",
1472+ "tar": "^6.0.2",
1473+ "unique-filename": "^1.1.1"
1474+ },
1475+ "dependencies": {
1476+ "chownr": {
1477+ "version": "2.0.0",
1478+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
1479+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
1480+ "dev": true
1481+ }
1482+ }
1483+ },
1484+ "chownr": {
1485+ "version": "1.1.4",
1486+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
1487+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
1488+ "dev": true
1489+ },
1490+ "clean-stack": {
1491+ "version": "2.2.0",
1492+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
1493+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
1494+ "dev": true
1495+ },
1496+ "concat-map": {
1497+ "version": "0.0.1",
1498+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
1499+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
1500+ "dev": true
1501+ },
1502+ "debug": {
1503+ "version": "4.3.4",
1504+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
1505+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
1506+ "dev": true,
1507+ "requires": {
1508+ "ms": "2.1.2"
1509+ }
1510+ },
1511+ "depd": {
1512+ "version": "1.1.2",
1513+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
1514+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
1515+ "dev": true
1516+ },
1517+ "devtools-protocol": {
1518+ "version": "0.0.854822",
1519+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.854822.tgz",
1520+ "integrity": "sha512-xd4D8kHQtB0KtWW0c9xBZD5LVtm9chkMOfs/3Yn01RhT/sFIsVtzTtypfKoFfWBaL+7xCYLxjOLkhwPXaX/Kcg==",
1521+ "dev": true
1522+ },
1523+ "encoding": {
1524+ "version": "0.1.13",
1525+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
1526+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
1527+ "dev": true,
1528+ "optional": true,
1529+ "requires": {
1530+ "iconv-lite": "^0.6.2"
1531+ }
1532+ },
1533+ "end-of-stream": {
1534+ "version": "1.4.4",
1535+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
1536+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
1537+ "dev": true,
1538+ "requires": {
1539+ "once": "^1.4.0"
1540+ }
1541+ },
1542+ "entities": {
1543+ "version": "2.1.0",
1544+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
1545+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
1546+ "dev": true
1547+ },
1548+ "err-code": {
1549+ "version": "2.0.3",
1550+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
1551+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
1552+ "dev": true
1553+ },
1554+ "esbuild": {
1555+ "version": "0.11.11",
1556+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.11.tgz",
1557+ "integrity": "sha512-iq5YdV63vY/nUAFIvY92BXVkYjMbOchnofLKoLKMPZIa4uuIJAJG9WRA+ZRjQBZbrsORUwvZcANeG2d3p46PJQ==",
1558+ "dev": true
1559+ },
1560+ "extract-zip": {
1561+ "version": "2.0.1",
1562+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
1563+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
1564+ "dev": true,
1565+ "requires": {
1566+ "@types/yauzl": "^2.9.1",
1567+ "debug": "^4.1.1",
1568+ "get-stream": "^5.1.0",
1569+ "yauzl": "^2.10.0"
1570+ }
1571+ },
1572+ "fd-slicer": {
1573+ "version": "1.1.0",
1574+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
1575+ "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
1576+ "dev": true,
1577+ "requires": {
1578+ "pend": "~1.2.0"
1579+ }
1580+ },
1581+ "fs-constants": {
1582+ "version": "1.0.0",
1583+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
1584+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
1585+ "dev": true
1586+ },
1587+ "fs-minipass": {
1588+ "version": "2.1.0",
1589+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
1590+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
1591+ "dev": true,
1592+ "requires": {
1593+ "minipass": "^3.0.0"
1594+ }
1595+ },
1596+ "fs.realpath": {
1597+ "version": "1.0.0",
1598+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
1599+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
1600+ "dev": true
1601+ },
1602+ "get-stream": {
1603+ "version": "5.2.0",
1604+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
1605+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
1606+ "dev": true,
1607+ "requires": {
1608+ "pump": "^3.0.0"
1609+ }
1610+ },
1611+ "glob": {
1612+ "version": "7.1.6",
1613+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
1614+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
1615+ "dev": true,
1616+ "requires": {
1617+ "fs.realpath": "^1.0.0",
1618+ "inflight": "^1.0.4",
1619+ "inherits": "2",
1620+ "minimatch": "^3.0.4",
1621+ "once": "^1.3.0",
1622+ "path-is-absolute": "^1.0.0"
1623+ }
1624+ },
1625+ "http-cache-semantics": {
1626+ "version": "4.1.0",
1627+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
1628+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
1629+ "dev": true
1630+ },
1631+ "http-proxy-agent": {
1632+ "version": "4.0.1",
1633+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
1634+ "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
1635+ "dev": true,
1636+ "requires": {
1637+ "@tootallnate/once": "1",
1638+ "agent-base": "6",
1639+ "debug": "4"
1640+ }
1641+ },
1642+ "https-proxy-agent": {
1643+ "version": "5.0.0",
1644+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
1645+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
1646+ "dev": true,
1647+ "requires": {
1648+ "agent-base": "6",
1649+ "debug": "4"
1650+ }
1651+ },
1652+ "humanize-ms": {
1653+ "version": "1.2.1",
1654+ "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
1655+ "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
1656+ "dev": true,
1657+ "requires": {
1658+ "ms": "^2.0.0"
1659+ }
1660+ },
1661+ "iconv-lite": {
1662+ "version": "0.6.3",
1663+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
1664+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
1665+ "dev": true,
1666+ "optional": true,
1667+ "requires": {
1668+ "safer-buffer": ">= 2.1.2 < 3.0.0"
1669+ }
1670+ },
1671+ "ieee754": {
1672+ "version": "1.2.1",
1673+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
1674+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
1675+ "dev": true
1676+ },
1677+ "imurmurhash": {
1678+ "version": "0.1.4",
1679+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
1680+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
1681+ "dev": true
1682+ },
1683+ "indent-string": {
1684+ "version": "4.0.0",
1685+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
1686+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
1687+ "dev": true
1688+ },
1689+ "infer-owner": {
1690+ "version": "1.0.4",
1691+ "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
1692+ "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
1693+ "dev": true
1694+ },
1695+ "inflight": {
1696+ "version": "1.0.6",
1697+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1698+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
1699+ "dev": true,
1700+ "requires": {
1701+ "once": "^1.3.0",
1702+ "wrappy": "1"
1703+ }
1704+ },
1705+ "inherits": {
1706+ "version": "2.0.4",
1707+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1708+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1709+ "dev": true
1710+ },
1711+ "ip": {
1712+ "version": "2.0.0",
1713+ "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
1714+ "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
1715+ "dev": true
1716+ },
1717+ "is-lambda": {
1718+ "version": "1.0.1",
1719+ "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
1720+ "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
1721+ "dev": true
1722+ },
1723+ "linkify-it": {
1724+ "version": "3.0.3",
1725+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
1726+ "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
1727+ "dev": true,
1728+ "requires": {
1729+ "uc.micro": "^1.0.1"
1730+ }
1731+ },
1732+ "lru-cache": {
1733+ "version": "6.0.0",
1734+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
1735+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
1736+ "dev": true,
1737+ "requires": {
1738+ "yallist": "^4.0.0"
1739+ }
1740+ },
1741+ "make-fetch-happen": {
1742+ "version": "9.1.0",
1743+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
1744+ "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
1745+ "dev": true,
1746+ "requires": {
1747+ "agentkeepalive": "^4.1.3",
1748+ "cacache": "^15.2.0",
1749+ "http-cache-semantics": "^4.1.0",
1750+ "http-proxy-agent": "^4.0.1",
1751+ "https-proxy-agent": "^5.0.0",
1752+ "is-lambda": "^1.0.1",
1753+ "lru-cache": "^6.0.0",
1754+ "minipass": "^3.1.3",
1755+ "minipass-collect": "^1.0.2",
1756+ "minipass-fetch": "^1.3.2",
1757+ "minipass-flush": "^1.0.5",
1758+ "minipass-pipeline": "^1.2.4",
1759+ "negotiator": "^0.6.2",
1760+ "promise-retry": "^2.0.1",
1761+ "socks-proxy-agent": "^6.0.0",
1762+ "ssri": "^8.0.0"
1763+ }
1764+ },
1765+ "markdown-it": {
1766+ "version": "12.3.2",
1767+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
1768+ "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
1769+ "dev": true,
1770+ "requires": {
1771+ "argparse": "^2.0.1",
1772+ "entities": "~2.1.0",
1773+ "linkify-it": "^3.0.1",
1774+ "mdurl": "^1.0.1",
1775+ "uc.micro": "^1.0.5"
1776+ }
1777+ },
1778+ "mdurl": {
1779+ "version": "1.0.1",
1780+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
1781+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
1782+ "dev": true
1783+ },
1784+ "minimatch": {
1785+ "version": "3.0.4",
1786+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
1787+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1788+ "dev": true,
1789+ "requires": {
1790+ "brace-expansion": "^1.1.7"
1791+ }
1792+ },
1793+ "minipass": {
1794+ "version": "3.3.4",
1795+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz",
1796+ "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==",
1797+ "dev": true,
1798+ "requires": {
1799+ "yallist": "^4.0.0"
1800+ }
1801+ },
1802+ "minipass-collect": {
1803+ "version": "1.0.2",
1804+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
1805+ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
1806+ "dev": true,
1807+ "requires": {
1808+ "minipass": "^3.0.0"
1809+ }
1810+ },
1811+ "minipass-fetch": {
1812+ "version": "1.4.1",
1813+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
1814+ "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
1815+ "dev": true,
1816+ "requires": {
1817+ "encoding": "^0.1.12",
1818+ "minipass": "^3.1.0",
1819+ "minipass-sized": "^1.0.3",
1820+ "minizlib": "^2.0.0"
1821+ }
1822+ },
1823+ "minipass-flush": {
1824+ "version": "1.0.5",
1825+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
1826+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
1827+ "dev": true,
1828+ "requires": {
1829+ "minipass": "^3.0.0"
1830+ }
1831+ },
1832+ "minipass-pipeline": {
1833+ "version": "1.2.4",
1834+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
1835+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
1836+ "dev": true,
1837+ "requires": {
1838+ "minipass": "^3.0.0"
1839+ }
1840+ },
1841+ "minipass-sized": {
1842+ "version": "1.0.3",
1843+ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
1844+ "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
1845+ "dev": true,
1846+ "requires": {
1847+ "minipass": "^3.0.0"
1848+ }
1849+ },
1850+ "minizlib": {
1851+ "version": "2.1.2",
1852+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
1853+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
1854+ "dev": true,
1855+ "requires": {
1856+ "minipass": "^3.0.0",
1857+ "yallist": "^4.0.0"
1858+ }
1859+ },
1860+ "mkdirp": {
1861+ "version": "1.0.4",
1862+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
1863+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
1864+ "dev": true
1865+ },
1866+ "mkdirp-classic": {
1867+ "version": "0.5.3",
1868+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
1869+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
1870+ "dev": true
1871+ },
1872+ "ms": {
1873+ "version": "2.1.2",
1874+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1875+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
1876+ "dev": true
1877+ },
1878+ "negotiator": {
1879+ "version": "0.6.3",
1880+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1881+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
1882+ "dev": true
1883+ },
1884+ "node-fetch": {
1885+ "version": "2.6.1",
1886+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
1887+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
1888+ "dev": true
1889+ },
1890+ "once": {
1891+ "version": "1.4.0",
1892+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1893+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1894+ "dev": true,
1895+ "requires": {
1896+ "wrappy": "1"
1897+ }
1898+ },
1899+ "p-limit": {
1900+ "version": "2.3.0",
1901+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
1902+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
1903+ "dev": true,
1904+ "requires": {
1905+ "p-try": "^2.0.0"
1906+ }
1907+ },
1908+ "p-map": {
1909+ "version": "4.0.0",
1910+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
1911+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
1912+ "dev": true,
1913+ "requires": {
1914+ "aggregate-error": "^3.0.0"
1915+ }
1916+ },
1917+ "p-try": {
1918+ "version": "2.2.0",
1919+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
1920+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
1921+ "dev": true
1922+ },
1923+ "path-is-absolute": {
1924+ "version": "1.0.1",
1925+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1926+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
1927+ "dev": true
1928+ },
1929+ "pend": {
1930+ "version": "1.2.0",
1931+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
1932+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
1933+ "dev": true
1934+ },
1935+ "pkg-dir": {
1936+ "version": "4.2.0",
1937+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
1938+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
1939+ "dev": true,
1940+ "requires": {
1941+ "find-up": "^4.0.0"
1942+ },
1943+ "dependencies": {
1944+ "find-up": {
1945+ "version": "4.1.0",
1946+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
1947+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
1948+ "dev": true,
1949+ "requires": {
1950+ "locate-path": "^5.0.0",
1951+ "path-exists": "^4.0.0"
1952+ }
1953+ },
1954+ "locate-path": {
1955+ "version": "5.0.0",
1956+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
1957+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
1958+ "dev": true,
1959+ "requires": {
1960+ "p-locate": "^4.1.0"
1961+ }
1962+ },
1963+ "p-locate": {
1964+ "version": "4.1.0",
1965+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
1966+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
1967+ "dev": true,
1968+ "requires": {
1969+ "p-limit": "^2.2.0"
1970+ }
1971+ },
1972+ "path-exists": {
1973+ "version": "4.0.0",
1974+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
1975+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
1976+ "dev": true
1977+ }
1978+ }
1979+ },
1980+ "progress": {
1981+ "version": "2.0.3",
1982+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
1983+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
1984+ "dev": true
1985+ },
1986+ "promise-inflight": {
1987+ "version": "1.0.1",
1988+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
1989+ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
1990+ "dev": true
1991+ },
1992+ "promise-retry": {
1993+ "version": "2.0.1",
1994+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
1995+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
1996+ "dev": true,
1997+ "requires": {
1998+ "err-code": "^2.0.2",
1999+ "retry": "^0.12.0"
2000+ }
2001+ },
2002+ "proxy-from-env": {
2003+ "version": "1.1.0",
2004+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
2005+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
2006+ "dev": true
2007+ },
2008+ "pump": {
2009+ "version": "3.0.0",
2010+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
2011+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
2012+ "dev": true,
2013+ "requires": {
2014+ "end-of-stream": "^1.1.0",
2015+ "once": "^1.3.1"
2016+ }
2017+ },
2018+ "punycode": {
2019+ "version": "2.1.1",
2020+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
2021+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
2022+ },
2023+ "puppeteer": {
2024+ "version": "8.0.0",
2025+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-8.0.0.tgz",
2026+ "integrity": "sha512-D0RzSWlepeWkxPPdK3xhTcefj8rjah1791GE82Pdjsri49sy11ci/JQsAO8K2NRukqvwEtcI+ImP5F4ZiMvtIQ==",
2027+ "dev": true,
2028+ "requires": {
2029+ "debug": "^4.1.0",
2030+ "devtools-protocol": "0.0.854822",
2031+ "extract-zip": "^2.0.0",
2032+ "https-proxy-agent": "^5.0.0",
2033+ "node-fetch": "^2.6.1",
2034+ "pkg-dir": "^4.2.0",
2035+ "progress": "^2.0.1",
2036+ "proxy-from-env": "^1.1.0",
2037+ "rimraf": "^3.0.2",
2038+ "tar-fs": "^2.0.0",
2039+ "unbzip2-stream": "^1.3.3",
2040+ "ws": "^7.2.3"
2041+ },
2042+ "dependencies": {
2043+ "ws": {
2044+ "version": "7.4.4",
2045+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
2046+ "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==",
2047+ "dev": true,
2048+ "requires": {}
2049+ }
2050+ }
2051+ },
2052+ "retry": {
2053+ "version": "0.12.0",
2054+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
2055+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
2056+ "dev": true
2057+ },
2058+ "rimraf": {
2059+ "version": "3.0.2",
2060+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
2061+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
2062+ "dev": true,
2063+ "requires": {
2064+ "glob": "^7.1.3"
2065+ }
2066+ },
2067+ "safe-buffer": {
2068+ "version": "5.2.1",
2069+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
2070+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
2071+ "dev": true
2072+ },
2073+ "safer-buffer": {
2074+ "version": "2.1.2",
2075+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
2076+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
2077+ "dev": true,
2078+ "optional": true
2079+ },
2080+ "semver": {
2081+ "version": "7.3.7",
2082+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
2083+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
2084+ "dev": true,
2085+ "requires": {
2086+ "lru-cache": "^6.0.0"
2087+ }
2088+ },
2089+ "smart-buffer": {
2090+ "version": "4.2.0",
2091+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
2092+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
2093+ "dev": true
2094+ },
2095+ "socks": {
2096+ "version": "2.7.0",
2097+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz",
2098+ "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==",
2099+ "dev": true,
2100+ "requires": {
2101+ "ip": "^2.0.0",
2102+ "smart-buffer": "^4.2.0"
2103+ }
2104+ },
2105+ "socks-proxy-agent": {
2106+ "version": "6.2.1",
2107+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
2108+ "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
2109+ "dev": true,
2110+ "requires": {
2111+ "agent-base": "^6.0.2",
2112+ "debug": "^4.3.3",
2113+ "socks": "^2.6.2"
2114+ }
2115+ },
2116+ "spago": {
2117+ "version": "0.20.9",
2118+ "resolved": "https://registry.npmjs.org/spago/-/spago-0.20.9.tgz",
2119+ "integrity": "sha512-r5TUxnYn9HawlQyMswlhIk24BGFSN2KGbqgZFZrn47GjTpMscU14xkt9CqTWgoSQYsoZieG+3dUtOxUQ7GYD7w==",
2120+ "dev": true,
2121+ "requires": {
2122+ "make-fetch-happen": "^9.1.0",
2123+ "tar": "^6.1.11"
2124+ }
2125+ },
2126+ "ssri": {
2127+ "version": "8.0.1",
2128+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
2129+ "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
2130+ "dev": true,
2131+ "requires": {
2132+ "minipass": "^3.1.1"
2133+ }
2134+ },
2135+ "string_decoder": {
2136+ "version": "1.3.0",
2137+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
2138+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
2139+ "dev": true,
2140+ "requires": {
2141+ "safe-buffer": "~5.2.0"
2142+ }
2143+ },
2144+ "tar": {
2145+ "version": "6.1.11",
2146+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
2147+ "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
2148+ "dev": true,
2149+ "requires": {
2150+ "chownr": "^2.0.0",
2151+ "fs-minipass": "^2.0.0",
2152+ "minipass": "^3.0.0",
2153+ "minizlib": "^2.1.1",
2154+ "mkdirp": "^1.0.3",
2155+ "yallist": "^4.0.0"
2156+ },
2157+ "dependencies": {
2158+ "chownr": {
2159+ "version": "2.0.0",
2160+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
2161+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
2162+ "dev": true
2163+ }
2164+ }
2165+ },
2166+ "tar-fs": {
2167+ "version": "2.1.1",
2168+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
2169+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
2170+ "dev": true,
2171+ "requires": {
2172+ "chownr": "^1.1.1",
2173+ "mkdirp-classic": "^0.5.2",
2174+ "pump": "^3.0.0",
2175+ "tar-stream": "^2.1.4"
2176+ }
2177+ },
2178+ "tar-stream": {
2179+ "version": "2.2.0",
2180+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
2181+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
2182+ "dev": true,
2183+ "requires": {
2184+ "bl": "^4.0.3",
2185+ "end-of-stream": "^1.4.1",
2186+ "fs-constants": "^1.0.0",
2187+ "inherits": "^2.0.3",
2188+ "readable-stream": "^3.1.1"
2189+ },
2190+ "dependencies": {
2191+ "readable-stream": {
2192+ "version": "3.6.0",
2193+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
2194+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
2195+ "dev": true,
2196+ "requires": {
2197+ "inherits": "^2.0.3",
2198+ "string_decoder": "^1.1.1",
2199+ "util-deprecate": "^1.0.1"
2200+ }
2201+ }
2202+ }
2203+ },
2204+ "through": {
2205+ "version": "2.3.8",
2206+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
2207+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
2208+ "dev": true
2209+ },
2210+ "uc.micro": {
2211+ "version": "1.0.6",
2212+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
2213+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
2214+ "dev": true
2215+ },
2216+ "unbzip2-stream": {
2217+ "version": "1.4.3",
2218+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
2219+ "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
2220+ "dev": true,
2221+ "requires": {
2222+ "buffer": "^5.2.1",
2223+ "through": "^2.3.8"
2224+ },
2225+ "dependencies": {
2226+ "buffer": {
2227+ "version": "5.7.1",
2228+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
2229+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
2230+ "dev": true,
2231+ "requires": {
2232+ "base64-js": "^1.3.1",
2233+ "ieee754": "^1.1.13"
2234+ }
2235+ }
2236+ }
2237+ },
2238+ "unique-filename": {
2239+ "version": "1.1.1",
2240+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
2241+ "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
2242+ "dev": true,
2243+ "requires": {
2244+ "unique-slug": "^2.0.0"
2245+ }
2246+ },
2247+ "unique-slug": {
2248+ "version": "2.0.2",
2249+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
2250+ "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
2251+ "dev": true,
2252+ "requires": {
2253+ "imurmurhash": "^0.1.4"
2254+ }
2255+ },
2256+ "util-deprecate": {
2257+ "version": "1.0.2",
2258+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
2259+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
2260+ "dev": true
2261+ },
2262+ "wrappy": {
2263+ "version": "1.0.2",
2264+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2265+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
2266+ "dev": true
2267+ },
2268+ "yallist": {
2269+ "version": "4.0.0",
2270+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
2271+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
2272+ "dev": true
2273+ },
2274+ "yauzl": {
2275+ "version": "2.10.0",
2276+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
2277+ "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
2278+ "dev": true,
2279+ "requires": {
2280+ "buffer-crc32": "~0.2.3",
2281+ "fd-slicer": "~1.1.0"
2282+ }
2283+ }
2284+ }
2285+}
package.json+23−20
@@ -1,37 +1,37 @@
11{
22 "name": "purescript-docs-search",
3− "version": "0.0.9",
3+ "type": "module",
4+ "version": "0.0.12",
45 "description": "Search frontend for the documentation generated by the PureScript compiler.",
56 "directories": {
67 "test": "test"
78 },
89 "bin": {
9− "purescript-docs-search": "dist/purescript-docs-search"
10+ "purescript-docs-search": "dist/purescript-docs-search.cjs"
1011 },
1112 "files": [
12− "dist/purescript-docs-search",
13+ "dist/purescript-docs-search.cjs",
1314 "dist/docs-search-app.js",
1415 "README.md",
1516 "CHANGELOG.md"
1617 ],
1718 "scripts": {
18− "test": "spago test && npm run check-version",
19+ "test": "spago docs --no-search && ./dist/purescript-docs-search.cjs build-index && spago test && npm run check-version",
1920 "bundle-app": "spago bundle-app --no-build --no-install -m Docs.Search.App --to dist/docs-search-app.js",
20− "parcel-app": "parcel build --no-source-maps --target browser --out-file dist/docs-search-app.js dist/docs-search-app.js",
21− "build-app": "npm run bundle-app && npm run parcel-app",
22− "bundle-main": "spago bundle-app --no-build --no-install -m Docs.Search.Main --to dist/main.js",
23− "parcel-main": "parcel build --no-source-maps --target node --bundle-node-modules --out-file dist/main.js dist/main.js",
24− "add-shebang": "echo \"#!/usr/bin/env node\" > dist/purescript-docs-search && cat dist/main.js >> dist/purescript-docs-search",
25− "chmod-main": "chmod +x dist/purescript-docs-search",
26− "build-main": "npm run bundle-main && npm run parcel-main && npm run add-shebang && rm dist/main.js && npm run chmod-main",
21+ "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",
22+ "build-app": "npm run bundle-app && npm run esbuild-app",
23+ "bundle-main": "spago bundle-app --no-build --no-install --platform node -m Docs.Search.Main --to dist/main.js",
24+ "esbuild-main": "esbuild dist/main.js --platform=node --bundle --minify --outfile=dist/main.min.js && mv dist/main.min.js dist/main.js",
25+ "add-shebang": "echo \"#!/usr/bin/env node\" > dist/purescript-docs-search.cjs && cat dist/main.js >> dist/purescript-docs-search.cjs",
26+ "chmod-main": "chmod +x dist/purescript-docs-search.cjs",
27+ "build-main": "npm run bundle-main && npm run esbuild-main && npm run add-shebang && rm dist/main.js && npm run chmod-main",
2728 "build": "spago build && npm run build-app && npm run build-main",
28− "build-dev": "spago build && npm run build-app && npm run bundle-main && npm run add-shebang && rm dist/main.js && npm run chmod-main",
2929 "clean": "rm -rf dist",
30− "check-version": "[ \"$(./dist/purescript-docs-search version)\" = \"$npm_package_version\" ]"
30+ "check-version": "[ \"$(./dist/purescript-docs-search.cjs version)\" = \"$npm_package_version\" ]"
3131 },
3232 "repository": {
3333 "type": "git",
34− "url": "git+https://github.com/spacchetti/purescript-docs-search.git"
34+ "url": "git+https://github.com/purescript/purescript-docs-search.git"
3535 },
3636 "keywords": [
3737 "purescript"
@@ -39,14 +39,17 @@
3939 "author": "Kalnitsky Vladimir <klntsky@gmail.com>",
4040 "license": "BSD-3-Clause",
4141 "bugs": {
42− "url": "https://github.com/spacchetti/purescript-docs-search/issues"
42+ "url": "https://github.com/purescript/purescript-docs-search/issues"
43+ },
44+ "homepage": "https://github.com/purescript/purescript-docs-search#readme",
45+ "dependencies": {
46+ "punycode": "^2.1.1"
4347 },
44− "homepage": "https://github.com/spacchetti/purescript-docs-search#readme",
45− "dependencies": {},
4648 "devDependencies": {
49+ "esbuild": "^0.11.10",
4750 "glob": "^7.1.6",
48− "markdown-it": "^11.0.0",
49− "parcel": "^1.12.4",
50− "spago": "^0.15.3"
51+ "markdown-it": "^12.0.4",
52+ "puppeteer": "^8.0.0",
53+ "spago": "^0.20.9"
5154 }
5255}
packages.dhall+114−26
@@ -1,10 +1,12 @@
11let mkPackage =
2− https://raw.githubusercontent.com/purescript/package-sets/psc-0.13.2-20190725/src/mkPackage.dhall sha256:0b197efa1d397ace6eb46b243ff2d73a3da5638d8d0ac8473e8e4a8fc528cf57
2+ https://raw.githubusercontent.com/purescript/package-sets/psc-0.13.2-20190725/src/mkPackage.dhall
3+ sha256:0b197efa1d397ace6eb46b243ff2d73a3da5638d8d0ac8473e8e4a8fc528cf57
34
45let upstream =
5− https://github.com/purescript/package-sets/releases/download/psc-0.13.8/packages.dhall sha256:0e95ec11604dc8afc1b129c4d405dcc17290ce56d7d0665a0ff15617e32bbf03
6+ https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20220829/packages.dhall
7+ sha256:9ec64ed24ec308770ccdd3d0edb74a814fcfbe34c7df5c28266935f0b5e585d7
68
7−let overrides = { metadata = upstream.metadata // { version = "v0.13.0" } }
9+let overrides = {=}
810
911let additions =
1012 { halogen =
@@ -13,12 +15,13 @@ let additions =
1315 , "avar"
1416 , "console"
1517 , "const"
16− , "coroutines"
1718 , "dom-indexed"
19+ , "effect"
1820 , "foreign"
1921 , "fork"
2022 , "free"
2123 , "freeap"
24+ , "halogen-subscriptions"
2225 , "halogen-vdom"
2326 , "media-types"
2427 , "nullable"
@@ -28,15 +31,24 @@ let additions =
2831 , "transformers"
2932 , "unsafe-coerce"
3033 , "unsafe-reference"
34+ , "web-file"
3135 , "web-uievents"
3236 ]
33− "https://github.com/slamdata/purescript-halogen.git"
34− "v5.0.0-rc.6"
35− , halogen-css =
37+ "https://github.com/purescript-halogen/purescript-halogen.git"
38+ "v7.0.0"
39+ , memoize =
3640 mkPackage
37− [ "css", "halogen" ]
38− "https://github.com/slamdata/purescript-halogen-css.git"
39− "v8.0.0"
41+ [ "prelude"
42+ , "lazy"
43+ , "either"
44+ , "maybe"
45+ , "tuples"
46+ , "integers"
47+ , "lists"
48+ , "strings"
49+ ]
50+ "https://github.com/paf31/purescript-memoize.git"
51+ "9960694e82adc212fd89f8ed8778cf55fcb72aeb"
4052 , optparse =
4153 mkPackage
4254 [ "prelude"
@@ -46,14 +58,14 @@ let additions =
4658 , "ordered-collections"
4759 , "arrays"
4860 , "console"
49− , "memoize"
5061 , "transformers"
5162 , "exists"
5263 , "node-process"
5364 , "free"
65+ , "memoize"
5466 ]
55− "https://github.com/f-o-a-m/purescript-optparse.git"
56− "v3.0.1"
67+ "https://github.com/klntsky/purescript-optparse.git"
68+ "2fe4265b7c6b09744c11190a43ca06777c752473"
5769 , exitcodes =
5870 mkPackage
5971 [ "enums" ]
@@ -62,33 +74,109 @@ let additions =
6274 , markdown-it =
6375 mkPackage
6476 [ "prelude", "effect", "options" ]
65− "https://github.com/nonbili/purescript-markdown-it.git"
66− "v0.4.0"
77+ "https://github.com/klntsky/purescript-markdown-it.git"
78+ "f3b7654783a83a80d7c09b6caaa7cd40b93ddce1"
79+ , string-parsers =
80+ mkPackage
81+ [ "arrays"
82+ , "assert"
83+ , "bifunctors"
84+ , "console"
85+ , "control"
86+ , "effect"
87+ , "either"
88+ , "enums"
89+ , "foldable-traversable"
90+ , "lists"
91+ , "maybe"
92+ , "minibench"
93+ , "nonempty"
94+ , "partial"
95+ , "prelude"
96+ , "strings"
97+ , "tailrec"
98+ , "transformers"
99+ , "unfoldable"
100+ ]
101+ "https://github.com/purescript-contrib/purescript-string-parsers.git"
102+ "v8.0.0"
67103 , html-parser-halogen =
68104 mkPackage
69− [ "string-parsers", "generics-rep", "halogen" ]
105+ [ "string-parsers", "halogen" ]
70106 "https://github.com/rnons/purescript-html-parser-halogen.git"
71− "890da763cdd2a1049ab8837e477c5ba1fcf6d4ce"
107+ "035a51d02ba9f8b70c3ffd9fe31a3f5bed19941c"
72108 , markdown-it-halogen =
73109 mkPackage
74110 [ "markdown-it", "html-parser-halogen" ]
75111 "https://github.com/nonbili/purescript-markdown-it-halogen.git"
76112 "08c9625015bf04214be14e45230e8ce12f3fa2bf"
77− , bower-json =
113+ , search-trie =
78114 mkPackage
79115 [ "prelude"
80− , "generics-rep"
81− , "maybe"
82116 , "arrays"
83− , "either"
84− , "newtype"
85− , "tuples"
117+ , "ordered-collections"
118+ , "lists"
86119 , "foldable-traversable"
87− , "argonaut-codecs"
120+ , "bifunctors"
121+ ]
122+ "https://github.com/klntsky/purescript-search-trie.git"
123+ "e7f7f22486a1dba22171ec885dbc2149dc815119"
124+ , css =
125+ mkPackage
126+ [ "colors"
127+ , "console"
128+ , "effect"
129+ , "exceptions"
130+ , "nonempty"
131+ , "profunctor"
132+ , "psci-support"
133+ , "strings"
134+ , "these"
135+ , "transformers"
136+ ]
137+ "https://github.com/purescript-contrib/purescript-css.git"
138+ "710d6a742beb88299faf08aaeb997ee1e24483ab"
139+ , jest =
140+ mkPackage
141+ [ "aff"
142+ , "aff-promise"
143+ , "effect"
144+ , "prelude"
145+ , "psci-support"
146+ , "foldable-traversable"
147+ ]
148+ "https://github.com/klntsky/purescript-jest.git"
149+ "7feaa5a880fc75002c4eca312993174e7220252b"
150+ , literals =
151+ mkPackage
152+ [ "assert"
153+ , "effect"
154+ , "console"
155+ , "integers"
156+ , "numbers"
157+ , "partial"
158+ , "psci-support"
159+ , "unsafe-coerce"
160+ , "typelevel-prelude"
161+ ]
162+ "https://github.com/jvliwanag/purescript-literals.git"
163+ "ae3ef4e9c1ae7c57ec77bd13906fa60ae8abba4a"
164+ , untagged-union =
165+ mkPackage
166+ [ "assert"
167+ , "console"
168+ , "effect"
169+ , "foreign"
88170 , "foreign-object"
171+ , "literals"
172+ , "maybe"
173+ , "newtype"
174+ , "psci-support"
175+ , "tuples"
176+ , "unsafe-coerce"
89177 ]
90− "https://github.com/klntsky/purescript-bower-json.git"
91− "v1.0.0"
178+ "https://github.com/jvliwanag/purescript-untagged-union.git"
179+ "ed8262a966e15e751322c327e2759a9b9c0ef3f3"
92180 }
93181
94182in upstream // overrides // additions
release.shnew file+24
@@ -0,0 +1,24 @@
1+#!/usr/bin/env bash
2+
3+set -euo pipefail
4+
5+# Please use this script to cut new releases.
6+# It will create a tag and push it, which will trigger CI to create a release,
7+# build release files, push them to the release, and publish a new version on NPM
8+
9+NEW_TAG=v$(jq -r ".version" package.json)
10+
11+# Fail if the new tag already exists
12+if git rev-parse "${NEW_TAG}" >/dev/null 2>&1; then
13+ echo "Tag '${NEW_TAG}' already exists, please bump the version in package.json";
14+ exit 1;
15+fi
16+
17+echo "Creating and pushing new tag '${NEW_TAG}'.."
18+
19+git tag "${NEW_TAG}"
20+
21+git push origin "${NEW_TAG}"
22+
23+echo "Done."
24+
spago.dhall+53−41
@@ -1,43 +1,55 @@
1−{ sources =
2− [ "src/**/*.purs", "test/**/*.purs" ]
3−, name =
4− "docs-search"
1+{ sources = [ "src/**/*.purs", "test/**/*.purs" ]
2+, name = "docs-search"
53, dependencies =
6− [ "aff-promise"
7− , "argonaut-codecs"
8− , "argonaut-core"
9− , "argonaut-generic"
10− , "arrays"
11− , "bower-json"
12− , "console"
13− , "control"
14− , "coroutines"
15− , "effect"
16− , "foldable-traversable"
17− , "generics-rep"
18− , "halogen"
19− , "halogen-css"
20− , "lists"
21− , "markdown-it"
22− , "markdown-it-halogen"
23− , "maybe"
24− , "newtype"
25− , "node-buffer"
26− , "node-fs"
27− , "node-fs-aff"
28− , "node-process"
29− , "node-readline"
30− , "optparse"
31− , "profunctor"
32− , "profunctor-lenses"
33− , "search-trie"
34− , "string-parsers"
35− , "strings"
36− , "test-unit"
37− , "web-dom"
38− , "web-html"
39− , "web-storage"
40− ]
41−, packages =
42− ./packages.dhall
4+ [ "aff"
5+ , "aff-promise"
6+ , "argonaut-codecs"
7+ , "argonaut-core"
8+ , "argonaut-generic"
9+ , "arrays"
10+ , "bower-json"
11+ , "console"
12+ , "control"
13+ , "css"
14+ , "effect"
15+ , "either"
16+ , "exceptions"
17+ , "foldable-traversable"
18+ , "foreign-object"
19+ , "halogen"
20+ , "halogen-css"
21+ , "halogen-subscriptions"
22+ , "identity"
23+ , "js-uri"
24+ , "lists"
25+ , "markdown-it"
26+ , "markdown-it-halogen"
27+ , "maybe"
28+ , "newtype"
29+ , "node-buffer"
30+ , "node-fs"
31+ , "node-fs-aff"
32+ , "node-process"
33+ , "node-readline"
34+ , "optparse"
35+ , "ordered-collections"
36+ , "parallel"
37+ , "partial"
38+ , "prelude"
39+ , "profunctor"
40+ , "profunctor-lenses"
41+ , "search-trie"
42+ , "spec"
43+ , "string-parsers"
44+ , "strings"
45+ , "transformers"
46+ , "tuples"
47+ , "unfoldable"
48+ , "web-dom"
49+ , "web-events"
50+ , "web-html"
51+ , "web-storage"
52+ , "web-uievents"
53+ ]
54+, packages = ./packages.dhall
4355}
src/Docs/Search/App.purs+41−33
@@ -13,19 +13,21 @@ import Docs.Search.Meta as Meta
1313import Prelude
1414
1515import Control.Alt (alt)
16−import Control.Coroutine as Coroutine
1716import Data.Maybe (Maybe(..))
1817import Data.Newtype (wrap)
18+import Data.Map as Map
1919import Data.Tuple (Tuple(..))
2020import Data.Tuple.Nested ((/\))
2121import Effect (Effect)
2222import Effect.Aff (launchAff_)
2323import Halogen as H
2424import Halogen.Aff as HA
25+import Halogen.Subscription (subscribe)
2526import Halogen.VDom.Driver (runUI)
2627import MarkdownIt as MD
2728import Web.DOM.ChildNode as ChildNode
2829import Web.DOM.Document as Document
30+import Web.DOM.Document (Document)
2931import Web.DOM.Element as Element
3032import Web.DOM.Node as Node
3133import Web.DOM.ParentNode as ParentNode
@@ -41,12 +43,11 @@ import Web.HTML.Window as Window
4143
4244main :: Effect Unit
4345main = do
44− win <- HTML.window
45− doc <- HTMLDocument.toDocument <$> Window.document win
46+ window <- HTML.window
4647
47− insertStyle doc
48− insertVersionInfo doc
49− mbContainers <- getContainers doc
48+ insertStyle
49+ insertVersionInfo
50+ mbContainers <- getContainers
5051
5152 -- Initialize a `markdown-it` instance (we need it to render the docs as markdown)
5253 markdownIt <- MD.newMarkdownIt MD.Default mempty
@@ -70,55 +71,57 @@ main = do
7071
7172 let initialSearchEngineState = { packageIndex
7273 , moduleIndex
73− , index: mempty
74− , typeIndex: mempty
74+ , index: wrap Map.empty
75+ , typeIndex: wrap Map.empty
7576 , scores
7677 }
77−
7878 resultsComponent =
7979 SearchResults.mkComponent
80− initialSearchEngineState
81− pageContents
82− markdownIt
83− meta
80+ initialSearchEngineState
81+ pageContents
82+ markdownIt
83+ meta
8484
8585 sfio <- runUI SearchField.component unit searchField
8686 srio <- runUI resultsComponent unit searchResults
8787
88− sfio.subscribe $
89− Coroutine.consumer (srio.query <<< H.tell <<< SearchResults.MessageFromSearchField)
88+ void $ H.liftEffect $ subscribe sfio.messages $ \sfm -> do
89+ launchAff_ $ void do
90+ srio.query (SearchResults.MessageFromSearchField sfm unit)
9091
9192 -- We need to read the URI hash only when both components are initialized and
9293 -- the search field is subscribed to the main component.
93− void $ sfio.query $ H.tell SearchField.ReadURIHash
94+ void $ sfio.query $ SearchField.ReadURIHash unit
9495
9596 -- Subscribe to URI hash updates
9697 H.liftEffect do
9798
9899 listener <-
99− eventListener \event ->
100− launchAff_ do
101− sfio.query $ H.tell SearchField.ReadURIHash
100+ eventListener \_event ->
101+ launchAff_ $ void do
102+ sfio.query $ SearchField.ReadURIHash unit
102103
103− addEventListener hashchange listener true (Window.toEventTarget win)
104+ addEventListener hashchange listener true (Window.toEventTarget window)
104105
105106 sbio <- do
106− component <- Sidebar.mkComponent moduleIndex.packageModules isIndexHTML meta
107+ component <- Sidebar.mkComponent moduleIndex isIndexHTML meta
107108 runUI component unit sidebarContainer
108109
109110 -- Subscribe to window focus events
110111 H.liftEffect do
111112
112113 listener <-
113− eventListener \event ->
114− launchAff_ do
115− sbio.query $ H.tell Sidebar.UpdateModuleGrouping
114+ eventListener \_event ->
115+ launchAff_ $ void do
116+ sbio.query $ Sidebar.UpdateModuleGrouping unit
117+
118+ addEventListener focus listener true (Window.toEventTarget window)
116119
117− addEventListener focus listener true (Window.toEventTarget win)
118120
121+insertStyle :: Effect Unit
122+insertStyle = do
123+ doc <- getDocument
119124
120−insertStyle :: Document.Document -> Effect Unit
121−insertStyle doc = do
122125 let styleContents = """
123126 .top-banner__actions {
124127 width: 10%;
@@ -183,8 +186,9 @@ insertStyle doc = do
183186 void $ Node.appendChild (Element.toNode style) (Element.toNode head)
184187
185188
186−insertVersionInfo :: Document.Document -> Effect Unit
187−insertVersionInfo doc = do
189+insertVersionInfo :: Effect Unit
190+insertVersionInfo = do
191+ doc <- getDocument
188192 let docPN = Document.toParentNode doc
189193 mbVersionInfo <-
190194 ParentNode.querySelector (wrap ".footer > p") docPN
@@ -193,7 +197,7 @@ insertVersionInfo doc = do
193197 prefix <- Document.createTextNode " - patched by " doc <#> Text.toNode
194198 linkElement <- Document.createElement "a" doc
195199 let linkNode = Element.toNode linkElement
196− Element.setAttribute "href" "https://github.com/spacchetti/purescript-docs-search" linkElement
200+ Element.setAttribute "href" "https://github.com/purescript/purescript-docs-search" linkElement
197201 Element.setAttribute "target" "_blank" linkElement
198202 linkText <- Document.createTextNode ("docs-search") doc <#> Text.toNode
199203 suffix <- Document.createTextNode (" " <> Config.version) doc <#> Text.toNode
@@ -206,15 +210,15 @@ insertVersionInfo doc = do
206210-- | Query the DOM for specific elements that should always be present and determine if we are on
207211-- | `index.html` or not.
208212getContainers
209− :: Document.Document
210− -> Effect (Maybe { searchField :: HTML.HTMLElement
213+ :: Effect (Maybe { searchField :: HTML.HTMLElement
211214 , searchResults :: HTML.HTMLElement
212215 , pageContents :: Element.Element
213216 , sidebarContainer :: HTML.HTMLElement
214217 , realSidebar :: Element.Element
215218 , isIndexHTML :: Sidebar.IsIndexHTML
216219 })
217−getContainers doc = do
220+getContainers = do
221+ doc <- getDocument
218222 let docPN = Document.toParentNode doc
219223 mbBanner <-
220224 ParentNode.querySelector (wrap ".top-banner > .container") docPN
@@ -250,3 +254,7 @@ getContainers doc = do
250254 , isIndexHTML
251255 }
252256 | otherwise -> pure Nothing
257+
258+
259+getDocument :: Effect Document
260+getDocument = HTML.window >>= map HTMLDocument.toDocument <<< Window.document
src/Docs/Search/App/SearchField.purs+11−10
@@ -15,7 +15,7 @@ import Halogen.HTML as HH
1515import Halogen.HTML.CSS as HS
1616import Halogen.HTML.Events as HE
1717import Halogen.HTML.Properties as HP
18−import Halogen.Query.EventSource as ES
18+import Halogen.Query.Event as ES
1919import Web.DOM.Document as Document
2020import Web.DOM.ParentNode as ParentNode
2121import Web.HTML as HTML
@@ -36,6 +36,7 @@ data Action
3636 | FocusChanged Boolean
3737 | InitKeyboardListener
3838 | HandleKey H.SubscriptionId KeyboardEvent
39+ | NoOp
3940
4041data Query a
4142 = ReadURIHash a
@@ -46,7 +47,7 @@ data SearchFieldMessage
4647 | Focused
4748 | LostFocus
4849
49−component :: forall i. H.Component HH.HTML Query i SearchFieldMessage Aff
50+component :: forall i. H.Component Query i SearchFieldMessage Aff
5051component =
5152 H.mkComponent
5253 { initialState
@@ -73,12 +74,12 @@ initialState _ = { input: "", focused: false }
7374
7475handleAction :: Action -> H.HalogenM State Action () SearchFieldMessage Aff Unit
7576handleAction = case _ of
76−
77+ NoOp -> pure unit
7778 InitKeyboardListener -> do
7879
7980 document <- H.liftEffect $ Window.document =<< HTML.window
8081 H.subscribe' \sid ->
81− ES.eventListenerEventSource
82+ ES.eventListener
8283 KET.keyup
8384 (HTMLDocument.toEventTarget document)
8485 (map (HandleKey sid) <<< KE.fromEvent)
@@ -155,15 +156,15 @@ render state =
155156 [ HH.input
156157 [ HP.value state.input
157158 , HP.placeholder "Search for definitions... (S to focus)"
158− , HP.id_ "docs-search-query-field"
159+ , HP.id "docs-search-query-field"
159160 , HP.type_ HP.InputText
160161 , HE.onKeyUp (\event ->
161162 case KeyboardEvent.code event of
162− "Enter" -> Just EnterPressed
163− _ -> Nothing)
164− , HE.onValueInput (Just <<< InputAction)
165− , HE.onFocusIn $ const $ Just $ FocusChanged true
166− , HE.onFocusOut $ const $ Just $ FocusChanged false
163+ "Enter" -> EnterPressed
164+ _ -> NoOp)
165+ , HE.onValueInput InputAction
166+ , HE.onFocusIn $ const $ FocusChanged true
167+ , HE.onFocusOut $ const $ FocusChanged false
167168 , HS.style do
168169
169170 let pursuitColor = rgb 0x1d 0x22 0x2d
src/Docs/Search/App/SearchResults.purs+18−22
@@ -12,13 +12,13 @@ import Docs.Search.Extra (homePageFromRepository, (>#>))
1212import Docs.Search.ModuleIndex (ModuleResult)
1313import Docs.Search.PackageIndex (PackageResult)
1414import Docs.Search.SearchResult (ResultInfo(..), SearchResult(..))
15−import Docs.Search.TypeDecoder (Constraint(..), FunDep(..), FunDeps(..), Kind(..), QualifiedName(..), Type(..), TypeArgument(..), joinForAlls, joinRows)
15+import Docs.Search.TypeDecoder (Constraint(..), FunDep(..), FunDeps(..), QualifiedName(..), Type(..), TypeArgument(..), joinForAlls, joinRows)
1616import Docs.Search.TypeIndex (TypeIndex)
1717import Docs.Search.Types (Identifier(..), ModuleName(..), PackageName)
1818import Docs.Search.Meta (Meta)
1919
2020import Prelude
21−
21+import Prim hiding (Type, Constraint)
2222import Data.Array ((!!))
2323import Data.Array as Array
2424import Data.List as List
@@ -76,7 +76,7 @@ mkComponent
7676 -> Element
7777 -> MD.MarkdownIt
7878 -> Meta
79− -> H.Component HH.HTML Query i o Aff
79+ -> H.Component Query i o Aff
8080mkComponent initialEngineState contents markdownIt { localPackageName } =
8181 H.mkComponent
8282 { initialState: const { engineState: initialEngineState
@@ -202,10 +202,10 @@ render state@{ mode: Active } =
202202 , HH.div_ $
203203 Array.concat $ shownResults <#> renderResult state
204204
205− , HH.div [ HP.class_ (wrap "load_more"), HP.id_ "load-more" ]
205+ , HH.div [ HP.class_ (wrap "load_more"), HP.id "load-more" ]
206206 [ if Array.length shownResults < Array.length state.results
207− then HH.a [ HP.id_ "load-more-link"
208− , HE.onClick $ const $ Just MoreResultsRequested ]
207+ then HH.a [ HP.id "load-more-link"
208+ , HE.onClick $ const MoreResultsRequested ]
209209 [ HH.text "Show more results" ]
210210 else HH.p_
211211 [ HH.text "No further results." ]
@@ -305,7 +305,7 @@ renderSearchResult state (SearchResult result) =
305305 [ HH.div [ HP.class_ (wrap "result") ]
306306 [ HH.h3 [ HP.class_ (wrap "result__title") ]
307307 [ HH.a [ HP.class_ (wrap "result__link")
308− , HE.onClick $ const $ Just $ SearchResultClicked result.moduleName
308+ , HE.onClick $ const $ SearchResultClicked result.moduleName
309309 , HP.href $
310310 unwrap result.moduleName <> ".html#" <>
311311 result.hashAnchor <> ":" <> unwrap result.name
@@ -386,7 +386,7 @@ renderValueSignature
386386 -> Array (HH.HTML a Action)
387387renderValueSignature result ty =
388388 [ HH.a [ makeHref ValueLevel false result.moduleName result.name
389− , HE.onClick $ const $ Just $ SearchResultClicked result.moduleName ]
389+ , HE.onClick $ const $ SearchResultClicked result.moduleName ]
390390 [ HH.text $ unwrap result.name ]
391391 , HH.text " :: "
392392 , renderType ty ]
@@ -417,7 +417,7 @@ renderTypeClassSignature { fundeps, arguments, superclasses } { name, moduleName
417417 ]
418418 , space
419419 , HH.a [ makeHref TypeLevel false moduleName name
420− , HE.onClick $ const $ Just $
420+ , HE.onClick $ const $
421421 SearchResultClicked moduleName
422422 ]
423423 [ HH.text $ unwrap name ]
@@ -510,7 +510,7 @@ renderTypeArgument (TypeArgument { name, mbKind }) =
510510 [ HH.text "("
511511 , HH.text $ name
512512 , HH.text " :: "
513− , renderKind kind
513+ , renderType kind
514514 , HH.text ")"
515515 ]
516516
@@ -545,6 +545,9 @@ renderType = case _ of
545545 , renderType t2
546546 ]
547547
548+ KindApp t1 t2 ->
549+ HH.span_ [ renderType t1, space, renderType t2 ]
550+
548551 ty@(ForAll _ _ _) ->
549552 renderForAll ty
550553
@@ -558,6 +561,9 @@ renderType = case _ of
558561 ty@REmpty -> renderRow true ty
559562 ty@(RCons _ _ _) -> renderRow true ty
560563
564+ Kinded t1 t2 ->
565+ HH.span_ [ renderType t1, space, syntax "::", space, renderType t2 ]
566+
561567 BinaryNoParensType op t1 t2 ->
562568 HH.span_
563569 [ renderType t1
@@ -592,7 +598,7 @@ renderForAll ty =
592598 HH.span_ [ HH.text $ " (" <> name <> " "
593599 , syntax "::"
594600 , space
595− , renderKind kind
601+ , renderType kind
596602 , HH.text ")" ]
597603 ) <>
598604
@@ -666,7 +672,7 @@ renderQualifiedName isInfix level (QualifiedName { moduleNameParts, name })
666672 = if isBuiltIn then
667673 HH.text $ unwrap name
668674 else
669− HH.a [ HE.onClick $ const $ Just $
675+ HH.a [ HE.onClick $ const $
670676 SearchResultClicked $ moduleName
671677 , makeHref level isInfix moduleName name
672678 ]
@@ -676,16 +682,6 @@ renderQualifiedName isInfix level (QualifiedName { moduleNameParts, name })
676682 isBuiltIn = moduleNameParts !! 0 == Just "Prim"
677683
678684
679−renderKind
680− :: forall a
681− . Kind
682− -> HH.HTML a Action
683−renderKind = case _ of
684− Row k1 -> HH.span_ [ HH.text "# ", renderKind k1 ]
685− FunKind k1 k2 -> HH.span_ [ renderKind k1, syntax " -> ", renderKind k2 ]
686− NamedKind qname -> renderQualifiedName false KindLevel qname
687−
688−
689685-- | Construct a `href` property value w.r.t. `DeclLevel`.
690686makeHref
691687 :: forall t rest
src/Docs/Search/App/Sidebar.purs+62−25
@@ -2,8 +2,8 @@ module Docs.Search.App.Sidebar where
22
33import Docs.Search.Config as Config
44import Docs.Search.Meta (Meta)
5−import Docs.Search.ModuleIndex (PackedModuleIndex)
6−import Docs.Search.Types (ModuleName, PackageInfo(..), PackageName)
5+import Docs.Search.ModuleIndex (ModuleIndex)
6+import Docs.Search.Types (ModuleName(..), PackageInfo(..), PackageName)
77
88import Prelude
99
@@ -13,11 +13,10 @@ import Data.Lens.Record (prop)
1313import Data.List (foldr)
1414import Data.Map (Map)
1515import Data.Map as Map
16−import Data.Maybe (Maybe(..), isJust)
16+import Data.Maybe (Maybe(..), isJust, fromMaybe)
1717import Data.Newtype (wrap, unwrap)
1818import Data.Set (Set)
1919import Data.Set as Set
20−import Data.Symbol (SProxy(..))
2120import Data.Tuple.Nested (type (/\), (/\))
2221import Effect (Effect)
2322import Effect.Aff (Aff)
@@ -25,9 +24,16 @@ import Halogen as H
2524import Halogen.HTML as HH
2625import Halogen.HTML.Events as HE
2726import Halogen.HTML.Properties as HP
27+import Type.Proxy (Proxy(..))
2828import Web.HTML as HTML
2929import Web.HTML.Window as Window
3030import Web.Storage.Storage as Storage
31+import Web.DOM.Document as Document
32+import Web.DOM.Element as Element
33+import Web.HTML.HTMLDocument as HTMLDocument
34+import Web.DOM.ParentNode as ParentNode
35+import Data.Traversable (traverse)
36+import Web.DOM.Node as Node
3137
3238
3339data Action = ToggleGrouping GroupingMode
@@ -44,29 +50,33 @@ data IsIndexHTML = IsIndexHTML | NotIndexHTML
4450
4551derive instance isIndexHTMLEq :: Eq IsIndexHTML
4652
47−type State = { moduleIndex :: Map PackageInfo (Set ModuleName)
53+type State = { packageModules :: Map PackageInfo (Set ModuleName)
4854 , groupingMode :: GroupingMode
4955 , moduleNames :: Array ModuleName
5056 , isIndexHTML :: IsIndexHTML
5157 , localPackageName :: PackageName
58+ , currentPackage :: PackageInfo
5259 }
5360
5461
5562mkComponent
5663 :: forall i
57− . PackedModuleIndex
64+ . ModuleIndex
5865 -> IsIndexHTML
5966 -> Meta
60− -> Aff (H.Component HH.HTML Query i Action Aff)
61−mkComponent moduleIndex isIndexHTML { localPackageName } = do
67+ -> Aff (H.Component Query i Action Aff)
68+mkComponent moduleIndex@{ packageModules } isIndexHTML { localPackageName } = do
6269 groupingMode <- H.liftEffect loadGroupingModeFromLocalStorage
70+ mbModuleName <- H.liftEffect getCurrentModuleName
71+ let currentPackage = getCurrentPackage moduleIndex mbModuleName
6372 pure $
6473 H.mkComponent
65− { initialState: const { moduleIndex
74+ { initialState: const { packageModules
6675 , groupingMode
6776 , moduleNames
6877 , isIndexHTML
6978 , localPackageName
79+ , currentPackage
7080 }
7181 , render
7282 , eval: H.mkEval $ H.defaultEval { handleAction = handleAction
@@ -74,7 +84,9 @@ mkComponent moduleIndex isIndexHTML { localPackageName } = do
7484 }
7585 }
7686 where
77− moduleNames = Array.sort $ Array.fromFoldable $ foldr Set.union mempty moduleIndex
87+ moduleNames =
88+ Array.sort $ Array.fromFoldable $
89+ foldr Set.union mempty moduleIndex.packageModules
7890
7991
8092handleAction
@@ -109,25 +121,25 @@ render
109121 :: forall m
110122 . State
111123 -> H.ComponentHTML Action () m
112−render { moduleIndex, groupingMode, moduleNames, isIndexHTML, localPackageName } =
124+render state@{ groupingMode, moduleNames, localPackageName } =
113125
114126 HH.div [ HP.classes [ wrap "col"
115− , wrap $ if isIndexHTML == IsIndexHTML
127+ , wrap $ if state.isIndexHTML == IsIndexHTML
116128 then "col--main"
117129 else "col--aside"
118130 ]
119131 ]
120132
121133 [ HH.h3_ [ HH.text $ if groupingMode == DontGroup then "Modules" else "Packages" ]
122− , HH.input [ HP.id_ "group-modules__input"
134+ , HH.input [ HP.id "group-modules__input"
123135 , HP.type_ HP.InputCheckbox
124136 , HP.checked (groupingMode == GroupByPackage)
125− , HE.onChecked $ Just <<< ToggleGrouping <<< isCheckedToGroupingMode
137+ , HE.onChecked $ ToggleGrouping <<< isCheckedToGroupingMode
126138 ]
127139
128140 , HH.text " "
129141 , HH.label [ HP.for "group-modules__input"
130− , HP.id_ "group-modules__label"
142+ , HP.id "group-modules__label"
131143 ]
132144 [ HH.text " GROUP BY PACKAGE" ]
133145
@@ -139,17 +151,26 @@ render { moduleIndex, groupingMode, moduleNames, isIndexHTML, localPackageName }
139151
140152 renderPackageEntry (package /\ modules) =
141153 HH.li [ HP.classes [ wrap "li-package" ] ]
142− [ HH.details_ $
143− [ HH.summary_ [ HH.text $
144− case package of
145− Package packageName -> unwrap packageName
146− LocalPackage -> unwrap localPackageName
147− Builtin -> "Built-in"
148− UnknownPackage -> "Unknown package"
149− ]
154+ [ HH.details
155+ (if isCurrentPackage then [ HP.attr (wrap "open") "" ] else [])
156+ [ HH.summary_
157+ [ HH.text $
158+ case package of
159+ Package packageName -> unwrap packageName
160+ LocalPackage -> unwrap localPackageName
161+ Builtin -> "<builtins>"
162+ UnknownPackage -> "<unknown>"
163+ ]
150164 , HH.ul_ $ Set.toUnfoldable modules <#> renderModuleName
151165 ]
152166 ]
167+ where
168+
169+ isCurrentPackage =
170+ state.currentPackage == package &&
171+ -- If we don't know which package we are in, we don't want to expand
172+ -- "Unknown package" section
173+ state.currentPackage /= UnknownPackage
153174
154175 renderModuleName moduleName =
155176 HH.li_
@@ -158,7 +179,7 @@ render { moduleIndex, groupingMode, moduleNames, isIndexHTML, localPackageName }
158179 ]
159180
160181 packageList :: Array (PackageInfo /\ Set ModuleName)
161− packageList = Map.toUnfoldable moduleIndex
182+ packageList = Map.toUnfoldable state.packageModules
162183
163184
164185-- | Decide whether to group modules by package in the sidebar, using localStorage.
@@ -170,6 +191,22 @@ loadGroupingModeFromLocalStorage = do
170191 pure $ if isJust mbDontGroupModules then DontGroup else GroupByPackage
171192
172193
194+-- | Extract current module name from page title element.
195+getCurrentModuleName :: Effect (Maybe ModuleName)
196+getCurrentModuleName = do
197+ win <- HTML.window
198+ docPN <- Document.toParentNode <$> HTMLDocument.toDocument <$> Window.document win
199+ mbPageTitleEl <- ParentNode.querySelector (wrap ".page-title__title") docPN
200+ map ModuleName <$> traverse (Node.textContent <<< Element.toNode) mbPageTitleEl
201+
202+
203+-- | Given a module name, get `PackageInfo` for a package this module name belongs to.
204+getCurrentPackage :: ModuleIndex -> Maybe ModuleName -> PackageInfo
205+getCurrentPackage { modulePackages } (Just moduleName) =
206+ fromMaybe UnknownPackage $ Map.lookup moduleName modulePackages
207+getCurrentPackage { modulePackages } Nothing = UnknownPackage
208+
209+
173210-- | Convert checkbox status to sidebar mode
174211isCheckedToGroupingMode :: Boolean -> GroupingMode
175212isCheckedToGroupingMode = if _ then GroupByPackage else DontGroup
@@ -178,4 +215,4 @@ isCheckedToGroupingMode = if _ then GroupByPackage else DontGroup
178215-- Some optics:
179216
180217_groupingMode :: forall a b rest. (a -> b) -> { groupingMode :: a | rest } -> { groupingMode :: b | rest }
181−_groupingMode = prop (SProxy :: SProxy "groupingMode")
218+_groupingMode = prop (Proxy :: Proxy "groupingMode")
src/Docs/Search/BrowserEngine.js+1−1
@@ -1,6 +1,6 @@
11/* global exports */
22
3−exports.loadIndex_ = function (partId) {
3+export function loadIndex_ (partId) {
44 return function (url) {
55 return function () {
66 return new Promise(function(resolve, reject) {
src/Docs/Search/BrowserEngine.purs−3
@@ -36,9 +36,6 @@ newtype PartialIndex
3636 = PartialIndex (Map PartId Index)
3737
3838derive instance newtypePartialIndex :: Newtype PartialIndex _
39−derive newtype instance semigroupPartialIndex :: Semigroup PartialIndex
40−derive newtype instance monoidPartialIndex :: Monoid PartialIndex
41−
4239
4340type BrowserEngineState = EngineState PartialIndex TypeIndex
4441
src/Docs/Search/Config.purs+1−1
@@ -7,7 +7,7 @@ import Prelude
77import Data.Newtype (wrap)
88
99version :: String
10−version = "0.0.9"
10+version = "0.0.12"
1111
1212mkShapeScriptPath :: String -> String
1313mkShapeScriptPath shape = "./index/types/" <> shape <> ".js"
src/Docs/Search/Declarations.purs+31−6
@@ -3,15 +3,15 @@ module Docs.Search.Declarations where
33import Docs.Search.DocsJson (ChildDeclType(..), ChildDeclaration(..), DeclType(..), Declaration(..), DocsJson(..), SourceSpan)
44import Docs.Search.Score (Scores, getPackageScore, getPackageScoreForPackageName)
55import Docs.Search.SearchResult (ResultInfo(..), SearchResult(..))
6−import Docs.Search.TypeDecoder (Constraint(..), QualifiedName(..), Type(..), Kind, joinForAlls)
6+import Docs.Search.TypeDecoder (Constraint(..), QualifiedName(..), Type(..), joinForAlls)
77import Docs.Search.Types (ModuleName(..), PackageName(..), PackageInfo(..), Identifier(..))
88
99import Prelude
10−
10+import Prim hiding (Type)
1111import Control.Alt ((<|>))
1212import Data.Array ((!!))
1313import Data.Array as Array
14−import Data.Foldable (foldr)
14+import Data.Foldable (foldl, foldr)
1515import Data.List (List, (:))
1616import Data.List as List
1717import Data.Maybe (Maybe(..), fromMaybe)
@@ -244,8 +244,33 @@ mkChildInfo
244244 (SearchResult { info: parentInfo, moduleName, name: resultName })
245245 (ChildDeclaration { info } )
246246
247− | ChildDeclDataConstructor <- info.declType =
248− info.arguments <#> \arguments -> DataConstructorResult { arguments }
247+ | ChildDeclDataConstructor <- info.declType
248+ , DataResult { dataDeclType, typeArguments } <- parentInfo =
249+ let
250+ parentTypeCtor :: Type
251+ parentTypeCtor = TypeConstructor
252+ $ QualifiedName { moduleNameParts:
253+ String.split (wrap ".") (unwrap moduleName)
254+ , name: resultName }
255+
256+ parentTypeArgs :: Array Type
257+ parentTypeArgs = typeArguments <#> unwrap >>> \{ name } -> TypeVar name
258+
259+ parentType :: Type
260+ parentType = foldl TypeApp parentTypeCtor parentTypeArgs
261+
262+ typeArrow :: Type -> Type
263+ typeArrow =
264+ TypeApp (TypeConstructor (QualifiedName { moduleNameParts: [ "Prim" ]
265+ , name: Identifier "Function" }))
266+
267+ makeType :: Array Type -> Type
268+ makeType = foldr (\a b -> TypeApp (typeArrow a) b) parentType
269+ in
270+ info.arguments <#> \arguments ->
271+ DataConstructorResult { dataDeclType
272+ , "type": makeType arguments
273+ }
249274
250275 | ChildDeclTypeClassMember <- info.declType
251276 , TypeClassResult { arguments } <- parentInfo =
@@ -271,7 +296,7 @@ mkChildInfo
271296 -- We concatenate two lists:
272297 -- * a list of type parameters of the type class, and
273298 -- * a list of quantified variables of the unconstrained type
274− allArguments :: Array { name :: String, mbKind :: Maybe Kind }
299+ allArguments :: Array { name :: String, mbKind :: Maybe Type }
275300 allArguments =
276301 (arguments <#> unwrap) <> List.toUnfoldable binders
277302
src/Docs/Search/DocsJson.purs+15−10
@@ -2,15 +2,16 @@
22module Docs.Search.DocsJson where
33
44import Prelude
5−
6−import Docs.Search.TypeDecoder (Constraint, FunDeps, Kind, Type, TypeArgument)
5+import Prim hiding (Type, Constraint)
6+import Docs.Search.TypeDecoder (Constraint, FunDeps, Type, TypeArgument)
77
88import Data.Argonaut.Core (fromString, stringify, toString)
99import Data.Argonaut.Decode (class DecodeJson, decodeJson, (.:), (.:?))
10+import Data.Argonaut.Decode.Error (JsonDecodeError(..))
1011import Data.Argonaut.Encode (class EncodeJson, encodeJson)
1112import Data.Either (Either(..))
1213import Data.Generic.Rep (class Generic)
13−import Data.Generic.Rep.Show (genericShow)
14+import Data.Show.Generic (genericShow)
1415import Data.Maybe (Maybe(..))
1516import Data.Newtype (class Newtype, unwrap)
1617
@@ -43,7 +44,7 @@ newtype Declaration
4344 , comments :: Maybe String
4445 , info :: { declType :: DeclType
4546 , dataDeclType :: Maybe DataDeclType
46− , kind :: Maybe Kind
47+ , kind :: Maybe Type
4748 , typeArguments :: Maybe (Array TypeArgument)
4849 , type :: Maybe Type
4950 , superclasses :: Maybe (Array Constraint)
@@ -151,7 +152,7 @@ instance encodeJsonDeclType :: EncodeJson DeclType where
151152instance decodeJsonDeclType :: DecodeJson DeclType where
152153 decodeJson json =
153154 case toString json of
154− Nothing -> Left $ "Couldn't decode DeclType: " <> stringify json
155+ Nothing -> errorWith $ "Couldn't decode DeclType: " <> stringify json
155156 Just string ->
156157 case string of
157158 "value" -> Right DeclValue
@@ -161,7 +162,7 @@ instance decodeJsonDeclType :: DecodeJson DeclType where
161162 "typeClass" -> Right DeclTypeClass
162163 "alias" -> Right DeclAlias
163164 "kind" -> Right DeclExternKind
164− _ -> Left $ "Couldn't decode DeclType: " <> string
165+ _ -> errorWith $ "Couldn't decode DeclType: " <> string
165166
166167
167168data ChildDeclType
@@ -184,13 +185,13 @@ instance encodeJsonChildDeclType :: EncodeJson ChildDeclType where
184185instance decodeJsonChildDeclType :: DecodeJson ChildDeclType where
185186 decodeJson json =
186187 case toString json of
187− Nothing -> Left $ "Couldn't decode ChildDeclType: " <> stringify json
188+ Nothing -> errorWith $ "Couldn't decode ChildDeclType: " <> stringify json
188189 Just tag ->
189190 case tag of
190191 "instance" -> Right ChildDeclInstance
191192 "dataConstructor" -> Right ChildDeclDataConstructor
192193 "typeClassMember" -> Right ChildDeclTypeClassMember
193− _ -> Left $ "Couldn't decode ChildDeclType: " <> tag
194+ _ -> errorWith $ "Couldn't decode ChildDeclType: " <> tag
194195
195196
196197data DataDeclType
@@ -215,5 +216,9 @@ instance decodeJsonDataDeclType :: DecodeJson DataDeclType where
215216 case tag of
216217 "newtype" -> Right NewtypeDataDecl
217218 "data" -> Right DataDataDecl
218− _ -> Left $ "Couldn't decode DataDeclType: " <> tag
219− Nothing -> Left $ "Couldn't decode DataDeclType: " <> stringify json
219+ _ -> errorWith $ "Couldn't decode DataDeclType: " <> tag
220+ Nothing -> errorWith $ "Couldn't decode DataDeclType: " <> stringify json
221+
222+
223+errorWith :: forall a. String -> Either JsonDecodeError a
224+errorWith = Left <<< TypeMismatch
src/Docs/Search/IndexBuilder.js+4−5
@@ -1,14 +1,13 @@
11/* global __dirname require exports */
22
3−var path = require('path');
4−var glob = require('glob');
3+import globMain from "glob";
54
6−exports.getDirname = function () {
5+export function getDirname () {
76 return __dirname;
87};
98
10−exports.glob = function (pattern) {
9+export function glob (pattern) {
1110 return function () {
12− return glob.sync(pattern);
11+ return globMain.sync(pattern);
1312 };
1413};
src/Docs/Search/IndexBuilder.purs+48−15
@@ -5,19 +5,23 @@ import Docs.Search.Config as Config
55import Docs.Search.Declarations (Declarations(..), mkDeclarations)
66import Docs.Search.DocsJson (DocsJson)
77import Docs.Search.Extra ((>#>))
8+import Docs.Search.Meta (Meta)
89import Docs.Search.ModuleIndex (PackedModuleIndex, mkPackedModuleIndex)
10+import Docs.Search.ModuleParser (parseModuleName)
911import Docs.Search.PackageIndex (PackageInfo, mkPackageInfo)
1012import Docs.Search.Score (mkScores)
1113import Docs.Search.SearchResult (SearchResult)
1214import Docs.Search.TypeIndex (TypeIndex, mkTypeIndex)
13−import Docs.Search.Types (PackageName, PartId)
14−import Docs.Search.Meta (Meta)
15+import Docs.Search.Types (ModuleName, PackageName, PartId)
1516
1617import Prelude
18+
1719import Data.Argonaut.Core (stringify)
1820import Data.Argonaut.Decode (decodeJson)
21+import Data.Argonaut.Decode.Error (printJsonDecodeError)
1922import Data.Argonaut.Encode (encodeJson)
2023import Data.Argonaut.Parser (jsonParser)
24+import Data.Array (concat)
2125import Data.Array as Array
2226import Data.Either (Either(..), either)
2327import Data.Foldable (sum)
@@ -27,6 +31,7 @@ import Data.Map (Map)
2731import Data.Map as Map
2832import Data.Maybe (Maybe(..), fromMaybe)
2933import Data.Newtype (unwrap)
34+import Data.Profunctor.Choice (left)
3035import Data.Search.Trie as Trie
3136import Data.Set as Set
3237import Data.String.CodePoints (contains) as String
@@ -35,13 +40,15 @@ import Data.String.Common (replace) as String
3540import Data.String.Pattern (Pattern(..), Replacement(..))
3641import Data.Traversable (for, for_)
3742import Data.Tuple (Tuple(..), fst)
43+import Data.Tuple.Nested ((/\))
3844import Effect (Effect)
3945import Effect.Aff (Aff, launchAff_, parallel, sequential)
4046import Effect.Class (liftEffect)
4147import Effect.Console (log)
4248import Node.Encoding (Encoding(UTF8))
43−import Node.FS.Aff (exists, mkdir, readFile, readTextFile, readdir, stat, writeFile, writeTextFile)
49+import Node.FS.Aff (mkdir, readFile, readTextFile, readdir, stat, writeFile, writeTextFile)
4450import Node.FS.Stats (isDirectory, isFile)
51+import Node.FS.Sync (exists)
4552import Node.Process as Process
4653import Web.Bower.PackageMeta (PackageMeta(..))
4754
@@ -52,6 +59,7 @@ type Config =
5259 , generatedDocs :: String
5360 , noPatch :: Boolean
5461 , packageName :: PackageName
62+ , sourceFiles :: Array String
5563 }
5664
5765
@@ -67,8 +75,11 @@ run' cfg = do
6775 liftEffect do
6876 log "Building the search index..."
6977
70− docsJsons <- decodeDocsJsons cfg
71− packageMetas <- decodeBowerJsons cfg
78+ docsJsons /\ moduleNames /\ packageMetas <- sequential $
79+ (\d h m -> d /\ h /\ m)
80+ <$> parallel (decodeDocsJsons cfg)
81+ <*> parallel (parseModuleHeaders cfg.sourceFiles)
82+ <*> parallel (decodeBowerJsons cfg)
7283
7384 let countOfPackages = Array.length packageMetas
7485 countOfModules = Array.length docsJsons
@@ -85,14 +96,14 @@ run' cfg = do
8596 index = mkDeclarations scores docsJsons
8697 typeIndex = mkTypeIndex scores docsJsons
8798 packageInfo = mkPackageInfo scores packageMetas
88− moduleIndex = mkPackedModuleIndex index
99+ moduleIndex = mkPackedModuleIndex index moduleNames
89100 meta = { localPackageName: cfg.packageName }
90101
91102 createDirectories cfg
92103
93104 void $ sequential do
94105 ignore <$> parallel (writeIndex cfg index)
95− <*> parallel (writeTypeIndex cfg typeIndex)
106+ <*> parallel (writeTypeIndex typeIndex)
96107 <*> parallel (writePackageInfo packageInfo)
97108 <*> parallel (writeModuleIndex moduleIndex)
98109 <*> parallel (writeMeta meta)
@@ -151,7 +162,7 @@ decodeDocsJsons cfg@{ docsFiles } = do
151162 if doesExist then do
152163
153164 contents <- readTextFile UTF8 jsonFile
154− let eiResult = jsonParser contents >>= decodeJson
165+ let eiResult = jsonParser contents >>= left printJsonDecodeError <<< decodeJson
155166
156167 case eiResult of
157168 Left error -> do
@@ -172,6 +183,28 @@ decodeDocsJsons cfg@{ docsFiles } = do
172183
173184 pure docsJsons
174185
186+-- | This function accepts an array of globs pointing to project sources
187+-- | and returns a list of module names extracted from these files.
188+-- | Unfortunately, we can't get all module names from `docs.json`s, because
189+-- | reexport-only modules do not have a single declaration in them, so we can't
190+-- | count them normally in `mkPackedModuleIndex.extract`, where we only look at
191+-- | exported declarations.
192+parseModuleHeaders :: Array String -> Aff (Array ModuleName)
193+parseModuleHeaders globs = do
194+ files <- getPathsByGlobs globs
195+
196+ -- we are not checking if the globs match at least one file, because
197+ -- we want to support scenarios where there is no "current project"
198+
199+ concat <$> for files \filePath -> do
200+ fileContents <- readTextFile UTF8 filePath
201+ case parseModuleName fileContents of
202+ Nothing -> do
203+ liftEffect $ log $
204+ "Module header decoding failed for " <> filePath <>
205+ ", unable to extract module name"
206+ pure []
207+ Just res -> pure [res]
175208
176209decodeBowerJsons
177210 :: forall rest
@@ -192,7 +225,7 @@ decodeBowerJsons { bowerFiles } = do
192225 join <$> withExisting jsonFileName
193226 \contents ->
194227 either (logError jsonFileName) pure
195− (jsonParser contents >>= decodeJson)
228+ (jsonParser contents >>= left printJsonDecodeError <<< decodeJson)
196229
197230 where
198231 compareNames
@@ -206,8 +239,8 @@ decodeBowerJsons { bowerFiles } = do
206239
207240
208241-- | Write type index parts to files.
209−writeTypeIndex :: Config -> TypeIndex -> Aff Unit
210−writeTypeIndex { generatedDocs } typeIndex =
242+writeTypeIndex :: TypeIndex -> Aff Unit
243+writeTypeIndex typeIndex =
211244 for_ entries \(Tuple typeShape results) -> do
212245 writeTextFile UTF8 (unwrap Config.typeIndexDirectory <> "/" <> typeShape <> ".js")
213246 (mkHeader typeShape <> stringify (encodeJson results))
@@ -246,7 +279,7 @@ writeMeta meta = do
246279-- | Get a mapping from index parts to index contents.
247280getIndex :: Declarations -> Map PartId (Array (Tuple String (Array SearchResult)))
248281getIndex (Declarations trie) =
249− Array.foldr insert mempty parts
282+ Array.foldr insert Map.empty parts
250283 where
251284 insert part = Map.insertWith append (getPartId part.prefix) part.results
252285
@@ -261,7 +294,7 @@ getIndex (Declarations trie) =
261294 Trie.query prefix trie
262295 else
263296 -- Entries with path lengths > 1 have been added already.
264− List.filter (\(Tuple path value) -> List.length path == 1) (
297+ List.filter (\(Tuple path _value) -> List.length path == 1) (
265298 Trie.query prefix trie
266299 )
267300 in
@@ -366,7 +399,7 @@ copyAppFile { generatedDocs } = do
366399
367400directoryExists :: String -> Aff Boolean
368401directoryExists path = do
369− doesExist <- exists path
402+ doesExist <- liftEffect $ exists path
370403 case doesExist of
371404 false -> pure false
372405 true -> isDirectory <$> stat path
@@ -374,7 +407,7 @@ directoryExists path = do
374407
375408fileExists :: String -> Aff Boolean
376409fileExists path = do
377− doesExist <- exists path
410+ doesExist <- liftEffect $ exists path
378411 case doesExist of
379412 false -> pure false
380413 true -> isFile <$> stat path
src/Docs/Search/Interactive.purs+41−8
@@ -6,6 +6,7 @@ import Docs.Search.DocsJson (DataDeclType(..))
66import Docs.Search.Engine (mkEngineState, packageInfoToString, Result(..))
77import Docs.Search.Engine as Engine
88import Docs.Search.Extra (stringToList, (>#>))
9+import Docs.Search.IndexBuilder (parseModuleHeaders)
910import Docs.Search.IndexBuilder as IndexBuilder
1011import Docs.Search.ModuleIndex (ModuleResult, mkPackedModuleIndex, unpackModuleIndex)
1112import Docs.Search.NodeEngine (nodeEngine)
@@ -13,13 +14,14 @@ import Docs.Search.PackageIndex (PackageResult, mkPackageIndex, mkPackageInfo)
1314import Docs.Search.Score (mkScores)
1415import Docs.Search.SearchResult (ResultInfo(..), SearchResult(..))
1516import Docs.Search.Terminal (bold, cyan, green, yellow)
16−import Docs.Search.TypeDecoder (Constraint, FunDeps, Kind, QualifiedName, Type, TypeArgument)
17+import Docs.Search.TypeDecoder (Constraint, FunDeps, QualifiedName, Type, TypeArgument)
1718import Docs.Search.TypeIndex (resultsWithTypes)
18−import Docs.Search.TypePrinter (keyword, showConstraint, showFunDeps, showKind, showType, showTypeArgument, space, syntax)
19+import Docs.Search.TypePrinter (keyword, showConstraint, showFunDeps, showType, showTypeArgument, space, syntax)
1920import Docs.Search.Types (ModuleName, PackageName, PackageInfo, Identifier)
2021
2122import Prelude
2223
24+import Control.Parallel (parallel, sequential)
2325import Data.Array as Array
2426import Data.Identity (Identity(..))
2527import Data.List as List
@@ -28,17 +30,20 @@ import Data.Newtype (un, unwrap, wrap)
2830import Data.Search.Trie as Trie
2931import Data.String (length) as String
3032import Data.String.Common (split, toLower, trim) as String
33+import Data.Tuple.Nested ((/\))
3134import Effect (Effect)
3235import Effect.Aff (launchAff_)
3336import Effect.Class (liftEffect)
3437import Effect.Console (log, clear) as Console
3538import Node.ReadLine (createConsoleInterface, question)
39+import Prim hiding (Type, Constraint)
3640
3741
3842type Config =
3943 { docsFiles :: Array String
4044 , bowerFiles :: Array String
4145 , packageName :: PackageName
46+ , sourceFiles :: Array String
4247 }
4348
4449
@@ -48,14 +53,17 @@ run cfg = launchAff_ $ do
4853 liftEffect do
4954 Console.log "Loading search index..."
5055
51− docsJsons <- IndexBuilder.decodeDocsJsons cfg
52− packageMetas <- IndexBuilder.decodeBowerJsons cfg
56+ docsJsons /\ moduleNames /\ packageMetas <- sequential $
57+ (\d h m -> d /\ h /\ m)
58+ <$> parallel (IndexBuilder.decodeDocsJsons cfg)
59+ <*> parallel (parseModuleHeaders cfg.sourceFiles)
60+ <*> parallel (IndexBuilder.decodeBowerJsons cfg)
5361
5462 let scores = mkScores packageMetas
5563 index = mkDeclarations scores docsJsons
5664 typeIndex = docsJsons >>= resultsWithTypes scores
5765 packageIndex = mkPackageIndex $ mkPackageInfo scores packageMetas
58− moduleIndex = unpackModuleIndex $ mkPackedModuleIndex index
66+ moduleIndex = unpackModuleIndex $ mkPackedModuleIndex index moduleNames
5967 engineState = mkEngineState (unwrap index) typeIndex packageIndex moduleIndex scores
6068
6169 let countOfDefinitions = Trie.size $ unwrap index
@@ -186,6 +194,9 @@ showSignature result@{ name, info } =
186194 ValueAliasResult ->
187195 yellow ("(" <> unwrap name <> ")")
188196
197+ DataConstructorResult info' ->
198+ showDataConstructorSignature info' result
199+
189200 _ -> yellow $ unwrap name
190201
191202
@@ -279,16 +290,38 @@ showTypeSynonymSignature { type: ty, arguments } { name } =
279290
280291showExternDataSignature
281292 :: forall rest
282− . { kind :: Kind }
293+ . { kind :: Type }
283294 -> { name :: Identifier | rest }
284295 -> String
285296showExternDataSignature { kind } { name } =
286297 keyword "foreign data" <>
287298 space <>
288299 yellow (unwrap name) <>
289− space <>
290300 syntax " :: " <>
291− showKind kind
301+ showType kind
302+
303+
304+showDataConstructorSignature
305+ :: forall rest
306+ . { dataDeclType :: DataDeclType
307+ , "type" :: Type
308+ }
309+ -> { name :: Identifier
310+ | rest
311+ }
312+ -> String
313+showDataConstructorSignature { dataDeclType, type: ctorType } { name } =
314+ ( keyword
315+ case dataDeclType of
316+ NewtypeDataDecl -> "newtype constructor"
317+ DataDataDecl -> "data constructor"
318+ ) <>
319+ space <>
320+ yellow (unwrap name) <>
321+ space <>
322+ syntax "::" <>
323+ space <>
324+ showType ctorType
292325
293326
294327leftShift :: Int -> String -> String
src/Docs/Search/Loader.js+1−1
@@ -1,6 +1,6 @@
11/* global exports */
22
3−exports.loadFromScript = function (globalIdentifier) {
3+export function loadFromScript (globalIdentifier) {
44 return function (url) {
55 return function () {
66 return new Promise(function (resolve, reject) {
src/Docs/Search/Loader.purs+2−1
@@ -7,6 +7,7 @@ import Prelude
77import Control.Monad.Error.Class (throwError)
88import Control.Promise (Promise, toAffE)
99import Data.Argonaut.Core (Json)
10+import Data.Argonaut.Decode.Error (printJsonDecodeError)
1011import Data.Argonaut.Decode.Class (class DecodeJson, decodeJson)
1112import Data.Either (either)
1213import Data.Newtype (unwrap)
@@ -28,7 +29,7 @@ load globalIdentifier url = do
2829 where
2930 throw err = throwError $ error $
3031 "Couldn't load content from window." <>
31− unwrap globalIdentifier <> ": " <> err
32+ unwrap globalIdentifier <> ": " <> printJsonDecodeError err
3233
3334
3435foreign import loadFromScript
src/Docs/Search/Main.purs+26−26
@@ -1,19 +1,19 @@
11-- | The main module of the CLI interface app.
22module Docs.Search.Main where
33
4−import Prelude
5−
4+import Docs.Search.Config as Config
65import Docs.Search.IndexBuilder as IndexBuilder
76import Docs.Search.Interactive as Interactive
8−import Docs.Search.Config as Config
97import Docs.Search.Types (PackageName(..))
108
9+import Prelude
10+
1111import Data.Generic.Rep (class Generic)
12−import Data.Generic.Rep.Show (genericShow)
1312import Data.List as List
1413import Data.List.NonEmpty as NonEmpty
1514import Data.Maybe (Maybe, fromMaybe, optional)
1615import Data.Newtype (unwrap)
16+import Data.Show.Generic (genericShow)
1717import Data.Unfoldable (class Unfoldable)
1818import Effect (Effect)
1919import Effect.Console (log)
@@ -28,6 +28,7 @@ main = do
2828 let defaultCommands = Search { docsFiles: defaultDocsFiles
2929 , bowerFiles: defaultBowerFiles
3030 , packageName: Config.defaultPackageName
31+ , sourceFiles: defaultSourceFiles
3132 }
3233
3334 case fromMaybe defaultCommands args of
@@ -35,7 +36,6 @@ main = do
3536 Search cfg -> Interactive.run cfg
3637 Version -> log Config.version
3738
38−
3939getArgs :: Effect (Maybe Commands)
4040getArgs = execParser opts
4141 where
@@ -45,19 +45,16 @@ getArgs = execParser opts
4545 <> progDesc "Search frontend for the documentation generated by the PureScript compiler."
4646 )
4747
48−
4948data Commands
5049 = BuildIndex IndexBuilder.Config
5150 | Search Interactive.Config
5251 | Version
5352
54−
5553derive instance genericCommands :: Generic Commands _
5654
5755instance showCommands :: Show Commands where
5856 show = genericShow
5957
60−
6158commands :: Parser (Maybe Commands)
6259commands = optional $ subparser
6360 ( command "build-index"
@@ -80,39 +77,30 @@ commands = optional $ subparser
8077
8178buildIndex :: Parser Commands
8279buildIndex = ado
83−
8480 docsFiles <- docsFilesOption
85−
8681 bowerFiles <- bowerFilesOption
87−
8882 packageName <- packageNameOption
89−
83+ sourceFiles <- sourceFilesOption
9084 generatedDocs <- strOption
9185 ( long "generated-docs"
9286 <> metavar "DIR"
9387 <> value "./generated-docs/"
88+ <> help "Path to the generated documentation HTML that will be patched. Search app will be injected into each HTML document."
9489 )
95−
9690 noPatch <- flag false true
9791 ( long "no-patch"
9892 <> help "Do not patch the HTML docs, only build indices"
9993 )
100−
101−
102− in BuildIndex { docsFiles, bowerFiles, generatedDocs, noPatch, packageName }
94+ in BuildIndex { docsFiles, bowerFiles, generatedDocs, noPatch, packageName, sourceFiles }
10395
10496
10597startInteractive :: Parser Commands
10698startInteractive = ado
107−
10899 docsFiles <- docsFilesOption
109−
110100 bowerFiles <- bowerFilesOption
111−
112101 packageName <- packageNameOption
113−
114− in Search { docsFiles, bowerFiles, packageName }
115−
102+ sourceFiles <- sourceFilesOption
103+ in Search { docsFiles, bowerFiles, packageName, sourceFiles }
116104
117105docsFilesOption :: Parser (Array String)
118106docsFilesOption = fromMaybe defaultDocsFiles <$>
@@ -121,11 +109,11 @@ docsFilesOption = fromMaybe defaultDocsFiles <$>
121109 ( strOption
122110 ( long "docs-files"
123111 <> metavar "GLOB"
112+ <> help "Glob that captures `docs.json` files that should be used to build the index"
124113 )
125114 )
126115 )
127116
128−
129117bowerFilesOption :: Parser (Array String)
130118bowerFilesOption = fromMaybe defaultBowerFiles <$>
131119 optional
@@ -133,31 +121,43 @@ bowerFilesOption = fromMaybe defaultBowerFiles <$>
133121 ( strOption
134122 ( long "bower-jsons"
135123 <> metavar "GLOB"
124+ <> 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."
136125 )
137126 )
138127 )
139128
140−
141129packageNameOption :: Parser PackageName
142130packageNameOption =
143131 PackageName <$> strOption
144132 ( long "package-name"
145133 <> metavar "PACKAGE"
146134 <> value (unwrap Config.defaultPackageName)
135+ <> help "Local package name as it should appear in the search results"
147136 )
148137
138+sourceFilesOption :: Parser (Array String)
139+sourceFilesOption = fromMaybe defaultSourceFiles <$>
140+ optional
141+ ( some
142+ ( strOption
143+ ( long "source-files"
144+ <> metavar "GLOB"
145+ <> help "Path to project source files, used for more precise module indexing (see #62). Default: src/**/*.purs"
146+ )
147+ )
148+ )
149149
150150defaultDocsFiles :: Array String
151151defaultDocsFiles = [ "output/**/docs.json" ]
152152
153−
154153defaultBowerFiles :: Array String
155154defaultBowerFiles = [ ".spago/*/*/bower.json", "bower_components/purescript-*/bower.json" ]
156155
156+defaultSourceFiles :: Array String
157+defaultSourceFiles = [ "src/**/*.purs" ]
157158
158159many :: forall a f. Unfoldable f => Parser a -> Parser (f a)
159160many x = CA.many x <#> List.toUnfoldable
160161
161−
162162some :: forall a f. Unfoldable f => Parser a -> Parser (f a)
163163some x = CA.some x <#> NonEmpty.toUnfoldable
src/Docs/Search/ModuleIndex.js+1−1
@@ -1,6 +1,6 @@
11/* global exports */
22
3−exports.load = function (url) {
3+export function load (url) {
44 return function () {
55 return new Promise(function (resolve, reject) {
66 if (typeof window.DocsSearchModuleIndex === 'undefined') {
src/Docs/Search/ModuleIndex.purs+17−13
@@ -2,10 +2,10 @@ module Docs.Search.ModuleIndex where
22
33import Docs.Search.Config as Config
44import Docs.Search.Declarations (Declarations(..))
5−import Docs.Search.SearchResult (SearchResult(..))
6−import Docs.Search.Types (ModuleName, PackageInfo, PackageScore)
75import Docs.Search.Extra (stringToList)
86import Docs.Search.Score (Scores, getPackageScore)
7+import Docs.Search.SearchResult (SearchResult(..))
8+import Docs.Search.Types (ModuleName, PackageInfo(..), PackageScore)
99
1010import Prelude
1111
@@ -21,7 +21,7 @@ import Data.Lens.Record (prop)
2121import Data.List (List, (:))
2222import Data.Map (Map)
2323import Data.Map as Map
24−import Data.Maybe (fromMaybe)
24+import Data.Maybe (Maybe(..), fromMaybe)
2525import Data.Newtype (unwrap)
2626import Data.Search.Trie (Trie)
2727import Data.Search.Trie as Trie
@@ -30,12 +30,11 @@ import Data.Set as Set
3030import Data.String.CodeUnits (toCharArray) as String
3131import Data.String.Common (split, toLower) as String
3232import Data.String.Pattern (Pattern(..))
33−import Data.Symbol (SProxy(..))
3433import Data.Traversable (foldr, for_)
3534import Data.Tuple.Nested ((/\))
3635import Effect (Effect)
3736import Effect.Aff (Aff)
38−
37+import Type.Proxy (Proxy(..))
3938
4039-- | Module index that is actually stored in a JS file.
4140type PackedModuleIndex = Map PackageInfo (Set ModuleName)
@@ -56,7 +55,7 @@ type ModuleResult
5655
5756unpackModuleIndex :: PackedModuleIndex -> ModuleIndex
5857unpackModuleIndex packageModules =
59− flip execState { packageModules, modulePackages: mempty, index: mempty } do
58+ flip execState { packageModules, modulePackages: Map.empty, index: mempty } do
6059 for_ (Map.toUnfoldableUnordered packageModules :: Array _)
6160 \(package /\ moduleNames) -> do
6261 for_ moduleNames \moduleName -> do
@@ -92,14 +91,19 @@ queryModuleIndex scores { index, modulePackages } query =
9291
9392
9493-- | Constructs a mapping from packages to modules
95−mkPackedModuleIndex :: Declarations -> PackedModuleIndex
96−mkPackedModuleIndex (Declarations trie) =
97− foldr (Map.unionWith Set.union) mempty $ extract <$> Trie.values trie
94+mkPackedModuleIndex :: Declarations -> Array ModuleName -> PackedModuleIndex
95+mkPackedModuleIndex (Declarations trie) moduleNames =
96+ addLocalPackageModuleNames $
97+ foldr (Map.unionWith Set.union) Map.empty $ extract <$> Trie.values trie
9898 where
99+ -- Add modules from src/ that may not contain any definitions, only
100+ -- re-exports
101+ addLocalPackageModuleNames = flip Map.alter LocalPackage $
102+ Just <<< append (Set.fromFoldable moduleNames) <<< fromMaybe Set.empty
99103 extract
100104 :: List SearchResult
101105 -> Map PackageInfo (Set ModuleName)
102− extract = foldr (Map.unionWith Set.union) mempty <<< map mkEntry
106+ extract = foldr (Map.unionWith Set.union) Map.empty <<< map mkEntry
103107 where
104108 mkEntry (SearchResult { packageInfo, moduleName }) =
105109 Map.singleton packageInfo (Set.singleton moduleName)
@@ -107,7 +111,7 @@ mkPackedModuleIndex (Declarations trie) =
107111loadModuleIndex :: Aff PackedModuleIndex
108112loadModuleIndex = do
109113 json <- toAffE $ load Config.moduleIndexLoadPath
110− pure $ fromMaybe mempty $ hush $ decodeJson json
114+ pure $ fromMaybe Map.empty $ hush $ decodeJson json
111115
112116
113117foreign import load
@@ -116,7 +120,7 @@ foreign import load
116120
117121
118122_modulePackages :: forall a b rest. (a -> b) -> { modulePackages :: a | rest } -> { modulePackages :: b | rest }
119−_modulePackages = prop (SProxy :: SProxy "modulePackages")
123+_modulePackages = prop (Proxy :: Proxy "modulePackages")
120124
121125_index :: forall a b rest. (a -> b) -> { index :: a | rest } -> { index :: b | rest }
122−_index = prop (SProxy :: SProxy "index")
126+_index = prop (Proxy :: Proxy "index")
src/Docs/Search/ModuleParser.pursnew file+50
@@ -0,0 +1,50 @@
1+module Docs.Search.ModuleParser where
2+
3+import Prelude
4+
5+import Control.Alt ((<|>))
6+import Data.Either (hush)
7+import Data.Foldable (intercalate)
8+import Data.Maybe (Maybe)
9+import Data.Newtype (wrap)
10+import Docs.Search.Types (ModuleName)
11+import Effect (Effect)
12+import StringParser (Parser, char, choice, fix, many, manyTill, noneOf, regex, runParser, sepBy, sepBy1, string, try, whiteSpace)
13+
14+parseModuleName :: String -> Maybe ModuleName
15+parseModuleName = map wrap <<< hush <<< runParser do
16+ void $ many whiteSpaceOrComment
17+ moduleHeader
18+
19+whiteSpaceOrComment :: Parser Unit
20+whiteSpaceOrComment =
21+ choice
22+ [ try $ multiLineComment
23+ , try $ singleLineComment
24+ , try $ void whiteSpace
25+ ]
26+
27+multiLineComment :: Parser Unit
28+multiLineComment = do
29+ void $ string "{-"
30+ void $ manyTill (void $ noneOf []) (string "-}")
31+
32+singleLineComment :: Parser Unit
33+singleLineComment = do
34+ void $ string "--"
35+ void $ manyTill (void $ noneOf ['\n']) (char '\n')
36+
37+moduleHeader :: Parser String
38+moduleHeader = do
39+ void $ string "module"
40+ void $ many whiteSpaceOrComment
41+ moduleName
42+
43+moduleName :: Parser String
44+moduleName = sepBy1 moduleNameWord (string ".") <#> intercalate "."
45+
46+moduleNameWord :: Parser String
47+moduleNameWord = do
48+ first <- regex "[A-Z]"
49+ rest <- regex "[A-Za-z0-9]*"
50+ pure $ first <> rest
src/Docs/Search/PackageIndex.purs+4−3
@@ -36,7 +36,7 @@ mkPackageInfo :: Scores -> Array PackageMeta -> PackageInfo
3636mkPackageInfo packageScores pms =
3737 Array.fromFoldable $
3838 Map.values $
39− Array.foldr insert mempty pms
39+ Array.foldr insert Map.empty pms
4040
4141 where
4242 insert
@@ -56,7 +56,7 @@ mkPackageInfo packageScores pms =
5656 , score: getPackageScoreForPackageName packageScores packageName
5757 , dependencies:
5858 unwrap dependencies <#>
59− (_.packageName >>> RawPackageName >>> normalizePackageName)
59+ _.packageName >>> RawPackageName >>> normalizePackageName
6060 , repository: repository <#> (_.url)
6161 }
6262
@@ -64,7 +64,8 @@ mkPackageInfo packageScores pms =
6464
6565mkScoresFromPackageIndex :: PackageIndex -> Scores
6666mkScoresFromPackageIndex =
67− Trie.values >>> Array.foldr (\ { name, score } -> Map.insert name score) mempty
67+ Trie.values >>> Array.fromFoldable >>>
68+ Array.foldr (\ { name, score } -> Map.insert name score) Map.empty
6869
6970
7071loadPackageIndex :: Aff PackageIndex
src/Docs/Search/Score.purs+1−1
@@ -29,7 +29,7 @@ mkScores =
2929 updateScoresFor (unwrap pm).dependencies >>>
3030 updateScoresFor (unwrap pm).devDependencies
3131 )
32− mempty
32+ Map.empty
3333
3434 where
3535 updateScoresFor :: Dependencies -> Scores -> Scores
src/Docs/Search/SearchResult.purs+7−6
@@ -1,15 +1,15 @@
11module Docs.Search.SearchResult where
22
33import Docs.Search.DocsJson (DataDeclType)
4−import Docs.Search.TypeDecoder (Constraint, FunDeps, Kind, QualifiedName, Type, TypeArgument)
4+import Docs.Search.TypeDecoder (Constraint, FunDeps, QualifiedName, Type, TypeArgument)
55import Docs.Search.Types (ModuleName, PackageInfo, Identifier, PackageScore)
66
77import Prelude
8−
8+import Prim hiding (Type, Constraint)
99import Data.Argonaut.Decode (class DecodeJson)
10−import Data.Argonaut.Decode.Generic.Rep (genericDecodeJson)
10+import Data.Argonaut.Decode.Generic (genericDecodeJson)
1111import Data.Argonaut.Encode (class EncodeJson)
12−import Data.Argonaut.Encode.Generic.Rep (genericEncodeJson)
12+import Data.Argonaut.Encode.Generic (genericEncodeJson)
1313import Data.Generic.Rep (class Generic)
1414import Data.Maybe (Maybe(..))
1515import Data.Newtype (class Newtype, un)
@@ -19,10 +19,11 @@ import Data.Newtype (class Newtype, un)
1919data ResultInfo
2020 = DataResult { typeArguments :: Array TypeArgument
2121 , dataDeclType :: DataDeclType }
22− | ExternDataResult { kind :: Kind }
22+ | ExternDataResult { kind :: Type }
2323 | TypeSynonymResult { arguments :: Array TypeArgument
2424 , type :: Type }
25− | DataConstructorResult { arguments :: Array Type }
25+ | DataConstructorResult { dataDeclType :: DataDeclType
26+ , type :: Type }
2627 | TypeClassMemberResult { type :: Type
2728 , typeClass :: QualifiedName
2829 , typeClassArguments :: Array TypeArgument }
src/Docs/Search/TypeDecoder.purs+36−70
@@ -1,20 +1,21 @@
1+-- | A decoder for types located in 'Language.PureScript.Types'.
12module Docs.Search.TypeDecoder where
23
34import Docs.Search.Types (Identifier)
45
56import Prelude
6−
7+import Prim hiding (Type, Constraint)
78import Control.Alt ((<|>))
89import Data.Argonaut.Core (Json, caseJsonObject, fromArray, fromObject, jsonEmptyObject, stringify, toArray)
910import Data.Argonaut.Decode (class DecodeJson, decodeJson, (.:))
1011import Data.Argonaut.Encode (class EncodeJson, encodeJson)
11−import Data.Array ((!!))
12+import Data.Argonaut.Decode.Error (JsonDecodeError(..))
1213import Data.Either (Either(..))
1314import Data.Generic.Rep (class Generic)
14−import Data.Generic.Rep.Show (genericShow)
15+import Data.Show.Generic (genericShow)
1516import Data.List (List(..), (:))
1617import Data.List as List
17−import Data.Maybe (Maybe(..), fromMaybe)
18+import Data.Maybe (Maybe(..))
1819import Data.Newtype (class Newtype)
1920import Data.Tuple (Tuple(..))
2021import Foreign.Object as Object
@@ -42,56 +43,13 @@ instance encodeJsonQualifiedName :: EncodeJson QualifiedName where
4243 encodeJson (QualifiedName { moduleNameParts, name }) =
4344 encodeTuple moduleNameParts name
4445
45−mkJsonError :: String -> Json -> (forall i. i -> String)
46+mkJsonError :: String -> Json -> (forall i. i -> JsonDecodeError)
4647mkJsonError name json _ =
47− "Couldn't parse " <> name <> " from " <> stringify json
48+ TypeMismatch $ "Couldn't parse " <> name <> " from " <> stringify json
4849
49−mkJsonError' :: String -> Json -> String
50+mkJsonError' :: String -> Json -> JsonDecodeError
5051mkJsonError' name json = mkJsonError name json unit
5152
52−-- | The data type of kinds
53−data Kind
54− -- | Kinds for labelled, unordered rows without duplicates
55− = Row Kind
56− -- | Function kinds
57− | FunKind Kind Kind
58− -- | A named kind
59− | NamedKind QualifiedName
60−
61−derive instance eqKind :: Eq Kind
62−derive instance genericKind :: Generic Kind _
63−
64−instance showKind :: Show Kind where
65− show x = genericShow x
66−
67−instance decodeJsonKind :: DecodeJson Kind where
68− decodeJson json = do
69− handle <- decodeJson json
70− tag <- handle .: "tag"
71− case tag of
72− "NamedKind" -> do
73− contents <- handle .: "contents"
74− pure $ NamedKind contents
75− "Row" -> do
76− contents <- handle .: "contents"
77− pure $ Row contents
78− "FunKind" -> do
79− contents <- handle .: "contents"
80− case contents of
81− [k1, k2] ->
82− Right $ FunKind k1 k2
83− _ -> Left $ mkJsonError' "FunKind" json
84− _ -> Left $ mkJsonError' "Kind" json
85−
86−instance encodeJsonKind :: EncodeJson Kind where
87− encodeJson = case _ of
88− Row k ->
89− tagged "Row" (encodeJson k)
90− FunKind k1 k2 ->
91− tagged "FunKind" (encodeTuple k1 k2)
92− NamedKind qname ->
93− tagged "NamedKind" (encodeJson qname)
94−
9553-- | A typeclass constraint
9654newtype Constraint = Constraint
9755 { constraintClass :: QualifiedName
@@ -140,8 +98,10 @@ data Type
14098 | TypeOp QualifiedName
14199 -- | A type application
142100 | TypeApp Type Type
101+ -- | Explicit kind application
102+ | KindApp Type Type
143103 -- | Forall quantifier
144− | ForAll String (Maybe Kind) Type
104+ | ForAll String (Maybe Type) Type
145105 -- | A type withset of type class constraints
146106 | ConstrainedType Constraint Type
147107 {-
@@ -152,10 +112,8 @@ data Type
152112 | REmpty
153113 -- | A non-empty row
154114 | RCons Identifier Type Type
155− {-
156115 -- | A type with a kind annotation
157− | Kinded Type Kind
158− -}
116+ | Kinded Type Type
159117 -- | Binary operator application. During the rebracketing phase of desugaring,
160118 -- this data constructor will be removed.
161119 | BinaryNoParensType Type Type Type
@@ -181,6 +139,9 @@ instance decodeJsonType :: DecodeJson Type where
181139 "TypeApp" ->
182140 decodeContents (decodeTuple TypeApp (const err)) (Left err) json
183141 where err = mkJsonError' "TypeApp" json
142+ "KindApp" ->
143+ decodeContents (decodeTuple KindApp (const err)) (Left err) json
144+ where err = mkJsonError' "KindApp" json
184145 "ForAll" ->
185146 decodeContents
186147 (decodeTriple
@@ -189,9 +150,10 @@ instance decodeJsonType :: DecodeJson Type where
189150 (Left $ err unit)
190151 json
191152 <|>
153+ -- Ignore SkolemScope
192154 decodeContents
193155 (decodeQuadriple
194− (\f (k :: Kind) a (_ :: Maybe Int) ->
156+ (\f (k :: Type) a (_ :: Maybe Int) ->
195157 ForAll f (Just k) a)
196158 err)
197159 (Left $ err unit)
@@ -204,6 +166,9 @@ instance decodeJsonType :: DecodeJson Type where
204166 "RCons" ->
205167 decodeContents (decodeTriple RCons (const err)) (Left err) json
206168 where err = mkJsonError' "RCons" json
169+ "KindedType" ->
170+ decodeContents (decodeTuple Kinded (const err)) (Left err) json
171+ where err = mkJsonError' "KindedType" json
207172 "BinaryNoParensType" ->
208173 decodeContents (decodeTriple BinaryNoParensType (const err)) (Left err) json
209174 where err = mkJsonError' "BinaryNoParens" json
@@ -221,11 +186,13 @@ instance encodeJsonType :: EncodeJson Type where
221186 TypeConstructor val -> tagged "TypeConstructor" (encodeJson val)
222187 TypeOp val -> tagged "TypeOp" (encodeJson val)
223188 TypeApp t1 t2 -> tagged "TypeApp" (encodeTuple t1 t2)
189+ KindApp t1 t2 -> tagged "KindApp" (encodeTuple t1 t2)
224190 ForAll str Nothing ty -> tagged "ForAll" (encodeTriple str ty emptySkolemScope)
225191 ForAll str (Just k) ty -> tagged "ForAll" (encodeQuadriple str k ty emptySkolemScope)
226192 ConstrainedType c t -> tagged "ConstrainedType" (encodeTuple c t)
227193 REmpty -> tagged "REmpty" jsonEmptyObject
228194 RCons s t1 t2 -> tagged "RCons" (encodeTriple s t1 t2)
195+ Kinded t1 t2 -> tagged "KindedType" (encodeTuple t1 t2)
229196 ParensInType t -> tagged "ParensInType" (encodeJson t)
230197 TypeWildcard -> tagged "TypeWildcard" jsonEmptyObject
231198 BinaryNoParensType t1 t2 t3 ->
@@ -270,7 +237,7 @@ instance encodeJsonFunDeps :: EncodeJson FunDeps where
270237newtype TypeArgument
271238 = TypeArgument
272239 { name :: String
273− , mbKind :: Maybe Kind
240+ , mbKind :: Maybe Type
274241 }
275242
276243derive newtype instance eqTypeArgument :: Eq TypeArgument
@@ -294,17 +261,16 @@ decodeTuple
294261 . DecodeJson fst
295262 => DecodeJson sec
296263 => (fst -> sec -> res)
297− -> (forall a. a -> String)
264+ -> (forall a. a -> JsonDecodeError)
298265 -> Json
299− -> Either String res
266+ -> Either JsonDecodeError res
300267decodeTuple cont err json =
301− fromMaybe (Left $ err unit) $
302− toArray json >>= \jsons ->
303− jsons !! 0 >>= \json1 ->
304− jsons !! 1 >>= \json2 -> pure $ do
305− fst <- decodeJson json1
306− sec <- decodeJson json2
307− pure $ cont fst sec
268+ case toArray json of
269+ Just [ json1, json2 ] -> do
270+ fst <- decodeJson json1
271+ sec <- decodeJson json2
272+ pure $ cont fst sec
273+ _ -> Left $ err unit
308274
309275-- | Decode a heterogeneous triple.
310276decodeTriple
@@ -313,9 +279,9 @@ decodeTriple
313279 => DecodeJson sec
314280 => DecodeJson trd
315281 => (fst -> sec -> trd -> res)
316− -> (forall a. a -> String)
282+ -> (forall a. a -> JsonDecodeError)
317283 -> Json
318− -> Either String res
284+ -> Either JsonDecodeError res
319285decodeTriple cont err json =
320286 case toArray json of
321287 Just [ json1, json2, json3 ] -> do
@@ -333,9 +299,9 @@ decodeQuadriple
333299 => DecodeJson trd
334300 => DecodeJson frt
335301 => (fst -> sec -> trd -> frt -> res)
336− -> (forall a. a -> String)
302+ -> (forall a. a -> JsonDecodeError)
337303 -> Json
338− -> Either String res
304+ -> Either JsonDecodeError res
339305decodeQuadriple cont err json =
340306 case toArray json of
341307 Just [ json1, json2, json3, json4 ] -> do
@@ -405,7 +371,7 @@ tagged tag contents =
405371joinForAlls
406372 :: Type
407373 -> { binders :: List { name :: String
408− , mbKind :: Maybe Kind }
374+ , mbKind :: Maybe Type }
409375 , ty :: Type
410376 }
411377joinForAlls ty = go Nil ty
src/Docs/Search/TypeIndex.js+1−1
@@ -1,6 +1,6 @@
11/* global exports */
22
3−exports.lookup_ = function (shape) {
3+export function lookup_ (shape) {
44 return function (url) {
55 return function () {
66 return new Promise(function (resolve, reject) {
src/Docs/Search/TypeIndex.purs+4−5
@@ -12,12 +12,13 @@ import Docs.Search.Types (ModuleName(..))
1212import Docs.Search.TypeShape (shapeOfType, shapeOfTypeQuery, stringifyShape)
1313
1414import Prelude
15−
15+import Prim hiding (Type)
1616import Control.Promise (Promise, toAffE)
1717import Data.Argonaut.Core (Json)
1818import Data.Argonaut.Decode (decodeJson)
1919import Data.Array as Array
2020import Data.Either (hush)
21+import Data.Foldable (fold, foldr)
2122import Data.Map (Map)
2223import Data.Map as Map
2324import Data.Maybe (Maybe(..), fromMaybe', isJust)
@@ -28,14 +29,12 @@ import Effect.Aff (Aff, try)
2829
2930newtype TypeIndex = TypeIndex (Map String (Maybe (Array SearchResult)))
3031
31−derive newtype instance semigroupTypeIndex :: Semigroup TypeIndex
32−derive newtype instance monoidTypeIndex :: Monoid TypeIndex
3332derive instance newtypeTypeIndex :: Newtype TypeIndex _
3433
3534
3635mkTypeIndex :: Scores -> Array DocsJson -> TypeIndex
3736mkTypeIndex scores docsJsons =
38− TypeIndex $ map Just $ Array.foldr insert mempty docsJsons
37+ TypeIndex $ map Just $ foldr insert Map.empty docsJsons
3938 where
4039 insert :: DocsJson -> Map String (Array SearchResult) -> Map String (Array SearchResult)
4140 insert docsJson mp =
@@ -78,7 +77,7 @@ lookup
7877 -> Aff { index :: TypeIndex, results :: Array SearchResult }
7978lookup key index@(TypeIndex map) =
8079 case Map.lookup key map of
81− Just results -> pure { index, results: Array.fold results }
80+ Just results -> pure { index, results: fold results }
8281 Nothing -> do
8382 eiJson <- try (toAffE (lookup_ key $ Config.mkShapeScriptPath key))
8483 pure $ fromMaybe'
src/Docs/Search/TypePrinter.purs+10−14
@@ -1,10 +1,10 @@
11module Docs.Search.TypePrinter where
22
33import Prelude
4−
4+import Prim hiding (Type, Constraint)
55import Docs.Search.Extra ((>#>))
66import Docs.Search.Terminal (cyan)
7−import Docs.Search.TypeDecoder (Constraint(..), FunDep(..), FunDeps(..), Kind(..), QualifiedName(..), Type(..), TypeArgument(..), joinForAlls, joinRows)
7+import Docs.Search.TypeDecoder (Constraint(..), FunDep(..), FunDeps(..), QualifiedName(..), Type(..), TypeArgument(..), joinForAlls, joinRows)
88import Docs.Search.Types (Identifier(..))
99
1010import Data.Array as Array
@@ -37,6 +37,9 @@ showType = case _ of
3737 TypeApp t1 t2 ->
3838 showType t1 <> " " <> showType t2
3939
40+ KindApp t1 t2 ->
41+ showType t1 <> " " <> showType t2
42+
4043 ty@(ForAll _ _ _) ->
4144 showForAll ty
4245
@@ -48,6 +51,8 @@ showType = case _ of
4851 ty@REmpty -> showRow true ty
4952 ty@(RCons _ _ _) -> showRow true ty
5053
54+ Kinded t1 t2 -> showType t1 <> " :: " <> showType t2
55+
5156 BinaryNoParensType op t1 t2 ->
5257 showType t1 <>
5358 space <>
@@ -70,7 +75,7 @@ showTypeArgument (TypeArgument { name, mbKind }) =
7075 "(" <>
7176 name <>
7277 " :: " <>
73− showKind kind <>
78+ showType kind <>
7479 ")"
7580
7681
@@ -127,7 +132,7 @@ showForAll
127132showForAll ty =
128133 keyword "forall" <>
129134
130− ( Array.fold $ foralls.binders <#>
135+ ( Array.fold $ Array.fromFoldable $ foralls.binders <#>
131136 \ { name, mbKind } ->
132137 case mbKind of
133138 Nothing -> " " <> name
@@ -135,7 +140,7 @@ showForAll ty =
135140 " (" <> name <> " "
136141 <> syntax "::"
137142 <> space
138− <> showKind kind
143+ <> showType kind
139144 <> ")"
140145 ) <>
141146
@@ -146,15 +151,6 @@ showForAll ty =
146151 foralls = joinForAlls ty
147152
148153
149−showKind
150− :: Kind
151− -> String
152−showKind = case _ of
153− Row k1 -> "# " <> showKind k1
154− FunKind k1 k2 -> showKind k1 <> syntax " -> " <> showKind k2
155− NamedKind qname -> showQualifiedName qname
156−
157−
158154showConstraint
159155 :: Constraint
160156 -> String
src/Docs/Search/TypeQuery.purs+20−11
@@ -16,12 +16,12 @@ import Docs.Search.TypeDecoder (QualifiedName(..), Type(..), joinConstraints, jo
1616import Docs.Search.Types (Identifier(..))
1717
1818import Prelude
19−
19+import Prim hiding (Type)
2020import Control.Alt ((<|>))
2121import Data.Array as Array
2222import Data.Either (Either)
2323import Data.Generic.Rep (class Generic)
24−import Data.Generic.Rep.Show (genericShow)
24+import Data.Show.Generic (genericShow)
2525import Data.List (List(..), many, some, (:))
2626import Data.List as List
2727import Data.List.NonEmpty (NonEmptyList)
@@ -34,9 +34,9 @@ import Data.Set as Set
3434import Data.String.CodeUnits (fromCharArray)
3535import Data.String.Common (trim) as String
3636import Data.Tuple (Tuple(..), fst, snd)
37−import Text.Parsing.StringParser (ParseError, Parser, runParser, try)
38−import Text.Parsing.StringParser.CodePoints (alphaNum, anyLetter, char, eof, lowerCaseChar, skipSpaces, string, upperCaseChar)
39−import Text.Parsing.StringParser.Combinators (fix, sepBy, sepBy1, sepEndBy, sepEndBy1)
37+import StringParser (ParseError, Parser, runParser, try)
38+import StringParser.CodePoints (alphaNum, anyLetter, char, eof, lowerCaseChar, skipSpaces, string, upperCaseChar)
39+import StringParser.Combinators (fix, sepBy, sepBy1, sepEndBy, sepEndBy1)
4040
4141
4242-- | 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_ })
236236 -- * Names
237237 go acc ({ q: QConst qname, t: TypeConstructor (QualifiedName { name }) } : rest) =
238238 go (Match qname name : acc) rest
239− go acc ({ q: QConst qname, t } : rest) =
239+ go acc ({ q: QConst _, t } : rest) =
240240 go (TypeMismatch t : acc) rest
241− go acc ({ q, t: TypeConstructor (QualifiedName { name }) } : rest) =
241+ go acc ({ q, t: TypeConstructor (QualifiedName _) } : rest) =
242242 go (QueryMismatch q : acc) rest
243243
244244 -- type operators can't appear in type queries: this is always a mismatch
245− go acc ({ q, t: TypeOp (QualifiedName { name }) } : rest) =
245+ go acc ({ q, t: TypeOp (QualifiedName _) } : rest) =
246246 go (QueryMismatch q : acc) rest
247247 go acc ({ q, t: t@(BinaryNoParensType _ _ _) } : rest) =
248248 go (Mismatch q t : acc) rest
@@ -253,7 +253,7 @@ unify query type_ = go Nil (List.singleton { q: query, t: type_ })
253253 (QualifiedName { moduleNameParts: [ "Prim" ]
254254 , name: Identifier "Function" })) t1) t2 } : rest) =
255255 go acc ({ q: q1, t: t1 } : { q: q2, t: t2 } : rest)
256− go acc ({ q: q@(QFun q1 q2), t } : rest) =
256+ go acc ({ q: q@(QFun _ _), t } : rest) =
257257 go (Mismatch q t : acc) rest
258258
259259 -- * Rows
@@ -261,7 +261,7 @@ unify query type_ = go Nil (List.singleton { q: query, t: type_ })
261261 , t: TypeApp (TypeConstructor
262262 (QualifiedName { moduleNameParts: [ "Prim" ]
263263 , name: Identifier "Record" })) row } : rest) =
264− let { rows, ty } = joinRows row
264+ let { rows } = joinRows row
265265 qRowsLength = List.length qRows
266266 rowsLength = List.length rows in
267267 if rowsLength == qRowsLength then
@@ -297,6 +297,12 @@ unify query type_ = go Nil (List.singleton { q: query, t: type_ })
297297 go acc ({ q, t: REmpty } : rest) =
298298 go (QueryMismatch q : acc) rest
299299
300+ go acc ({ q, t: Kinded _ _} : rest) =
301+ go (QueryMismatch q : acc) rest
302+
303+ go acc ({ t: t@(KindApp _ _) } : rest) =
304+ go (TypeMismatch t : acc) rest
305+
300306
301307-- | Sum various penalties.
302308penalty :: TypeQuery -> Type -> Int
@@ -331,7 +337,7 @@ typeVarPenalty substs =
331337 Substitute v1 v2 ->
332338 f v1 v2
333339 _ -> identity
334− ) mempty substs
340+ ) Map.empty substs
335341
336342
337343-- | Penalty for name mismatches.
@@ -411,6 +417,7 @@ typeSize = go 0 <<< List.singleton
411417 go (n + 1) rest
412418 go n (TypeOp _ : rest) =
413419 go (n + 1) rest
420+ go n (KindApp t1 t2 : res) = go n (t1 : t2 : res)
414421 go n (TypeApp (TypeApp (TypeConstructor
415422 (QualifiedName { moduleNameParts: [ "Prim" ]
416423 , name: Identifier "Function" })) t1) t2 : rest) =
@@ -425,6 +432,8 @@ typeSize = go 0 <<< List.singleton
425432 go (n + 1) (t1 : t2 : rest)
426433 go n (REmpty : rest) =
427434 go (n + 1) rest
435+ go n (Kinded t1 t2 : rest) =
436+ go n (t1 : t2 : rest)
428437 go n (BinaryNoParensType op t1 t2 : rest) =
429438 go (n + 1) (t1 : t2 : rest)
430439 go n (ParensInType t : rest) =
src/Docs/Search/TypeShape.js+1−1
@@ -1,6 +1,6 @@
11/* global exports */
22
3−exports.hash = function (string) {
3+export function hash (string) {
44 var hash = Math.floor(Number.MAX_SAFE_INTEGER / 2);
55 if (string.length == 0) {
66 return hash;
src/Docs/Search/TypeShape.purs+7−2
@@ -8,9 +8,9 @@ import Docs.Search.TypeQuery (TypeQuery(..), getFreeVariables)
88import Docs.Search.Types (Identifier(..))
99
1010import Prelude
11−
11+import Prim hiding (Type)
1212import Data.Generic.Rep (class Generic)
13−import Data.Generic.Rep.Show (genericShow)
13+import Data.Show.Generic (genericShow)
1414import Data.List (List(..), (:))
1515import Data.List as List
1616import Data.List.NonEmpty as NonEmptyList
@@ -115,6 +115,9 @@ shapeOfType ty = List.reverse $ go (pure ty) Nil
115115 TypeApp child1 child2 ->
116116 go (child1 : child2 : rest) (PApp : acc)
117117
118+ KindApp child1 child2 ->
119+ go (child1 : child2 : rest) (PApp : acc)
120+
118121 forallType@(ForAll _ _ _) ->
119122 go (foralls.ty : rest) (PForAll (List.length foralls.binders) : acc)
120123 where foralls = joinForAlls forallType
@@ -136,6 +139,8 @@ shapeOfType ty = List.reverse $ go (pure ty) Nil
136139 sorted = List.sortBy (\x y -> compare x.row y.row) joined.rows
137140 typesInRow = sorted <#> (_.ty)
138141
142+ Kinded t1 _t2 -> go (t1 : rest) acc
143+
139144 BinaryNoParensType op l r ->
140145 go (TypeApp (TypeApp op l) r : rest) acc
141146
src/Docs/Search/Types.purs+9−6
@@ -3,11 +3,11 @@ module Docs.Search.Types where
33import Prelude
44
55import Data.Argonaut.Decode (class DecodeJson)
6−import Data.Argonaut.Decode.Generic.Rep (genericDecodeJson)
6+import Data.Argonaut.Decode.Generic (genericDecodeJson)
77import Data.Argonaut.Encode (class EncodeJson)
8−import Data.Argonaut.Encode.Generic.Rep (genericEncodeJson)
8+import Data.Argonaut.Encode.Generic (genericEncodeJson)
99import Data.Generic.Rep (class Generic)
10−import Data.Generic.Rep.Show (genericShow)
10+import Data.Show.Generic (genericShow)
1111import Data.Newtype (class Newtype)
1212
1313
@@ -31,6 +31,9 @@ derive newtype instance ordModuleName :: Ord ModuleName
3131derive newtype instance decodeJsonModuleName :: DecodeJson ModuleName
3232derive newtype instance encodeJsonModuleName :: EncodeJson ModuleName
3333
34+instance Show ModuleName where
35+ show = genericShow
36+
3437
3538-- | Non-normalized package name, e.g. `purescript-prelude` or just `prelude`.
3639newtype RawPackageName = RawPackageName String
@@ -55,14 +58,14 @@ data PackageInfo = LocalPackage | Builtin | Package PackageName | UnknownPackage
5558derive instance eqPackageInfo :: Eq PackageInfo
5659derive instance ordPackageInfo :: Ord PackageInfo
5760derive instance genericPackageInfo :: Generic PackageInfo _
58−instance showPackageInfo :: Show PackageInfo where
59− show = genericShow
60−
6161instance decodeJsonPackageInfo :: DecodeJson PackageInfo where
6262 decodeJson = genericDecodeJson
6363instance encodeJsonPackageInfo :: EncodeJson PackageInfo where
6464 encodeJson = genericEncodeJson
6565
66+instance showPackageInfo :: Show PackageInfo where
67+ show = genericShow
68+
6669
6770newtype PackageScore = PackageScore Int
6871
src/Docs/Search/URIHash.js+1−1
@@ -1,7 +1,7 @@
11/* global exports history */
22
33// https://stackoverflow.com/questions/1397329
4−exports.removeHash = function () {
4+export function removeHash () {
55 var scrollV, scrollH, loc = window.location;
66 if ("pushState" in history)
77 history.pushState("", document.title, loc.pathname + loc.search);
src/Docs/Search/URIHash.purs+3−3
@@ -7,10 +7,10 @@ where
77
88import Prelude
99
10−import Data.Maybe (Maybe(Just), fromMaybe)
10+import Data.Maybe (fromMaybe)
1111import Data.String.CodeUnits as String
1212import Effect (Effect)
13−import Global (decodeURIComponent, encodeURIComponent)
13+import JSURI (decodeURIComponent, encodeURIComponent)
1414import Web.HTML as HTML
1515import Web.HTML.Location as Location
1616import Web.HTML.Window as Window
@@ -31,7 +31,7 @@ getInput = do
3131 location <- Window.location window
3232 hash <- Location.hash location
3333 pure $
34− if String.slice 0 8 hash == Just "#search:"
34+ if String.slice 0 8 hash == "#search:"
3535 then fromMaybe "" $
3636 decodeURIComponent $
3737 String.drop 8 hash
test/Main.purs+14−526
@@ -2,540 +2,28 @@ module Test.Main where
22
33import Prelude
44
5−import Docs.Search.TypeDecoder (Constraint(..), FunDep(..), FunDeps(..), Kind(..), QualifiedName(..), Type(..))
6−import Docs.Search.Types (Identifier(..))
7−import Test.TypeQuery as TypeQuery
8−import Test.IndexBuilder as IndexBuilder
5+import Effect (Effect)
6+import Effect.Aff (launchAff_)
97import Test.Declarations as Declarations
8+import Test.IndexBuilder as IndexBuilder
109import Test.ModuleIndex as ModuleIndex
11−
12−import Test.Extra (assertRight)
13−
14−import Data.Argonaut.Decode (decodeJson)
15−import Data.Argonaut.Encode (encodeJson)
16−import Data.Argonaut.Parser (jsonParser)
17−import Data.Either (fromRight)
18−import Data.Maybe (Maybe(..))
19−import Effect (Effect)
20−import Partial.Unsafe (unsafePartial)
21−import Test.Unit (TestSuite, suite, test)
22−import Test.Unit.Main (runTest)
10+import Test.ModuleParser as ModuleParser
11+import Test.Spec (Spec)
12+import Test.Spec.Reporter.Console (consoleReporter)
13+import Test.Spec.Runner (runSpec)
14+import Test.TypeJson as TypeJson
15+import Test.TypeQuery as TypeQuery
2316
2417main :: Effect Unit
2518main = do
26− runTest mainTest
19+ launchAff_ $ runSpec [consoleReporter] mainTest
20+ -- UI.main
2721
28−mainTest :: TestSuite
22+mainTest :: Spec Unit
2923mainTest = do
24+ ModuleParser.tests
3025 TypeQuery.tests
26+ TypeJson.tests
3127 IndexBuilder.tests
3228 Declarations.tests
3329 ModuleIndex.tests
34−
35− let mkJson x = unsafePartial $ fromRight $ jsonParser x
36− suite "FunDeps decoder" do
37− test "FunDeps" do
38− let funDeps = mkJson """
39− [
40− [
41− [
42− "lhs",
43− "rhs"
44− ],
45− [
46− "output"
47− ]
48− ]
49− ]
50− """
51− assertRight (decodeJson funDeps)
52− (FunDeps [ FunDep { lhs: [ "lhs", "rhs" ]
53− , rhs: [ "output"]
54− }
55− ])
56−
57− suite "Kind decoder" do
58−
59− test "QualifiedName" do
60−
61− let qualifiedName = mkJson """
62− [
63− [
64− "Prim"
65− ],
66− "Type"
67− ]
68− """
69−
70− assertRight (decodeJson qualifiedName)
71− (qualified ["Prim"] "Type")
72−
73− test "NamedKind" do
74− let namedKind = mkJson """
75− {
76− "annotation": [],
77− "tag": "NamedKind",
78− "contents": [
79− [
80− "Prim"
81− ],
82− "Type"
83− ]
84− }
85− """
86−
87− assertRight (decodeJson namedKind)
88− (NamedKind $ qualified ["Prim"] "Type")
89−
90− test "Row" do
91− let row = mkJson """
92− {
93− "annotation": [],
94− "tag": "Row",
95− "contents": {
96− "annotation": [],
97− "tag": "NamedKind",
98− "contents": [
99− [
100− "Prim"
101− ],
102− "Type"
103− ]
104− }
105− }
106− """
107−
108− assertRight (decodeJson row) (Row $ NamedKind $ qualified ["Prim"] "Type")
109−
110− test "FunKind" do
111− let funKind = mkJson """
112− {
113− "annotation": [],
114− "tag": "FunKind",
115− "contents": [
116− {
117− "annotation": [],
118− "tag": "Row",
119− "contents": {
120− "annotation": [],
121− "tag": "NamedKind",
122− "contents": [
123− [
124− "Prim"
125− ],
126− "Type"
127− ]
128− }
129− },
130− {
131− "annotation": [],
132− "tag": "Row",
133− "contents": {
134− "annotation": [],
135− "tag": "NamedKind",
136− "contents": [
137− [
138− "Prim"
139− ],
140− "Type"
141− ]
142− }
143− }
144− ]
145− }
146− """
147− assertRight (decodeJson funKind)
148− (FunKind (Row $ NamedKind $ qualified ["Prim"] "Type")
149− (Row $ NamedKind $ qualified ["Prim"] "Type")
150− )
151−
152−
153− suite "Constraint decoder" do
154− test "Constraint" do
155− let constraint = mkJson """
156− {
157− "constraintAnn": [],
158− "constraintClass": [
159− [
160− "Prim"
161− ],
162− "Partial"
163− ],
164− "constraintArgs": [],
165− "constraintData": null
166− }
167− """
168− assertRight (decodeJson constraint)
169− (Constraint { constraintClass: qualified ["Prim"] "Partial"
170− , constraintArgs: []
171− })
172−
173− suite "Type decoder" do
174− test "TypeVar" do
175− let typeVar = mkJson """
176− {
177− "annotation": [],
178− "tag": "TypeVar",
179− "contents": "m"
180− }
181− """
182−
183− assertRight (decodeJson typeVar)
184− (TypeVar "m")
185−
186− test "TypeApp" do
187− let typeApp1 = mkJson """
188− {
189− "annotation": [],
190− "tag": "TypeApp",
191− "contents": [
192− {
193− "annotation": [],
194− "tag": "TypeConstructor",
195− "contents": [
196− [
197− "Control",
198− "Monad",
199− "ST",
200− "Internal"
201− ],
202− "ST"
203− ]
204− },
205− {
206− "annotation": [],
207− "tag": "TypeVar",
208− "contents": "h"
209− }
210− ]
211− }
212− """
213−
214− assertRight (decodeJson typeApp1) $
215− TypeApp
216− (TypeConstructor (qualified [ "Control"
217− , "Monad"
218− , "ST"
219− , "Internal"
220− ]
221− "ST"
222− ))
223− (TypeVar "h")
224−
225− test "TypeOp" do
226− let typeOp = mkJson """
227− {
228− "annotation": [],
229− "tag": "TypeOp",
230− "contents": [
231− [
232− "Data",
233− "NaturalTransformation"
234− ],
235− "~>"
236− ]
237− }
238− """
239− assertRight (decodeJson typeOp) $
240− TypeOp $ qualified [ "Data", "NaturalTransformation" ] "~>"
241−
242− test "BinaryNoParens" do
243− let binaryNoParens = mkJson """
244− {
245− "annotation": [],
246− "tag": "BinaryNoParensType",
247− "contents": [
248− {
249− "annotation": [],
250− "tag": "TypeOp",
251− "contents": [
252− [
253− "Data",
254− "NaturalTransformation"
255− ],
256− "~>"
257− ]
258− },
259− {
260− "annotation": [],
261− "tag": "TypeVar",
262− "contents": "m"
263− },
264− {
265− "annotation": [],
266− "tag": "TypeVar",
267− "contents": "n"
268− }
269− ]
270− }
271− """
272−
273− assertRight (decodeJson binaryNoParens) $
274− BinaryNoParensType
275− (TypeOp $ qualified ["Data", "NaturalTransformation"] "~>")
276− (TypeVar "m")
277− (TypeVar "n")
278−
279− test "ParensInType" do
280− let parensInType = mkJson """
281− {
282− "annotation": [],
283− "tag": "ParensInType",
284− "contents": {
285− "annotation": [],
286− "tag": "TypeApp",
287− "contents": [
288− {
289− "annotation": [],
290− "tag": "TypeConstructor",
291− "contents": [
292− [
293− "Data",
294− "Maybe"
295− ],
296− "Maybe"
297− ]
298− },
299− {
300− "annotation": [],
301− "tag": "TypeConstructor",
302− "contents": [
303− [
304− "Prim"
305− ],
306− "String"
307− ]
308− }
309− ]
310− }
311− }
312− """
313−
314− assertRight (decodeJson parensInType) $
315− ParensInType $
316− TypeApp
317− (TypeConstructor (qualified [ "Data", "Maybe" ] "Maybe"))
318− (TypeConstructor (qualified [ "Prim" ] "String"))
319− test "RCons" do
320−
321− let rcons = mkJson """
322− {
323− "annotation": [],
324− "tag": "RCons",
325− "contents": [
326− "tail",
327− {
328− "annotation": [],
329− "tag": "TypeApp",
330− "contents": [
331− {
332− "annotation": [],
333− "tag": "TypeConstructor",
334− "contents": [
335− [
336− "Data",
337− "Symbol"
338− ],
339− "SProxy"
340− ]
341− },
342− {
343− "annotation": [],
344− "tag": "TypeVar",
345− "contents": "t"
346− }
347− ]
348− },
349− {
350− "annotation": [],
351− "tag": "REmpty"
352− }
353− ]
354− }
355− """
356−
357− assertRight (decodeJson rcons) $
358− RCons
359− (Identifier "tail")
360− (TypeApp (TypeConstructor $ qualified [ "Data", "Symbol" ] "SProxy")
361− (TypeVar "t"))
362− REmpty
363−
364− test "ForAll #1" do
365− let forallJson = mkJson """
366− {"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]}
367− """
368− assertRight (decodeJson forallJson) $
369− ForAll "a" Nothing (TypeApp (TypeApp (TypeConstructor $ qualified ["Prim"] "Function")
370− (TypeConstructor $ qualified ["Prim"] "String"))
371− (TypeVar "a"))
372−
373− test "ForAll #2" do
374− let forallJson = mkJson """
375−{
376− "annotation": [],
377− "tag": "ForAll",
378− "contents": [
379− "f",
380− {
381− "annotation": [],
382− "tag": "FunKind",
383− "contents": [
384− {
385− "annotation": [],
386− "tag": "NamedKind",
387− "contents": [
388− [
389− "Prim",
390− "RowList"
391− ],
392− "RowList"
393− ]
394− },
395− {
396− "annotation": [],
397− "tag": "NamedKind",
398− "contents": [
399− [
400− "Prim"
401− ],
402− "Type"
403− ]
404− }
405− ]
406− },
407− {
408− "annotation": [],
409− "tag": "TypeApp",
410− "contents": [
411− {
412− "annotation": [],
413− "tag": "TypeApp",
414− "contents": [
415− {
416− "annotation": [],
417− "tag": "TypeConstructor",
418− "contents": [
419− [
420− "Prim"
421− ],
422− "Function"
423− ]
424− },
425− {
426− "annotation": [],
427− "tag": "TypeApp",
428− "contents": [
429− {
430− "annotation": [],
431− "tag": "TypeVar",
432− "contents": "f"
433− },
434− {
435− "annotation": [],
436− "tag": "TypeVar",
437− "contents": "l"
438− }
439− ]
440− }
441− ]
442− },
443− {
444− "annotation": [],
445− "tag": "TypeApp",
446− "contents": [
447− {
448− "annotation": [],
449− "tag": "TypeConstructor",
450− "contents": [
451− [
452− "Data",
453− "List",
454− "Types"
455− ],
456− "List"
457− ]
458− },
459− {
460− "annotation": [],
461− "tag": "ParensInType",
462− "contents": {
463− "annotation": [],
464− "tag": "TypeApp",
465− "contents": [
466− {
467− "annotation": [],
468− "tag": "TypeApp",
469− "contents": [
470− {
471− "annotation": [],
472− "tag": "TypeConstructor",
473− "contents": [
474− [
475− "Data",
476− "Tuple"
477− ],
478− "Tuple"
479− ]
480− },
481− {
482− "annotation": [],
483− "tag": "TypeConstructor",
484− "contents": [
485− [
486− "Prim"
487− ],
488− "String"
489− ]
490− }
491− ]
492− },
493− {
494− "annotation": [],
495− "tag": "TypeConstructor",
496− "contents": [
497− [
498− "Prim"
499− ],
500− "String"
501− ]
502− }
503− ]
504− }
505− }
506− ]
507− }
508− ]
509− },
510− null
511− ]
512−}
513− """
514− assertRight (decodeJson forallJson) $
515− ForAll "f"
516− (Just (FunKind (NamedKind (QualifiedName { moduleNameParts: ["Prim","RowList"], name: Identifier "RowList" })) (NamedKind (QualifiedName { moduleNameParts: ["Prim"], name: Identifier "Type" }))))
517− (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: Identifier "Function" })) (TypeApp (TypeVar "f") (TypeVar "l"))) (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Data","List","Types"], name: Identifier "List" })) (ParensInType (TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Data","Tuple"], name: Identifier "Tuple" })) (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: Identifier "String" }))) (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"], name: Identifier "String" }))))))
518−
519−
520−
521−
522− suite "jsons" do
523−
524− test "jsons #1" do
525− let json = mkJson """
526−{"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]}
527− """
528−
529− 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"))))))))
530−
531− suite "Kind encoder" do
532− test "FunKind" do
533− let k1 =
534− FunKind (Row (NamedKind $ qualified [] "a"))
535− (FunKind (NamedKind $ qualified [] "b")
536− (NamedKind $ qualified [] "b"))
537− assertRight (decodeJson $ encodeJson $ k1) k1
538−
539−
540−qualified :: Array String -> String -> QualifiedName
541−qualified moduleNameParts name = QualifiedName { moduleNameParts, name: Identifier name }
test/Test/Declarations.purs+12−13
@@ -7,33 +7,32 @@ import Docs.Search.Types (PackageName(..), PackageInfo(..))
77
88import Data.Maybe (Maybe(..))
99import Data.Newtype (wrap)
10+import Test.Spec (Spec, describe, it)
11+import Test.Spec.Assertions (shouldEqual)
1012
11−import Test.Unit (TestSuite, suite, test)
12−import Test.Unit.Assert as Assert
13−
14−tests :: TestSuite
13+tests :: Spec Unit
1514tests = do
16− suite "Declarations" do
17− test "extractPackageName" do
18− Assert.equal Builtin (extractPackageName (wrap "Prim") Nothing)
19− Assert.equal Builtin (extractPackageName (wrap "Prim.Foo") Nothing)
20− Assert.equal Builtin (extractPackageName (wrap "Prim.Foo.Bar") Nothing)
21− Assert.equal UnknownPackage (extractPackageName (wrap "Primitive") Nothing)
22− Assert.equal (Package $ PackageName "foo")
15+ describe "Declarations" do
16+ it "extractPackageName works correctly" do
17+ Builtin `shouldEqual` (extractPackageName (wrap "Prim") Nothing)
18+ Builtin `shouldEqual` (extractPackageName (wrap "Prim.Foo") Nothing)
19+ Builtin `shouldEqual` (extractPackageName (wrap "Prim.Foo.Bar") Nothing)
20+ UnknownPackage `shouldEqual` (extractPackageName (wrap "Primitive") Nothing)
21+ Package (PackageName "foo") `shouldEqual`
2322 (extractPackageName (wrap "Foo") $
2423 Just { start: []
2524 , end: []
2625 , name: ".spago/foo/src/Foo.purs"
2726 }
2827 )
29− Assert.equal (Package $ PackageName "bar")
28+ Package (PackageName "bar") `shouldEqual`
3029 (extractPackageName (wrap "Bar") $
3130 Just { start: []
3231 , end: []
3332 , name: "/path/to/somewhere/bower_components/bar/src/Bar.purs"
3433 }
3534 )
36− Assert.equal LocalPackage
35+ LocalPackage `shouldEqual`
3736 (extractPackageName (wrap "Bar") $
3837 Just { start: []
3938 , end: []
test/Test/Extra.purs+6−5
@@ -4,7 +4,8 @@ import Prelude
44
55import Data.Either (Either(..))
66import Effect.Aff (Aff)
7−import Test.Unit.Assert as Assert
7+import Test.Spec.Assertions (shouldEqual)
8+
89
910assertRight
1011 :: forall a b
@@ -17,7 +18,7 @@ assertRight
1718 -> Aff Unit
1819assertRight eiActual expected =
1920 case eiActual of
20− Left string -> do
21− Assert.equal (Right expected) eiActual
22− Right actual -> do
23− Assert.equal (Right expected) eiActual
21+ Left _ -> do
22+ Right expected `shouldEqual` eiActual
23+ Right _ -> do
24+ Right expected `shouldEqual` eiActual
test/Test/IndexBuilder.purs+9−9
@@ -5,16 +5,16 @@ import Prelude
55import Docs.Search.IndexBuilder (patchHTML)
66
77import Data.Tuple (snd)
8−import Test.Unit (TestSuite, suite, test)
9−import Test.Unit.Assert as Assert
8+import Test.Spec (Spec, describe, it)
9+import Test.Spec.Assertions (shouldEqual, shouldNotSatisfy)
1010
11−tests :: TestSuite
11+tests :: Spec Unit
1212tests = do
13− suite "IndexBuilder" do
14− suite "patchHTML" do
15− test "works" do
13+ describe "IndexBuilder" do
14+ describe "patchHTML" do
15+ it "works" do
1616 let input = "</body>"
17− Assert.assertFalse "patchHTML works" (snd (patchHTML input) == input)
18− test "is idempotent" do
17+ shouldNotSatisfy (snd (patchHTML input)) (eq input)
18+ it "is idempotent" do
1919 let input = "</body>"
20− Assert.equal (snd $ patchHTML $ snd $ patchHTML input) (snd $ patchHTML input)
20+ shouldEqual (snd $ patchHTML $ snd $ patchHTML input) (snd $ patchHTML input)
test/Test/ModuleIndex.purs+8−10
@@ -6,20 +6,18 @@ import Prelude
66
77import Data.List as List
88import Data.Newtype (wrap)
9−import Test.Unit (TestSuite, suite, test)
10−import Test.Unit.Assert as Assert
9+import Test.Spec (Spec, describe, it)
10+import Test.Spec.Assertions (shouldEqual)
1111
1212
13−tests :: TestSuite
13+tests :: Spec Unit
1414tests = do
15− suite "ModuleIndex" do
15+ describe "ModuleIndex" do
1616
17− test "test #0" do
18− Assert.equal (extractModuleNameParts $ wrap "Data.Array.ST") (
17+ it "test #0" do
18+ extractModuleNameParts (wrap "Data.Array.ST") `shouldEqual`
1919 List.fromFoldable [ "st", "array.st", "data.array.st" ]
20− )
2120
22− test "test #1" do
23− Assert.equal (extractModuleNameParts $ wrap "Foo") (
21+ it "test #1" do
22+ extractModuleNameParts (wrap "Foo") `shouldEqual`
2423 List.fromFoldable [ "foo" ]
25− )
test/Test/ModuleParser.pursnew file+61
@@ -0,0 +1,61 @@
1+module Test.ModuleParser where
2+
3+import Docs.Search.IndexBuilder (getPathsByGlobs)
4+import Docs.Search.ModuleParser (multiLineComment, parseModuleName, singleLineComment)
5+import Docs.Search.Types (ModuleName(..))
6+
7+import Prelude
8+
9+import Data.Array as Array
10+import Data.Either (Either(..))
11+import Data.Foldable (for_)
12+import Data.Maybe (Maybe(..))
13+import Effect.Class (liftEffect)
14+import Effect.Console as Console
15+import Effect.Exception (throw)
16+import Node.Encoding (Encoding(..))
17+import Node.FS.Aff (readTextFile)
18+import StringParser (runParser)
19+import Test.Spec (Spec, describe, it)
20+import Test.Spec.Assertions (shouldEqual)
21+
22+tests :: Spec Unit
23+tests = do
24+ describe "ModuleParser" do
25+ it "test #0" do
26+ parseModuleName "module Foo" `shouldEqual` Just (ModuleName "Foo")
27+ it "test #1" do
28+ parseModuleName "module Foo.Bar.B" `shouldEqual` Just (ModuleName "Foo.Bar.B")
29+ it "test #2" do
30+ parseModuleName " module Foo" `shouldEqual` Just (ModuleName "Foo")
31+ it "test #3" do
32+ parseModuleName " {- asdas -} module Foo" `shouldEqual` Just (ModuleName "Foo")
33+ it "test #4" do
34+ parseModuleName "{--}module Foo" `shouldEqual` Just (ModuleName "Foo")
35+ it "test #5" do
36+ parseModuleName "--\nmodule Foo" `shouldEqual` Just (ModuleName "Foo")
37+ it "test #6" do
38+ parseModuleName "--\n-- foo\nmodule Foo" `shouldEqual` Just (ModuleName "Foo")
39+ it "test #7" do
40+ parseModuleName "-- \n -- foo\n {- bar -} --baz\n module Foo" `shouldEqual` Just (ModuleName "Foo")
41+ it "multiline comment #1" do
42+ runParser multiLineComment "{--}" `shouldEqual` Right unit
43+ it "multiline comment #1" do
44+ runParser multiLineComment "{- foo -}" `shouldEqual` Right unit
45+ it "multiline comment #1" do
46+ runParser multiLineComment "{- foo\nbar\nbar\n -}" `shouldEqual` Right unit
47+ it "single line comment #1" do
48+ runParser singleLineComment "-- asd\n" `shouldEqual` Right unit
49+ it "single line comment #1" do
50+ runParser singleLineComment "--\n" `shouldEqual` Right unit
51+ it "Parses every module in .spago/" do
52+ files <- getPathsByGlobs ["./.spago/**/*.purs"]
53+ liftEffect $ Console.log $ "Modules in .spago: " <> show (Array.length files)
54+ for_ files \filePath -> do
55+ fileContents <- readTextFile UTF8 filePath
56+ case parseModuleName fileContents of
57+ Nothing -> do
58+ liftEffect $ throw $
59+ "Module header decoding failed for " <> filePath <>
60+ ", unable to extract module name"
61+ Just _ -> pure unit
test/Test/TypeJson.pursnew file+300
@@ -0,0 +1,300 @@
1+module Test.TypeJson
2+ ( tests )
3+where
4+
5+import Prelude
6+
7+import Docs.Search.TypeDecoder (Constraint(..), FunDep(..), FunDeps(..), QualifiedName(..), Type(..))
8+import Docs.Search.Types (Identifier(..))
9+import Test.Extra (assertRight)
10+import Test.TypeQuery as TypeQuery
11+
12+import Data.Argonaut.Core (Json)
13+import Data.Argonaut.Decode (decodeJson)
14+import Data.Argonaut.Parser (jsonParser)
15+import Data.Either (Either(..))
16+import Data.Maybe (Maybe(..))
17+import Partial.Unsafe (unsafePartial)
18+import Test.Spec (Spec, describe, it)
19+
20+
21+tests :: Spec Unit
22+tests = do
23+ describe "FunDeps decoder" do
24+ it "FunDeps" do
25+ let
26+ funDeps = mkJson """
27+ [
28+ [
29+ [
30+ "lhs",
31+ "rhs"
32+ ],
33+ [
34+ "output"
35+ ]
36+ ]
37+ ]
38+ """
39+ assertRight (decodeJson funDeps)
40+ (FunDeps [ FunDep { lhs: [ "lhs", "rhs" ]
41+ , rhs: [ "output"]
42+ }
43+ ])
44+
45+ describe "Constraint decoder" do
46+ it "Constraint" do
47+ let constraint = mkJson """
48+ {
49+ "constraintAnn": [],
50+ "constraintClass": [
51+ [
52+ "Prim"
53+ ],
54+ "Partial"
55+ ],
56+ "constraintArgs": [],
57+ "constraintData": null
58+ }
59+ """
60+ assertRight (decodeJson constraint)
61+ (Constraint { constraintClass: qualified ["Prim"] "Partial"
62+ , constraintArgs: []
63+ })
64+
65+ describe "Type decoder" do
66+ it "TypeVar" do
67+ let typeVar = mkJson """
68+ {
69+ "annotation": [],
70+ "tag": "TypeVar",
71+ "contents": "m"
72+ }
73+ """
74+
75+ assertRight (decodeJson typeVar)
76+ (TypeVar "m")
77+
78+ it "TypeApp" do
79+ let typeApp1 = mkJson """
80+ {
81+ "annotation": [],
82+ "tag": "TypeApp",
83+ "contents": [
84+ {
85+ "annotation": [],
86+ "tag": "TypeConstructor",
87+ "contents": [
88+ [
89+ "Control",
90+ "Monad",
91+ "ST",
92+ "Internal"
93+ ],
94+ "ST"
95+ ]
96+ },
97+ {
98+ "annotation": [],
99+ "tag": "TypeVar",
100+ "contents": "h"
101+ }
102+ ]
103+ }
104+ """
105+
106+ assertRight (decodeJson typeApp1) $
107+ TypeApp
108+ (TypeConstructor (qualified [ "Control"
109+ , "Monad"
110+ , "ST"
111+ , "Internal"
112+ ]
113+ "ST"
114+ ))
115+ (TypeVar "h")
116+
117+ it "TypeOp" do
118+ let typeOp = mkJson """
119+ {
120+ "annotation": [],
121+ "tag": "TypeOp",
122+ "contents": [
123+ [
124+ "Data",
125+ "NaturalTransformation"
126+ ],
127+ "~>"
128+ ]
129+ }
130+ """
131+ assertRight (decodeJson typeOp) $
132+ TypeOp $ qualified [ "Data", "NaturalTransformation" ] "~>"
133+
134+ it "BinaryNoParens" do
135+ let binaryNoParens = mkJson """
136+ {
137+ "annotation": [],
138+ "tag": "BinaryNoParensType",
139+ "contents": [
140+ {
141+ "annotation": [],
142+ "tag": "TypeOp",
143+ "contents": [
144+ [
145+ "Data",
146+ "NaturalTransformation"
147+ ],
148+ "~>"
149+ ]
150+ },
151+ {
152+ "annotation": [],
153+ "tag": "TypeVar",
154+ "contents": "m"
155+ },
156+ {
157+ "annotation": [],
158+ "tag": "TypeVar",
159+ "contents": "n"
160+ }
161+ ]
162+ }
163+ """
164+
165+ assertRight (decodeJson binaryNoParens) $
166+ BinaryNoParensType
167+ (TypeOp $ qualified ["Data", "NaturalTransformation"] "~>")
168+ (TypeVar "m")
169+ (TypeVar "n")
170+
171+ it "ParensInType" do
172+ let parensInType = mkJson """
173+ {
174+ "annotation": [],
175+ "tag": "ParensInType",
176+ "contents": {
177+ "annotation": [],
178+ "tag": "TypeApp",
179+ "contents": [
180+ {
181+ "annotation": [],
182+ "tag": "TypeConstructor",
183+ "contents": [
184+ [
185+ "Data",
186+ "Maybe"
187+ ],
188+ "Maybe"
189+ ]
190+ },
191+ {
192+ "annotation": [],
193+ "tag": "TypeConstructor",
194+ "contents": [
195+ [
196+ "Prim"
197+ ],
198+ "String"
199+ ]
200+ }
201+ ]
202+ }
203+ }
204+ """
205+
206+ assertRight (decodeJson parensInType) $
207+ ParensInType $
208+ TypeApp
209+ (TypeConstructor (qualified [ "Data", "Maybe" ] "Maybe"))
210+ (TypeConstructor (qualified [ "Prim" ] "String"))
211+ it "RCons" do
212+
213+ let rcons = mkJson """
214+ {
215+ "annotation": [],
216+ "tag": "RCons",
217+ "contents": [
218+ "tail",
219+ {
220+ "annotation": [],
221+ "tag": "TypeApp",
222+ "contents": [
223+ {
224+ "annotation": [],
225+ "tag": "TypeConstructor",
226+ "contents": [
227+ [
228+ "Data",
229+ "Symbol"
230+ ],
231+ "SProxy"
232+ ]
233+ },
234+ {
235+ "annotation": [],
236+ "tag": "TypeVar",
237+ "contents": "t"
238+ }
239+ ]
240+ },
241+ {
242+ "annotation": [],
243+ "tag": "REmpty"
244+ }
245+ ]
246+ }
247+ """
248+
249+ assertRight (decodeJson rcons) $
250+ RCons
251+ (Identifier "tail")
252+ (TypeApp (TypeConstructor $ qualified [ "Data", "Symbol" ] "SProxy")
253+ (TypeVar "t"))
254+ REmpty
255+
256+ it "ForAll #1" do
257+ let forallJson = mkJson """
258+ {"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]}
259+ """
260+ assertRight (decodeJson forallJson) $
261+ ForAll "a" Nothing (TypeApp (TypeApp (TypeConstructor $ qualified ["Prim"] "Function")
262+ (TypeConstructor $ qualified ["Prim"] "String"))
263+ (TypeVar "a"))
264+
265+ it "KindApp" do
266+ let kindAppJson = mkJson """
267+ {"annotation":[],"tag":"KindApp","contents":[{"annotation":[],"tag":"REmpty"},{"annotation":[],"tag":"TypeConstructor","contents":[["Prim"],"Type"]}]}
268+ """
269+ assertRight (decodeJson kindAppJson) $
270+ KindApp REmpty (TypeConstructor (qualified ["Prim"] "Type"))
271+ it "KindedType" do
272+ let kindedTypeJson = mkJson """
273+ {"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"]}]}]}
274+ """
275+ assertRight (decodeJson kindedTypeJson) $
276+ Kinded
277+ (TypeApp
278+ (TypeConstructor (qualified ["Data","Const"] "Const"))
279+ (TypeConstructor (qualified ["Data","Void"] "Void")))
280+ (TypeApp (TypeApp
281+ (TypeConstructor (qualified ["Prim"] "Function"))
282+ (TypeConstructor (qualified ["Prim"] "Type" )))
283+ (TypeConstructor (qualified ["Prim"] "Type")))
284+ describe "jsons" do
285+
286+ it "jsons #1" do
287+ let json = mkJson """
288+{"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]}
289+ """
290+
291+ 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"))))))))
292+
293+
294+qualified :: Array String -> String -> QualifiedName
295+qualified = TypeQuery.qname
296+
297+mkJson :: String -> Json
298+mkJson str =
299+ unsafePartial $ case jsonParser str of
300+ Right r -> r
test/Test/TypeQuery.purs+384−230
@@ -6,7 +6,7 @@ import Docs.Search.TypeShape (ShapeChunk(..), shapeOfType, shapeOfTypeQuery)
66import Docs.Search.Types (Identifier(..))
77
88import Prelude
9−
9+import Prim hiding (Constraint, Type)
1010import Data.Foldable (class Foldable)
1111import Data.List (List(..), (:))
1212import Data.List as List
@@ -15,384 +15,535 @@ import Data.List.NonEmpty as NonEmptyList
1515import Data.Set as Set
1616import Data.Tuple (Tuple(..))
1717import Test.Extra (assertRight)
18−import Test.Unit (TestSuite, suite, test)
19−import Test.Unit.Assert as Assert
18+import Test.Spec (Spec, describe, it)
19+import Test.Spec.Assertions (shouldEqual, shouldSatisfy)
2020import Data.Maybe (Maybe(..))
2121
22−
23−tests :: TestSuite
22+tests :: Spec Unit
2423tests = do
25− suite "TypeQuery parser" do
24+ describe "TypeQuery parser" do
2625
27− test "test #0" do
26+ it "test #0" do
2827 let input = "a"
2928 assertRight (parseTypeQuery input) (qVar "a")
3029
31− test "test #1" do
30+ it "test #1" do
3231 let input = "ab"
3332 assertRight (parseTypeQuery input) (qVar "ab")
3433
35− test "test #2" do
34+ it "test #2" do
3635 let input = "a b"
3736 assertRight (parseTypeQuery input) (QApp (qVar "a") (qVar "b"))
3837
39− test "test #3" do
38+ it "test #3" do
4039 let input = "a b c"
4140 assertRight (parseTypeQuery input) (QApp (QApp (qVar "a") (qVar "b")) (qVar "c"))
4241
43− test "test #4" do
42+ it "test #4" do
4443 let input = "a -> b"
4544 assertRight (parseTypeQuery input) (QFun (qVar "a") (qVar "b"))
4645
47− test "test #5" do
46+ it "test #5" do
4847 let input = "a -> b c"
4948 assertRight (parseTypeQuery input) (QFun (qVar "a") (QApp (qVar "b") (qVar "c")))
5049
51− test "test #6" do
50+ it "test #6" do
5251 let input = "a b -> c"
5352 assertRight (parseTypeQuery input) (QFun (QApp (qVar "a") (qVar "b")) (qVar "c"))
5453
55− test "test #7" do
54+ it "test #7" do
5655 let input = "a b"
5756 assertRight (parseTypeQuery input) (QApp (qVar "a") (qVar "b"))
5857
59− test "test #8" do
58+ it "test #8" do
6059 let input = "a (b c)"
6160 assertRight (parseTypeQuery input) (QApp (qVar "a") (QApp (qVar "b") (qVar "c")))
6261
63− test "test #9" do
62+ it "test #9" do
6463 let input = "(a b) (c d)"
6564 assertRight (parseTypeQuery input)
66− (QApp (QApp (qVar "a") (qVar "b"))
67− (QApp (qVar "c") (qVar "d")))
65+ ( QApp (QApp (qVar "a") (qVar "b"))
66+ (QApp (qVar "c") (qVar "d"))
67+ )
6868
69− test "test #10" do
69+ it "test #10" do
7070 let input = "a ( b c )"
7171 assertRight (parseTypeQuery input) (QApp (qVar "a") (QApp (qVar "b") (qVar "c")))
7272
73− test "test #11" do
73+ it "test #11" do
7474 let input = "aaa"
7575 assertRight (parseTypeQuery input) (qVar "aaa")
7676
77− test "test #12" do
77+ it "test #12" do
7878 let input = "aaa ( bbb ccc )"
7979 assertRight (parseTypeQuery input) (QApp (qVar "aaa") (QApp (qVar "bbb") (qVar "ccc")))
8080
81− test "test #13" do
81+ it "test #13" do
8282 let input = "(a -> b) -> (c -> d)"
83− assertRight (parseTypeQuery input) (QFun (QFun (qVar "a") (qVar "b"))
84− (QFun (qVar "c") (qVar "d")))
83+ assertRight (parseTypeQuery input)
84+ ( QFun (QFun (qVar "a") (qVar "b"))
85+ (QFun (qVar "c") (qVar "d"))
86+ )
8587
86− test "test #14" do
88+ it "test #14" do
8789 let input = "a -> b -> c -> d"
88− assertRight (parseTypeQuery input) (QFun (qVar "a")
89− (QFun (qVar "b")
90− (QFun (qVar "c") (qVar "d"))))
90+ assertRight (parseTypeQuery input)
91+ ( QFun (qVar "a")
92+ ( QFun (qVar "b")
93+ (QFun (qVar "c") (qVar "d"))
94+ )
95+ )
9196
92− test "test #15" do
97+ it "test #15" do
9398 let input = "a -> b -> c"
94− assertRight (parseTypeQuery input) (QFun (qVar "a")
95− (QFun (qVar "b")
96− (qVar "c")))
99+ assertRight (parseTypeQuery input)
100+ ( QFun (qVar "a")
101+ ( QFun (qVar "b")
102+ (qVar "c")
103+ )
104+ )
97105
98− test "test #16" do
106+ it "test #16" do
99107 let input = "forall a b c. c"
100− assertRight (parseTypeQuery input) (QForAll (nl "a" ["b", "c"]) (qVar "c"))
108+ assertRight (parseTypeQuery input) (QForAll (nl "a" [ "b", "c" ]) (qVar "c"))
101109
102− test "test #17" do
110+ it "test #17" do
103111 let input = "forall a. Maybe a"
104112 assertRight (parseTypeQuery input) (QForAll (nl "a" $ []) (QApp (qConst "Maybe") (qVar "a")))
105113
106− test "test #18" do
114+ it "test #18" do
107115 let input = "forall m a. Monad m => a -> m a"
108116 assertRight (parseTypeQuery input)
109− (QForAll (nl "m" ["a"])
110− (qConstraint "Monad" (l [qVar "m"])
111− (QFun (qVar "a")
112− (QApp (qVar "m") (qVar "a")))))
113−
114− test "test #19" do
117+ ( QForAll (nl "m" [ "a" ])
118+ ( qConstraint "Monad" (l [ qVar "m" ])
119+ ( QFun (qVar "a")
120+ (QApp (qVar "m") (qVar "a"))
121+ )
122+ )
123+ )
124+
125+ it "test #19" do
115126 let input = "{ a :: Int }"
116127 assertRight (parseTypeQuery input)
117128 (QApp (qConst "Record") (QRow (pure (Tuple (Identifier "a") (qConst "Int")))))
118129
119− test "test #20" do
130+ it "test #20" do
120131 let input = "{a::Int}"
121132 assertRight (parseTypeQuery input)
122133 (QApp (qConst "Record") (QRow (pure (Tuple (Identifier "a") (qConst "Int")))))
123134
124− test "test #21" do
135+ it "test #21" do
125136 let input = "Int"
126137 assertRight (parseTypeQuery input) (qConst "Int")
127138
128− test "test #22" do
139+ it "test #22" do
129140 let input = "a->b"
130141 assertRight (parseTypeQuery input) (QFun (qVar "a") (qVar "b"))
131142
132− test "test #23" do
143+ it "test #23" do
133144 let input = "forall m a. MonadRec m => Process m a -> m a"
134− assertRight (parseTypeQuery input) (QForAll (nl "m" ("a" : Nil))
135− (qConstraint "MonadRec" (l [qVar "m"])
136− (QFun (QApp (QApp (qConst "Process")
137− (qVar "m")) (qVar "a"))
138− (QApp (qVar "m") (qVar "a")))))
139−
140− test "test #24" do
145+ assertRight (parseTypeQuery input)
146+ ( QForAll (nl "m" ("a" : Nil))
147+ ( qConstraint "MonadRec" (l [ qVar "m" ])
148+ ( QFun
149+ ( QApp
150+ ( QApp (qConst "Process")
151+ (qVar "m")
152+ )
153+ (qVar "a")
154+ )
155+ (QApp (qVar "m") (qVar "a"))
156+ )
157+ )
158+ )
159+
160+ it "test #24" do
141161 let input = "forall t f a. Foldable1 t => Apply f => f"
142− assertRight (parseTypeQuery input) (QForAll (nl "t" ["f", "a"])
143− (qConstraint "Foldable1" (l [qVar "t"])
144− (qConstraint "Apply" (l [qVar "f"]) (qVar "f"))))
162+ assertRight (parseTypeQuery input)
163+ ( QForAll (nl "t" [ "f", "a" ])
164+ ( qConstraint "Foldable1" (l [ qVar "t" ])
165+ (qConstraint "Apply" (l [ qVar "f" ]) (qVar "f"))
166+ )
167+ )
145168
146− test "test #25" do
169+ it "test #25" do
147170 let input = "forall m a.MonadRec m=>Process m a->m a"
148− assertRight (parseTypeQuery input) ((QForAll (nl "m" ("a" : Nil))
149− (qConstraint "MonadRec" (l [qVar "m"])
150− (QFun (QApp (QApp (qConst "Process")
151− (qVar "m")) (qVar "a"))
152− (QApp (qVar "m") (qVar "a"))))))
153−
154− test "test #26" do
171+ assertRight (parseTypeQuery input)
172+ ( ( QForAll (nl "m" ("a" : Nil))
173+ ( qConstraint "MonadRec" (l [ qVar "m" ])
174+ ( QFun
175+ ( QApp
176+ ( QApp (qConst "Process")
177+ (qVar "m")
178+ )
179+ (qVar "a")
180+ )
181+ (QApp (qVar "m") (qVar "a"))
182+ )
183+ )
184+ )
185+ )
186+
187+ it "test #26" do
155188 let input = "m a -> (a -> m b) -> m b"
156189 assertRight (parseTypeQuery input) (QFun (QApp (qVar "m") (qVar "a")) (QFun (QFun (qVar "a") (QApp (qVar "m") (qVar "b"))) (QApp (qVar "m") (qVar "b"))))
157190
158− test "test #27" do
191+ it "test #27" do
159192 let input = "forall f a. Alternative f => Lazy (f (List a)) => f a -> f (List a)"
160− assertRight (parseTypeQuery input) ((QForAll (nl "f" ["a"]))
161− (qConstraint "Alternative" (l [qVar "f"])
162− (qConstraint "Lazy" (l [QApp (qVar "f")
163− (QApp (qConst "List") (qVar "a"))])
164− (QFun (QApp (qVar "f") (qVar "a"))
165− (QApp (qVar "f")
166− (QApp (qConst "List") (qVar "a")))))))
167−
168− test "test #28" do
193+ assertRight (parseTypeQuery input)
194+ ( (QForAll (nl "f" [ "a" ]))
195+ ( qConstraint "Alternative" (l [ qVar "f" ])
196+ ( qConstraint "Lazy"
197+ ( l
198+ [ QApp (qVar "f")
199+ (QApp (qConst "List") (qVar "a"))
200+ ]
201+ )
202+ ( QFun (QApp (qVar "f") (qVar "a"))
203+ ( QApp (qVar "f")
204+ (QApp (qConst "List") (qVar "a"))
205+ )
206+ )
207+ )
208+ )
209+ )
210+
211+ it "test #28" do
169212 let input = "forall f a. Alternative f => Lazy(f (List a))=>f a -> f (List a)"
170− assertRight (parseTypeQuery input) ((QForAll (nl "f" ["a"]))
171− (qConstraint "Alternative" (l [qVar "f"])
172− (qConstraint "Lazy" (l [QApp (qVar "f")
173− (QApp (qConst "List") (qVar "a"))])
174− (QFun (QApp (qVar "f") (qVar "a"))
175− (QApp (qVar "f")
176− (QApp (qConst "List") (qVar "a")))))))
177−
178− test "test #29" do
213+ assertRight (parseTypeQuery input)
214+ ( (QForAll (nl "f" [ "a" ]))
215+ ( qConstraint "Alternative" (l [ qVar "f" ])
216+ ( qConstraint "Lazy"
217+ ( l
218+ [ QApp (qVar "f")
219+ (QApp (qConst "List") (qVar "a"))
220+ ]
221+ )
222+ ( QFun (QApp (qVar "f") (qVar "a"))
223+ ( QApp (qVar "f")
224+ (QApp (qConst "List") (qVar "a"))
225+ )
226+ )
227+ )
228+ )
229+ )
230+
231+ it "test #29" do
179232 let input = "{a::Int,b::Int}"
180233 assertRight (parseTypeQuery input)
181− (QApp (qConst "Record") (QRow (List.fromFoldable
182− [ Tuple (Identifier "a") (qConst "Int")
183− , Tuple (Identifier "b") (qConst "Int")])))
184−
185− test "test #30" do
234+ ( QApp (qConst "Record")
235+ ( QRow
236+ ( List.fromFoldable
237+ [ Tuple (Identifier "a") (qConst "Int")
238+ , Tuple (Identifier "b") (qConst "Int")
239+ ]
240+ )
241+ )
242+ )
243+
244+ it "test #30" do
186245 let input = "{record''' :: Int}"
187246 assertRight (parseTypeQuery input)
188− (QApp (qConst "Record") (QRow (List.fromFoldable [ Tuple (Identifier "record'''") (qConst "Int")])))
247+ (QApp (qConst "Record") (QRow (List.fromFoldable [ Tuple (Identifier "record'''") (qConst "Int") ])))
189248
190− test "test #31" do
249+ it "test #31" do
191250 let input = "(row''' :: Int)"
192251 assertRight (parseTypeQuery input)
193− (QRow (List.fromFoldable [ Tuple (Identifier "row'''") (qConst "Int")]))
252+ (QRow (List.fromFoldable [ Tuple (Identifier "row'''") (qConst "Int") ]))
194253
195− test "test #32" do
254+ it "test #32" do
196255 let input = "(row1 :: Int, row2 :: (),row3::(row4::{}))"
197256 assertRight (parseTypeQuery input)
198− (QRow (l [ Tuple (Identifier "row1") (qConst "Int")
199− , Tuple (Identifier "row2") (QRow Nil)
200− , Tuple (Identifier "row3") (QRow (l [ Tuple (Identifier "row4") (QApp (qConst "Record") (QRow Nil)) ])) ]))
201−
202− test "test #33" do
257+ ( QRow
258+ ( l
259+ [ Tuple (Identifier "row1") (qConst "Int")
260+ , Tuple (Identifier "row2") (QRow Nil)
261+ , Tuple (Identifier "row3") (QRow (l [ Tuple (Identifier "row4") (QApp (qConst "Record") (QRow Nil)) ]))
262+ ]
263+ )
264+ )
265+
266+ it "test #33" do
203267 let input = "Foldable1 t => Apply f => t (f a) -> f Unit"
204268 assertRight (parseTypeQuery input)
205269 (qConstraint "Foldable1" ((qVar "t") : Nil) (qConstraint "Apply" ((qVar "f") : Nil) (QFun (QApp (qVar "t") (QApp (qVar "f") (qVar "a"))) (QApp (qVar "f") (qConst "Unit")))))
206270
207− test "test #34" do
271+ it "test #34" do
208272 let input = "Foldable1 t => Apply f => t (f a) -> f a"
209273 assertRight (parseTypeQuery input)
210274 (qConstraint "Foldable1" ((qVar "t") : Nil) (qConstraint "Apply" ((qVar "f") : Nil) (QFun (QApp (qVar "t") (QApp (qVar "f") (qVar "a"))) (QApp (qVar "f") (qVar "a")))))
211275
212− test "test #35" do
276+ it "test #35" do
213277 let input = "Generic a rep => GenericEq rep => a -> a -> Boolean"
214278 assertRight (parseTypeQuery input)
215− (qConstraint "Generic" ((qVar "a") : (qVar "rep") : Nil)
216− (qConstraint "GenericEq" ((qVar "rep") : Nil)
217− (QFun (qVar "a") (QFun (qVar "a") (qConst "Boolean")))))
279+ ( qConstraint "Generic" ((qVar "a") : (qVar "rep") : Nil)
280+ ( qConstraint "GenericEq" ((qVar "rep") : Nil)
281+ (QFun (qVar "a") (QFun (qVar "a") (qConst "Boolean")))
282+ )
283+ )
218284
219− suite "polish notation" do
285+ describe "polish notation" do
220286
221− test "test #1" do
287+ it "test #1" do
222288 let input = "(a -> b) -> (b -> ((a -> b) -> c))"
223289 assertRight (shapeOfTypeQuery <$> parseTypeQuery input)
224− (l [ PForAll 3, PFun, PFun, PVar, PVar, PFun, PVar, PFun, PFun
225− , PVar, PVar, PVar ])
226−
227− test "test #2" do
290+ ( l
291+ [ PForAll 3
292+ , PFun
293+ , PFun
294+ , PVar
295+ , PVar
296+ , PFun
297+ , PVar
298+ , PFun
299+ , PFun
300+ , PVar
301+ , PVar
302+ , PVar
303+ ]
304+ )
305+
306+ it "test #2" do
228307 let input = "forall a. (a -> b) -> (b -> ((a -> b) -> c))"
229308 assertRight (shapeOfTypeQuery <$> parseTypeQuery input)
230− (l [ PForAll 3, PFun, PFun, PVar, PVar, PFun, PVar, PFun, PFun
231− , PVar, PVar, PVar ])
232−
233− test "test #3" do
309+ ( l
310+ [ PForAll 3
311+ , PFun
312+ , PFun
313+ , PVar
314+ , PVar
315+ , PFun
316+ , PVar
317+ , PFun
318+ , PFun
319+ , PVar
320+ , PVar
321+ , PVar
322+ ]
323+ )
324+
325+ it "test #3" do
234326 let input = "forall a. (a -> b) -> (b -> ((a -> b) -> c))"
235327 assertRight (shapeOfTypeQuery <$> parseTypeQuery input)
236− (l [ PForAll 3, PFun, PFun, PVar, PVar, PFun, PVar, PFun, PFun
237− , PVar, PVar, PVar ])
238−
239− test "test #4" do
328+ ( l
329+ [ PForAll 3
330+ , PFun
331+ , PFun
332+ , PVar
333+ , PVar
334+ , PFun
335+ , PVar
336+ , PFun
337+ , PFun
338+ , PVar
339+ , PVar
340+ , PVar
341+ ]
342+ )
343+
344+ it "test #4" do
240345 let input = "forall a. (forall h. ST h (STArray h a)) -> Array a"
241346 assertRight (shapeOfTypeQuery <$> parseTypeQuery input)
242− (l [ PForAll 1, PFun, PForAll 1, PApp, PApp, PVar, PVar, PApp, PApp, PVar, PVar, PVar, PApp, PVar, PVar ])
243−
244− suite "type shapes" do
245− test "test #1" do
246− let query = "Generic a rep => GenericEq rep => a -> a -> Boolean"
247− c1 = constr (qname [""] "Generic") [TypeVar "a", TypeVar "rep"]
248− c2 = constr (qname [""] "GenericEq") [TypeVar "rep"]
249−
250− fun t1 t2 =
251− TypeApp (TypeApp (TypeConstructor (QualifiedName { moduleNameParts: ["Prim"]
252− , name: Identifier "Function" })) t1) t2
253− type_ =
254− ForAll "a" Nothing $
255− ForAll "rep" Nothing $
256− ConstrainedType c1
257− (ConstrainedType c2
258− (fun (TypeVar "a") (fun (TypeVar "b")
259− (TypeConstructor $ qname ["Prim", "Boolean"] "Boolean"))))
260− shape = shapeOfTypeQuery <$> parseTypeQuery query
261− Assert.equal (pure $ shapeOfType type_) shape
262−
263− suite "free variable counting" do
264−
265− test "test #1" do
347+ (l [ PForAll 1, PFun, PForAll 1, PApp, PApp, PVar, PVar, PApp, PApp, PVar, PVar, PVar, PApp, PVar, PVar ])
348+
349+ describe "type shapes" do
350+ it "test #1" do
351+ let
352+ query = "Generic a rep => GenericEq rep => a -> a -> Boolean"
353+ c1 = constr (qname [ "" ] "Generic") [ TypeVar "a", TypeVar "rep" ]
354+ c2 = constr (qname [ "" ] "GenericEq") [ TypeVar "rep" ]
355+
356+ fun t1 t2 =
357+ TypeApp
358+ ( TypeApp
359+ ( TypeConstructor
360+ ( QualifiedName
361+ { moduleNameParts: [ "Prim" ]
362+ , name: Identifier "Function"
363+ }
364+ )
365+ )
366+ t1
367+ )
368+ t2
369+ type_ =
370+ ForAll "a" Nothing
371+ $ ForAll "rep" Nothing
372+ $
373+ ConstrainedType c1
374+ ( ConstrainedType c2
375+ ( fun (TypeVar "a")
376+ ( fun (TypeVar "b")
377+ (TypeConstructor $ qname [ "Prim", "Boolean" ] "Boolean")
378+ )
379+ )
380+ )
381+ shape = shapeOfTypeQuery <$> parseTypeQuery query
382+ pure (shapeOfType type_) `shouldEqual` shape
383+
384+ describe "free variable counting" do
385+
386+ it "test #1" do
266387 let input = "forall a. (a -> b) -> (b -> ((a -> b) -> c))"
267388 assertRight (countFreeVars <$> parseTypeQuery input) 2
268389
269− test "test #2" do
390+ it "test #2" do
270391 -- `b` is not bound on the left, `a` is not bound on the right
271392 let input = "(forall a. (a -> b)) -> forall b. (b -> a)"
272393 assertRight (countFreeVars <$> parseTypeQuery input) 2
273394
274− test "test #3" do
395+ it "test #3" do
275396 let input = "a -> forall a. a"
276397 assertRight (countFreeVars <$> parseTypeQuery input) 1
277398
278− test "test #4" do
399+ it "test #4" do
279400 let input = "(forall a. a) -> a"
280401 assertRight (countFreeVars <$> parseTypeQuery input) 1
281402
282− test "test #5" do
403+ it "test #5" do
283404 let input = "forall a. a -> a"
284405 assertRight (countFreeVars <$> parseTypeQuery input) 0
285406
286− test "test #6" do
407+ it "test #6" do
287408 let input = "a -> b -> c"
288409 assertRight (countFreeVars <$> parseTypeQuery input) 3
289410
290− test "test #7" do
411+ it "test #7" do
291412 let input = "forall m a. Monad m => a -> m a"
292413 assertRight (countFreeVars <$> parseTypeQuery input) 0
293414
294− test "test #8" do
415+ it "test #8" do
295416 let input = "Monad m => a -> m a"
296417 assertRight (countFreeVars <$> parseTypeQuery input) 2
297418
298− test "test #9" do
419+ it "test #9" do
299420 let input = "Monad m => a -> a"
300421 assertRight (countFreeVars <$> parseTypeQuery input) 2
301422
302− test "test #10" do
423+ it "test #10" do
303424 let input = "forall a. (forall a. a) a"
304425 assertRight (countFreeVars <$> parseTypeQuery input) 0
305426
306− test "test #11" do
427+ it "test #11" do
307428 let input = "forall a. (forall b. a) a"
308429 assertRight (countFreeVars <$> parseTypeQuery input) 0
309430
310− test "test #12" do
431+ it "test #12" do
311432 let input = "forall a. (forall b. a) a b"
312433 assertRight (countFreeVars <$> parseTypeQuery input) 1
313434
314− suite "typeVarPenalty" do
315−
316− test "#0" do
317− Assert.equal 0 (typeVarPenalty mempty)
318−
319− test "#1" do
320− Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "b"
321− , substitute "b" "a"
322− ])
323−
324− test "#2" do
325− Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "b"
326− , substitute "a" "b"
327− , substitute "a" "b"
328− ])
329−
330− test "#3" do
331− Assert.equal 1 (typeVarPenalty $ l [ substitute "a" "b"
332− , substitute "a" "c"
333− ])
334−
335− test "#4" do
336− Assert.equal 1 (typeVarPenalty $ l [ substitute "a" "b"
337− , substitute "b" "a"
338− , substitute "b" "c"
339− ])
340−
341− test "#5" do
342− Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "b"
343− , substitute "b" "c"
344− , substitute "c" "a"
345− ])
346−
347− test "#6" do
348− Assert.equal 2 (typeVarPenalty $ l [ substitute "a" "b"
349− , substitute "a" "c"
350− , substitute "a" "a"
351− ])
352−
353− test "#7" do
354− Assert.equal 2 (typeVarPenalty $ l [ substitute "a" "a"
355− , substitute "b" "a"
356− , substitute "c" "a"
357− ])
358−
359− test "#8" do
360− Assert.equal 4 (typeVarPenalty $ l [ substitute "a" "a"
361− , substitute "b" "a"
362− , substitute "c" "a"
363− , substitute "a" "b"
364− , substitute "a" "c"
365− , substitute "a" "a"
366− ])
367−
368− test "#9" do
369− Assert.equal 0 (typeVarPenalty $ l [ substitute "a" "e"
370− , substitute "b" "d"
371− , substitute "c" "f"
372− ])
373−
374− suite "unification" do
375− test "instantiation #0" do
376− let mVarQuery = qVar "m"
377− unitConstQuery = qConst "Unit"
378−
379− Assert.assert "instantiation #0" $
380− (penalty unitConstQuery unitType < penalty mVarQuery unitType)
381−
382− test "generalization #0" do
383− let query = qVar "m"
384− t1 = TypeVar "m"
385−
386− Assert.assert "qeneralization #0" $
387− (penalty query unitType > penalty query t1)
388−
435+ describe "typeVarPenalty" do
436+
437+ it "#0" do
438+ 0 `shouldEqual` (typeVarPenalty mempty)
439+
440+ it "#1" do
441+ 0 `shouldEqual`
442+ ( typeVarPenalty $ l
443+ [ substitute "a" "b"
444+ , substitute "b" "a"
445+ ]
446+ )
447+
448+ it "#2" do
449+ 0 `shouldEqual`
450+ ( typeVarPenalty $ l
451+ [ substitute "a" "b"
452+ , substitute "a" "b"
453+ , substitute "a" "b"
454+ ]
455+ )
456+
457+ it "#3" do
458+ 1 `shouldEqual`
459+ ( typeVarPenalty $ l
460+ [ substitute "a" "b"
461+ , substitute "a" "c"
462+ ]
463+ )
464+
465+ it "#4" do
466+ 1 `shouldEqual`
467+ ( typeVarPenalty $ l
468+ [ substitute "a" "b"
469+ , substitute "b" "a"
470+ , substitute "b" "c"
471+ ]
472+ )
473+
474+ it "#5" do
475+ 0 `shouldEqual`
476+ ( typeVarPenalty $ l
477+ [ substitute "a" "b"
478+ , substitute "b" "c"
479+ , substitute "c" "a"
480+ ]
481+ )
482+
483+ it "#6" do
484+ 2 `shouldEqual`
485+ ( typeVarPenalty $ l
486+ [ substitute "a" "b"
487+ , substitute "a" "c"
488+ , substitute "a" "a"
489+ ]
490+ )
491+
492+ it "#7" do
493+ 2 `shouldEqual`
494+ ( typeVarPenalty $ l
495+ [ substitute "a" "a"
496+ , substitute "b" "a"
497+ , substitute "c" "a"
498+ ]
499+ )
500+
501+ it "#8" do
502+ 4 `shouldEqual`
503+ ( typeVarPenalty $ l
504+ [ substitute "a" "a"
505+ , substitute "b" "a"
506+ , substitute "c" "a"
507+ , substitute "a" "b"
508+ , substitute "a" "c"
509+ , substitute "a" "a"
510+ ]
511+ )
512+
513+ it "#9" do
514+ 0 `shouldEqual`
515+ ( typeVarPenalty $ l
516+ [ substitute "a" "e"
517+ , substitute "b" "d"
518+ , substitute "c" "f"
519+ ]
520+ )
521+
522+ describe "unification" do
523+ it "instantiation #0" do
524+ let
525+ mVarQuery = qVar "m"
526+ unitConstQuery = qConst "Unit"
527+
528+ shouldSatisfy
529+ (penalty unitConstQuery unitType)
530+ (_ < penalty mVarQuery unitType)
531+
532+ it "generalization #0" do
533+ let
534+ query = qVar "m"
535+ t1 = TypeVar "m"
536+
537+ shouldSatisfy
538+ (penalty query unitType)
539+ (_ > penalty query t1)
389540
390541l :: forall f. Foldable f => (forall a. f a -> List a)
391542l = List.fromFoldable
392543
393544nl
394545 :: forall t
395− . Foldable t
546+ . Foldable t
396547 => Functor t
397548 => String
398549 -> t String
@@ -400,9 +551,12 @@ nl
400551nl x rst = NonEmptyList.cons' (Identifier x) $ List.fromFoldable (rst <#> Identifier)
401552
402553unitType :: Type
403−unitType = TypeConstructor (QualifiedName { moduleNameParts: []
404− , name: Identifier "Unit"
405− })
554+unitType = TypeConstructor
555+ ( QualifiedName
556+ { moduleNameParts: []
557+ , name: Identifier "Unit"
558+ }
559+ )
406560
407561countFreeVars :: TypeQuery -> Int
408562countFreeVars = getFreeVariables >>> Set.size
test/Test/UI.pursnew file+68
@@ -0,0 +1,68 @@
1+module Test.UI where
2+
3+-- import Prelude
4+
5+-- import Data.Array as Array
6+-- import Data.Foldable (for_)
7+-- import Data.Newtype (unwrap)
8+-- import Effect (Effect)
9+-- import Effect.Aff (Aff, launchAff_)
10+-- import Effect.Class (liftEffect)
11+-- import Effect.Console as Console
12+-- import Foreign (Foreign)
13+-- import Foreign as Foreign
14+-- import Node.FS.Sync (realpath)
15+-- import Test.Spec.Assertions (shouldSatisfy)
16+-- -- import Toppokki as T
17+-- -- import Playwright as P
18+
19+-- main :: Effect Unit
20+-- main = launchAff_ do
21+-- pure unit
22+-- path <- liftEffect $ realpath "."
23+
24+-- let indexHTML = T.URL $ "file://" <> path <> "/generated-docs/html/index.html"
25+-- prim = T.URL $ "file://" <> path <> "/generated-docs/html/Prim.html"
26+-- docsSearch = T.URL $ "file://" <> path <> "/generated-docs/html/Docs.Search.App.html"
27+
28+-- for_ [ indexHTML, prim, docsSearch ] \url -> do
29+-- withPage url \page -> do
30+-- void $ T.pageWaitForSelector (T.Selector "#group-modules__label") { timeout: 10000 } page
31+-- log $ "has module grouping: " <> unwrap url
32+
33+-- withPage url \page -> do
34+-- T.keyboardPress (T.KeyboardKey "s") {} page
35+-- void $ T.keyboardType "slice" {} page
36+-- T.keyboardPress (T.KeyboardKey "Enter") {} page
37+-- void $ T.pageWaitForSelector (T.Selector ".result__actions__item") { timeout: 10000 } page
38+-- log $ "has working search field: " <> unwrap url
39+
40+-- withPage url \page -> do
41+-- T.keyboardPress (T.KeyboardKey "s") {} page
42+-- void $ T.keyboardType "a -> b" {} page
43+-- T.keyboardPress (T.KeyboardKey "Enter") {} page
44+-- void $ T.pageWaitForSelector (T.Selector ".result__actions__item") { timeout: 10000 } page
45+-- arr <- readStringArray <$> T.unsafeEvaluateStringFunction getResultTitlesCode page
46+-- arr `shouldSatisfy` (Array.elem "unsafeCoerce")
47+-- log $ "is able to find unsafeCoerce by type: " <> unwrap url
48+
49+-- withPage (T.URL $ unwrap url <> "#search:unsafeCoerce") \page -> do
50+-- void $ T.pageWaitForSelector (T.Selector ".result__actions__item") { timeout: 10000 } page
51+-- arr <- readStringArray <$> T.unsafeEvaluateStringFunction getResultTitlesCode page
52+-- arr `shouldSatisfy` (Array.elem "unsafeCoerce")
53+-- log $ "can read URI hash: " <> unwrap url
54+
55+-- where
56+-- log = liftEffect <<< Console.log
57+-- getResultTitlesCode = "[].map.call(document.querySelectorAll('.result__title'), el => el.textContent)"
58+-- readStringArray :: Foreign -> Array String
59+-- readStringArray = Foreign.unsafeFromForeign
60+
61+
62+-- withPage :: forall a. T.URL -> (T.Page -> Aff a) -> Aff Unit
63+-- withPage url f = do
64+-- browser <- T.launch {}
65+-- page <- T.newPage browser
66+-- T.goto url page
67+-- void $ f page
68+-- T.close browser