├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.js ├── package.json ├── spago.lock ├── spago.yaml ├── src ├── Main.js └── Main.purs └── testcase ├── .gitignore ├── Foo.purs ├── Main.purs ├── bower.json └── lib └── Lib.purs /.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | /.pulp-cache/ 4 | /output/ 5 | /dist/ 6 | /.psci* 7 | /src/.webpack.js 8 | npm-debug.log 9 | .psa-stash 10 | .psc-ide-port 11 | .purs-repl 12 | .spago -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | /.pulp-cache/ 4 | /.psci* 5 | /src/.webpack.js 6 | /test/ 7 | /bin/ 8 | /output/*/externs.json 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### v0.8.2 (2021-01-25) 2 | 3 | * Don't swallow "Compiling..." messages (@hdgarrood) 4 | 5 | ### v0.8.1 (2021-01-23) 6 | 7 | * Fix ignored `--purs=` command-line argument (@joneshf) 8 | 9 | ### v0.8.0 (2020-10-01) 10 | 11 | * Add .spago to lib dirs by default (@d0liver) 12 | * Support both 0.13 and 0.14 compiler versions (@hdgarrood) 13 | 14 | ### v0.7.3 (2018-08-23) 15 | 16 | * Fix file not found exception when processing errors that have no file information 17 | 18 | ### v0.7.2 (2018-07-20) 19 | 20 | * Fix lib detection when purs emits an absolute path 21 | 22 | ### v0.7.1 (2018-07-18) 23 | 24 | * Removed stray log statement 25 | 26 | ### v0.7.0 (2018-07-13) 27 | 28 | * Account for changes in 0.12 for relative paths in errors 29 | 30 | ### v0.6.0 (2018-01-06) 31 | 32 | * Added `--censor-stats` option (@Rufflewind) 33 | 34 | ### v0.5.1 (2017-04-08) 35 | 36 | * Fix parsing of `--purs` options (@bfly2000) 37 | 38 | ### v0.5.0 (2017-03-28) 39 | 40 | * Updated to call `purs build`. 41 | 42 | ### v0.4.0 (2016-11-19) 43 | 44 | * Filtering/censoring warnings is applied before --strict 45 | 46 | ### v0.3.9 (2016-6-4) 47 | 48 | * Support for 0.9.x suggestions 49 | 50 | ### v0.3.8 (2016-5-8) 51 | 52 | * Always show errors, regardless of filter/censor configuration 53 | 54 | ### v0.3.7 (2016-4-18) 55 | 56 | * Apply filters and stash to `--json-errors` 57 | 58 | ### v0.3.6 (2016-4-15) 59 | 60 | * Fix edge-case position trimming 61 | * Bump dependencies 62 | 63 | ### v0.3.5 (2016-3-5) 64 | 65 | * Retry with `.cmd` on Windows 66 | * Proxy psc output when called with `--json-errors` (for tooling) 67 | 68 | ### v0.3.4 (2016-2-20) 69 | 70 | * Only read the stash file when `--stash` is set 71 | 72 | ### v0.3.3 (2016-2-20) 73 | 74 | * Purge stale `--stash` warnings based on file modification time 75 | 76 | ### v0.3.2 (2016-1-22) 77 | 78 | * Better handling of `--is-lib` as a real directory 79 | 80 | ### v0.3.0 (2016-1-20) 81 | 82 | * Add `--strict` flag 83 | * Change `--lib-dir` to `--is-lib` for clarity 84 | 85 | ### v0.2.1 (2016-1-18) 86 | 87 | * Always print to stderr 88 | 89 | ### v0.2.0 (2016-1-12) 90 | 91 | * Fix stale stash bug 92 | * Add `--verbose-stats` flag 93 | 94 | ### v0.1.3 (2016-1-10) 95 | 96 | * Add `--stash` options for persisting warnings 97 | 98 | ### v0.1.2 (2016-1-8) 99 | 100 | * Fix stdout piping 101 | 102 | ### v0.1.1 (2016-1-8) 103 | 104 | * Pipe psc stdout 105 | 106 | ### v0.1.0 (2016-1-8) 107 | 108 | * Initial release 109 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Nathan Faubion 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | psa 2 | === 3 | 4 | A pretty, flexible error/warning reporting frontend for the PureScript compiler 5 | (`psc`). 6 | 7 | * Colors! 8 | * Original source spans in errors 9 | * Fine-grained warning filtering 10 | * Warning persistence 11 | 12 | Install 13 | ------- 14 | 15 | ``` 16 | npm install -g purescript-psa 17 | ``` 18 | 19 | Sample Usage 20 | ------------ 21 | 22 | Censor all warnings: 23 | ``` 24 | psa --censor-warnings 25 | ``` 26 | 27 | Censor library warnings: 28 | ``` 29 | psa --censor-lib 30 | ``` 31 | 32 | Censor source warnings: 33 | ``` 34 | psa --censor-src 35 | ``` 36 | 37 | Censor specific warning codes: 38 | ``` 39 | psa --censor-codes=ShadowedName,ImplicitImport,MissingTypeDeclaration 40 | ``` 41 | 42 | Only show specific warning codes: 43 | ``` 44 | psa --filter-codes=DeprecatedOperatorDecl,DeprecatedClassExport 45 | ``` 46 | 47 | Turn source warnings into errors: 48 | ``` 49 | psa --strict 50 | ``` 51 | 52 | **Note:** It's assumed `psc` is in your path. If you'd like to use a custom 53 | binary location you can set the `--psc=/foo/bar/psc` flag. 54 | 55 | Persisting Warnings 56 | ------------------- 57 | 58 | `psc` does not persist warnings between compilations, but `psa` can do it with 59 | the `--stash` flag. This serializes the set of warnings to disk and merges it 60 | with the new set on each compilation. 61 | 62 | ``` 63 | psa --stash 64 | ``` 65 | 66 | If you are compiling multiple projects from the same root, you can specify 67 | which stash file should be used: 68 | 69 | ``` 70 | psa --stash=.foo-stash 71 | ``` 72 | 73 | Usage with pulp 74 | --------------- 75 | 76 | [Pulp](https://github.com/bodil/pulp) supports building with `psa`: it will be used by default if it is installed, and options will be passed through, eg: 77 | 78 | ``` 79 | pulp build -- --stash --censor-lib 80 | ``` 81 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import * as Main from './dist/index.js'; 3 | Main.main(); 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-psa", 3 | "version": "0.9.0", 4 | "type": "module", 5 | "description": "Error/Warning reporting frontend for psc", 6 | "keywords": [ 7 | "purescript", 8 | "psc" 9 | ], 10 | "author": "Nathan Faubion (https://github.com/natefaubion/)", 11 | "license": "MIT", 12 | "repository": "natefaubion/purescript-psa", 13 | "files": [ 14 | "dist/*", 15 | "index.js" 16 | ], 17 | "bin": { 18 | "psa": "index.js" 19 | }, 20 | "directories": { 21 | "test": "testcase" 22 | }, 23 | "scripts": { 24 | "version": "echo 'export const version = \"v'$npm_package_version'\";' > ./src/Main.js && git add ./src/Main.js", 25 | "postversion": "git push && git push --tags", 26 | "build": "npm run compile", 27 | "compile": "spago bundle --outfile dist/index.js --bundle-type module --platform node", 28 | "compile-self": "node index.js -c \"src/**/*.purs\" \".spago/p/**/src/**/*.purs\"", 29 | "pretest": "rm -rf testcase/output", 30 | "test": "node index.js --is-lib=testcase/bower_components --is-lib=testcase/lib -o \"testcase/output\" \"testcase/*.purs\" \"testcase/lib/*.purs\" \"testcase/bower_components/purescript-*/src/**/*.purs\"", 31 | "pretest-purs": "rm -rf testcase/output", 32 | "test-purs": "purs compile --output=testcase/output \"testcase/*.purs\" \"testcase/bower_components/purescript-*/src/**/*.purs\"", 33 | "prepare": "rm -rf output && npm run compile" 34 | }, 35 | "devDependencies": { 36 | "bower": "^1.8.14", 37 | "esbuild": "^0.21.5", 38 | "purescript": "^0.15.15", 39 | "spago": "^0.93.29" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /spago.lock: -------------------------------------------------------------------------------- 1 | workspace: 2 | packages: 3 | psa: 4 | path: ./ 5 | dependencies: 6 | - console 7 | - datetime 8 | - debug 9 | - effect 10 | - foreign-object 11 | - node-buffer 12 | - node-child-process 13 | - node-fs 14 | - node-process 15 | - node-streams 16 | - now 17 | - ordered-collections 18 | - prelude 19 | - psa-utils 20 | - refs 21 | - st 22 | - versions 23 | test_dependencies: [] 24 | build_plan: 25 | - aff 26 | - ansi 27 | - argonaut-codecs 28 | - argonaut-core 29 | - arraybuffer-types 30 | - arrays 31 | - bifunctors 32 | - console 33 | - const 34 | - contravariant 35 | - control 36 | - datetime 37 | - debug 38 | - distributive 39 | - effect 40 | - either 41 | - enums 42 | - exceptions 43 | - exists 44 | - foldable-traversable 45 | - foreign 46 | - foreign-object 47 | - functions 48 | - functors 49 | - gen 50 | - identity 51 | - integers 52 | - invariant 53 | - js-date 54 | - lazy 55 | - lists 56 | - maybe 57 | - newtype 58 | - node-buffer 59 | - node-child-process 60 | - node-event-emitter 61 | - node-fs 62 | - node-os 63 | - node-path 64 | - node-process 65 | - node-streams 66 | - nonempty 67 | - now 68 | - nullable 69 | - numbers 70 | - ordered-collections 71 | - orders 72 | - parallel 73 | - parsing 74 | - partial 75 | - posix-types 76 | - prelude 77 | - profunctor 78 | - psa-utils 79 | - record 80 | - refs 81 | - safe-coerce 82 | - st 83 | - strings 84 | - tailrec 85 | - transformers 86 | - tuples 87 | - type-equality 88 | - typelevel-prelude 89 | - unfoldable 90 | - unicode 91 | - unsafe-coerce 92 | - versions 93 | package_set: 94 | address: 95 | registry: 50.13.0 96 | compiler: ">=0.15.15 <0.16.0" 97 | content: 98 | abc-parser: 2.0.1 99 | ace: 9.1.0 100 | address-rfc2821: 0.1.1 101 | aff: 7.1.0 102 | aff-bus: 6.0.0 103 | aff-coroutines: 9.0.0 104 | aff-promise: 4.0.0 105 | aff-retry: 2.0.0 106 | affjax: 13.0.0 107 | affjax-node: 1.0.0 108 | affjax-web: 1.0.0 109 | ansi: 7.0.0 110 | apexcharts: 0.5.0 111 | applicative-phases: 1.0.0 112 | argonaut: 9.0.0 113 | argonaut-aeson-generic: 0.4.1 114 | argonaut-codecs: 9.1.0 115 | argonaut-core: 7.0.0 116 | argonaut-generic: 8.0.0 117 | argonaut-traversals: 10.0.0 118 | argparse-basic: 2.0.0 119 | array-builder: 0.1.2 120 | array-search: 0.5.6 121 | arraybuffer: 13.2.0 122 | arraybuffer-builder: 3.1.0 123 | arraybuffer-types: 3.0.2 124 | arrays: 7.3.0 125 | arrays-extra: 0.6.1 126 | arrays-zipper: 2.0.1 127 | ask: 1.0.0 128 | assert: 6.0.0 129 | assert-multiple: 0.3.4 130 | avar: 5.0.0 131 | b64: 0.0.8 132 | barbies: 1.0.1 133 | barlow-lens: 0.9.0 134 | bifunctors: 6.0.0 135 | bigints: 7.0.1 136 | bolson: 0.3.9 137 | bookhound: 0.1.7 138 | bower-json: 3.0.0 139 | call-by-name: 4.0.1 140 | canvas: 6.0.0 141 | canvas-action: 9.0.0 142 | cartesian: 1.0.6 143 | catenable-lists: 7.0.0 144 | chameleon: 1.0.0 145 | chameleon-halogen: 1.0.3 146 | chameleon-react-basic: 1.1.0 147 | chameleon-styled: 2.5.0 148 | chameleon-transformers: 1.0.0 149 | channel: 1.0.0 150 | checked-exceptions: 3.1.1 151 | choku: 1.0.1 152 | classless: 0.1.1 153 | classless-arbitrary: 0.1.1 154 | classless-decode-json: 0.1.1 155 | classless-encode-json: 0.1.3 156 | classnames: 2.0.0 157 | codec: 6.1.0 158 | codec-argonaut: 10.0.0 159 | codec-json: 1.1.0 160 | colors: 7.0.1 161 | concur-core: 0.5.0 162 | concur-react: 0.5.0 163 | concurrent-queues: 3.0.0 164 | console: 6.1.0 165 | const: 6.0.0 166 | contravariant: 6.0.0 167 | control: 6.0.0 168 | convertable-options: 1.0.0 169 | coroutines: 7.0.0 170 | css: 6.0.0 171 | css-frameworks: 1.0.1 172 | csv-stream: 1.1.0 173 | data-mvc: 0.0.2 174 | datetime: 6.1.0 175 | datetime-parsing: 0.2.0 176 | debug: 6.0.2 177 | decimals: 7.1.0 178 | default-values: 1.0.1 179 | deku: 0.9.23 180 | deno: 0.0.5 181 | dissect: 1.0.0 182 | distributive: 6.0.0 183 | dom-filereader: 7.0.0 184 | dom-indexed: 12.0.0 185 | dom-simple: 0.4.0 186 | dotenv: 4.0.3 187 | droplet: 0.6.0 188 | dts: 1.0.0 189 | dual-numbers: 1.0.2 190 | dynamic-buffer: 3.0.1 191 | echarts-simple: 0.0.1 192 | effect: 4.0.0 193 | either: 6.1.0 194 | elmish: 0.11.3 195 | elmish-enzyme: 0.1.1 196 | elmish-hooks: 0.10.0 197 | elmish-html: 0.8.2 198 | elmish-testing-library: 0.3.2 199 | email-validate: 7.0.0 200 | encoding: 0.0.9 201 | enums: 6.0.1 202 | env-names: 0.3.4 203 | error: 2.0.0 204 | eta-conversion: 0.3.2 205 | exceptions: 6.0.0 206 | exists: 6.0.0 207 | exitcodes: 4.0.0 208 | expect-inferred: 3.0.0 209 | fahrtwind: 2.0.0 210 | fallback: 0.1.0 211 | fast-vect: 1.2.0 212 | fetch: 4.1.0 213 | fetch-argonaut: 1.0.1 214 | fetch-core: 5.1.0 215 | fetch-yoga-json: 1.1.0 216 | ffi-simple: 0.5.1 217 | fft-js: 0.1.0 218 | filterable: 5.0.0 219 | fix-functor: 0.1.0 220 | fixed-points: 7.0.0 221 | fixed-precision: 5.0.0 222 | flame: 1.3.0 223 | float32: 2.0.0 224 | fmt: 0.2.1 225 | foldable-traversable: 6.0.0 226 | foldable-traversable-extra: 0.0.6 227 | foreign: 7.0.0 228 | foreign-object: 4.1.0 229 | foreign-readwrite: 3.4.0 230 | forgetmenot: 0.1.0 231 | fork: 6.0.0 232 | form-urlencoded: 7.0.0 233 | formatters: 7.0.0 234 | framer-motion: 1.0.1 235 | free: 7.1.0 236 | freeap: 7.0.0 237 | freer-free: 0.0.1 238 | freet: 7.0.0 239 | functions: 6.0.0 240 | functor1: 3.0.0 241 | functors: 5.0.0 242 | fuzzy: 0.4.0 243 | gen: 4.0.0 244 | generate-values: 1.0.1 245 | generic-router: 0.0.1 246 | geojson: 0.0.5 247 | geometry-plane: 1.0.3 248 | gojs: 0.1.1 249 | grain: 3.0.0 250 | grain-router: 3.0.0 251 | grain-virtualized: 3.0.0 252 | graphs: 8.1.0 253 | group: 4.1.1 254 | halogen: 7.0.0 255 | halogen-bootstrap5: 5.3.2 256 | halogen-canvas: 1.0.0 257 | halogen-css: 10.0.0 258 | halogen-echarts-simple: 0.0.4 259 | halogen-formless: 4.0.3 260 | halogen-helix: 1.0.0 261 | halogen-hooks: 0.6.3 262 | halogen-hooks-extra: 0.9.0 263 | halogen-infinite-scroll: 1.1.0 264 | halogen-store: 0.5.4 265 | halogen-storybook: 2.0.0 266 | halogen-subscriptions: 2.0.0 267 | halogen-svg-elems: 8.0.0 268 | halogen-typewriter: 1.0.4 269 | halogen-vdom: 8.0.0 270 | halogen-vdom-string-renderer: 0.5.0 271 | halogen-xterm: 2.0.0 272 | heckin: 2.0.1 273 | heterogeneous: 0.6.0 274 | homogeneous: 0.4.0 275 | http-methods: 6.0.0 276 | httpurple: 4.0.0 277 | humdrum: 0.0.1 278 | hyrule: 2.3.8 279 | identity: 6.0.0 280 | identy: 4.0.1 281 | indexed-db: 1.0.0 282 | indexed-monad: 3.0.0 283 | int64: 3.0.0 284 | integers: 6.0.0 285 | interpolate: 5.0.2 286 | intersection-observer: 1.0.1 287 | invariant: 6.0.0 288 | jarilo: 1.0.1 289 | jelly: 0.10.0 290 | jelly-router: 0.3.0 291 | jelly-signal: 0.4.0 292 | jest: 1.0.0 293 | js-abort-controller: 1.0.0 294 | js-bigints: 2.2.1 295 | js-date: 8.0.0 296 | js-fetch: 0.2.1 297 | js-fileio: 3.0.0 298 | js-intl: 1.0.4 299 | js-iterators: 0.1.1 300 | js-maps: 0.1.2 301 | js-promise: 1.0.0 302 | js-promise-aff: 1.0.0 303 | js-timers: 6.1.0 304 | js-uri: 3.1.0 305 | json: 1.0.0 306 | json-codecs: 5.0.0 307 | justifill: 0.5.0 308 | jwt: 0.0.9 309 | labeled-data: 0.2.0 310 | language-cst-parser: 0.14.0 311 | lazy: 6.0.0 312 | lazy-joe: 1.0.0 313 | lcg: 4.0.0 314 | leibniz: 5.0.0 315 | leveldb: 1.0.1 316 | liminal: 1.0.1 317 | linalg: 6.0.0 318 | lists: 7.0.0 319 | literals: 1.0.2 320 | logging: 3.0.0 321 | logging-journald: 0.4.0 322 | lumi-components: 18.0.0 323 | machines: 7.0.0 324 | maps-eager: 0.4.1 325 | marionette: 1.0.0 326 | marionette-react-basic-hooks: 0.1.1 327 | marked: 0.1.0 328 | matrices: 5.0.1 329 | matryoshka: 1.0.0 330 | maybe: 6.0.0 331 | media-types: 6.0.0 332 | meowclient: 1.0.0 333 | midi: 4.0.0 334 | milkis: 9.0.0 335 | minibench: 4.0.1 336 | mmorph: 7.0.0 337 | monad-control: 5.0.0 338 | monad-logger: 1.3.1 339 | monad-loops: 0.5.0 340 | monad-unlift: 1.0.1 341 | monoid-extras: 0.0.1 342 | monoidal: 0.16.0 343 | morello: 0.4.0 344 | mote: 3.0.0 345 | motsunabe: 2.0.0 346 | mvc: 0.0.1 347 | mysql: 6.0.1 348 | n3: 0.1.0 349 | nano-id: 1.1.0 350 | nanoid: 0.1.0 351 | naturals: 3.0.0 352 | nested-functor: 0.2.1 353 | newtype: 5.0.0 354 | nextjs: 0.1.1 355 | nextui: 0.2.0 356 | node-buffer: 9.0.0 357 | node-child-process: 11.1.0 358 | node-event-emitter: 3.0.0 359 | node-execa: 5.0.0 360 | node-fs: 9.1.0 361 | node-glob-basic: 1.3.0 362 | node-http: 9.1.0 363 | node-http2: 1.1.1 364 | node-human-signals: 1.0.0 365 | node-net: 5.1.0 366 | node-os: 5.1.0 367 | node-path: 5.0.0 368 | node-process: 11.2.0 369 | node-readline: 8.1.0 370 | node-sqlite3: 8.0.0 371 | node-streams: 9.0.0 372 | node-tls: 0.3.1 373 | node-url: 7.0.1 374 | node-zlib: 0.4.0 375 | nonempty: 7.0.0 376 | now: 6.0.0 377 | npm-package-json: 2.0.0 378 | nullable: 6.0.0 379 | numberfield: 0.1.0 380 | numbers: 9.0.1 381 | oak: 3.1.1 382 | oak-debug: 1.2.2 383 | object-maps: 0.3.0 384 | ocarina: 1.5.4 385 | open-folds: 6.3.0 386 | open-memoize: 6.1.0 387 | open-pairing: 6.1.0 388 | options: 7.0.0 389 | optparse: 5.0.1 390 | ordered-collections: 3.2.0 391 | ordered-set: 0.4.0 392 | orders: 6.0.0 393 | owoify: 1.2.0 394 | pairs: 9.0.1 395 | parallel: 7.0.0 396 | parsing: 10.2.0 397 | parsing-dataview: 3.2.4 398 | partial: 4.0.0 399 | pathy: 9.0.0 400 | pha: 0.13.0 401 | phaser: 0.7.0 402 | phylio: 1.1.2 403 | pipes: 8.0.0 404 | pirates-charm: 0.0.1 405 | pmock: 0.9.0 406 | point-free: 1.0.0 407 | pointed-list: 0.5.1 408 | polymorphic-vectors: 4.0.0 409 | posix-types: 6.0.0 410 | postgresql: 1.5.1 411 | precise: 6.0.0 412 | precise-datetime: 7.0.0 413 | prelude: 6.0.1 414 | prettier-printer: 3.0.0 415 | profunctor: 6.0.1 416 | profunctor-lenses: 8.0.0 417 | protobuf: 4.3.0 418 | psa-utils: 8.0.0 419 | psci-support: 6.0.0 420 | punycode: 1.0.0 421 | qualified-do: 2.2.0 422 | quantities: 12.2.0 423 | quickcheck: 8.0.1 424 | quickcheck-combinators: 0.1.3 425 | quickcheck-laws: 7.0.0 426 | quickcheck-utf8: 0.0.0 427 | random: 6.0.0 428 | rationals: 6.0.0 429 | rdf: 0.1.0 430 | react: 11.0.0 431 | react-aria: 0.2.0 432 | react-basic: 17.0.0 433 | react-basic-classic: 3.0.0 434 | react-basic-dnd: 10.1.0 435 | react-basic-dom: 6.1.0 436 | react-basic-emotion: 7.1.0 437 | react-basic-hooks: 8.2.0 438 | react-basic-storybook: 2.0.0 439 | react-dom: 8.0.0 440 | react-halo: 3.0.0 441 | react-icons: 1.1.5 442 | react-markdown: 0.1.0 443 | react-testing-library: 4.0.1 444 | react-virtuoso: 1.0.0 445 | reactix: 0.6.0 446 | read: 1.0.1 447 | recharts: 1.1.0 448 | record: 4.0.0 449 | record-extra: 5.0.1 450 | record-ptional-fields: 0.1.2 451 | record-studio: 1.0.4 452 | refs: 6.0.0 453 | remotedata: 5.0.1 454 | resize-observer: 1.0.0 455 | resource: 2.0.1 456 | resourcet: 1.0.0 457 | result: 1.0.3 458 | return: 0.2.0 459 | ring-modules: 5.0.1 460 | rito: 0.3.4 461 | rough-notation: 1.0.2 462 | routing: 11.0.0 463 | routing-duplex: 0.7.0 464 | run: 5.0.0 465 | safe-coerce: 2.0.0 466 | safely: 4.0.1 467 | school-of-music: 1.3.0 468 | selection-foldable: 0.2.0 469 | selective-functors: 1.0.1 470 | semirings: 7.0.0 471 | signal: 13.0.0 472 | simple-emitter: 3.0.1 473 | simple-i18n: 2.0.1 474 | simple-json: 9.0.0 475 | simple-json-generics: 0.2.1 476 | simple-ulid: 3.0.0 477 | sized-matrices: 1.0.0 478 | sized-vectors: 5.0.2 479 | slug: 3.0.8 480 | small-ffi: 4.0.1 481 | soundfonts: 4.1.0 482 | sparse-matrices: 1.3.0 483 | sparse-polynomials: 2.0.5 484 | spec: 7.6.0 485 | spec-mocha: 5.1.0 486 | spec-quickcheck: 5.0.0 487 | splitmix: 2.1.0 488 | ssrs: 1.0.0 489 | st: 6.2.0 490 | statistics: 0.3.2 491 | strictlypositiveint: 1.0.1 492 | string-parsers: 8.0.0 493 | strings: 6.0.1 494 | strings-extra: 4.0.0 495 | stringutils: 0.0.12 496 | substitute: 0.2.3 497 | supply: 0.2.0 498 | svg-parser: 3.0.0 499 | systemd-journald: 0.3.0 500 | tagged: 4.0.2 501 | tailrec: 6.1.0 502 | tecton: 0.2.1 503 | tecton-halogen: 0.2.0 504 | test-unit: 17.0.0 505 | thermite: 6.3.1 506 | thermite-dom: 0.3.1 507 | these: 6.0.0 508 | toestand: 0.9.0 509 | transformation-matrix: 1.0.1 510 | transformers: 6.0.0 511 | tree-rose: 4.0.2 512 | ts-bridge: 4.0.0 513 | tuples: 7.0.0 514 | two-or-more: 1.0.0 515 | type-equality: 4.0.1 516 | typedenv: 2.0.1 517 | typelevel: 6.0.0 518 | typelevel-lists: 2.1.0 519 | typelevel-peano: 1.0.1 520 | typelevel-prelude: 7.0.0 521 | typelevel-regex: 0.0.3 522 | typelevel-rows: 0.1.0 523 | typisch: 0.4.0 524 | uint: 7.0.0 525 | ulid: 3.0.1 526 | uncurried-transformers: 1.1.0 527 | undefined: 2.0.0 528 | undefined-is-not-a-problem: 1.1.0 529 | unfoldable: 6.0.0 530 | unicode: 6.0.0 531 | unique: 0.6.1 532 | unlift: 1.0.1 533 | unordered-collections: 3.1.0 534 | unsafe-coerce: 6.0.0 535 | unsafe-reference: 5.0.0 536 | untagged-to-tagged: 0.1.4 537 | untagged-union: 1.0.0 538 | uri: 9.0.0 539 | uuid: 9.0.0 540 | uuidv4: 1.0.0 541 | validation: 6.0.0 542 | variant: 8.0.0 543 | variant-encodings: 2.0.0 544 | vectorfield: 1.0.1 545 | vectors: 2.1.0 546 | versions: 7.0.0 547 | visx: 0.0.2 548 | web-clipboard: 5.0.0 549 | web-cssom: 2.0.0 550 | web-cssom-view: 0.1.0 551 | web-dom: 6.0.0 552 | web-dom-parser: 8.0.0 553 | web-dom-xpath: 3.0.0 554 | web-encoding: 3.0.0 555 | web-events: 4.0.0 556 | web-fetch: 4.0.1 557 | web-file: 4.0.0 558 | web-geometry: 0.1.0 559 | web-html: 4.1.0 560 | web-pointerevents: 2.0.0 561 | web-proletarian: 1.0.0 562 | web-promise: 3.2.0 563 | web-resize-observer: 2.1.0 564 | web-router: 1.0.0 565 | web-socket: 4.0.0 566 | web-storage: 5.0.0 567 | web-streams: 4.0.0 568 | web-touchevents: 4.0.0 569 | web-uievents: 5.0.0 570 | web-url: 2.0.0 571 | web-workers: 1.1.0 572 | web-xhr: 5.0.1 573 | webextension-polyfill: 0.1.0 574 | webgpu: 0.0.1 575 | which: 2.0.0 576 | xterm: 1.0.0 577 | yoga-fetch: 1.0.1 578 | yoga-json: 5.1.0 579 | yoga-om: 0.1.0 580 | yoga-postgres: 6.0.0 581 | yoga-tree: 1.0.0 582 | z3: 0.0.2 583 | zipperarray: 2.0.0 584 | extra_packages: 585 | psa-utils: 586 | git: https://github.com/natefaubion/purescript-psa-utils.git 587 | ref: master 588 | packages: 589 | aff: 590 | type: registry 591 | version: 7.1.0 592 | integrity: sha256-7hOC6uQO9XBAI5FD8F33ChLjFAiZVfd4BJMqlMh7TNU= 593 | dependencies: 594 | - arrays 595 | - bifunctors 596 | - control 597 | - datetime 598 | - effect 599 | - either 600 | - exceptions 601 | - foldable-traversable 602 | - functions 603 | - maybe 604 | - newtype 605 | - parallel 606 | - prelude 607 | - refs 608 | - tailrec 609 | - transformers 610 | - unsafe-coerce 611 | ansi: 612 | type: registry 613 | version: 7.0.0 614 | integrity: sha256-ZMB6HD+q9CXvn9fRCmJ8dvuDrOVHcjombL3oNOerVnE= 615 | dependencies: 616 | - foldable-traversable 617 | - lists 618 | - strings 619 | argonaut-codecs: 620 | type: registry 621 | version: 9.1.0 622 | integrity: sha256-N6efXByUeg848ompEqJfVvZuZPfdRYDGlTDFn0G0Oh8= 623 | dependencies: 624 | - argonaut-core 625 | - arrays 626 | - effect 627 | - foreign-object 628 | - identity 629 | - integers 630 | - maybe 631 | - nonempty 632 | - ordered-collections 633 | - prelude 634 | - record 635 | argonaut-core: 636 | type: registry 637 | version: 7.0.0 638 | integrity: sha256-RC82GfAjItydxrO24cdX373KHVZiLqybu19b5X8u7B4= 639 | dependencies: 640 | - arrays 641 | - control 642 | - either 643 | - foreign-object 644 | - functions 645 | - gen 646 | - maybe 647 | - nonempty 648 | - prelude 649 | - strings 650 | - tailrec 651 | arraybuffer-types: 652 | type: registry 653 | version: 3.0.2 654 | integrity: sha256-mQKokysYVkooS4uXbO+yovmV/s8b138Ws3zQvOwIHRA= 655 | dependencies: [] 656 | arrays: 657 | type: registry 658 | version: 7.3.0 659 | integrity: sha256-tmcklBlc/muUtUfr9RapdCPwnlQeB3aSrC4dK85gQlc= 660 | dependencies: 661 | - bifunctors 662 | - control 663 | - foldable-traversable 664 | - functions 665 | - maybe 666 | - nonempty 667 | - partial 668 | - prelude 669 | - safe-coerce 670 | - st 671 | - tailrec 672 | - tuples 673 | - unfoldable 674 | - unsafe-coerce 675 | bifunctors: 676 | type: registry 677 | version: 6.0.0 678 | integrity: sha256-/gZwC9YhNxZNQpnHa5BIYerCGM2jeX9ukZiEvYxm5Nw= 679 | dependencies: 680 | - const 681 | - either 682 | - newtype 683 | - prelude 684 | - tuples 685 | console: 686 | type: registry 687 | version: 6.1.0 688 | integrity: sha256-CxmAzjgyuGDmt9FZW51VhV6rBPwR6o0YeKUzA9rSzcM= 689 | dependencies: 690 | - effect 691 | - prelude 692 | const: 693 | type: registry 694 | version: 6.0.0 695 | integrity: sha256-tNrxDW8D8H4jdHE2HiPzpLy08zkzJMmGHdRqt5BQuTc= 696 | dependencies: 697 | - invariant 698 | - newtype 699 | - prelude 700 | contravariant: 701 | type: registry 702 | version: 6.0.0 703 | integrity: sha256-TP+ooAp3vvmdjfQsQJSichF5B4BPDHp3wAJoWchip6c= 704 | dependencies: 705 | - const 706 | - either 707 | - newtype 708 | - prelude 709 | - tuples 710 | control: 711 | type: registry 712 | version: 6.0.0 713 | integrity: sha256-sH7Pg9E96JCPF9PIA6oQ8+BjTyO/BH1ZuE/bOcyj4Jk= 714 | dependencies: 715 | - newtype 716 | - prelude 717 | datetime: 718 | type: registry 719 | version: 6.1.0 720 | integrity: sha256-g/5X5BBegQWLpI9IWD+sY6mcaYpzzlW5lz5NBzaMtyI= 721 | dependencies: 722 | - bifunctors 723 | - control 724 | - either 725 | - enums 726 | - foldable-traversable 727 | - functions 728 | - gen 729 | - integers 730 | - lists 731 | - maybe 732 | - newtype 733 | - numbers 734 | - ordered-collections 735 | - partial 736 | - prelude 737 | - tuples 738 | debug: 739 | type: registry 740 | version: 6.0.2 741 | integrity: sha256-vmkYFuXYuELBzeauvgHG6E6Kf/Hp1dAnxwE9ByHfwSg= 742 | dependencies: 743 | - functions 744 | - prelude 745 | distributive: 746 | type: registry 747 | version: 6.0.0 748 | integrity: sha256-HTDdmEnzigMl+02SJB88j+gAXDx9VKsbvR4MJGDPbOQ= 749 | dependencies: 750 | - identity 751 | - newtype 752 | - prelude 753 | - tuples 754 | - type-equality 755 | effect: 756 | type: registry 757 | version: 4.0.0 758 | integrity: sha256-eBtZu+HZcMa5HilvI6kaDyVX3ji8p0W9MGKy2K4T6+M= 759 | dependencies: 760 | - prelude 761 | either: 762 | type: registry 763 | version: 6.1.0 764 | integrity: sha256-6hgTPisnMWVwQivOu2PKYcH8uqjEOOqDyaDQVUchTpY= 765 | dependencies: 766 | - control 767 | - invariant 768 | - maybe 769 | - prelude 770 | enums: 771 | type: registry 772 | version: 6.0.1 773 | integrity: sha256-HWaD73JFLorc4A6trKIRUeDMdzE+GpkJaEOM1nTNkC8= 774 | dependencies: 775 | - control 776 | - either 777 | - gen 778 | - maybe 779 | - newtype 780 | - nonempty 781 | - partial 782 | - prelude 783 | - tuples 784 | - unfoldable 785 | exceptions: 786 | type: registry 787 | version: 6.0.0 788 | integrity: sha256-y/xTAEIZIARCE+50/u1di0ncebJ+CIwNOLswyOWzMTw= 789 | dependencies: 790 | - effect 791 | - either 792 | - maybe 793 | - prelude 794 | exists: 795 | type: registry 796 | version: 6.0.0 797 | integrity: sha256-A0JQHpTfo1dNOj9U5/Fd3xndlRSE0g2IQWOGor2yXn8= 798 | dependencies: 799 | - unsafe-coerce 800 | foldable-traversable: 801 | type: registry 802 | version: 6.0.0 803 | integrity: sha256-fLeqRYM4jUrZD5H4WqcwUgzU7XfYkzO4zhgtNc3jcWM= 804 | dependencies: 805 | - bifunctors 806 | - const 807 | - control 808 | - either 809 | - functors 810 | - identity 811 | - maybe 812 | - newtype 813 | - orders 814 | - prelude 815 | - tuples 816 | foreign: 817 | type: registry 818 | version: 7.0.0 819 | integrity: sha256-1ORiqoS3HW+qfwSZAppHPWy4/6AQysxZ2t29jcdUMNA= 820 | dependencies: 821 | - either 822 | - functions 823 | - identity 824 | - integers 825 | - lists 826 | - maybe 827 | - prelude 828 | - strings 829 | - transformers 830 | foreign-object: 831 | type: registry 832 | version: 4.1.0 833 | integrity: sha256-q24okj6mT+yGHYQ+ei/pYPj5ih6sTbu7eDv/WU56JVo= 834 | dependencies: 835 | - arrays 836 | - foldable-traversable 837 | - functions 838 | - gen 839 | - lists 840 | - maybe 841 | - prelude 842 | - st 843 | - tailrec 844 | - tuples 845 | - typelevel-prelude 846 | - unfoldable 847 | functions: 848 | type: registry 849 | version: 6.0.0 850 | integrity: sha256-adMyJNEnhGde2unHHAP79gPtlNjNqzgLB8arEOn9hLI= 851 | dependencies: 852 | - prelude 853 | functors: 854 | type: registry 855 | version: 5.0.0 856 | integrity: sha256-zfPWWYisbD84MqwpJSZFlvM6v86McM68ob8p9s27ywU= 857 | dependencies: 858 | - bifunctors 859 | - const 860 | - contravariant 861 | - control 862 | - distributive 863 | - either 864 | - invariant 865 | - maybe 866 | - newtype 867 | - prelude 868 | - profunctor 869 | - tuples 870 | - unsafe-coerce 871 | gen: 872 | type: registry 873 | version: 4.0.0 874 | integrity: sha256-f7yzAXWwr+xnaqEOcvyO3ezKdoes8+WXWdXIHDBCAPI= 875 | dependencies: 876 | - either 877 | - foldable-traversable 878 | - identity 879 | - maybe 880 | - newtype 881 | - nonempty 882 | - prelude 883 | - tailrec 884 | - tuples 885 | - unfoldable 886 | identity: 887 | type: registry 888 | version: 6.0.0 889 | integrity: sha256-4wY0XZbAksjY6UAg99WkuKyJlQlWAfTi2ssadH0wVMY= 890 | dependencies: 891 | - control 892 | - invariant 893 | - newtype 894 | - prelude 895 | integers: 896 | type: registry 897 | version: 6.0.0 898 | integrity: sha256-sf+sK26R1hzwl3NhXR7WAu9zCDjQnfoXwcyGoseX158= 899 | dependencies: 900 | - maybe 901 | - numbers 902 | - prelude 903 | invariant: 904 | type: registry 905 | version: 6.0.0 906 | integrity: sha256-RGWWyYrz0Hs1KjPDA+87Kia67ZFBhfJ5lMGOMCEFoLo= 907 | dependencies: 908 | - control 909 | - prelude 910 | js-date: 911 | type: registry 912 | version: 8.0.0 913 | integrity: sha256-6TVF4DWg5JL+jRAsoMssYw8rgOVALMUHT1CuNZt8NRo= 914 | dependencies: 915 | - datetime 916 | - effect 917 | - exceptions 918 | - foreign 919 | - integers 920 | - now 921 | lazy: 922 | type: registry 923 | version: 6.0.0 924 | integrity: sha256-lMsfFOnlqfe4KzRRiW8ot5ge6HtcU3Eyh2XkXcP5IgU= 925 | dependencies: 926 | - control 927 | - foldable-traversable 928 | - invariant 929 | - prelude 930 | lists: 931 | type: registry 932 | version: 7.0.0 933 | integrity: sha256-EKF15qYqucuXP2lT/xPxhqy58f0FFT6KHdIB/yBOayI= 934 | dependencies: 935 | - bifunctors 936 | - control 937 | - foldable-traversable 938 | - lazy 939 | - maybe 940 | - newtype 941 | - nonempty 942 | - partial 943 | - prelude 944 | - tailrec 945 | - tuples 946 | - unfoldable 947 | maybe: 948 | type: registry 949 | version: 6.0.0 950 | integrity: sha256-5cCIb0wPwbat2PRkQhUeZO0jcAmf8jCt2qE0wbC3v2Q= 951 | dependencies: 952 | - control 953 | - invariant 954 | - newtype 955 | - prelude 956 | newtype: 957 | type: registry 958 | version: 5.0.0 959 | integrity: sha256-gdrQu8oGe9eZE6L3wOI8ql/igOg+zEGB5ITh2g+uttw= 960 | dependencies: 961 | - prelude 962 | - safe-coerce 963 | node-buffer: 964 | type: registry 965 | version: 9.0.0 966 | integrity: sha256-PWE2DJ5ruBLCmeA/fUiuySEFmUJ/VuRfyrnCuVZBlu4= 967 | dependencies: 968 | - arraybuffer-types 969 | - effect 970 | - maybe 971 | - nullable 972 | - st 973 | - unsafe-coerce 974 | node-child-process: 975 | type: registry 976 | version: 11.1.0 977 | integrity: sha256-vioMNgk8p+CGwlb6T3I3TIir27el85Yg4satLE/I89w= 978 | dependencies: 979 | - exceptions 980 | - foreign 981 | - foreign-object 982 | - functions 983 | - node-event-emitter 984 | - node-fs 985 | - node-os 986 | - node-streams 987 | - nullable 988 | - posix-types 989 | - unsafe-coerce 990 | node-event-emitter: 991 | type: registry 992 | version: 3.0.0 993 | integrity: sha256-Qw0MjsT4xRH2j2i4K8JmRjcMKnH5z1Cw39t00q4LE4w= 994 | dependencies: 995 | - effect 996 | - either 997 | - functions 998 | - maybe 999 | - nullable 1000 | - prelude 1001 | - unsafe-coerce 1002 | node-fs: 1003 | type: registry 1004 | version: 9.1.0 1005 | integrity: sha256-TzhvGdrwcM0bazDvrWSqh+M/H8GKYf1Na6aGm2Qg4+c= 1006 | dependencies: 1007 | - datetime 1008 | - effect 1009 | - either 1010 | - enums 1011 | - exceptions 1012 | - functions 1013 | - integers 1014 | - js-date 1015 | - maybe 1016 | - node-buffer 1017 | - node-path 1018 | - node-streams 1019 | - nullable 1020 | - partial 1021 | - prelude 1022 | - strings 1023 | - unsafe-coerce 1024 | node-os: 1025 | type: registry 1026 | version: 5.1.0 1027 | integrity: sha256-K3gcu9AXanN1+qtk1900+Fi+CuO0s3/H/RMNRNgIzso= 1028 | dependencies: 1029 | - arrays 1030 | - bifunctors 1031 | - console 1032 | - control 1033 | - datetime 1034 | - effect 1035 | - either 1036 | - exceptions 1037 | - foldable-traversable 1038 | - foreign 1039 | - foreign-object 1040 | - functions 1041 | - maybe 1042 | - node-buffer 1043 | - nullable 1044 | - partial 1045 | - posix-types 1046 | - prelude 1047 | - unsafe-coerce 1048 | node-path: 1049 | type: registry 1050 | version: 5.0.0 1051 | integrity: sha256-pd82nQ+2l5UThzaxPdKttgDt7xlsgIDLpPG0yxDEdyE= 1052 | dependencies: 1053 | - effect 1054 | node-process: 1055 | type: registry 1056 | version: 11.2.0 1057 | integrity: sha256-+2MQDYChjGbVbapCyJtuWYwD41jk+BntF/kcOTKBMVs= 1058 | dependencies: 1059 | - effect 1060 | - foreign 1061 | - foreign-object 1062 | - maybe 1063 | - node-event-emitter 1064 | - node-streams 1065 | - posix-types 1066 | - prelude 1067 | - unsafe-coerce 1068 | node-streams: 1069 | type: registry 1070 | version: 9.0.0 1071 | integrity: sha256-2n6dq7YWleTDmD1Kur/ul7Cn08IvWrScgPf+0PgX2TQ= 1072 | dependencies: 1073 | - aff 1074 | - effect 1075 | - either 1076 | - exceptions 1077 | - node-buffer 1078 | - node-event-emitter 1079 | - nullable 1080 | - prelude 1081 | nonempty: 1082 | type: registry 1083 | version: 7.0.0 1084 | integrity: sha256-54ablJZUHGvvlTJzi3oXyPCuvY6zsrWJuH/dMJ/MFLs= 1085 | dependencies: 1086 | - control 1087 | - foldable-traversable 1088 | - maybe 1089 | - prelude 1090 | - tuples 1091 | - unfoldable 1092 | now: 1093 | type: registry 1094 | version: 6.0.0 1095 | integrity: sha256-xZ7x37ZMREfs6GCDw/h+FaKHV/3sPWmtqBZRGTxybQY= 1096 | dependencies: 1097 | - datetime 1098 | - effect 1099 | nullable: 1100 | type: registry 1101 | version: 6.0.0 1102 | integrity: sha256-yiGBVl3AD+Guy4kNWWeN+zl1gCiJK+oeIFtZtPCw4+o= 1103 | dependencies: 1104 | - effect 1105 | - functions 1106 | - maybe 1107 | numbers: 1108 | type: registry 1109 | version: 9.0.1 1110 | integrity: sha256-/9M6aeMDBdB4cwYDeJvLFprAHZ49EbtKQLIJsneXLIk= 1111 | dependencies: 1112 | - functions 1113 | - maybe 1114 | ordered-collections: 1115 | type: registry 1116 | version: 3.2.0 1117 | integrity: sha256-o9jqsj5rpJmMdoe/zyufWHFjYYFTTsJpgcuCnqCO6PM= 1118 | dependencies: 1119 | - arrays 1120 | - foldable-traversable 1121 | - gen 1122 | - lists 1123 | - maybe 1124 | - partial 1125 | - prelude 1126 | - st 1127 | - tailrec 1128 | - tuples 1129 | - unfoldable 1130 | orders: 1131 | type: registry 1132 | version: 6.0.0 1133 | integrity: sha256-nBA0g3/ai0euH8q9pSbGqk53W2q6agm/dECZTHcoink= 1134 | dependencies: 1135 | - newtype 1136 | - prelude 1137 | parallel: 1138 | type: registry 1139 | version: 7.0.0 1140 | integrity: sha256-gUC9i4Txnx9K9RcMLsjujbwZz6BB1bnE2MLvw4GIw5o= 1141 | dependencies: 1142 | - control 1143 | - effect 1144 | - either 1145 | - foldable-traversable 1146 | - functors 1147 | - maybe 1148 | - newtype 1149 | - prelude 1150 | - profunctor 1151 | - refs 1152 | - transformers 1153 | parsing: 1154 | type: registry 1155 | version: 10.2.0 1156 | integrity: sha256-ZDIdMFAKkst57x6BVa1aUWJnS8smoZnXsZ339Aq1mPA= 1157 | dependencies: 1158 | - arrays 1159 | - control 1160 | - effect 1161 | - either 1162 | - enums 1163 | - foldable-traversable 1164 | - functions 1165 | - identity 1166 | - integers 1167 | - lazy 1168 | - lists 1169 | - maybe 1170 | - newtype 1171 | - nullable 1172 | - numbers 1173 | - partial 1174 | - prelude 1175 | - st 1176 | - strings 1177 | - tailrec 1178 | - transformers 1179 | - tuples 1180 | - unfoldable 1181 | - unicode 1182 | - unsafe-coerce 1183 | partial: 1184 | type: registry 1185 | version: 4.0.0 1186 | integrity: sha256-fwXerld6Xw1VkReh8yeQsdtLVrjfGiVuC5bA1Wyo/J4= 1187 | dependencies: [] 1188 | posix-types: 1189 | type: registry 1190 | version: 6.0.0 1191 | integrity: sha256-ZfFz8RR1lee/o/Prccyeut3Q+9tYd08mlR72sIh6GzA= 1192 | dependencies: 1193 | - maybe 1194 | - prelude 1195 | prelude: 1196 | type: registry 1197 | version: 6.0.1 1198 | integrity: sha256-o8p6SLYmVPqzXZhQFd2hGAWEwBoXl1swxLG/scpJ0V0= 1199 | dependencies: [] 1200 | profunctor: 1201 | type: registry 1202 | version: 6.0.1 1203 | integrity: sha256-E58hSYdJvF2Qjf9dnWLPlJKh2Z2fLfFLkQoYi16vsFk= 1204 | dependencies: 1205 | - control 1206 | - distributive 1207 | - either 1208 | - exists 1209 | - invariant 1210 | - newtype 1211 | - prelude 1212 | - tuples 1213 | psa-utils: 1214 | type: git 1215 | url: https://github.com/natefaubion/purescript-psa-utils.git 1216 | rev: 2b801ed2af4d7fd035dc967324f2391ad2b1a0cf 1217 | dependencies: 1218 | - ansi 1219 | - argonaut-codecs 1220 | - argonaut-core 1221 | - arrays 1222 | - console 1223 | - control 1224 | - effect 1225 | - either 1226 | - foldable-traversable 1227 | - maybe 1228 | - node-path 1229 | - ordered-collections 1230 | - prelude 1231 | - strings 1232 | - tuples 1233 | - unsafe-coerce 1234 | record: 1235 | type: registry 1236 | version: 4.0.0 1237 | integrity: sha256-Za5U85bTRJEfGK5Sk4hM41oXy84YQI0I8TL3WUn1Qzg= 1238 | dependencies: 1239 | - functions 1240 | - prelude 1241 | - unsafe-coerce 1242 | refs: 1243 | type: registry 1244 | version: 6.0.0 1245 | integrity: sha256-Vgwne7jIbD3ZMoLNNETLT8Litw6lIYo3MfYNdtYWj9s= 1246 | dependencies: 1247 | - effect 1248 | - prelude 1249 | safe-coerce: 1250 | type: registry 1251 | version: 2.0.0 1252 | integrity: sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU= 1253 | dependencies: 1254 | - unsafe-coerce 1255 | st: 1256 | type: registry 1257 | version: 6.2.0 1258 | integrity: sha256-z9X0WsOUlPwNx9GlCC+YccCyz8MejC8Wb0C4+9fiBRY= 1259 | dependencies: 1260 | - partial 1261 | - prelude 1262 | - tailrec 1263 | - unsafe-coerce 1264 | strings: 1265 | type: registry 1266 | version: 6.0.1 1267 | integrity: sha256-WssD3DbX4OPzxSdjvRMX0yvc9+pS7n5gyPv5I2Trb7k= 1268 | dependencies: 1269 | - arrays 1270 | - control 1271 | - either 1272 | - enums 1273 | - foldable-traversable 1274 | - gen 1275 | - integers 1276 | - maybe 1277 | - newtype 1278 | - nonempty 1279 | - partial 1280 | - prelude 1281 | - tailrec 1282 | - tuples 1283 | - unfoldable 1284 | - unsafe-coerce 1285 | tailrec: 1286 | type: registry 1287 | version: 6.1.0 1288 | integrity: sha256-Xx19ECVDRrDWpz9D2GxQHHV89vd61dnXxQm0IcYQHGk= 1289 | dependencies: 1290 | - bifunctors 1291 | - effect 1292 | - either 1293 | - identity 1294 | - maybe 1295 | - partial 1296 | - prelude 1297 | - refs 1298 | transformers: 1299 | type: registry 1300 | version: 6.0.0 1301 | integrity: sha256-Pzw40HjthX77tdPAYzjx43LK3X5Bb7ZspYAp27wksFA= 1302 | dependencies: 1303 | - control 1304 | - distributive 1305 | - effect 1306 | - either 1307 | - exceptions 1308 | - foldable-traversable 1309 | - identity 1310 | - lazy 1311 | - maybe 1312 | - newtype 1313 | - prelude 1314 | - tailrec 1315 | - tuples 1316 | - unfoldable 1317 | tuples: 1318 | type: registry 1319 | version: 7.0.0 1320 | integrity: sha256-1rXgTomes9105BjgXqIw0FL6Fz1lqqUTLWOumhWec1M= 1321 | dependencies: 1322 | - control 1323 | - invariant 1324 | - prelude 1325 | type-equality: 1326 | type: registry 1327 | version: 4.0.1 1328 | integrity: sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw= 1329 | dependencies: [] 1330 | typelevel-prelude: 1331 | type: registry 1332 | version: 7.0.0 1333 | integrity: sha256-uFF2ph+vHcQpfPuPf2a3ukJDFmLhApmkpTMviHIWgJM= 1334 | dependencies: 1335 | - prelude 1336 | - type-equality 1337 | unfoldable: 1338 | type: registry 1339 | version: 6.0.0 1340 | integrity: sha256-JtikvJdktRap7vr/K4ITlxUX1QexpnqBq0G/InLr6eg= 1341 | dependencies: 1342 | - foldable-traversable 1343 | - maybe 1344 | - partial 1345 | - prelude 1346 | - tuples 1347 | unicode: 1348 | type: registry 1349 | version: 6.0.0 1350 | integrity: sha256-QJnTVZpmihEAUiMeYrfkusVoziJWp2hJsgi9bMQLue8= 1351 | dependencies: 1352 | - foldable-traversable 1353 | - maybe 1354 | - strings 1355 | unsafe-coerce: 1356 | type: registry 1357 | version: 6.0.0 1358 | integrity: sha256-IqIYW4Vkevn8sI+6aUwRGvd87tVL36BBeOr0cGAE7t0= 1359 | dependencies: [] 1360 | versions: 1361 | type: registry 1362 | version: 7.0.0 1363 | integrity: sha256-+7qxEsCbSl8JDsOsGQO/XxCfcCYak13lJHEXmCzUjIs= 1364 | dependencies: 1365 | - control 1366 | - either 1367 | - foldable-traversable 1368 | - functions 1369 | - integers 1370 | - lists 1371 | - maybe 1372 | - orders 1373 | - parsing 1374 | - partial 1375 | - strings 1376 | -------------------------------------------------------------------------------- /spago.yaml: -------------------------------------------------------------------------------- 1 | package: 2 | name: psa 3 | dependencies: 4 | - console 5 | - effect 6 | - prelude 7 | - node-fs 8 | - node-buffer 9 | - node-child-process 10 | - node-process 11 | - node-streams 12 | - st 13 | - foreign-object 14 | - now 15 | - datetime 16 | - psa-utils 17 | - refs 18 | - ordered-collections 19 | - versions 20 | - debug 21 | workspace: 22 | packageSet: 23 | registry: 50.13.0 24 | extraPackages: 25 | psa-utils: 26 | git: https://github.com/natefaubion/purescript-psa-utils.git 27 | ref: master 28 | 29 | -------------------------------------------------------------------------------- /src/Main.js: -------------------------------------------------------------------------------- 1 | export const version = "v0.9.0"; 2 | -------------------------------------------------------------------------------- /src/Main.purs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Prelude 4 | 5 | import Data.Argonaut.Core (stringify) 6 | import Data.Argonaut.Decode (decodeJson, printJsonDecodeError) 7 | import Data.Argonaut.Encode (encodeJson) 8 | import Data.Argonaut.Parser (jsonParser) 9 | import Data.Array as Array 10 | import Data.Bifunctor (lmap) 11 | import Data.DateTime (DateTime) 12 | import Data.DateTime.Instant (toDateTime) 13 | import Data.Either (Either(..)) 14 | import Data.Foldable (fold, foldr, for_, traverse_) 15 | import Data.Maybe (Maybe(..), maybe) 16 | import Data.Nullable (toMaybe) 17 | import Data.Set as Set 18 | import Data.String as Str 19 | import Data.Traversable (traverse) 20 | import Data.Tuple (Tuple(..)) 21 | import Data.Version as Version 22 | import Effect (Effect) 23 | import Effect.Console as Console 24 | import Effect.Exception (catchException, throw, throwException) 25 | import Effect.Now (now) 26 | import Effect.Ref as Ref 27 | import Foreign.Object as FO 28 | import Node.Buffer as Buffer 29 | import Node.ChildProcess.Types (Exit(..), pipe, shareStream) 30 | import Node.Encoding (Encoding(..)) 31 | import Node.Encoding as Encoding 32 | import Node.Errors.SystemError (code, toError) 33 | import Node.EventEmitter as H 34 | import Node.FS.Stats as Stats 35 | import Node.FS.Sync as File 36 | import Node.Path as Path 37 | import Node.Platform (Platform(Win32)) 38 | import Node.Process (stderr, stdout) 39 | import Node.Process as Process 40 | import Node.Stream (dataH) 41 | import Node.UnsafeChildProcess.Safe (errorH, exitH) as UnsafeChild 42 | import Node.UnsafeChildProcess.Unsafe (spawn', unsafeStderr, unsafeStdout) as UnsafeChild 43 | import Psa (PsaOptions, StatVerbosity(..), parsePsaResult, parsePsaError, encodePsaError, output) 44 | import Psa.Printer.Default as DefaultPrinter 45 | import Psa.Printer.Json as JsonPrinter 46 | 47 | foreign import version :: String 48 | 49 | defaultOptions :: PsaOptions 50 | defaultOptions = 51 | { ansi: true 52 | , censorWarnings: false 53 | , censorLib: false 54 | , censorSrc: false 55 | , censorCodes: Set.empty 56 | , filterCodes: Set.empty 57 | , statVerbosity: CompactStats 58 | , libDirs: [] 59 | , strict: false 60 | , cwd: "" 61 | } 62 | 63 | type ParseOptions = 64 | { extra :: Array String 65 | , opts :: PsaOptions 66 | , purs :: String 67 | , showSource :: Boolean 68 | , stash :: Boolean 69 | , stashFile :: String 70 | , jsonErrors :: Boolean 71 | } 72 | 73 | parseOptions 74 | :: PsaOptions 75 | -> Array String 76 | -> Effect ParseOptions 77 | parseOptions opts args = 78 | defaultLibDir <$> 79 | Array.foldM parse 80 | { extra: [] 81 | , purs: "purs" 82 | , showSource: true 83 | , stash: false 84 | , stashFile: ".psa-stash" 85 | , jsonErrors: false 86 | , opts 87 | } 88 | args 89 | where 90 | parse p arg 91 | | arg == "--version" || arg == "-v" = 92 | Console.log version *> Process.exit' 0 93 | 94 | | arg == "--help" || arg == "-h" = 95 | Console.log usage *> Process.exit' 0 96 | 97 | | arg == "--stash" = 98 | pure p { stash = true } 99 | 100 | | arg == "--json-errors" = 101 | pure p { jsonErrors = true } 102 | 103 | | arg == "--no-source" = 104 | pure p { showSource = false } 105 | 106 | | arg == "--no-colors" || arg == "--monochrome" = 107 | pure p { opts = p.opts { ansi = false } } 108 | 109 | | arg == "--verbose-stats" = 110 | pure p { opts = p.opts { statVerbosity = VerboseStats } } 111 | 112 | | arg == "--censor-stats" = 113 | pure p { opts = p.opts { statVerbosity = NoStats } } 114 | 115 | | arg == "--strict" = 116 | pure p { opts = p.opts { strict = true } } 117 | 118 | | arg == "--censor-warnings" = 119 | pure p { opts = p.opts { censorWarnings = true } } 120 | 121 | | arg == "--censor-lib" = 122 | pure p { opts = p.opts { censorLib = true } } 123 | 124 | | arg == "--censor-src" = 125 | pure p { opts = p.opts { censorSrc = true } } 126 | 127 | | isPrefix "--censor-codes=" arg = 128 | pure p { opts = p.opts { censorCodes = foldr Set.insert p.opts.censorCodes (Str.split (Str.Pattern ",") (Str.drop 15 arg)) } } 129 | 130 | | isPrefix "--filter-codes=" arg = 131 | pure p { opts = p.opts { filterCodes = foldr Set.insert p.opts.filterCodes (Str.split (Str.Pattern ",") (Str.drop 15 arg)) } } 132 | 133 | | isPrefix "--is-lib=" arg = 134 | pure p { opts = p.opts { libDirs = Array.snoc p.opts.libDirs (Str.drop 9 arg) } } 135 | 136 | | isPrefix "--purs=" arg = 137 | pure p { purs = Str.drop 7 arg } 138 | 139 | | isPrefix "--stash=" arg = 140 | pure p { stash = true, stashFile = Str.drop 8 arg } 141 | 142 | | otherwise = pure p { extra = Array.snoc p.extra arg } 143 | 144 | isPrefix s str = 145 | case Str.indexOf (Str.Pattern s) str of 146 | Just x | x == 0 -> true 147 | _ -> false 148 | 149 | defaultLibDir x 150 | | Array.length x.opts.libDirs == 0 = 151 | x { opts = x.opts { libDirs = [ "bower_components", ".spago" ] } } 152 | | otherwise = x 153 | 154 | main :: Effect Unit 155 | main = void do 156 | cwd <- Process.cwd 157 | argv <- Array.drop 2 <$> Process.argv 158 | 159 | { extra 160 | , opts 161 | , purs 162 | , showSource 163 | , stash 164 | , stashFile 165 | , jsonErrors 166 | } <- parseOptions (defaultOptions { cwd = cwd }) argv 167 | 168 | libDirs <- traverse (Path.resolve [cwd] >>> map (_ <> Path.sep)) opts.libDirs 169 | let opts' = opts { libDirs = libDirs } 170 | args = Array.cons "compile" $ Array.cons "--json-errors" extra 171 | 172 | stashData <- 173 | if stash 174 | then readStashFile stashFile 175 | else emptyStash 176 | 177 | readPursVersion purs \pursVer -> do 178 | let outputStream = 179 | -- As of 0.14.0, JSON errors/warnings are written to stdout, but 180 | -- beforehand they were written to stderr. 181 | -- 182 | -- We need to use Tuple like this because prerelease versions compare 183 | -- less than normal versions with the same major, minor, and patch 184 | -- numbers according to the semver spec. 185 | if Tuple (Version.major pursVer) (Version.minor pursVer) >= Tuple 0 14 186 | then Stdout 187 | else Stderr 188 | spawn' outputStream purs args \pursResult -> do 189 | for_ (Str.split (Str.Pattern "\n") pursResult.output) \err -> 190 | case jsonParser err >>= (lmap printJsonDecodeError <<< decodeJson) >>= parsePsaResult of 191 | Left _ -> Console.error err 192 | Right out -> do 193 | files <- Ref.new FO.empty 194 | let loadLinesImpl = if showSource then loadLines files else loadNothing 195 | filenames = insertFilenames (insertFilenames Set.empty out.errors) out.warnings 196 | merged <- mergeWarnings filenames stashData.date stashData.stash out.warnings 197 | when stash $ writeStashFile stashFile merged 198 | out' <- output loadLinesImpl opts' out { warnings = merged } 199 | if jsonErrors 200 | then JsonPrinter.print out' 201 | else DefaultPrinter.print opts' out' 202 | if FO.isEmpty out'.stats.allErrors 203 | then Process.exit' pursResult.exitCode 204 | else Process.exit' 1 205 | 206 | where 207 | insertFilenames = foldr \x s -> maybe s (flip Set.insert s) x.filename 208 | loadNothing _ _ = pure Nothing 209 | 210 | spawn' outputStream cmd args onExit = do 211 | let stdio = 212 | case outputStream of 213 | Stdout -> [ pipe, pipe, shareStream stderr ] 214 | Stderr -> [ pipe, shareStream stdout, pipe ] 215 | 216 | child <- UnsafeChild.spawn' cmd args { stdio, detached: false } 217 | buffer <- Ref.new "" 218 | traverse_ (fillBuffer buffer) $ toMaybe case outputStream of 219 | Stdout -> UnsafeChild.unsafeStdout child 220 | Stderr -> UnsafeChild.unsafeStderr child 221 | child # H.on_ UnsafeChild.exitH \status -> 222 | case status of 223 | Normally n -> do 224 | output <- Ref.read buffer 225 | onExit { output, exitCode: n } 226 | BySignal s -> do 227 | Console.error (show s) 228 | Process.exit' 1 229 | child # H.on_ UnsafeChild.errorH (retryWithCmd outputStream cmd args onExit) 230 | 231 | fillBuffer buffer stream = 232 | stream # H.on dataH \chunk -> do 233 | val <- Buffer.toString UTF8 chunk 234 | Ref.modify_ (_ <> val) buffer 235 | 236 | readPursVersion :: String -> (Version.Version -> Effect Unit) -> Effect Unit 237 | readPursVersion purs cb = do 238 | spawn' Stdout purs ["--version"] \{ output } -> do 239 | let verStr = Str.takeWhile (_ /= Str.codePointFromChar ' ') $ Str.trim output 240 | case Version.parseVersion verStr of 241 | Right v -> 242 | cb v 243 | Left _ -> do 244 | throw $ fold 245 | [ "Unable to parse the version from `purs`. (Saw: " 246 | , verStr 247 | , "). Please check that the right executable is on your PATH." 248 | ] 249 | 250 | retryWithCmd outputStream cmd args onExit err 251 | | code err == "ENOENT" = do 252 | -- On windows, if the executable wasn't found, try adding .cmd 253 | if Process.platform == Just Win32 254 | then 255 | case Str.stripSuffix (Str.Pattern ".cmd") cmd of 256 | Nothing -> spawn' outputStream (cmd <> ".cmd") args onExit 257 | Just bareCmd -> throw $ "`" <> bareCmd <> "` executable not found. (nor `" <> cmd <> "`)" 258 | else 259 | throw $ "`" <> cmd <> "` executable not found." 260 | | otherwise = 261 | throwException (toError err) 262 | 263 | isEmptySpan filename pos = 264 | filename == "" || 265 | pos.startLine == 0 && pos.endLine == 0 && 266 | pos.startColumn == 0 && pos.endColumn == 0 267 | 268 | -- TODO: Handle exceptions 269 | loadLines files filename pos 270 | | isEmptySpan filename pos = pure Nothing 271 | | otherwise = catchException (const (pure Nothing)) do 272 | cache <- FO.lookup filename <$> Ref.read files 273 | contents <- 274 | case cache of 275 | Just lines -> pure lines 276 | Nothing -> do 277 | lines <- Str.split (Str.Pattern "\n") <$> File.readTextFile Encoding.UTF8 filename 278 | Ref.modify_ (FO.insert filename lines) files 279 | pure lines 280 | let source = Array.slice (pos.startLine - 1) (pos.endLine) contents 281 | pure $ Just source 282 | 283 | decodeStash s = jsonParser s >>= (lmap printJsonDecodeError <<< decodeJson) >>= traverse parsePsaError 284 | encodeStash s = encodeJson (encodePsaError <$> s) 285 | 286 | emptyStash :: forall a. Effect { date :: DateTime, stash :: Array a } 287 | emptyStash = { date: _ , stash: [] } <$> toDateTime <$> now 288 | 289 | readStashFile stashFile = catchException (const emptyStash) do 290 | stat <- File.stat stashFile 291 | file <- File.readTextFile Encoding.UTF8 stashFile 292 | case decodeStash file of 293 | Left _ -> emptyStash 294 | Right stash -> pure { date: Stats.modifiedTime stat, stash } 295 | 296 | writeStashFile stashFile warnings = do 297 | let file = stringify (encodeStash warnings) 298 | File.writeTextFile Encoding.UTF8 stashFile file 299 | 300 | mergeWarnings filenames date old new = do 301 | fileStat <- Ref.new FO.empty 302 | old' <- flip Array.filterA old \x -> 303 | case x.filename of 304 | Nothing -> pure false 305 | Just f -> 306 | if Set.member f filenames 307 | then pure false 308 | else do 309 | stat <- FO.lookup f <$> Ref.read fileStat 310 | case stat of 311 | Just s -> pure s 312 | Nothing -> do 313 | s <- catchException (\_ -> pure false) $ 314 | (date > _) <<< Stats.modifiedTime <$> File.stat f 315 | _ <- Ref.modify_ (FO.insert f s) fileStat 316 | pure s 317 | pure $ old' <> new 318 | 319 | -- Indicates which output stream we are interested in when spawning a child process. 320 | data OutputStream = Stdout | Stderr 321 | 322 | usage :: String 323 | usage = """psa - Error/Warning reporting frontend for 'purs compile' 324 | 325 | Usage: psa [--censor-lib] [--censor-src] 326 | [--censor-codes=CODES] [--filter-codes=CODES] 327 | [--no-colors] [--no-source] 328 | [--is-lib=DIR] [--purs=PURS] [--stash] 329 | PSC_OPTIONS 330 | 331 | Available options: 332 | -v,--version Show the version number 333 | -h,--help Show this help text 334 | --verbose-stats Show counts for each warning type 335 | --censor-stats Censor warning/error summary 336 | --censor-warnings Censor all warnings 337 | --censor-lib Censor warnings from library sources 338 | --censor-src Censor warnings from project sources 339 | --censor-codes=CODES Censor specific error codes 340 | --filter-codes=CODES Only show specific error codes 341 | --no-colors Disable ANSI colors 342 | --no-source Disable original source code printing 343 | --strict Promotes src warnings to errors 344 | --stash Enable persistent warnings (defaults to .psa-stash) 345 | --stash=FILE Enable persistent warnings using a specific stash file 346 | --is-lib=DIR Distinguishing library path (defaults to 'bower_components') 347 | --purs=PURS Name of purs executable (defaults to 'purs') 348 | 349 | CODES Comma-separated list of purs error codes 350 | PSC_OPTIONS Any extra options are passed to 'purs compile' 351 | """ 352 | -------------------------------------------------------------------------------- /testcase/.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | /.pulp-cache/ 4 | /output/ 5 | /.psci* 6 | /src/.webpack.js 7 | -------------------------------------------------------------------------------- /testcase/Foo.purs: -------------------------------------------------------------------------------- 1 | module Test.Foo where 2 | 3 | foo = "foo" 4 | 5 | 6 | foobarbabsbabs = 42 7 | -------------------------------------------------------------------------------- /testcase/Main.purs: -------------------------------------------------------------------------------- 1 | module Test.Main where 2 | 3 | import Prelude (show, append) 4 | import Test.Foo 5 | 6 | main = 7 | (foo 8 | (foo 9 | (foo 10 | (foo 11 | (foo 12 | (foo 13 | (foo 14 | (foo 15 | 42)))))))) 16 | 17 | 18 | bar = show 12 19 | -------------------------------------------------------------------------------- /testcase/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "dependencies": { 4 | "purescript-prelude": "^6.0.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /testcase/lib/Lib.purs: -------------------------------------------------------------------------------- 1 | module Test.Lib where 2 | 3 | import Prelude 4 | 5 | lib = "lib" 6 | --------------------------------------------------------------------------------