git.iko.soy/rowtype-yoga/purs-eval
on main help sign in
18 files changed+680−431
since splitsnapshots
unifiedsplit
.github/dependabot.yml+11 .github/workflows/release.yml+41 .github/workflows/test.yml+17 .github/workflows/todo.yml+14 .github/workflows/update-flake-lock.yml+30 .gitignore+1 .npmignore+6 CHANGELOG.md+63 README.md+19−1 flake.lock+91−384 flake.nix+102−41 package-lock.json+35 package.json+8 src/Compiler.purs+99 src/Main.purs+18−5 test/Main.purs+8 test/Test/Compiler.purs+40 test/Test/Compiler/ServerMock.purs+77
.github/dependabot.ymlnew file+11
@@ -0,0 +1,11 @@
1+version: 2
2+updates:
3+ - package-ecosystem: "github-actions"
4+ directory: "/"
5+ schedule:
6+ interval: "weekly"
7+
8+ - package-ecosystem: "npm"
9+ directory: "/"
10+ schedule:
11+ interval: "weekly"
.github/workflows/release.ymlnew file+41
@@ -0,0 +1,41 @@
1+on:
2+ push:
3+ branches:
4+ - main
5+name: release
6+jobs:
7+ release:
8+ runs-on: ubuntu-latest
9+ steps:
10+ - uses: googleapis/release-please-action@v5
11+ id: release
12+ with:
13+ release-type: node
14+ - uses: actions/checkout@v7
15+ if: ${{ steps.release.outputs.release_created }}
16+ - uses: cachix/install-nix-action@v31
17+ if: ${{ steps.release.outputs.release_created }}
18+ with:
19+ extra_nix_config: |
20+ access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
21+ - uses: cachix/cachix-action@v17
22+ if: ${{ steps.release.outputs.release_created }}
23+ with:
24+ name: klarkc
25+ authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
26+ - run: |
27+ nix build .#npm
28+ mkdir -p dist
29+ cp result dist/purs-eval
30+ if: ${{ steps.release.outputs.release_created }}
31+ - uses: actions/setup-node@v7
32+ if: ${{ steps.release.outputs.release_created }}
33+ with:
34+ node-version: 18
35+ registry-url: 'https://registry.npmjs.org'
36+ - run: npm ci
37+ if: ${{ steps.release.outputs.release_created }}
38+ - run: npm publish
39+ if: ${{ steps.release.outputs.release_created }}
40+ env:
41+ NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
.github/workflows/test.ymlnew file+17
@@ -0,0 +1,17 @@
1+name: "Test"
2+on:
3+ pull_request:
4+jobs:
5+ tests:
6+ runs-on: ubuntu-latest
7+ steps:
8+ - uses: actions/checkout@v7
9+ - uses: cachix/install-nix-action@v31
10+ with:
11+ extra_nix_config: |
12+ access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
13+ - uses: cachix/cachix-action@v17
14+ with:
15+ name: klarkc
16+ authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
17+ - run: nix flake check
.github/workflows/todo.ymlnew file+14
@@ -0,0 +1,14 @@
1+name: "Run TODO to Issue"
2+on:
3+ push:
4+ branches:
5+ - main
6+jobs:
7+ build:
8+ runs-on: "ubuntu-latest"
9+ steps:
10+ - uses: "actions/checkout@v7"
11+ - name: "TODO to Issue"
12+ uses: "alstr/todo-to-issue-action@v5"
13+ with:
14+ IDENTIFIERS: '[{"name": "TODO", "labels": ["help wanted"]}, {"name": "FIXME", "labels": ["bug"]}]'
.github/workflows/update-flake-lock.ymlnew file+30
@@ -0,0 +1,30 @@
1+name: update-flake-lock
2+on:
3+ workflow_dispatch: # allows manual triggering
4+ schedule:
5+ - cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
6+
7+jobs:
8+ lockfile:
9+ runs-on: ubuntu-latest
10+ steps:
11+ - name: Checkout repository
12+ uses: actions/checkout@v7
13+ - name: Install Nix
14+ uses: cachix/install-nix-action@v31
15+ with:
16+ extra_nix_config: |
17+ access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
18+ - uses: cachix/cachix-action@v17
19+ with:
20+ name: klarkc
21+ authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
22+ - name: Update flake.lock
23+ uses: DeterminateSystems/update-flake-lock@v29
24+ with:
25+ commit-msg: "build(deps): Bump flake.lock dependencies"
26+ pr-title: "Update flake.lock"
27+ pr-labels: |
28+ dependencies
29+ automated
30+ token: ${{ secrets.PAT_TOKEN }}
.gitignore+1
@@ -9,3 +9,4 @@
99/.psa*
1010/.spago
1111/result
12+/dist
.npmignorenew file+6
@@ -0,0 +1,6 @@
1+/.github
2+/flake.*
3+/test
4+/src
5+/test
6+/.psc-ide-port
CHANGELOG.mdnew file+63
@@ -0,0 +1,63 @@
1+# Changelog
2+
3+## [1.5.0](https://github.com/rowtype-yoga/purs-eval/compare/v1.4.1...v1.5.0) (2024-07-11)
4+
5+
6+### Features
7+
8+* upgrade purs-nix and change mock server to httpurple ([ddaad01](https://github.com/rowtype-yoga/purs-eval/commit/ddaad01eed68afa45f584c807ed577abc565c247))
9+
10+
11+### Bug Fixes
12+
13+* npm published version not running ([3f1a295](https://github.com/rowtype-yoga/purs-eval/commit/3f1a29567365000f57e6b2c9c54c55448c3a83c7))
14+
15+## [1.4.1](https://github.com/klarkc/purs-eval/compare/v1.4.0...v1.4.1) (2023-08-21)
16+
17+
18+### Bug Fixes
19+
20+* flake changes causing CI breakage ([d5d6085](https://github.com/klarkc/purs-eval/commit/d5d608561096f002d7004c1d54e0ae5aaebc67c8))
21+
22+## [1.4.0](https://github.com/klarkc/purs-eval/compare/v1.3.0...v1.4.0) (2023-08-21)
23+
24+
25+### Features
26+
27+* add LSP to flake ([bb9f0e7](https://github.com/klarkc/purs-eval/commit/bb9f0e7b57980e7972c4ee454227351c599b5d35))
28+
29+
30+### Bug Fixes
31+
32+* library API change ([b5acee9](https://github.com/klarkc/purs-eval/commit/b5acee96178b09f8c0505098a6e29171e27377a0))
33+* npmlock2nix refusing to build ([3270052](https://github.com/klarkc/purs-eval/commit/3270052badb0fd9f1fa9c2166cec6cc2a4db4a75))
34+* purs-nix API changes ([025f93e](https://github.com/klarkc/purs-eval/commit/025f93e75b82009d5d51061937093f052dbbea9e))
35+
36+## [1.3.0](https://github.com/klarkc/purs-eval/compare/v1.2.0...v1.3.0) (2022-12-17)
37+
38+
39+### Features
40+
41+* remove deprecated code ([bd857f1](https://github.com/klarkc/purs-eval/commit/bd857f17d0bae24376f734373c39682290acd1ff))
42+
43+## 1.2.0 (2022-11-02)
44+
45+
46+### Features
47+
48+* add capabilities and launch the compiler ([c5609ef](https://github.com/klarkc/purs-eval/commit/c5609ef15b5c55a994886d5b609a617aabb6aa58))
49+* add compile ([bcf123b](https://github.com/klarkc/purs-eval/commit/bcf123b4367614a2d7630c9fcb6c7a583ee0cf7b))
50+* add import rename ([981f0da](https://github.com/klarkc/purs-eval/commit/981f0da6a9154826a6c2518c87505e224c67a442))
51+* add main append ([69684e1](https://github.com/klarkc/purs-eval/commit/69684e1c82808c68218f0359a2d870ced0b54b4b))
52+* add purs-eval npm publication ([a3fe337](https://github.com/klarkc/purs-eval/commit/a3fe33766551755e228bbd8ae7f8199452f500e4))
53+* add stream lib ([f2fb650](https://github.com/klarkc/purs-eval/commit/f2fb650818f424b081f6051ef2ea4bebb09af75c))
54+* add try pparsing ([3e10f28](https://github.com/klarkc/purs-eval/commit/3e10f2827355cccb9900204ae16fdeaa8fb56748))
55+* bootstrap purs-nix project ([ba47715](https://github.com/klarkc/purs-eval/commit/ba477157cf817a36f89944b9dfeccac3483f0f4b))
56+* Initial commit ([6c4e7d1](https://github.com/klarkc/purs-eval/commit/6c4e7d17bc3a932b872076b8cbc31f7f9e83b981))
57+
58+
59+### Bug Fixes
60+
61+* add missing xhr ffi dep ([6a0965b](https://github.com/klarkc/purs-eval/commit/6a0965b236deca5d9ec975febbf5b0b0da7f76bd))
62+* incorrect purescript URL ([736ee61](https://github.com/klarkc/purs-eval/commit/736ee612a149e291e0606ae70210ab51c8a8a3f8))
63+* npm bin not being found ([fa97556](https://github.com/klarkc/purs-eval/commit/fa97556f4d207b31d06e499e446068e882b98697))
README.md+19−1
@@ -1,2 +1,20 @@
11# purs-eval
2−A simple PureScript expression evaluation tool
2+A simple PureScript expression evaluation tool. It uses [try.purescript.org](https://try.purescript.org) as a compilation backend; for this reason, it currently does not support embedding local files or modules.
3+
4+## Usage
5+
6+```bash
7+EXAMPLE="module Main where\nimport Effect.Console (log)\nmain = log \"hello from PS\""
8+
9+# With npm
10+echo -e $EXAMPLE | npx purs-eval
11+
12+# With nix
13+echo -e $EXAMPLE | nix run github:rowtype-yoga/purs-eval
14+
15+# Pipe node (>v18)
16+echo -e $EXAMPLE | nix run github:rowtype-yoga/purs-eval | nix run nixpkgs#nodejs -- --experimental-network-imports --input-type module
17+
18+# or with npx
19+echo -e $EXAMPLE | npx purs-eval | node --experimental-network-imports --input-type module
20+```
flake.lock+91−384
@@ -1,55 +1,13 @@
11{
22 "nodes": {
3− "deadnix": {
4− "inputs": {
5− "fenix": "fenix",
6− "naersk": "naersk",
7− "nixpkgs": "nixpkgs_4",
8− "utils": "utils"
9− },
10− "locked": {
11− "lastModified": 1655647809,
12− "narHash": "sha256-npyHYIJW7HyGIFpCZZK+t5JM/v2LsyFhAGJxX1DXO7E=",
13− "owner": "astro",
14− "repo": "deadnix",
15− "rev": "83c42cc64d190ecb72f5929eab0f64fe88e25dc4",
16− "type": "github"
17− },
18− "original": {
19− "owner": "astro",
20− "repo": "deadnix",
21− "type": "github"
22− }
23− },
24− "deadnix_2": {
25− "inputs": {
26− "fenix": "fenix_2",
27− "naersk": "naersk_2",
28− "nixpkgs": "nixpkgs_8",
29− "utils": "utils_2"
30− },
31− "locked": {
32− "lastModified": 1656370114,
33− "narHash": "sha256-XBbSWeBuF6Ck0jc634yAp2hjPXWM2JyRDPCdK0dh3w4=",
34− "owner": "astro",
35− "repo": "deadnix",
36− "rev": "9f450f7250ad7680cb5f12ce5985cc18496c2d5f",
37− "type": "github"
38− },
39− "original": {
40− "owner": "astro",
41− "repo": "deadnix",
42− "type": "github"
43− }
44− },
453 "docs-search": {
464 "flake": false,
475 "locked": {
48− "lastModified": 1661787609,
49− "narHash": "sha256-jgOl8PKisRmcaHOya3HzArI3eKjVErx+XIBGminh9Zk=",
6+ "lastModified": 1675992564,
7+ "narHash": "sha256-Tk9VSogFHXtXe9O9vuCEfM/PV/S7plMIO0I++fCZn7U=",
508 "owner": "purs-nix",
519 "repo": "purescript-docs-search",
52− "rev": "4620575e21886fcbf516d0b43910ba4ead2a60d0",
10+ "rev": "35822b1d6ce65b1a07f80dd9e2caf15c3ee83e2c",
5311 "type": "github"
5412 },
5513 "original": {
@@ -58,68 +16,37 @@
5816 "type": "github"
5917 }
6018 },
61− "fenix": {
62− "inputs": {
63− "nixpkgs": "nixpkgs_2",
64− "rust-analyzer-src": "rust-analyzer-src"
65− },
66− "locked": {
67− "lastModified": 1655533500,
68− "narHash": "sha256-qJJmLVoMYfDLywI9MNL7sb0W/GsKQF9HDatdHm1tSl0=",
69− "owner": "nix-community",
70− "repo": "fenix",
71− "rev": "b6630603af13df17d0dd4df8629e9a24e6ba0fbd",
72− "type": "github"
73− },
74− "original": {
75− "owner": "nix-community",
76− "repo": "fenix",
77− "type": "github"
78− }
79− },
80− "fenix_2": {
81− "inputs": {
82− "nixpkgs": "nixpkgs_6",
83− "rust-analyzer-src": "rust-analyzer-src_2"
84− },
19+ "flake-utils": {
8520 "locked": {
86− "lastModified": 1655533500,
87− "narHash": "sha256-qJJmLVoMYfDLywI9MNL7sb0W/GsKQF9HDatdHm1tSl0=",
88− "owner": "nix-community",
89− "repo": "fenix",
90− "rev": "b6630603af13df17d0dd4df8629e9a24e6ba0fbd",
21+ "lastModified": 1644229661,
22+ "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
23+ "owner": "numtide",
24+ "repo": "flake-utils",
25+ "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
9126 "type": "github"
9227 },
9328 "original": {
94− "owner": "nix-community",
95− "repo": "fenix",
29+ "owner": "numtide",
30+ "repo": "flake-utils",
9631 "type": "github"
9732 }
9833 },
99− "fenix_3": {
100− "inputs": {
101− "nixpkgs": [
102− "purs-nix",
103− "statix",
104− "nixpkgs"
105− ],
106− "rust-analyzer-src": "rust-analyzer-src_3"
107− },
34+ "flake-utils_2": {
10835 "locked": {
109− "lastModified": 1645251813,
110− "narHash": "sha256-cQ66tGjnZclBCS3nD26mZ5fUH+3/HnysGffBiWXUSHk=",
111− "owner": "nix-community",
112− "repo": "fenix",
113− "rev": "9892337b588c38ec59466a1c89befce464aae7f8",
36+ "lastModified": 1618217525,
37+ "narHash": "sha256-WGrhVczjXTiswQaoxQ+0PTfbLNeOQM6M36zvLn78AYg=",
38+ "owner": "numtide",
39+ "repo": "flake-utils",
40+ "rev": "c6169a2772643c4a93a0b5ac1c61e296cba68544",
11441 "type": "github"
11542 },
11643 "original": {
117− "owner": "nix-community",
118− "repo": "fenix",
44+ "owner": "numtide",
45+ "repo": "flake-utils",
11946 "type": "github"
12047 }
12148 },
122− "flake-utils": {
49+ "flake-utils_3": {
12350 "locked": {
12451 "lastModified": 1618217525,
12552 "narHash": "sha256-WGrhVczjXTiswQaoxQ+0PTfbLNeOQM6M36zvLn78AYg=",
@@ -134,7 +61,7 @@
13461 "type": "github"
13562 }
13663 },
137− "flake-utils_2": {
64+ "flake-utils_4": {
13865 "locked": {
13966 "lastModified": 1618217525,
14067 "narHash": "sha256-WGrhVczjXTiswQaoxQ+0PTfbLNeOQM6M36zvLn78AYg=",
@@ -164,25 +91,41 @@
16491 "type": "github"
16592 }
16693 },
167− "gitignore": {
94+ "httpurple-argonaut": {
95+ "flake": false,
96+ "locked": {
97+ "lastModified": 1655138308,
98+ "narHash": "sha256-tWTgc2gERJLkv+XzK4HtqJJbqvw10svVu1cmXFADtls=",
99+ "owner": "sigma-andex",
100+ "repo": "purescript-httpurple-argonaut",
101+ "rev": "3187fba4fe0682849b4acbf215e6a6fc1f6493de",
102+ "type": "github"
103+ },
104+ "original": {
105+ "owner": "sigma-andex",
106+ "repo": "purescript-httpurple-argonaut",
107+ "type": "github"
108+ }
109+ },
110+ "lint-utils": {
168111 "inputs": {
112+ "flake-utils": "flake-utils",
169113 "nixpkgs": [
170114 "purs-nix",
171− "statix",
172115 "nixpkgs"
173116 ]
174117 },
175118 "locked": {
176− "lastModified": 1635165013,
177− "narHash": "sha256-o/BdVjNwcB6jOmzZjOH703BesSkkS5O7ej3xhyO8hAY=",
178− "owner": "hercules-ci",
179− "repo": "gitignore.nix",
180− "rev": "5b9e0ff9d3b551234b4f3eb3983744fa354b17f1",
119+ "lastModified": 1707777931,
120+ "narHash": "sha256-PsPb5xMBZ9dPDP04o9vqKEUIEG80Z84/74fPuOMs0ZI=",
121+ "owner": "homotopic",
122+ "repo": "lint-utils",
123+ "rev": "5f11e3e51d8f1aa4ed62a89e90f05953931e105a",
181124 "type": "github"
182125 },
183126 "original": {
184− "owner": "hercules-ci",
185− "repo": "gitignore.nix",
127+ "owner": "homotopic",
128+ "repo": "lint-utils",
186129 "type": "github"
187130 }
188131 },
@@ -218,49 +161,13 @@
218161 "type": "github"
219162 }
220163 },
221− "naersk": {
222− "inputs": {
223− "nixpkgs": "nixpkgs_3"
224− },
225− "locked": {
226− "lastModified": 1655042882,
227− "narHash": "sha256-9BX8Fuez5YJlN7cdPO63InoyBy7dm3VlJkkmTt6fS1A=",
228− "owner": "nix-community",
229− "repo": "naersk",
230− "rev": "cddffb5aa211f50c4b8750adbec0bbbdfb26bb9f",
231− "type": "github"
232− },
233− "original": {
234− "owner": "nix-community",
235− "repo": "naersk",
236− "type": "github"
237− }
238− },
239− "naersk_2": {
240− "inputs": {
241− "nixpkgs": "nixpkgs_7"
242− },
243− "locked": {
244− "lastModified": 1655042882,
245− "narHash": "sha256-9BX8Fuez5YJlN7cdPO63InoyBy7dm3VlJkkmTt6fS1A=",
246− "owner": "nix-community",
247− "repo": "naersk",
248− "rev": "cddffb5aa211f50c4b8750adbec0bbbdfb26bb9f",
249− "type": "github"
250− },
251− "original": {
252− "owner": "nix-community",
253− "repo": "naersk",
254− "type": "github"
255− }
256− },
257164 "nixpkgs": {
258165 "locked": {
259− "lastModified": 1662934689,
260− "narHash": "sha256-mXi8hmhiunOVTeHiuouWXb0vTqjzp9v9kshMmI561Us=",
166+ "lastModified": 1704161960,
167+ "narHash": "sha256-QGua89Pmq+FBAro8NriTuoO/wNaUtugt29/qqA8zeeM=",
261168 "owner": "NixOS",
262169 "repo": "nixpkgs",
263− "rev": "a0b7e70db7a55088d3de0cc370a59f9fbcc906c3",
170+ "rev": "63143ac2c9186be6d9da6035fa22620018c85932",
264171 "type": "github"
265172 },
266173 "original": {
@@ -270,73 +177,13 @@
270177 "type": "github"
271178 }
272179 },
273− "nixpkgs_10": {
274− "locked": {
275− "lastModified": 1645013224,
276− "narHash": "sha256-b7OEC8vwzJv3rsz9pwnTX2LQDkeOWz2DbKypkVvNHXc=",
277− "owner": "nixos",
278− "repo": "nixpkgs",
279− "rev": "b66b39216b1fef2d8c33cc7a5c72d8da80b79970",
280− "type": "github"
281− },
282− "original": {
283− "owner": "nixos",
284− "ref": "nixpkgs-unstable",
285− "repo": "nixpkgs",
286− "type": "github"
287− }
288− },
289180 "nixpkgs_2": {
290181 "locked": {
291− "lastModified": 1655400192,
292− "narHash": "sha256-49OBVVRgb9H/PSmNT9W61+NRdDbuSJVuDDflwXlaUKU=",
293− "owner": "nixos",
294− "repo": "nixpkgs",
295− "rev": "3d7435c638baffaa826b85459df0fff47f12317d",
296− "type": "github"
297− },
298− "original": {
299− "owner": "nixos",
300− "ref": "nixos-unstable",
301− "repo": "nixpkgs",
302− "type": "github"
303− }
304− },
305− "nixpkgs_3": {
306− "locked": {
307− "lastModified": 1655481042,
308− "narHash": "sha256-XHbcywq2vIQ5CeH1OK3TN793jkiNAAZsSctS1PFgseo=",
309− "owner": "NixOS",
310− "repo": "nixpkgs",
311− "rev": "103a4c0ae46afa9cf008c30744175315ca38e9f9",
312− "type": "github"
313− },
314− "original": {
315− "id": "nixpkgs",
316− "type": "indirect"
317− }
318− },
319− "nixpkgs_4": {
320− "locked": {
321− "lastModified": 1655481042,
322− "narHash": "sha256-XHbcywq2vIQ5CeH1OK3TN793jkiNAAZsSctS1PFgseo=",
323− "owner": "NixOS",
324− "repo": "nixpkgs",
325− "rev": "103a4c0ae46afa9cf008c30744175315ca38e9f9",
326− "type": "github"
327− },
328− "original": {
329− "id": "nixpkgs",
330− "type": "indirect"
331− }
332− },
333− "nixpkgs_5": {
334− "locked": {
335− "lastModified": 1646506091,
336− "narHash": "sha256-sWNAJE2m+HOh1jtXlHcnhxsj6/sXrHgbqVNcVRlveK4=",
182+ "lastModified": 1656549732,
183+ "narHash": "sha256-eILutFZGjfk2bEzfim8S/qyYc//0S1KsCeO+OWbtoR0=",
337184 "owner": "NixOS",
338185 "repo": "nixpkgs",
339− "rev": "3e644bd62489b516292c816f70bf0052c693b3c7",
186+ "rev": "d3248619647234b5dc74a6921bcdf6dd8323eb22",
340187 "type": "github"
341188 },
342189 "original": {
@@ -346,63 +193,19 @@
346193 "type": "github"
347194 }
348195 },
349− "nixpkgs_6": {
350− "locked": {
351− "lastModified": 1655400192,
352− "narHash": "sha256-49OBVVRgb9H/PSmNT9W61+NRdDbuSJVuDDflwXlaUKU=",
353− "owner": "nixos",
354− "repo": "nixpkgs",
355− "rev": "3d7435c638baffaa826b85459df0fff47f12317d",
356− "type": "github"
357− },
358− "original": {
359− "owner": "nixos",
360− "ref": "nixos-unstable",
361− "repo": "nixpkgs",
362− "type": "github"
363− }
364− },
365− "nixpkgs_7": {
366− "locked": {
367− "lastModified": 1655481042,
368− "narHash": "sha256-XHbcywq2vIQ5CeH1OK3TN793jkiNAAZsSctS1PFgseo=",
369− "owner": "NixOS",
370− "repo": "nixpkgs",
371− "rev": "103a4c0ae46afa9cf008c30744175315ca38e9f9",
372− "type": "github"
373− },
374− "original": {
375− "id": "nixpkgs",
376− "type": "indirect"
377− }
378− },
379− "nixpkgs_8": {
380− "locked": {
381− "lastModified": 1655481042,
382− "narHash": "sha256-XHbcywq2vIQ5CeH1OK3TN793jkiNAAZsSctS1PFgseo=",
383− "owner": "NixOS",
384− "repo": "nixpkgs",
385− "rev": "103a4c0ae46afa9cf008c30744175315ca38e9f9",
386− "type": "github"
387− },
388− "original": {
389− "id": "nixpkgs",
390− "type": "indirect"
391− }
392− },
393− "nixpkgs_9": {
196+ "npmlock2nix": {
197+ "flake": false,
394198 "locked": {
395− "lastModified": 1656549732,
396− "narHash": "sha256-eILutFZGjfk2bEzfim8S/qyYc//0S1KsCeO+OWbtoR0=",
397− "owner": "NixOS",
398− "repo": "nixpkgs",
399− "rev": "d3248619647234b5dc74a6921bcdf6dd8323eb22",
199+ "lastModified": 1673447413,
200+ "narHash": "sha256-sJM82Sj8yfQYs9axEmGZ9Evzdv/kDcI9sddqJ45frrU=",
201+ "owner": "nix-community",
202+ "repo": "npmlock2nix",
203+ "rev": "9197bbf397d76059a76310523d45df10d2e4ca81",
400204 "type": "github"
401205 },
402206 "original": {
403− "owner": "NixOS",
404− "ref": "nixpkgs-unstable",
405− "repo": "nixpkgs",
207+ "owner": "nix-community",
208+ "repo": "npmlock2nix",
406209 "type": "github"
407210 }
408211 },
@@ -423,17 +226,16 @@
423226 },
424227 "ps-tools": {
425228 "inputs": {
426− "deadnix": "deadnix_2",
427229 "make-shell": "make-shell_2",
428− "nixpkgs": "nixpkgs_9",
429− "utils": "utils_3"
230+ "nixpkgs": "nixpkgs_2",
231+ "utils": "utils"
430232 },
431233 "locked": {
432− "lastModified": 1658374818,
433− "narHash": "sha256-WxbQ/BR4Ep8tBbaOikXechspyZlvwfL5XNmRNEnaOFo=",
234+ "lastModified": 1704567308,
235+ "narHash": "sha256-WbFPIkKLtyQOPBUjintckKIYnfs7MvIbmfVsLRSAPlc=",
434236 "owner": "purs-nix",
435237 "repo": "purescript-tools",
436− "rev": "c0f887f60ea2331dfdc5b0e8be2e732976887345",
238+ "rev": "ac626313141cbee78f06eb3c5e90359f695aef9b",
437239 "type": "github"
438240 },
439241 "original": {
@@ -444,146 +246,48 @@
444246 },
445247 "purs-nix": {
446248 "inputs": {
447− "deadnix": "deadnix",
448249 "docs-search": "docs-search",
449250 "get-flake": "get-flake",
251+ "lint-utils": "lint-utils",
450252 "make-shell": "make-shell",
451− "nixpkgs": "nixpkgs_5",
253+ "nixpkgs": "nixpkgs",
452254 "parsec": "parsec",
453255 "ps-tools": "ps-tools",
454− "statix": "statix",
455− "utils": "utils_4"
256+ "utils": "utils_2"
456257 },
457258 "locked": {
458− "lastModified": 1661787645,
459− "narHash": "sha256-mWSDMKgdpFsXL8+GMQmGOXdJq21wKyljk0mjNKt3f4Q=",
259+ "lastModified": 1711996073,
260+ "narHash": "sha256-NDV8q9qtpKjHgIcMVBgdNqEfhpfK1d19rHYNa7yq0Qs=",
460261 "owner": "purs-nix",
461262 "repo": "purs-nix",
462− "rev": "beea53406d7225f083e3ea4798a3428a2b676e91",
263+ "rev": "8caa40f7fe69b9fcd05baae04c4ec9eb43953e2e",
463264 "type": "github"
464265 },
465266 "original": {
466267 "owner": "purs-nix",
467− "ref": "ps-0.15",
468268 "repo": "purs-nix",
469269 "type": "github"
470270 }
471271 },
472272 "root": {
473273 "inputs": {
474− "nixpkgs": "nixpkgs",
274+ "httpurple-argonaut": "httpurple-argonaut",
275+ "nixpkgs": [
276+ "purs-nix",
277+ "nixpkgs"
278+ ],
279+ "npmlock2nix": "npmlock2nix",
475280 "ps-tools": [
476281 "purs-nix",
477282 "ps-tools"
478283 ],
479284 "purs-nix": "purs-nix",
480− "utils": "utils_5"
481− }
482− },
483− "rust-analyzer-src": {
484− "flake": false,
485− "locked": {
486− "lastModified": 1655507737,
487− "narHash": "sha256-o+AqNsjL6o2RHh4InZHQVpkmqg570YFJL4Db8mKq+fs=",
488− "owner": "rust-lang",
489− "repo": "rust-analyzer",
490− "rev": "12dd81092e37df28b7a3591cae9675e668927198",
491− "type": "github"
492− },
493− "original": {
494− "owner": "rust-lang",
495− "ref": "nightly",
496− "repo": "rust-analyzer",
497− "type": "github"
498− }
499− },
500− "rust-analyzer-src_2": {
501− "flake": false,
502− "locked": {
503− "lastModified": 1655507737,
504− "narHash": "sha256-o+AqNsjL6o2RHh4InZHQVpkmqg570YFJL4Db8mKq+fs=",
505− "owner": "rust-lang",
506− "repo": "rust-analyzer",
507− "rev": "12dd81092e37df28b7a3591cae9675e668927198",
508− "type": "github"
509− },
510− "original": {
511− "owner": "rust-lang",
512− "ref": "nightly",
513− "repo": "rust-analyzer",
514− "type": "github"
515− }
516− },
517− "rust-analyzer-src_3": {
518− "flake": false,
519− "locked": {
520− "lastModified": 1645205556,
521− "narHash": "sha256-e4lZW3qRyOEJ+vLKFQP7m2Dxh5P44NrnekZYLxlucww=",
522− "owner": "rust-analyzer",
523− "repo": "rust-analyzer",
524− "rev": "acf5874b39f3dc5262317a6074d9fc7285081161",
525− "type": "github"
526− },
527− "original": {
528− "owner": "rust-analyzer",
529− "ref": "nightly",
530− "repo": "rust-analyzer",
531− "type": "github"
532− }
533− },
534− "statix": {
535− "inputs": {
536− "fenix": "fenix_3",
537− "gitignore": "gitignore",
538− "nixpkgs": "nixpkgs_10"
539− },
540− "locked": {
541− "lastModified": 1657460333,
542− "narHash": "sha256-5o6zMBASEsGKtjKDb3SizJnN9A7qpOcbzWBXsacfMyc=",
543− "owner": "nerdypepper",
544− "repo": "statix",
545− "rev": "6422c959d365dee2fda5eda8858fefad31f17b25",
546− "type": "github"
547− },
548− "original": {
549− "owner": "nerdypepper",
550− "repo": "statix",
551− "type": "github"
285+ "utils": "utils_3"
552286 }
553287 },
554288 "utils": {
555− "locked": {
556− "lastModified": 1653893745,
557− "narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
558− "owner": "numtide",
559− "repo": "flake-utils",
560− "rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
561− "type": "github"
562− },
563− "original": {
564− "owner": "numtide",
565− "repo": "flake-utils",
566− "type": "github"
567− }
568− },
569− "utils_2": {
570− "locked": {
571− "lastModified": 1653893745,
572− "narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
573− "owner": "numtide",
574− "repo": "flake-utils",
575− "rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
576− "type": "github"
577− },
578− "original": {
579− "owner": "numtide",
580− "repo": "flake-utils",
581− "type": "github"
582− }
583− },
584− "utils_3": {
585289 "inputs": {
586− "flake-utils": "flake-utils"
290+ "flake-utils": "flake-utils_2"
587291 },
588292 "locked": {
589293 "lastModified": 1656044990,
@@ -600,9 +304,9 @@
600304 "type": "github"
601305 }
602306 },
603− "utils_4": {
307+ "utils_2": {
604308 "inputs": {
605− "flake-utils": "flake-utils_2"
309+ "flake-utils": "flake-utils_3"
606310 },
607311 "locked": {
608312 "lastModified": 1656044990,
@@ -619,17 +323,20 @@
619323 "type": "github"
620324 }
621325 },
622− "utils_5": {
326+ "utils_3": {
327+ "inputs": {
328+ "flake-utils": "flake-utils_4"
329+ },
623330 "locked": {
624− "lastModified": 1659877975,
625− "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
626− "owner": "numtide",
331+ "lastModified": 1658606827,
332+ "narHash": "sha256-3kSWTDpV4+uApt/Xd0kv2m7TR1Y6A7SgYUeX86/qYuU=",
333+ "owner": "ursi",
627334 "repo": "flake-utils",
628− "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
335+ "rev": "faec5f7431da6747a69957a9cd65e35b5173e10a",
629336 "type": "github"
630337 },
631338 "original": {
632− "owner": "numtide",
339+ "owner": "ursi",
633340 "repo": "flake-utils",
634341 "type": "github"
635342 }
flake.nix+102−41
@@ -1,49 +1,110 @@
1−{ inputs =
2− { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
1+{
2+ inputs =
3+ {
4+ purs-nix.url = "github:purs-nix/purs-nix";
5+ nixpkgs.follows = "purs-nix/nixpkgs";
6+ utils.url = "github:ursi/flake-utils";
37 ps-tools.follows = "purs-nix/ps-tools";
4− purs-nix.url = "github:purs-nix/purs-nix/ps-0.15";
5− utils.url = "github:numtide/flake-utils";
8+ npmlock2nix = {
9+ url = "github:nix-community/npmlock2nix";
10+ flake = false;
11+ };
12+ httpurple-argonaut = {
13+ url = "github:sigma-andex/purescript-httpurple-argonaut";
14+ flake = false;
15+ };
616 };
717
8− outputs = { nixpkgs, utils, ... }@inputs:
9− utils.lib.eachSystem [ "x86_64-linux" "x86_64-darwin" ]
10− (system:
11− let
12− pkgs = nixpkgs.legacyPackages.${system};
13− ps-tools = inputs.ps-tools.legacyPackages.${system};
14− purs-nix = inputs.purs-nix { inherit system; };
18+ outputs = { self, utils, ... }@inputs:
19+ utils.apply-systems
20+ {
21+ inherit inputs;
22+ # Limited by ps-tools
23+ systems = [ "x86_64-linux" "x86_64-darwin" ];
24+ }
25+ ({ pkgs, system, ... }@ctx:
26+ let
27+ inherit (pkgs) nodejs;
28+ npm = import inputs.npmlock2nix { inherit pkgs; };
29+ node_modules = npm.v2.node_modules { src = ./.; inherit nodejs; } + /node_modules;
30+ inherit (ctx.ps-tools) purescript purs-tidy purescript-language-server;
31+ purs-nix = inputs.purs-nix { inherit system; };
32+ affjax-node_ = pkgs.lib.recursiveUpdate purs-nix.ps-pkgs.affjax-node {
33+ purs-nix-info.foreign."Affjax.Node" = { inherit node_modules; };
34+ };
35+ # TODO use httpurple-argonaut from official index
36+ httpurple-argonaut_ = purs-nix.build
37+ {
38+ name = "httpurple-argonaut";
39+ src.path = inputs.httpurple-argonaut;
40+ info.dependencies = [ "argonaut" "console" "effect" "either" "httpurple" "prelude"];
41+ };
42+ ps =
43+ purs-nix.purs
44+ {
45+ dir = ./.;
46+ dependencies =
47+ with purs-nix.ps-pkgs;
48+ [
49+ prelude
50+ debug
51+ aff
52+ affjax-node_
53+ argonaut-codecs
54+ argonaut-generic
55+ effect
56+ httpurple
57+ httpurple-argonaut_
58+ test-unit
59+ parsing
60+ ];
61+ inherit purescript nodejs;
62+ };
63+ name = "purs-eval";
64+ in
65+ with ps;
66+ rec {
67+ apps.default =
68+ {
69+ type = "app";
70+ program = "${packages.default}/bin/${name}";
71+ };
1572
16− ps =
17− purs-nix.purs
18− { dependencies =
19− with purs-nix.ps-pkgs;
20− [ console
21− effect
22− prelude
23− ];
73+ packages =
74+ {
75+ default = app { inherit name; };
76+ # npm version does not publish a nix-store path
77+ npm = pkgs.runCommand
78+ "purs-eval-npm"
79+ {}
80+ ''
81+ echo "#!/usr/bin/env node" > $out
82+ tail -n +2 ${packages.default}/bin/purs-eval >> $out
83+ '';
84+ };
2485
25− dir = ./.;
26− };
27− in
28− { packages.default = ps.modules.Main.app { name = "purs-eval"; };
86+ checks.test = test.check { };
2987
30− devShells.default =
31− pkgs.mkShell
32− { packages =
33− with pkgs;
34− [ entr
35− nodejs
36− (ps.command {})
37− ps-tools.for-0_15.purescript-language-server
38− purs-nix.esbuild
39− purs-nix.purescript
40− ];
41−
42− shellHook =
43− ''
44− alias watch="find src | entr -s 'echo bundling; purs-nix bundle'"
45− '';
46− };
47− }
88+ devShells.default = pkgs.mkShell {
89+ packages = with pkgs; [
90+ nodejs
91+ (ps.command { })
92+ purescript-language-server
93+ purs-tidy
94+ purescript
95+ purs-nix.esbuild
96+ ];
97+ };
98+ }
4899 );
100+
101+ nixConfig = {
102+ extra-experimental-features = "nix-command flakes";
103+ extra-substituters = [
104+ "https://klarkc.cachix.org"
105+ ];
106+ extra-trusted-public-keys = [
107+ "klarkc.cachix.org-1:R+z+m4Cq0hMgfZ7AQ42WRpGuHJumLLx3k0XhwpNFq9U="
108+ ];
109+ };
49110}
package-lock.jsonnew file+35
@@ -0,0 +1,35 @@
1+{
2+ "name": "purs-eval",
3+ "lockfileVersion": 2,
4+ "requires": true,
5+ "packages": {
6+ "": {
7+ "name": "purs-eval",
8+ "bin": {
9+ "purs-eval": "result/bin/purs-eval"
10+ },
11+ "devDependencies": {
12+ "xhr2": "^0.2.1"
13+ },
14+ "version": "1.5.0"
15+ },
16+ "node_modules/xhr2": {
17+ "version": "0.2.1",
18+ "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz",
19+ "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==",
20+ "dev": true,
21+ "engines": {
22+ "node": ">= 6"
23+ }
24+ }
25+ },
26+ "dependencies": {
27+ "xhr2": {
28+ "version": "0.2.1",
29+ "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz",
30+ "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==",
31+ "dev": true
32+ }
33+ },
34+ "version": "1.5.0"
35+}
package.jsonnew file+8
@@ -0,0 +1,8 @@
1+{
2+ "name": "purs-eval",
3+ "bin": "dist/purs-eval",
4+ "devDependencies": {
5+ "xhr2": "^0.2.1"
6+ },
7+ "version": "1.5.0"
8+}
src/Compiler.pursnew file+99
@@ -0,0 +1,99 @@
1+module Compiler
2+ ( Settings
3+ , Code
4+ , ErrorPosition
5+ , Suggestion
6+ , CompileWarning
7+ , SuccessResult
8+ , successFromJson
9+ , runCompiler
10+ , appendMain
11+ )
12+ where
13+
14+import Prelude (bind, pure, show, ($), (<<<), const)
15+import Control.Monad.Error.Class (liftEither)
16+import Control.Monad.Reader.Trans (ReaderT, runReaderT, ask)
17+import Control.Monad.Trans.Class (lift)
18+import Data.Argonaut.Core (Json)
19+import Data.Argonaut.Decode (printJsonDecodeError)
20+import Data.Argonaut.Decode.Class (decodeJson)
21+import Data.Argonaut.Parser (jsonParser)
22+import Data.Functor ((<$>))
23+import Data.Bifunctor (lmap)
24+import Data.Either (Either)
25+import Data.Maybe (Maybe(Just))
26+import Data.Monoid ((<>))
27+import Effect.Aff (Aff, error)
28+import Effect.Exception (Error)
29+import Affjax.ResponseFormat (string)
30+import Affjax.Node (post, printError)
31+import Affjax.RequestBody (RequestBody (String))
32+import Parsing.String as PS
33+import Parsing.String.Replace as PS.Replace
34+
35+type Settings = { protocol :: String
36+ , hostname :: String
37+ , port :: Int
38+ , parser :: Json -> Either Error SuccessResult
39+ }
40+type Code = String
41+type Compiler = ReaderT Code (ReaderT Settings Aff)
42+
43+-- extracted from github:purescript/trypurescript
44+type ErrorPosition =
45+ { startLine :: Int
46+ , endLine :: Int
47+ , startColumn :: Int
48+ , endColumn :: Int
49+ }
50+type Suggestion =
51+ { replacement :: String
52+ , replaceRange :: Maybe ErrorPosition
53+ }
54+type CompileWarning =
55+ { errorCode :: String
56+ , message :: String
57+ , position :: Maybe ErrorPosition
58+ , suggestion :: Maybe Suggestion
59+ }
60+type SuccessResult =
61+ { js :: String
62+ , warnings :: Maybe (Array CompileWarning)
63+ }
64+-- end of imports from github:purescript/trypurescript
65+
66+successFromJson :: Json -> Either Error SuccessResult
67+successFromJson json = (error <<< printJsonDecodeError) `lmap` (decodeJson json)
68+
69+askCode :: Compiler Code
70+askCode = ask
71+
72+askSettings :: Compiler Settings
73+askSettings = lift ask
74+
75+liftAff :: forall a. Aff a -> Compiler a
76+liftAff h = lift $ lift h
77+
78+rename :: String -> String -> Code -> Code
79+rename url output code = PS.Replace.replace code (prefix <$> PS.string "from \"..") where
80+ prefix = const $ "from \"" <> url <> output
81+
82+appendMain :: Code -> Code
83+appendMain code = code <> "\nmain();"
84+
85+compile :: Compiler Code
86+compile = do
87+ code <- askCode
88+ s <- askSettings
89+ let url = s.protocol <> "://" <> s.hostname <> ":" <> show s.port
90+ endpoint = "/compile"
91+ output = "/output"
92+ mRes <- liftAff $ post string (url <> endpoint) $ Just $ String code
93+ res <- liftEither $ (error <<< printError) `lmap` mRes
94+ body <- liftEither $ error `lmap` (jsonParser res.body)
95+ succ <- liftEither $ s.parser body
96+ pure $ appendMain $ rename url output succ.js
97+
98+runCompiler :: Settings -> Code -> Aff Code
99+runCompiler s code = runReaderT (runReaderT compile code) s
src/Main.purs+18−5
@@ -1,9 +1,22 @@
1−module Main where
2−
3−import Prelude
1+module Main (main) where
42
3+import Prelude (Unit, bind, discard)
54import Effect (Effect)
6−import Effect.Console (log)
5+import Effect.Aff (launchAff_)
6+import Node.Process (stdin, stdout)
7+import Node.Stream.Aff (readSome, write, end, toStringUTF8, fromStringUTF8)
8+import Compiler (successFromJson, runCompiler)
79
810main :: Effect Unit
9−main = log "❄"
11+main = launchAff_ do
12+ { buffers } <- readSome stdin
13+ code <- toStringUTF8 buffers
14+ let settings = { protocol: "https"
15+ , hostname: "compile.purescript.org"
16+ , port: 443
17+ , parser: successFromJson
18+ }
19+ code' <- runCompiler settings code
20+ output <- fromStringUTF8 code'
21+ write stdout output
22+ end stdout
test/Main.pursnew file+8
@@ -0,0 +1,8 @@
1+module Test.Main (main) where
2+
3+import Prelude (Unit)
4+import Effect (Effect)
5+import Test.Compiler as Compiler
6+
7+main :: Effect Unit
8+main = Compiler.runTests
test/Test/Compiler.pursnew file+40
@@ -0,0 +1,40 @@
1+module Test.Compiler (runTests) where
2+
3+import Prelude (Unit, bind, discard, show)
4+import Data.Semigroup ((<>))
5+import Data.Foldable (foldMap)
6+import Data.Tuple (Tuple(Tuple))
7+import Effect (Effect)
8+import Test.Unit (suite, test)
9+import Test.Unit.Main (runTest)
10+import Test.Unit.Assert (equal)
11+import Test.Compiler.ServerMock (settings, setupSrv)
12+import Compiler (Code, runCompiler, appendMain)
13+
14+mkImport :: String -> String -> Tuple Code Code
15+mkImport url mod = let
16+ impa = "import * as " <> mod <> "from \""
17+ impb = mod <> "/index.js\";"
18+ code = impa <> "../" <> impb <> "\n"
19+ expected = impa <> url <> "/output/" <> impb <> "\n"
20+in Tuple code expected
21+
22+runTests :: Effect Unit
23+runTests = runTest do
24+ suite "compile" do
25+ test "produces expected output" do
26+ let srv = "compiled-code"
27+ compile = runCompiler settings
28+ expected = appendMain srv
29+ actual <- setupSrv srv (compile "code")
30+ expected `equal` actual
31+ test "rename imports" do
32+ let url = settings.protocol
33+ <> "://"
34+ <> settings.hostname
35+ <> ":"
36+ <> show settings.port
37+ Tuple code expected = mkImport url `foldMap` [ "Prelude", "Effect" ]
38+ compile = runCompiler settings
39+ actual <- setupSrv code (compile code)
40+ (appendMain expected) `equal` actual
test/Test/Compiler/ServerMock.pursnew file+77
@@ -0,0 +1,77 @@
1+module Test.Compiler.ServerMock (settings, setupSrv) where
2+
3+import Prelude (Unit, ($), (<<<), unit, pure, bind, const)
4+import Data.Argonaut.Core (Json)
5+import Data.Argonaut.Decode (JsonDecodeError, printJsonDecodeError)
6+import Data.Argonaut.Decode.Class (class DecodeJson, decodeJson)
7+import Data.Argonaut.Decode.Generic (genericDecodeJson)
8+import Data.Argonaut.Encode.Class (class EncodeJson, encodeJson)
9+import Data.Argonaut.Encode.Generic (genericEncodeJson)
10+import Data.Bifunctor (lmap)
11+import Data.Either (Either)
12+import Data.Functor ((<$>))
13+import Data.Generic.Rep (class Generic)
14+import Data.Maybe (Maybe(Nothing))
15+import Data.Newtype (class Newtype, unwrap, wrap)
16+import Node.HTTP.Types (ServerResponse)
17+import Effect (Effect)
18+import Effect.Aff (Aff, bracket)
19+import Effect.Class (liftEffect)
20+import Effect.Exception (Error, error)
21+import HTTPurple (RouteDuplex', Method(Post), (/), ResponseHeaders, noArgs, mkRoute, serve, ok, notFound, toJson)
22+import HTTPurple.Json.Argonaut (jsonEncoder)
23+import Compiler (Settings, Code, SuccessResult)
24+
25+
26+newtype SuccessResult_ = SuccessResult_ SuccessResult
27+
28+derive instance Generic SuccessResult_ _
29+
30+derive instance Newtype SuccessResult_ _
31+
32+instance EncodeJson SuccessResult_ where
33+ encodeJson = genericEncodeJson
34+
35+instance DecodeJson SuccessResult_ where
36+ decodeJson = genericDecodeJson
37+
38+successToJson :: SuccessResult -> Json
39+successToJson = (encodeJson :: SuccessResult_ -> Json) <<< wrap
40+
41+successFromJson_ :: Json -> Either Error SuccessResult
42+successFromJson_ json = unwrap <$> (error <<< printJsonDecodeError) `lmap` (decodeJson json :: Either JsonDecodeError SuccessResult_)
43+
44+settings :: Settings
45+settings = { protocol: "http"
46+ , hostname: "localhost"
47+ , port: 3000
48+ , parser: successFromJson_
49+ }
50+
51+data Route = Compile
52+
53+derive instance Generic Route _
54+
55+route :: RouteDuplex' Route
56+route = mkRoute
57+ { "Compile": "compile" / noArgs
58+ }
59+
60+
61+mkRouter
62+ :: forall a.
63+ String
64+ -> { method :: Method, route :: Route | a }
65+ -> Aff { headers :: ResponseHeaders, status :: Int , writeBody :: ServerResponse -> Aff Unit }
66+mkRouter js = case _ of
67+ { route: Compile, method: Post } -> ok $ toJson jsonEncoder $ successToJson { js, warnings: Nothing }
68+ _ -> notFound
69+
70+launchServerMock :: Code -> Aff (Effect Unit)
71+launchServerMock c = liftEffect do
72+ let router = mkRouter c
73+ close <- serve { port: settings.port } { route, router }
74+ pure $ close $ pure unit
75+
76+setupSrv :: forall b. Code -> Aff b -> Aff b
77+setupSrv code act = bracket (launchServerMock code) liftEffect (const act)