├── .github └── workflows │ └── publish.yml ├── .gitignore ├── LICENSE ├── README.md ├── bundle.js ├── index.js ├── license.js ├── package.json ├── packages.dhall ├── pnpm-lock.yaml ├── spago.dhall └── src ├── Main.purs └── Psvm ├── Files.js ├── Files.purs ├── Foreign ├── Download.js └── Download.purs ├── Ls.purs ├── Platform.purs ├── Types.purs └── Version.purs /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Package 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout Repository 12 | uses: actions/checkout@v2 13 | 14 | - name: Setup Node 15 | uses: actions/setup-node@v2 16 | with: 17 | node-version: '14.x' 18 | registry-url: 'https://registry.npmjs.org' 19 | 20 | - name: Setup PureScript 21 | uses: purescript-contrib/setup-purescript@main 22 | with: 23 | purescript: "0.14.4" 24 | spago: "0.20.3" 25 | 26 | - name: Install pnpm 27 | uses: pnpm/action-setup@v2.0.1 28 | with: 29 | version: 6.10.3 30 | 31 | - name: Install Dependencies 32 | run: | 33 | pnpm install 34 | pnpm bundle 35 | 36 | - name: Publish Package 37 | run: pnpm publish 38 | env: 39 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | /.pulp-cache/ 4 | /output/ 5 | /dce-output/ 6 | /dist/ 7 | /generated-docs/ 8 | /.psc-package/ 9 | /.psc* 10 | /.purs* 11 | /.psa* 12 | /.spago/ 13 | /psvm.js 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, PureFunctor 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # psvm-ps 2 | PureScript version management in PureScript, expanding upon [psvm-js](https://github.com/ThomasCrevoisier/psvm-js). 3 | 4 | Installs files under `$HOME/.psvm`, and as such, this tool currently only supports Linux given that I don't have access to Windows/MacOS environments. Pull requests to add compatibility for these two operating systems is welcome. 5 | 6 | ```sh 7 | $ psvm 8 | psvm-ps 9 | PureScript version management in PureScript. 10 | 11 | --help,-h Show this help message. 12 | --version,-v Show the installed psvm-ps version. 13 | 14 | clean Clean downloaded artifacts. 15 | install Install a PureScript version. 16 | ls List PureScript versions. 17 | uninstall Uninstall a PureScript version. 18 | use Use a PureScript version. 19 | ``` 20 | 21 | ## Installation 22 | ```sh 23 | $ npm install -g psvm-ps 24 | ``` 25 | -------------------------------------------------------------------------------- /bundle.js: -------------------------------------------------------------------------------- 1 | const esbuild = require("esbuild"); 2 | const path = require("path"); 3 | 4 | esbuild 5 | .build({ 6 | entryPoints: ["index.js", "psvm.js"], 7 | minify: true, 8 | outdir: "dist", 9 | platform: "node", 10 | banner: { 11 | "js": "#!/usr/bin/env node", 12 | }, 13 | }) 14 | .catch((_e) => process.exit(1)); 15 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const psvm = require("./psvm.js"); 2 | const meta = require("../package.json"); 3 | psvm.main(meta.name)(meta.version)(meta.description)(); 4 | -------------------------------------------------------------------------------- /license.js: -------------------------------------------------------------------------------- 1 | const glob = require("glob"); 2 | const fs = require("fs"); 3 | const path = require("path"); 4 | const stream = require("stream"); 5 | const MultiStream = require("multistream"); 6 | 7 | let output = fs.createWriteStream("./dist/LICENSE-purs", { flags: "w+" }); 8 | let licenses = (() => { 9 | let files = glob.sync(".spago/**/LICENSE") 10 | let tail = files.pop(); 11 | 12 | let copyLicense = (newline) => (license) => { 13 | let [_s, name, version, _l] = license.split(path.sep); 14 | return [ 15 | stream.Readable.from(`LICENSE - ${name} - ${version}\n\n`), 16 | fs.createReadStream(license), 17 | stream.Readable.from(newline ? "\n" : ""), 18 | ]; 19 | }; 20 | 21 | return files.flatMap(copyLicense(true)).concat(copyLicense(false)(tail)); 22 | })(); 23 | 24 | new MultiStream(licenses).pipe(output); 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "psvm-ps", 3 | "version": "0.2.3", 4 | "description": "PureScript version management in PureScript.", 5 | "license": "BSD-3-Clause", 6 | "private": false, 7 | "scripts": { 8 | "bundle": "spago bundle-module -t psvm.js && node bundle.js && node license.js" 9 | }, 10 | "bin": { 11 | "psvm": "dist/index.js" 12 | }, 13 | "files": [ 14 | "dist/index.js", 15 | "dist/psvm.js", 16 | "dist/LICENSE-purs" 17 | ], 18 | "devDependencies": { 19 | "esbuild": "^0.12.26", 20 | "glob": "^7.1.7", 21 | "multistream": "^4.1.0" 22 | }, 23 | "dependencies": { 24 | "cli-progress": "^3.9.0", 25 | "decompress": "^4.2.1", 26 | "download": "^8.0.0", 27 | "fs-extra": "^10.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages.dhall: -------------------------------------------------------------------------------- 1 | let upstream = 2 | https://github.com/purescript/package-sets/releases/download/psc-0.14.4-20210905/packages.dhall sha256:140f3630801f2b02d5f3a405d4872e0af317e4ef187016a6b00f97d59d6275c6 3 | 4 | in upstream 5 | with argparse-basic = 6 | { dependencies = 7 | [ "arrays" 8 | , "console" 9 | , "effect" 10 | , "either" 11 | , "foldable-traversable" 12 | , "free" 13 | , "lists" 14 | , "maybe" 15 | , "node-process" 16 | , "record" 17 | , "strings" 18 | , "transformers" 19 | ] 20 | , repo = "https://github.com/natefaubion/purescript-argparse-basic.git" 21 | , version = "v1.0.0" 22 | } 23 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.3 2 | 3 | specifiers: 4 | cli-progress: ^3.9.0 5 | decompress: ^4.2.1 6 | download: ^8.0.0 7 | esbuild: ^0.12.26 8 | fs-extra: ^10.0.0 9 | glob: ^7.1.7 10 | multistream: ^4.1.0 11 | 12 | dependencies: 13 | cli-progress: 3.9.0 14 | decompress: 4.2.1 15 | download: 8.0.0 16 | fs-extra: 10.0.0 17 | 18 | devDependencies: 19 | esbuild: 0.12.26 20 | glob: 7.1.7 21 | multistream: 4.1.0 22 | 23 | packages: 24 | 25 | /@sindresorhus/is/0.7.0: 26 | resolution: {integrity: sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==} 27 | engines: {node: '>=4'} 28 | dev: false 29 | 30 | /ansi-regex/5.0.0: 31 | resolution: {integrity: sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==} 32 | engines: {node: '>=8'} 33 | dev: false 34 | 35 | /archive-type/4.0.0: 36 | resolution: {integrity: sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=} 37 | engines: {node: '>=4'} 38 | dependencies: 39 | file-type: 4.4.0 40 | dev: false 41 | 42 | /balanced-match/1.0.2: 43 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 44 | dev: true 45 | 46 | /base64-js/1.5.1: 47 | resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} 48 | dev: false 49 | 50 | /bl/1.2.3: 51 | resolution: {integrity: sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==} 52 | dependencies: 53 | readable-stream: 2.3.7 54 | safe-buffer: 5.2.1 55 | dev: false 56 | 57 | /brace-expansion/1.1.11: 58 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 59 | dependencies: 60 | balanced-match: 1.0.2 61 | concat-map: 0.0.1 62 | dev: true 63 | 64 | /buffer-alloc-unsafe/1.1.0: 65 | resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} 66 | dev: false 67 | 68 | /buffer-alloc/1.2.0: 69 | resolution: {integrity: sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==} 70 | dependencies: 71 | buffer-alloc-unsafe: 1.1.0 72 | buffer-fill: 1.0.0 73 | dev: false 74 | 75 | /buffer-crc32/0.2.13: 76 | resolution: {integrity: sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=} 77 | dev: false 78 | 79 | /buffer-fill/1.0.0: 80 | resolution: {integrity: sha1-+PeLdniYiO858gXNY39o5wISKyw=} 81 | dev: false 82 | 83 | /buffer/5.7.1: 84 | resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} 85 | dependencies: 86 | base64-js: 1.5.1 87 | ieee754: 1.2.1 88 | dev: false 89 | 90 | /cacheable-request/2.1.4: 91 | resolution: {integrity: sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=} 92 | dependencies: 93 | clone-response: 1.0.2 94 | get-stream: 3.0.0 95 | http-cache-semantics: 3.8.1 96 | keyv: 3.0.0 97 | lowercase-keys: 1.0.0 98 | normalize-url: 2.0.1 99 | responselike: 1.0.2 100 | dev: false 101 | 102 | /cli-progress/3.9.0: 103 | resolution: {integrity: sha512-g7rLWfhAo/7pF+a/STFH/xPyosaL1zgADhI0OM83hl3c7S43iGvJWEAV2QuDOnQ8i6EMBj/u4+NTd0d5L+4JfA==} 104 | engines: {node: '>=4'} 105 | dependencies: 106 | colors: 1.4.0 107 | string-width: 4.2.2 108 | dev: false 109 | 110 | /clone-response/1.0.2: 111 | resolution: {integrity: sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=} 112 | dependencies: 113 | mimic-response: 1.0.1 114 | dev: false 115 | 116 | /colors/1.4.0: 117 | resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} 118 | engines: {node: '>=0.1.90'} 119 | dev: false 120 | 121 | /commander/2.20.3: 122 | resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} 123 | dev: false 124 | 125 | /concat-map/0.0.1: 126 | resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} 127 | dev: true 128 | 129 | /content-disposition/0.5.3: 130 | resolution: {integrity: sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==} 131 | engines: {node: '>= 0.6'} 132 | dependencies: 133 | safe-buffer: 5.1.2 134 | dev: false 135 | 136 | /core-util-is/1.0.3: 137 | resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} 138 | dev: false 139 | 140 | /decode-uri-component/0.2.0: 141 | resolution: {integrity: sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=} 142 | engines: {node: '>=0.10'} 143 | dev: false 144 | 145 | /decompress-response/3.3.0: 146 | resolution: {integrity: sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=} 147 | engines: {node: '>=4'} 148 | dependencies: 149 | mimic-response: 1.0.1 150 | dev: false 151 | 152 | /decompress-tar/4.1.1: 153 | resolution: {integrity: sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==} 154 | engines: {node: '>=4'} 155 | dependencies: 156 | file-type: 5.2.0 157 | is-stream: 1.1.0 158 | tar-stream: 1.6.2 159 | dev: false 160 | 161 | /decompress-tarbz2/4.1.1: 162 | resolution: {integrity: sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==} 163 | engines: {node: '>=4'} 164 | dependencies: 165 | decompress-tar: 4.1.1 166 | file-type: 6.2.0 167 | is-stream: 1.1.0 168 | seek-bzip: 1.0.6 169 | unbzip2-stream: 1.4.3 170 | dev: false 171 | 172 | /decompress-targz/4.1.1: 173 | resolution: {integrity: sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==} 174 | engines: {node: '>=4'} 175 | dependencies: 176 | decompress-tar: 4.1.1 177 | file-type: 5.2.0 178 | is-stream: 1.1.0 179 | dev: false 180 | 181 | /decompress-unzip/4.0.1: 182 | resolution: {integrity: sha1-3qrM39FK6vhVePczroIQ+bSEj2k=} 183 | engines: {node: '>=4'} 184 | dependencies: 185 | file-type: 3.9.0 186 | get-stream: 2.3.1 187 | pify: 2.3.0 188 | yauzl: 2.10.0 189 | dev: false 190 | 191 | /decompress/4.2.1: 192 | resolution: {integrity: sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==} 193 | engines: {node: '>=4'} 194 | dependencies: 195 | decompress-tar: 4.1.1 196 | decompress-tarbz2: 4.1.1 197 | decompress-targz: 4.1.1 198 | decompress-unzip: 4.0.1 199 | graceful-fs: 4.2.8 200 | make-dir: 1.3.0 201 | pify: 2.3.0 202 | strip-dirs: 2.1.0 203 | dev: false 204 | 205 | /download/8.0.0: 206 | resolution: {integrity: sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==} 207 | engines: {node: '>=10'} 208 | dependencies: 209 | archive-type: 4.0.0 210 | content-disposition: 0.5.3 211 | decompress: 4.2.1 212 | ext-name: 5.0.0 213 | file-type: 11.1.0 214 | filenamify: 3.0.0 215 | get-stream: 4.1.0 216 | got: 8.3.2 217 | make-dir: 2.1.0 218 | p-event: 2.3.1 219 | pify: 4.0.1 220 | dev: false 221 | 222 | /duplexer3/0.1.4: 223 | resolution: {integrity: sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=} 224 | dev: false 225 | 226 | /emoji-regex/8.0.0: 227 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 228 | dev: false 229 | 230 | /end-of-stream/1.4.4: 231 | resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} 232 | dependencies: 233 | once: 1.4.0 234 | dev: false 235 | 236 | /esbuild/0.12.26: 237 | resolution: {integrity: sha512-YmTkhPKjvTJ+G5e96NyhGf69bP+hzO0DscqaVJTi5GM34uaD4Ecj7omu5lJO+NrxCUBRhy2chONLK1h/2LwoXA==} 238 | hasBin: true 239 | requiresBuild: true 240 | dev: true 241 | 242 | /escape-string-regexp/1.0.5: 243 | resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} 244 | engines: {node: '>=0.8.0'} 245 | dev: false 246 | 247 | /ext-list/2.2.2: 248 | resolution: {integrity: sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==} 249 | engines: {node: '>=0.10.0'} 250 | dependencies: 251 | mime-db: 1.49.0 252 | dev: false 253 | 254 | /ext-name/5.0.0: 255 | resolution: {integrity: sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==} 256 | engines: {node: '>=4'} 257 | dependencies: 258 | ext-list: 2.2.2 259 | sort-keys-length: 1.0.1 260 | dev: false 261 | 262 | /fd-slicer/1.1.0: 263 | resolution: {integrity: sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=} 264 | dependencies: 265 | pend: 1.2.0 266 | dev: false 267 | 268 | /file-type/11.1.0: 269 | resolution: {integrity: sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==} 270 | engines: {node: '>=6'} 271 | dev: false 272 | 273 | /file-type/3.9.0: 274 | resolution: {integrity: sha1-JXoHg4TR24CHvESdEH1SpSZyuek=} 275 | engines: {node: '>=0.10.0'} 276 | dev: false 277 | 278 | /file-type/4.4.0: 279 | resolution: {integrity: sha1-G2AOX8ofvcboDApwxxyNul95BsU=} 280 | engines: {node: '>=4'} 281 | dev: false 282 | 283 | /file-type/5.2.0: 284 | resolution: {integrity: sha1-LdvqfHP/42No365J3DOMBYwritY=} 285 | engines: {node: '>=4'} 286 | dev: false 287 | 288 | /file-type/6.2.0: 289 | resolution: {integrity: sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==} 290 | engines: {node: '>=4'} 291 | dev: false 292 | 293 | /filename-reserved-regex/2.0.0: 294 | resolution: {integrity: sha1-q/c9+rc10EVECr/qLZHzieu/oik=} 295 | engines: {node: '>=4'} 296 | dev: false 297 | 298 | /filenamify/3.0.0: 299 | resolution: {integrity: sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==} 300 | engines: {node: '>=6'} 301 | dependencies: 302 | filename-reserved-regex: 2.0.0 303 | strip-outer: 1.0.1 304 | trim-repeated: 1.0.0 305 | dev: false 306 | 307 | /from2/2.3.0: 308 | resolution: {integrity: sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=} 309 | dependencies: 310 | inherits: 2.0.4 311 | readable-stream: 2.3.7 312 | dev: false 313 | 314 | /fs-constants/1.0.0: 315 | resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} 316 | dev: false 317 | 318 | /fs-extra/10.0.0: 319 | resolution: {integrity: sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==} 320 | engines: {node: '>=12'} 321 | dependencies: 322 | graceful-fs: 4.2.8 323 | jsonfile: 6.1.0 324 | universalify: 2.0.0 325 | dev: false 326 | 327 | /fs.realpath/1.0.0: 328 | resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} 329 | dev: true 330 | 331 | /get-stream/2.3.1: 332 | resolution: {integrity: sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=} 333 | engines: {node: '>=0.10.0'} 334 | dependencies: 335 | object-assign: 4.1.1 336 | pinkie-promise: 2.0.1 337 | dev: false 338 | 339 | /get-stream/3.0.0: 340 | resolution: {integrity: sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=} 341 | engines: {node: '>=4'} 342 | dev: false 343 | 344 | /get-stream/4.1.0: 345 | resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} 346 | engines: {node: '>=6'} 347 | dependencies: 348 | pump: 3.0.0 349 | dev: false 350 | 351 | /glob/7.1.7: 352 | resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} 353 | dependencies: 354 | fs.realpath: 1.0.0 355 | inflight: 1.0.6 356 | inherits: 2.0.4 357 | minimatch: 3.0.4 358 | once: 1.4.0 359 | path-is-absolute: 1.0.1 360 | dev: true 361 | 362 | /got/8.3.2: 363 | resolution: {integrity: sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==} 364 | engines: {node: '>=4'} 365 | dependencies: 366 | '@sindresorhus/is': 0.7.0 367 | cacheable-request: 2.1.4 368 | decompress-response: 3.3.0 369 | duplexer3: 0.1.4 370 | get-stream: 3.0.0 371 | into-stream: 3.1.0 372 | is-retry-allowed: 1.2.0 373 | isurl: 1.0.0 374 | lowercase-keys: 1.0.1 375 | mimic-response: 1.0.1 376 | p-cancelable: 0.4.1 377 | p-timeout: 2.0.1 378 | pify: 3.0.0 379 | safe-buffer: 5.2.1 380 | timed-out: 4.0.1 381 | url-parse-lax: 3.0.0 382 | url-to-options: 1.0.1 383 | dev: false 384 | 385 | /graceful-fs/4.2.8: 386 | resolution: {integrity: sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==} 387 | dev: false 388 | 389 | /has-symbol-support-x/1.4.2: 390 | resolution: {integrity: sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==} 391 | dev: false 392 | 393 | /has-to-string-tag-x/1.4.1: 394 | resolution: {integrity: sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==} 395 | dependencies: 396 | has-symbol-support-x: 1.4.2 397 | dev: false 398 | 399 | /http-cache-semantics/3.8.1: 400 | resolution: {integrity: sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==} 401 | dev: false 402 | 403 | /ieee754/1.2.1: 404 | resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 405 | dev: false 406 | 407 | /inflight/1.0.6: 408 | resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} 409 | dependencies: 410 | once: 1.4.0 411 | wrappy: 1.0.2 412 | dev: true 413 | 414 | /inherits/2.0.4: 415 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 416 | 417 | /into-stream/3.1.0: 418 | resolution: {integrity: sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=} 419 | engines: {node: '>=4'} 420 | dependencies: 421 | from2: 2.3.0 422 | p-is-promise: 1.1.0 423 | dev: false 424 | 425 | /is-fullwidth-code-point/3.0.0: 426 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 427 | engines: {node: '>=8'} 428 | dev: false 429 | 430 | /is-natural-number/4.0.1: 431 | resolution: {integrity: sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=} 432 | dev: false 433 | 434 | /is-object/1.0.2: 435 | resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==} 436 | dev: false 437 | 438 | /is-plain-obj/1.1.0: 439 | resolution: {integrity: sha1-caUMhCnfync8kqOQpKA7OfzVHT4=} 440 | engines: {node: '>=0.10.0'} 441 | dev: false 442 | 443 | /is-retry-allowed/1.2.0: 444 | resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} 445 | engines: {node: '>=0.10.0'} 446 | dev: false 447 | 448 | /is-stream/1.1.0: 449 | resolution: {integrity: sha1-EtSj3U5o4Lec6428hBc66A2RykQ=} 450 | engines: {node: '>=0.10.0'} 451 | dev: false 452 | 453 | /isarray/1.0.0: 454 | resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=} 455 | dev: false 456 | 457 | /isurl/1.0.0: 458 | resolution: {integrity: sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==} 459 | engines: {node: '>= 4'} 460 | dependencies: 461 | has-to-string-tag-x: 1.4.1 462 | is-object: 1.0.2 463 | dev: false 464 | 465 | /json-buffer/3.0.0: 466 | resolution: {integrity: sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=} 467 | dev: false 468 | 469 | /jsonfile/6.1.0: 470 | resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} 471 | dependencies: 472 | universalify: 2.0.0 473 | optionalDependencies: 474 | graceful-fs: 4.2.8 475 | dev: false 476 | 477 | /keyv/3.0.0: 478 | resolution: {integrity: sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==} 479 | dependencies: 480 | json-buffer: 3.0.0 481 | dev: false 482 | 483 | /lowercase-keys/1.0.0: 484 | resolution: {integrity: sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=} 485 | engines: {node: '>=0.10.0'} 486 | dev: false 487 | 488 | /lowercase-keys/1.0.1: 489 | resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} 490 | engines: {node: '>=0.10.0'} 491 | dev: false 492 | 493 | /make-dir/1.3.0: 494 | resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} 495 | engines: {node: '>=4'} 496 | dependencies: 497 | pify: 3.0.0 498 | dev: false 499 | 500 | /make-dir/2.1.0: 501 | resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} 502 | engines: {node: '>=6'} 503 | dependencies: 504 | pify: 4.0.1 505 | semver: 5.7.1 506 | dev: false 507 | 508 | /mime-db/1.49.0: 509 | resolution: {integrity: sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==} 510 | engines: {node: '>= 0.6'} 511 | dev: false 512 | 513 | /mimic-response/1.0.1: 514 | resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} 515 | engines: {node: '>=4'} 516 | dev: false 517 | 518 | /minimatch/3.0.4: 519 | resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} 520 | dependencies: 521 | brace-expansion: 1.1.11 522 | dev: true 523 | 524 | /multistream/4.1.0: 525 | resolution: {integrity: sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==} 526 | dependencies: 527 | once: 1.4.0 528 | readable-stream: 3.6.0 529 | dev: true 530 | 531 | /normalize-url/2.0.1: 532 | resolution: {integrity: sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==} 533 | engines: {node: '>=4'} 534 | dependencies: 535 | prepend-http: 2.0.0 536 | query-string: 5.1.1 537 | sort-keys: 2.0.0 538 | dev: false 539 | 540 | /object-assign/4.1.1: 541 | resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=} 542 | engines: {node: '>=0.10.0'} 543 | dev: false 544 | 545 | /once/1.4.0: 546 | resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} 547 | dependencies: 548 | wrappy: 1.0.2 549 | 550 | /p-cancelable/0.4.1: 551 | resolution: {integrity: sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==} 552 | engines: {node: '>=4'} 553 | dev: false 554 | 555 | /p-event/2.3.1: 556 | resolution: {integrity: sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==} 557 | engines: {node: '>=6'} 558 | dependencies: 559 | p-timeout: 2.0.1 560 | dev: false 561 | 562 | /p-finally/1.0.0: 563 | resolution: {integrity: sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=} 564 | engines: {node: '>=4'} 565 | dev: false 566 | 567 | /p-is-promise/1.1.0: 568 | resolution: {integrity: sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=} 569 | engines: {node: '>=4'} 570 | dev: false 571 | 572 | /p-timeout/2.0.1: 573 | resolution: {integrity: sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==} 574 | engines: {node: '>=4'} 575 | dependencies: 576 | p-finally: 1.0.0 577 | dev: false 578 | 579 | /path-is-absolute/1.0.1: 580 | resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} 581 | engines: {node: '>=0.10.0'} 582 | dev: true 583 | 584 | /pend/1.2.0: 585 | resolution: {integrity: sha1-elfrVQpng/kRUzH89GY9XI4AelA=} 586 | dev: false 587 | 588 | /pify/2.3.0: 589 | resolution: {integrity: sha1-7RQaasBDqEnqWISY59yosVMw6Qw=} 590 | engines: {node: '>=0.10.0'} 591 | dev: false 592 | 593 | /pify/3.0.0: 594 | resolution: {integrity: sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=} 595 | engines: {node: '>=4'} 596 | dev: false 597 | 598 | /pify/4.0.1: 599 | resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} 600 | engines: {node: '>=6'} 601 | dev: false 602 | 603 | /pinkie-promise/2.0.1: 604 | resolution: {integrity: sha1-ITXW36ejWMBprJsXh3YogihFD/o=} 605 | engines: {node: '>=0.10.0'} 606 | dependencies: 607 | pinkie: 2.0.4 608 | dev: false 609 | 610 | /pinkie/2.0.4: 611 | resolution: {integrity: sha1-clVrgM+g1IqXToDnckjoDtT3+HA=} 612 | engines: {node: '>=0.10.0'} 613 | dev: false 614 | 615 | /prepend-http/2.0.0: 616 | resolution: {integrity: sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=} 617 | engines: {node: '>=4'} 618 | dev: false 619 | 620 | /process-nextick-args/2.0.1: 621 | resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} 622 | dev: false 623 | 624 | /pump/3.0.0: 625 | resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} 626 | dependencies: 627 | end-of-stream: 1.4.4 628 | once: 1.4.0 629 | dev: false 630 | 631 | /query-string/5.1.1: 632 | resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==} 633 | engines: {node: '>=0.10.0'} 634 | dependencies: 635 | decode-uri-component: 0.2.0 636 | object-assign: 4.1.1 637 | strict-uri-encode: 1.1.0 638 | dev: false 639 | 640 | /readable-stream/2.3.7: 641 | resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} 642 | dependencies: 643 | core-util-is: 1.0.3 644 | inherits: 2.0.4 645 | isarray: 1.0.0 646 | process-nextick-args: 2.0.1 647 | safe-buffer: 5.1.2 648 | string_decoder: 1.1.1 649 | util-deprecate: 1.0.2 650 | dev: false 651 | 652 | /readable-stream/3.6.0: 653 | resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} 654 | engines: {node: '>= 6'} 655 | dependencies: 656 | inherits: 2.0.4 657 | string_decoder: 1.1.1 658 | util-deprecate: 1.0.2 659 | dev: true 660 | 661 | /responselike/1.0.2: 662 | resolution: {integrity: sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=} 663 | dependencies: 664 | lowercase-keys: 1.0.1 665 | dev: false 666 | 667 | /safe-buffer/5.1.2: 668 | resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} 669 | 670 | /safe-buffer/5.2.1: 671 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 672 | dev: false 673 | 674 | /seek-bzip/1.0.6: 675 | resolution: {integrity: sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==} 676 | hasBin: true 677 | dependencies: 678 | commander: 2.20.3 679 | dev: false 680 | 681 | /semver/5.7.1: 682 | resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} 683 | hasBin: true 684 | dev: false 685 | 686 | /sort-keys-length/1.0.1: 687 | resolution: {integrity: sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=} 688 | engines: {node: '>=0.10.0'} 689 | dependencies: 690 | sort-keys: 1.1.2 691 | dev: false 692 | 693 | /sort-keys/1.1.2: 694 | resolution: {integrity: sha1-RBttTTRnmPG05J6JIK37oOVD+a0=} 695 | engines: {node: '>=0.10.0'} 696 | dependencies: 697 | is-plain-obj: 1.1.0 698 | dev: false 699 | 700 | /sort-keys/2.0.0: 701 | resolution: {integrity: sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=} 702 | engines: {node: '>=4'} 703 | dependencies: 704 | is-plain-obj: 1.1.0 705 | dev: false 706 | 707 | /strict-uri-encode/1.1.0: 708 | resolution: {integrity: sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=} 709 | engines: {node: '>=0.10.0'} 710 | dev: false 711 | 712 | /string-width/4.2.2: 713 | resolution: {integrity: sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==} 714 | engines: {node: '>=8'} 715 | dependencies: 716 | emoji-regex: 8.0.0 717 | is-fullwidth-code-point: 3.0.0 718 | strip-ansi: 6.0.0 719 | dev: false 720 | 721 | /string_decoder/1.1.1: 722 | resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} 723 | dependencies: 724 | safe-buffer: 5.1.2 725 | 726 | /strip-ansi/6.0.0: 727 | resolution: {integrity: sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==} 728 | engines: {node: '>=8'} 729 | dependencies: 730 | ansi-regex: 5.0.0 731 | dev: false 732 | 733 | /strip-dirs/2.1.0: 734 | resolution: {integrity: sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==} 735 | dependencies: 736 | is-natural-number: 4.0.1 737 | dev: false 738 | 739 | /strip-outer/1.0.1: 740 | resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} 741 | engines: {node: '>=0.10.0'} 742 | dependencies: 743 | escape-string-regexp: 1.0.5 744 | dev: false 745 | 746 | /tar-stream/1.6.2: 747 | resolution: {integrity: sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==} 748 | engines: {node: '>= 0.8.0'} 749 | dependencies: 750 | bl: 1.2.3 751 | buffer-alloc: 1.2.0 752 | end-of-stream: 1.4.4 753 | fs-constants: 1.0.0 754 | readable-stream: 2.3.7 755 | to-buffer: 1.1.1 756 | xtend: 4.0.2 757 | dev: false 758 | 759 | /through/2.3.8: 760 | resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=} 761 | dev: false 762 | 763 | /timed-out/4.0.1: 764 | resolution: {integrity: sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=} 765 | engines: {node: '>=0.10.0'} 766 | dev: false 767 | 768 | /to-buffer/1.1.1: 769 | resolution: {integrity: sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==} 770 | dev: false 771 | 772 | /trim-repeated/1.0.0: 773 | resolution: {integrity: sha1-42RqLqTokTEr9+rObPsFOAvAHCE=} 774 | engines: {node: '>=0.10.0'} 775 | dependencies: 776 | escape-string-regexp: 1.0.5 777 | dev: false 778 | 779 | /unbzip2-stream/1.4.3: 780 | resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} 781 | dependencies: 782 | buffer: 5.7.1 783 | through: 2.3.8 784 | dev: false 785 | 786 | /universalify/2.0.0: 787 | resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} 788 | engines: {node: '>= 10.0.0'} 789 | dev: false 790 | 791 | /url-parse-lax/3.0.0: 792 | resolution: {integrity: sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=} 793 | engines: {node: '>=4'} 794 | dependencies: 795 | prepend-http: 2.0.0 796 | dev: false 797 | 798 | /url-to-options/1.0.1: 799 | resolution: {integrity: sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=} 800 | engines: {node: '>= 4'} 801 | dev: false 802 | 803 | /util-deprecate/1.0.2: 804 | resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} 805 | 806 | /wrappy/1.0.2: 807 | resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} 808 | 809 | /xtend/4.0.2: 810 | resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} 811 | engines: {node: '>=0.4'} 812 | dev: false 813 | 814 | /yauzl/2.10.0: 815 | resolution: {integrity: sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=} 816 | dependencies: 817 | buffer-crc32: 0.2.13 818 | fd-slicer: 1.1.0 819 | dev: false 820 | -------------------------------------------------------------------------------- /spago.dhall: -------------------------------------------------------------------------------- 1 | { name = "psvm-ps" 2 | , dependencies = 3 | [ "argonaut-codecs" 4 | , "argparse-basic" 5 | , "arrays" 6 | , "console" 7 | , "effect" 8 | , "either" 9 | , "foldable-traversable" 10 | , "foreign-object" 11 | , "integers" 12 | , "maybe" 13 | , "newtype" 14 | , "node-buffer" 15 | , "node-fs" 16 | , "node-http" 17 | , "node-path" 18 | , "node-process" 19 | , "node-streams" 20 | , "options" 21 | , "prelude" 22 | , "psci-support" 23 | , "refs" 24 | , "run" 25 | , "string-parsers" 26 | , "tuples" 27 | , "typelevel-prelude" 28 | ] 29 | , packages = ./packages.dhall 30 | , sources = [ "src/**/*.purs" ] 31 | } 32 | -------------------------------------------------------------------------------- /src/Main.purs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Prelude 4 | 5 | import ArgParse.Basic (ArgParser, anyNotFlag, boolean, choose, command, flag, flagHelp, flagInfo, parseArgs, printArgError) 6 | import Data.Array as Array 7 | import Data.Either (Either(..)) 8 | import Data.Generic.Rep (class Generic) 9 | import Data.Maybe (Maybe(..)) 10 | import Data.Show.Generic (genericShow) 11 | import Effect (Effect) 12 | import Node.Process as Process 13 | import Psvm.Files as Files 14 | import Psvm.Ls as Ls 15 | import Psvm.Types (Psvm, exit, runPsvm) 16 | import Psvm.Version (Version) 17 | import Psvm.Version as Version 18 | 19 | data Command 20 | = Install (Maybe Version) 21 | | Uninstall (Maybe Version) 22 | | Use (Maybe Version) 23 | | Ls { remote :: Boolean } 24 | | Clean 25 | 26 | derive instance Eq Command 27 | derive instance Generic Command _ 28 | 29 | instance Show Command where 30 | show = genericShow 31 | 32 | commandParser :: ArgParser Command 33 | commandParser = 34 | choose "command" 35 | [ command [ "install" ] "Install a PureScript version." $ 36 | flagHelp *> anyNotFlag "VERSION" "version to install" 37 | <#> Install <<< Version.fromString 38 | 39 | , command [ "uninstall" ] "Uninstall a PureScript version." $ 40 | flagHelp *> anyNotFlag "VERSION" "version to uninstall" 41 | <#> Uninstall <<< Version.fromString 42 | 43 | , command [ "use" ] "Use a PureScript version." $ 44 | flagHelp *> anyNotFlag "VERSION" "version to use" 45 | <#> Use <<< Version.fromString 46 | 47 | , command [ "ls" ] "List PureScript versions." $ 48 | flagHelp *> 49 | (flag [ "-r", "--remote" ] "List remote versions." # boolean) 50 | <#> \remote -> Ls { remote } 51 | 52 | , command [ "clean" ] "Clean downloaded artifacts." $ 53 | flagHelp $> Clean 54 | ] 55 | 56 | main :: String -> String -> String -> Effect Unit 57 | main name version about = do 58 | argv <- Array.drop 2 <$> Process.argv 59 | runPsvm {} (perform argv) 60 | where 61 | perform :: Array String -> Psvm Unit 62 | perform argv = 63 | case parseArgs name about parser argv of 64 | Left e -> 65 | exit 1 (printArgError e) 66 | Right c -> 67 | case c of 68 | Install v -> 69 | tryVersion v Files.installPurs 70 | 71 | Uninstall v -> 72 | tryVersion v Files.removePurs 73 | 74 | Use v -> do 75 | tryVersion v Files.selectPurs 76 | 77 | Ls { remote } 78 | | remote -> Ls.printRemote 79 | | otherwise -> Ls.printLocal 80 | 81 | Clean -> Files.cleanPurs 82 | where 83 | parser :: ArgParser Command 84 | parser = flagHelp *> versionFlag *> commandParser 85 | where 86 | versionFlag = 87 | flagInfo [ "--version", "-v" ] "Show the installed psvm-ps version." version 88 | 89 | tryVersion :: Maybe Version -> (Version -> Psvm Unit) -> Psvm Unit 90 | tryVersion v command = 91 | case v of 92 | Nothing -> exit 1 "Invalid version" 93 | Just v' -> command v' 94 | -------------------------------------------------------------------------------- /src/Psvm/Files.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs-extra"); 2 | 3 | 4 | exports.rmRecursive = function(dir) { 5 | return function(cb) { 6 | return function() { 7 | fs.remove(dir, function(err) { 8 | cb(); 9 | }); 10 | }; 11 | }; 12 | }; 13 | 14 | 15 | exports.copyFile = function(src) { 16 | return function(to) { 17 | return function(cb) { 18 | return function () { 19 | fs.copy(src, to, function(err) { 20 | cb(); 21 | }); 22 | }; 23 | }; 24 | }; 25 | }; 26 | 27 | 28 | exports.mkdirRecursive = function(dir) { 29 | return function(cb) { 30 | return function() { 31 | fs.mkdirp(dir, function(err) { 32 | cb(); 33 | }); 34 | }; 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /src/Psvm/Files.purs: -------------------------------------------------------------------------------- 1 | module Psvm.Files where 2 | 3 | import Prelude 4 | 5 | import Data.Either (Either(..)) 6 | import Effect (Effect) 7 | import Effect.Console (log) 8 | import Effect.Console as Console 9 | import Node.FS.Async as FS 10 | import Node.Path (FilePath) 11 | import Node.Path as Path 12 | import Node.Process as Process 13 | import Psvm.Foreign.Download (downloadUrlTo, extractFromTo) 14 | import Psvm.Platform as Platform 15 | import Psvm.Types (Psvm) 16 | import Psvm.Version (Version) 17 | import Run (liftEffect) 18 | 19 | type PsvmFolder = 20 | { archives :: FilePath 21 | , current :: FilePath 22 | , versions :: FilePath 23 | } 24 | 25 | askPsvmFolder :: Psvm PsvmFolder 26 | askPsvmFolder = do 27 | home <- Platform.askHome 28 | let base = Path.concat [ home, ".psvm" ] 29 | pure 30 | { archives: Path.concat [ base, "archives" ] 31 | , current: Path.concat [ base, "current" ] 32 | , versions: Path.concat [ base, "versions" ] 33 | } 34 | 35 | askDownloadUrl :: Version -> Psvm String 36 | askDownloadUrl version = do 37 | platform <- Platform.askReleaseName 38 | pure $ "https://github.com/purescript/purescript/releases/download/" 39 | <> show version 40 | <> "/" 41 | <> platform 42 | <> ".tar.gz" 43 | 44 | installPurs :: Version -> Psvm Unit 45 | installPurs version = do 46 | psvm <- askPsvmFolder 47 | url <- askDownloadUrl version 48 | 49 | let 50 | vrs = show version 51 | dnl = Path.concat [ psvm.archives, vrs <> ".tar.gz" ] 52 | unp = Path.concat [ psvm.versions, vrs ] 53 | 54 | liftEffect $ mkdirRecursive psvm.archives $ 55 | downloadUrlTo url dnl do 56 | log $ "Downloaded: " <> vrs 57 | extractFromTo dnl unp do 58 | log $ "Installed: " <> unp 59 | 60 | selectPurs :: Version -> Psvm Unit 61 | selectPurs version = do 62 | psvm <- askPsvmFolder 63 | 64 | let 65 | vrs = show version 66 | src = Path.concat [ psvm.versions, vrs, "purescript", "purs" ] 67 | to = Path.concat [ psvm.current, "bin", "purs" ] 68 | 69 | liftEffect $ mkdirRecursive psvm.archives $ 70 | copyFile src to do 71 | Console.log $ "Using PureScript: " <> vrs 72 | 73 | removePurs :: Version -> Psvm Unit 74 | removePurs version = do 75 | psvm <- askPsvmFolder 76 | 77 | let 78 | vrs = show version 79 | target = Path.concat [ psvm.versions, vrs ] 80 | 81 | liftEffect $ rmRecursive target do 82 | Console.log $ "Uninstalled PureScript: " <> vrs 83 | 84 | cleanPurs :: Psvm Unit 85 | cleanPurs = do 86 | psvm <- askPsvmFolder 87 | 88 | liftEffect $ rmRecursive psvm.archives do 89 | Console.log $ "Cleaned artifacts on: " <> psvm.archives 90 | 91 | listPurs :: PsvmFolder -> (Array String -> Effect Unit) -> Psvm Unit 92 | listPurs psvm cb = do 93 | liftEffect $ mkdirRecursive psvm.archives 94 | $ FS.readdir psvm.versions 95 | $ 96 | case _ of 97 | Left err -> do 98 | Console.error $ "Fatal error: " <> show err 99 | Process.exit 1 100 | Right files -> 101 | cb files 102 | 103 | foreign import mkdirRecursive :: String -> Effect Unit -> Effect Unit 104 | 105 | foreign import copyFile :: String -> String -> Effect Unit -> Effect Unit 106 | 107 | foreign import rmRecursive :: String -> Effect Unit -> Effect Unit 108 | -------------------------------------------------------------------------------- /src/Psvm/Foreign/Download.js: -------------------------------------------------------------------------------- 1 | const cliProgress = require("cli-progress"); 2 | const decompress = require("decompress"); 3 | const download = require("download"); 4 | const fs = require("fs"); 5 | 6 | 7 | exports.downloadUrlToImpl = function(url) { 8 | return function(to) { 9 | return function(cb) { 10 | return function () { 11 | const bar = new cliProgress.SingleBar({ 12 | format: "Fetching |{bar}| {percentage}% in {eta}s", 13 | barCompleteChar: '\u2588', 14 | barIncompleteChar: ' ', 15 | }); 16 | bar.start(100, 0, { speed: "N/A" }) 17 | 18 | const toStream = fs.createWriteStream(to); 19 | toStream.on("error", function(error) { 20 | console.error("Failed to write file.") 21 | }).on("finish", function() { 22 | bar.stop(); 23 | cb(); 24 | }); 25 | 26 | const dlStream = download(url); 27 | dlStream.on("downloadProgress", function(progress) { 28 | bar.update(progress.percent * 100); 29 | }).on("error", function() { 30 | bar.stop(); 31 | }); 32 | 33 | dlStream.pipe(toStream); 34 | }; 35 | }; 36 | }; 37 | }; 38 | 39 | 40 | exports.extractFromToImpl = function(src) { 41 | return function(to) { 42 | return function(cb) { 43 | return function() { 44 | decompress(src, to).then(function(files) { 45 | cb(); 46 | }); 47 | }; 48 | }; 49 | }; 50 | }; 51 | -------------------------------------------------------------------------------- /src/Psvm/Foreign/Download.purs: -------------------------------------------------------------------------------- 1 | module Psvm.Foreign.Download where 2 | 3 | import Data.Unit (Unit) 4 | import Effect (Effect) 5 | 6 | type Callback = Effect Unit 7 | 8 | foreign import downloadUrlToImpl :: String -> String -> Callback -> Effect Unit 9 | 10 | downloadUrlTo :: String -> String -> Callback -> Effect Unit 11 | downloadUrlTo = downloadUrlToImpl 12 | 13 | foreign import extractFromToImpl :: String -> String -> Callback -> Effect Unit 14 | 15 | extractFromTo :: String -> String -> Callback -> Effect Unit 16 | extractFromTo = extractFromToImpl 17 | -------------------------------------------------------------------------------- /src/Psvm/Ls.purs: -------------------------------------------------------------------------------- 1 | module Psvm.Ls where 2 | 3 | import Prelude 4 | 5 | import Data.Argonaut.Decode (class DecodeJson, decodeJson, parseJson, (.:)) 6 | import Data.Either (Either(..)) 7 | import Data.Newtype (class Newtype, unwrap) 8 | import Data.Options ((:=)) 9 | import Data.Traversable (for_) 10 | import Data.Tuple (Tuple(..)) 11 | import Effect (Effect) 12 | import Effect.Console as Console 13 | import Effect.Ref as Ref 14 | import Foreign.Object (fromFoldable) 15 | import Node.Encoding as Encoding 16 | import Node.HTTP.Client as Client 17 | import Node.Process as Process 18 | import Node.Stream (end, onDataString, onEnd) 19 | import Psvm.Files (askPsvmFolder, listPurs) 20 | import Psvm.Types (Psvm) 21 | import Run (liftEffect) 22 | 23 | releaseUrl :: String 24 | releaseUrl = "https://api.github.com/repos/purescript/purescript/releases" 25 | 26 | newtype ReleaseJson = ReleaseJson 27 | { tagName :: String 28 | , assetsUrl :: String 29 | } 30 | 31 | derive instance newtypeReleaseJson :: Newtype ReleaseJson _ 32 | derive newtype instance showReleaseJson :: Show ReleaseJson 33 | 34 | instance decodeJsonRleaseJson :: DecodeJson ReleaseJson where 35 | decodeJson json = do 36 | obj <- decodeJson json 37 | 38 | tagName <- obj .: "tag_name" 39 | assetsUrl <- obj .: "assets_url" 40 | 41 | pure $ ReleaseJson { tagName, assetsUrl } 42 | 43 | getReleases :: (Array ReleaseJson -> Effect Unit) -> Effect Unit 44 | getReleases cb = do 45 | let 46 | headers_ = Client.RequestHeaders $ fromFoldable 47 | [ Tuple "User-Agent" "psvm-ps" 48 | ] 49 | 50 | options = 51 | Client.headers := headers_ 52 | <> Client.hostname := "api.github.com" 53 | <> Client.path := "/repos/purescript/purescript/releases" 54 | <> Client.method := "GET" 55 | <> Client.protocol := "https:" 56 | <> 57 | Client.port := 443 58 | 59 | req <- Client.request options \response -> do 60 | let stream = Client.responseAsStream response 61 | 62 | buffer <- Ref.new "" 63 | 64 | onDataString stream Encoding.UTF8 \chunk -> do 65 | Ref.modify_ (_ <> chunk) buffer 66 | 67 | onEnd stream do 68 | result <- Ref.read buffer 69 | case parseJson result >>= decodeJson of 70 | Left err -> 71 | Console.errorShow err *> Process.exit 1 72 | Right releases -> do 73 | cb releases 74 | 75 | end (Client.requestAsStream req) (pure unit) 76 | 77 | printRemote :: Psvm Unit 78 | printRemote = do 79 | liftEffect $ getReleases \versions -> do 80 | Console.log "Available PureScript Versions:" 81 | for_ versions \version -> 82 | Console.log (" " <> (unwrap version).tagName) 83 | 84 | printLocal :: Psvm Unit 85 | printLocal = do 86 | psvm <- askPsvmFolder 87 | listPurs psvm \versions -> do 88 | Console.log "Available PureScript Versions:" 89 | for_ versions \version -> 90 | Console.log (" " <> version) 91 | -------------------------------------------------------------------------------- /src/Psvm/Platform.purs: -------------------------------------------------------------------------------- 1 | -- | Platform-related actions. 2 | module Psvm.Platform where 3 | 4 | import Prelude 5 | 6 | import Data.Maybe (Maybe(..)) 7 | import Node.Platform as Platform 8 | import Node.Process as Process 9 | import Psvm.Types (Psvm, exit) 10 | import Run (liftEffect) 11 | 12 | -- | Supported platforms. 13 | data SupportedPlatform 14 | = Darwin 15 | | Linux 16 | | Win32 17 | 18 | derive instance Eq SupportedPlatform 19 | 20 | instance Show SupportedPlatform where 21 | show Darwin = "Darwin" 22 | show Linux = "Linux" 23 | show Win32 = "Win32" 24 | 25 | platform :: Maybe SupportedPlatform 26 | platform = 27 | case Process.platform of 28 | Just platform' -> 29 | case platform' of 30 | Platform.Darwin -> Just Darwin 31 | Platform.Linux -> Just Linux 32 | Platform.Win32 -> Just Win32 33 | _ -> Nothing 34 | _ -> Nothing 35 | 36 | releaseName :: SupportedPlatform -> String 37 | releaseName = case _ of 38 | Darwin -> "macos" 39 | Linux -> "linux64" 40 | Win32 -> "win32" 41 | 42 | -- | Get the current platform. 43 | askPlatform :: Psvm SupportedPlatform 44 | askPlatform = do 45 | case platform of 46 | Nothing -> exit 1 "unknown platform" 47 | Just platform' -> pure platform' 48 | 49 | -- | Get the platform string for release URLs. 50 | askReleaseName :: Psvm String 51 | askReleaseName = releaseName <$> askPlatform 52 | 53 | -- | Get the home directory for the current platform. 54 | askHome :: Psvm String 55 | askHome = do 56 | platform' <- askPlatform 57 | home <- liftEffect $ case platform' of 58 | Darwin -> Process.lookupEnv "HOME" 59 | Linux -> Process.lookupEnv "HOME" 60 | Win32 -> Process.lookupEnv "USERPROFILE" 61 | case home of 62 | Nothing -> 63 | exit 1 "could not determine home directory from environment variables" 64 | Just home' -> 65 | pure home' 66 | -------------------------------------------------------------------------------- /src/Psvm/Types.purs: -------------------------------------------------------------------------------- 1 | module Psvm.Types where 2 | 3 | import Prelude 4 | 5 | import Data.Either (Either(..)) 6 | import Effect (Effect) 7 | import Effect.Console as Console 8 | import Node.Process as Process 9 | import Run (EFFECT, Run, liftEffect, runBaseEffect) 10 | import Run.Except (EXCEPT, Except(..), liftExcept, runExcept) 11 | import Run.Reader (READER, runReader) 12 | import Type.Row (type (+)) 13 | 14 | -- | Failure types consumed by the app. 15 | data Failure = Exit Int String 16 | 17 | derive instance Eq Failure 18 | 19 | -- | Exit with a code and message. 20 | exit :: forall a. Int -> String -> Psvm a 21 | exit c m = liftExcept $ Except (Exit c m) 22 | 23 | -- | Raise a `Failure` into `Effect`. 24 | runFailure :: forall r a. Run (EXCEPT Failure + EFFECT + r) a -> Run (EFFECT + r) a 25 | runFailure m = do 26 | u <- runExcept m 27 | case u of 28 | Left f -> case f of 29 | Exit code message -> liftEffect do 30 | Console.error message 31 | Process.exit code 32 | Right r -> pure r 33 | 34 | -- | Environment type consumed by the app. 35 | type Env = {} 36 | 37 | -- | Extensible row of effects for `run`. 38 | type PSVM = 39 | ( READER Env 40 | + EXCEPT Failure 41 | + EFFECT 42 | + () 43 | ) 44 | 45 | -- | Base monad type consumed by the app. 46 | type Psvm a = Run PSVM a 47 | 48 | -- | Run the `PSVM` effect stack. 49 | runPsvm :: forall a. Env -> Psvm a -> Effect a 50 | runPsvm e = runBaseEffect <<< runFailure <<< runReader e 51 | -------------------------------------------------------------------------------- /src/Psvm/Version.purs: -------------------------------------------------------------------------------- 1 | module Psvm.Version where 2 | 3 | import Prelude 4 | 5 | import Data.Array as Array 6 | import Data.Either (hush) 7 | import Data.Int as Int 8 | import Data.Maybe (Maybe) 9 | import Text.Parsing.StringParser (runParser) 10 | import Text.Parsing.StringParser.CodeUnits (char, regex) 11 | import Text.Parsing.StringParser.Combinators (optional) 12 | 13 | data Version = Version Int Int Int String 14 | 15 | derive instance eqVersion :: Eq Version 16 | 17 | instance Ord Version where 18 | compare (Version major minor patch _) (Version major' minor' patch' _) = 19 | Array.fold [ compare major major', compare minor minor', compare patch patch' ] 20 | 21 | instance Show Version where 22 | show = toString 23 | 24 | fromString :: String -> Maybe Version 25 | fromString = join <<< hush <<< runParser do 26 | _ <- optional $ char 'v' 27 | 28 | major <- Int.fromString <$> regex "\\d+" 29 | 30 | void $ char '.' 31 | 32 | minor <- Int.fromString <$> regex "\\d+" 33 | 34 | void $ char '.' 35 | 36 | patch <- Int.fromString <$> regex "\\d+" 37 | 38 | extra <- regex ".*" 39 | 40 | pure $ Version <$> major <*> minor <*> patch <*> pure extra 41 | 42 | toString :: Version -> String 43 | toString (Version major minor patch extra) = Array.intercalate "" 44 | [ "v", show major, ".", show minor, ".", show patch, extra ] 45 | --------------------------------------------------------------------------------