diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index a33d7ac..0e24489 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -11,18 +11,19 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up a PureScript toolchain uses: purescript-contrib/setup-purescript@main with: purescript: "unstable" purs-tidy: "latest" + spago: "1.0.4" - name: Cache PureScript dependencies - uses: actions/cache@v2 + uses: actions/cache@v4 with: - key: ${{ runner.os }}-spago-${{ hashFiles('**/*.dhall') }} + key: ${{ runner.os }}-spago-${{ hashFiles('spago.yaml') }} path: | .spago output @@ -30,17 +31,10 @@ jobs: run: spago install - name: Build source - run: spago build --no-install --purs-args '--censor-lib --strict' + run: spago build --strict - name: Run tests - run: spago -x test.dhall test + run: spago test - name: Check formatting run: purs-tidy check src test - - - name: Verify Bower & Pulp - if: ${{ github.ref == 'refs/heads/main' }} - run: | - npm install bower pulp@16.0.1 - npx bower install - npx pulp build -- --censor-lib --strict diff --git a/.gitignore b/.gitignore index ca5539a..1847748 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /bower_components /.psc-ide-port /.psa-stash +/.spec-results diff --git a/bower.json b/bower.json deleted file mode 100644 index 8c2f8de..0000000 --- a/bower.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "purescript-httpurple", - "license": [ - "MIT" - ], - "repository": { - "type": "git", - "url": "https://github.com/sigma-andex/purescript-httpurple.git" - }, - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "output" - ], - "dependencies": { - "purescript-aff": "^v7.1.0", - "purescript-arrays": "^v7.2.1", - "purescript-bifunctors": "^v6.0.0", - "purescript-console": "^v6.0.0", - "purescript-control": "^v6.0.0", - "purescript-debug": "^v6.0.2", - "purescript-effect": "^v4.0.0", - "purescript-either": "^v6.1.0", - "purescript-exceptions": "^v6.0.0", - "purescript-foldable-traversable": "^v6.0.0", - "purescript-foreign": "^v7.0.0", - "purescript-foreign-object": "^v4.1.0", - "purescript-functions": "^v6.0.0", - "purescript-js-uri": "https://github.com/purescript-contrib/purescript-js-uri.git#v3.1.0", - "purescript-justifill": "https://github.com/i-am-the-slime/purescript-justifill.git#v0.5.0", - "purescript-lists": "^v7.0.0", - "purescript-literals": "https://github.com/rowtype-yoga/purescript-literals.git#v1.0.2", - "purescript-maybe": "^v6.0.0", - "purescript-newtype": "^v5.0.0", - "purescript-node-buffer": "^v9.0.0", - "purescript-node-event-emitter": "https://github.com/purescript-node/purescript-node-event-emitter.git#v3.0.0", - "purescript-node-fs": "^v9.1.0", - "purescript-node-http": "^v9.1.0", - "purescript-node-net": "^v5.1.0", - "purescript-node-process": "^v11.2.0", - "purescript-node-streams": "^v9.0.0", - "purescript-options": "^v7.0.0", - "purescript-ordered-collections": "^v3.0.0", - "purescript-posix-types": "^v6.0.0", - "purescript-prelude": "^v6.0.1", - "purescript-profunctor": "^v6.0.0", - "purescript-record": "^v4.0.0", - "purescript-record-studio": "https://github.com/rowtype-yoga/purescript-record-studio.git#v1.0.4", - "purescript-refs": "^v6.0.0", - "purescript-routing-duplex": "^v0.7.0", - "purescript-safe-coerce": "^v2.0.0", - "purescript-strings": "^v6.0.1", - "purescript-transformers": "^v6.0.0", - "purescript-tuples": "^v7.0.0", - "purescript-type-equality": "^v4.0.1", - "purescript-typelevel-prelude": "^v7.0.0", - "purescript-unsafe-coerce": "^v6.0.0", - "purescript-untagged-union": "https://github.com/rowtype-yoga/purescript-untagged-union.git#v1.0.0" - } -} diff --git a/packages.dhall b/packages.dhall deleted file mode 100644 index 0617aab..0000000 --- a/packages.dhall +++ /dev/null @@ -1,155 +0,0 @@ -let upstream = - https://github.com/purescript/package-sets/releases/download/psc-0.15.10-20230804/packages.dhall - sha256:85d0df546868128fdbd6b4fc309252d69d2c0e99090c7e8ad80e97986f4d9ac4 - -in upstream - with node-event-emitter.version = "v3.0.0" - with node-event-emitter.dependencies = - [ "effect" - , "either" - , "functions" - , "maybe" - , "nullable" - , "prelude" - , "unsafe-coerce" - ] - with node-buffer.version = "v9.0.0" - with node-buffer.dependencies = - [ "arraybuffer-types" - , "effect" - , "maybe" - , "st" - , "unsafe-coerce" - , "nullable" - ] - with node-fs.version = "v9.1.0" - with node-fs.dependencies = - [ "datetime" - , "effect" - , "either" - , "enums" - , "exceptions" - , "functions" - , "integers" - , "js-date" - , "maybe" - , "node-buffer" - , "node-path" - , "node-streams" - , "nullable" - , "partial" - , "prelude" - , "strings" - , "unsafe-coerce" - ] - with node-streams.version = "v9.0.0" - with node-streams.dependencies = - [ "aff" - , "effect" - , "exceptions" - , "maybe" - , "node-buffer" - , "node-event-emitter" - , "nullable" - , "prelude" - , "unsafe-coerce" - ] - with node-process.version = "v11.2.0" - with node-process.dependencies = - [ "effect" - , "foreign-object" - , "foreign" - , "maybe" - , "node-streams" - , "node-event-emitter" - , "posix-types" - , "prelude" - , "unsafe-coerce" - ] - with node-net.version = "v5.1.0" - with node-net.dependencies = - [ "console" - , "datetime" - , "effect" - , "exceptions" - , "maybe" - , "node-buffer" - , "node-event-emitter" - , "node-fs" - , "node-streams" - , "nullable" - , "partial" - , "prelude" - , "unsafe-coerce" - ] - with node-url.version = "v7.0.0" - with node-url.dependencies = - [ "prelude" - , "effect" - , "foreign" - , "nullable" - , "tuples" - ] - with node-zlib = - { dependencies = - [ "aff" - , "console" - , "effect" - , "either" - , "functions" - , "node-buffer" - , "node-streams" - , "prelude" - , "unsafe-coerce" - ] - , repo = "https://github.com/purescript-node/purescript-node-zlib.git" - , version = "v0.4.0" - } - with node-readline.version = "v8.1.0" - with node-readline.dependencies = - [ "effect" - , "foreign" - , "node-event-emitter" - , "node-process" - , "node-streams" - , "options" - , "prelude" - ] - with node-tls = - { dependencies = - [ "console" - , "effect" - , "either" - , "exceptions" - , "foreign" - , "maybe" - , "node-buffer" - , "node-event-emitter" - , "node-net" - , "node-streams" - , "nullable" - , "partial" - , "prelude" - , "unsafe-coerce" - ] - , repo = "https://github.com/purescript-node/purescript-node-tls.git" - , version = "v0.3.1" - } - with node-http.version = "v9.1.0" - with node-http.dependencies = - [ "arraybuffer-types" - , "contravariant" - , "effect" - , "foreign" - , "foreign-object" - , "maybe" - , "node-buffer" - , "node-net" - , "node-streams" - , "node-tls" - , "node-url" - , "nullable" - , "options" - , "prelude" - , "unsafe-coerce" - ] diff --git a/spago.dhall b/spago.dhall deleted file mode 100644 index a4bd96c..0000000 --- a/spago.dhall +++ /dev/null @@ -1,46 +0,0 @@ -{ name = "httpurple" -, dependencies = - [ "aff" - , "arrays" - , "bifunctors" - , "console" - , "control" - , "effect" - , "either" - , "exceptions" - , "foldable-traversable" - , "foreign-object" - , "js-uri" - , "justifill" - , "literals" - , "maybe" - , "newtype" - , "node-buffer" - , "node-event-emitter" - , "node-fs" - , "node-net" - , "node-http" - , "node-process" - , "node-streams" - , "ordered-collections" - , "posix-types" - , "prelude" - , "profunctor" - , "record" - , "record-studio" - , "refs" - , "routing-duplex" - , "safe-coerce" - , "strings" - , "transformers" - , "tuples" - , "type-equality" - , "typelevel-prelude" - , "unsafe-coerce" - , "untagged-union" - ] -, packages = ./packages.dhall -, sources = [ "src/**/*.purs" ] -, license = "MIT" -, repository = "https://github.com/sigma-andex/purescript-httpurple.git" -} diff --git a/spago.lock b/spago.lock new file mode 100644 index 0000000..adf7c1a --- /dev/null +++ b/spago.lock @@ -0,0 +1,1986 @@ +{ + "workspace": { + "packages": { + "httpurple": { + "path": "./", + "core": { + "dependencies": [ + "aff", + "arrays", + "bifunctors", + "console", + "control", + "effect", + "either", + "exceptions", + "foldable-traversable", + "foreign-object", + "js-uri", + "justifill", + "literals", + "maybe", + "newtype", + "node-buffer", + "node-event-emitter", + "node-fs", + "node-http", + "node-net", + "node-process", + "node-streams", + "ordered-collections", + "posix-types", + "prelude", + "profunctor", + "record", + "record-studio", + "refs", + "routing-duplex", + "safe-coerce", + "strings", + "transformers", + "tuples", + "type-equality", + "typelevel-prelude", + "unsafe-coerce", + "untagged-union" + ] + }, + "test": { + "dependencies": [ + "exceptions", + "foreign", + "js-date", + "node-child-process", + "nullable", + "spec", + "spec-node", + "tailrec", + "transformers", + "typelevel-prelude", + "unsafe-coerce" + ] + } + } + }, + "package_set": { + "address": { + "registry": "77.6.0" + }, + "compiler": ">=0.15.15 <0.16.0", + "content": { + "abc-parser": "2.1.0", + "ace": "9.1.0", + "address-rfc2821": "0.1.1", + "aff": "8.0.0", + "aff-bus": "6.0.0", + "aff-coroutines": "9.0.0", + "aff-promise": "4.0.0", + "aff-retry": "2.0.0", + "affjax": "13.0.0", + "affjax-node": "1.0.0", + "affjax-web": "1.0.0", + "ansi": "7.0.0", + "apexcharts": "0.5.0", + "applicative-phases": "1.0.0", + "argonaut": "9.0.0", + "argonaut-aeson-generic": "0.4.1", + "argonaut-codecs": "9.1.0", + "argonaut-core": "7.0.0", + "argonaut-generic": "8.0.0", + "argonaut-traversals": "10.0.0", + "argparse-basic": "2.0.0", + "array-builder": "0.1.2", + "array-search": "0.6.0", + "arraybuffer": "13.2.0", + "arraybuffer-builder": "3.1.0", + "arraybuffer-types": "3.0.2", + "arrays": "7.3.0", + "arrays-extra": "0.6.1", + "arrays-zipper": "2.0.1", + "ask": "1.0.0", + "assert": "6.0.0", + "assert-multiple": "0.4.0", + "avar": "5.0.1", + "axon": "0.0.3", + "b64": "0.0.9", + "barbies": "1.0.1", + "barlow-lens": "0.9.0", + "benchlib": "0.0.4", + "bifunctors": "6.1.0", + "bigints": "7.0.1", + "blessed": "1.0.0", + "bolson": "0.3.9", + "bookhound": "0.1.7", + "bower-json": "3.0.0", + "call-by-name": "4.0.1", + "canvas": "6.0.0", + "canvas-action": "9.0.0", + "cartesian": "1.0.6", + "catenable-lists": "7.0.0", + "cbor-stream": "1.3.0", + "chameleon": "1.0.0", + "chameleon-halogen": "1.0.3", + "chameleon-react-basic": "1.1.0", + "chameleon-styled": "2.5.0", + "chameleon-transformers": "1.0.0", + "channel": "1.0.0", + "chartjs": "0.1.1", + "chartjs-halogen": "0.1.0", + "checked-exceptions": "3.1.1", + "choku": "1.0.2", + "classless": "0.1.1", + "classless-arbitrary": "0.1.1", + "classless-decode-json": "0.1.1", + "classless-encode-json": "0.1.3", + "classnames": "2.0.0", + "codec": "6.1.0", + "codec-argonaut": "10.0.0", + "codec-json": "2.0.0", + "colors": "7.0.1", + "compile-fail": "0.4.0", + "concur-core": "0.5.0", + "concur-react": "0.5.0", + "concurrent-queues": "3.0.0", + "console": "6.1.0", + "const": "6.0.0", + "contravariant": "6.0.0", + "control": "6.0.0", + "convertable-options": "1.0.0", + "coroutines": "7.0.0", + "css": "6.0.0", + "css-class-name-extractor": "0.0.4", + "css-frameworks": "1.1.0", + "csv-stream": "2.3.0", + "currency": "0.1.0", + "data-mvc": "0.0.2", + "datetime": "6.1.0", + "datetime-parsing": "0.2.0", + "debounce": "0.1.0", + "debug": "6.0.2", + "decimals": "7.1.0", + "default-values": "1.0.1", + "deku": "0.9.23", + "deno": "0.0.5", + "dissect": "1.0.0", + "distributive": "6.0.0", + "dodo-printer": "2.2.3", + "dom-filereader": "7.0.0", + "dom-indexed": "13.0.0", + "dom-simple": "0.4.0", + "dotenv": "4.0.3", + "droplet": "0.6.0", + "dts": "1.0.0", + "dual-numbers": "1.0.3", + "dynamic-buffer": "3.0.1", + "echarts-simple": "0.0.1", + "effect": "4.0.0", + "either": "6.1.0", + "elmish": "0.13.0", + "elmish-enzyme": "0.1.1", + "elmish-hooks": "0.11.0", + "elmish-html": "0.10.0", + "elmish-testing-library": "0.3.2", + "elmish-time-machine": "0.4.2", + "email-validate": "7.0.0", + "encoding": "0.0.10", + "enums": "6.0.1", + "env-names": "0.4.0", + "environment": "2.0.0", + "error": "2.0.0", + "eta-conversion": "0.3.2", + "exceptions": "6.1.0", + "exists": "6.0.0", + "exitcodes": "4.0.0", + "expect-inferred": "3.0.0", + "express": "0.9.1", + "ezfetch": "1.1.1", + "fahrtwind": "2.0.0", + "faker-ffi": "0.1.1", + "fakerjs": "0.0.1", + "fallback": "0.1.0", + "fast-vect": "1.2.0", + "fetch": "4.1.0", + "fetch-argonaut": "1.0.1", + "fetch-core": "5.1.0", + "fetch-yoga-json": "1.1.0", + "ffi-simple": "0.5.1", + "fft": "0.3.0", + "fft-js": "0.1.0", + "filterable": "5.0.0", + "fix-functor": "0.1.0", + "fixed-points": "7.0.0", + "fixed-precision": "5.0.0", + "flame": "1.6.0", + "float32": "2.0.0", + "fmt": "0.2.1", + "foldable-traversable": "6.0.0", + "foldable-traversable-extra": "0.0.6", + "foreign": "7.0.0", + "foreign-object": "4.1.0", + "foreign-readwrite": "3.4.0", + "forgetmenot": "0.1.0", + "fork": "6.0.0", + "form-urlencoded": "7.0.0", + "formatters": "7.0.0", + "framer-motion": "3.1.0", + "free": "7.1.0", + "freeap": "7.0.0", + "freer-free": "0.0.1", + "freet": "7.0.0", + "functions": "6.0.0", + "functor1": "3.0.0", + "functors": "5.0.0", + "fuzzy": "0.4.0", + "gen": "4.0.0", + "generate-values": "1.0.1", + "generic-router": "0.0.1", + "geojson": "0.0.5", + "geometria": "2.2.0", + "gesso": "1.0.1", + "gojs": "0.1.1", + "golden-test": "0.1.0", + "golem-fetch": "0.1.0", + "grain": "3.0.0", + "grain-router": "3.0.0", + "grain-virtualized": "3.0.0", + "graphql-client": "10.1.1", + "graphs": "8.1.0", + "group": "4.1.1", + "halogen": "7.0.0", + "halogen-bootstrap5": "5.3.2", + "halogen-canvas": "1.0.0", + "halogen-css": "10.0.0", + "halogen-declarative-canvas": "0.0.8", + "halogen-echarts-simple": "0.0.4", + "halogen-formless": "4.0.3", + "halogen-helix": "1.1.0", + "halogen-hooks": "0.6.3", + "halogen-hooks-extra": "0.9.0", + "halogen-infinite-scroll": "1.1.0", + "halogen-store": "0.5.4", + "halogen-storybook": "2.0.0", + "halogen-subscriptions": "2.0.0", + "halogen-svg-elems": "8.0.0", + "halogen-typewriter": "1.0.4", + "halogen-use-trigger-hooks": "1.0.0", + "halogen-vdom": "8.0.0", + "halogen-vdom-string-renderer": "0.5.0", + "halogen-xterm": "2.0.0", + "heckin": "2.0.1", + "heterogeneous": "0.7.0", + "homogeneous": "0.4.0", + "http-methods": "6.0.0", + "httpurple": "4.0.0", + "huffman": "0.4.0", + "humdrum": "0.0.1", + "hylograph-canvas": "0.1.0", + "hylograph-d3-kernel": "0.1.0", + "hylograph-graph": "0.3.0", + "hylograph-layout": "0.3.0", + "hylograph-music": "0.4.0", + "hylograph-optics": "0.1.0", + "hylograph-selection": "0.5.1", + "hylograph-simulation": "0.5.0", + "hylograph-simulation-core": "0.1.0", + "hylograph-simulation-halogen": "0.5.0", + "hylograph-transitions": "0.1.0", + "hylograph-wasm-kernel": "0.1.0", + "hyrule": "2.3.8", + "i18next": "0.1.0", + "idb": "0.2.0", + "identity": "6.0.0", + "identy": "4.0.1", + "indexed-db": "1.0.0", + "indexed-monad": "3.0.0", + "ink": "0.0.1", + "int64": "3.0.0", + "integers": "6.0.0", + "interpolate": "5.0.2", + "intersection-observer": "1.0.1", + "invariant": "6.0.0", + "jarilo": "1.0.1", + "jelly": "0.10.0", + "jelly-router": "0.3.0", + "jelly-signal": "0.4.0", + "jest": "1.0.0", + "js-abort-controller": "1.0.0", + "js-bigints": "2.2.1", + "js-date": "8.0.0", + "js-fetch": "0.2.1", + "js-fileio": "3.0.0", + "js-intl": "1.3.0", + "js-iterators": "0.1.1", + "js-maps": "0.1.2", + "js-promise": "1.0.0", + "js-promise-aff": "1.0.0", + "js-temporal": "3.0.0", + "js-timers": "6.1.0", + "js-uri": "3.1.0", + "jsdom": "1.0.0", + "jsinc": "0.5.1", + "json": "1.1.0", + "json-codecs": "5.0.0", + "justifill": "0.5.0", + "jwt": "0.0.9", + "labeled-data": "0.2.0", + "language-cst-parser": "0.14.1", + "lazy": "6.0.0", + "lazy-joe": "1.0.0", + "lcg": "4.0.0", + "leibniz": "5.0.0", + "leveldb": "1.0.1", + "liminal": "1.0.1", + "linalg": "6.0.0", + "linear": "0.1.0", + "lists": "7.0.0", + "literals": "1.0.2", + "logging": "3.0.0", + "logging-journald": "0.4.0", + "lumi-components": "18.0.0", + "machines": "7.0.0", + "maps-eager": "0.5.0", + "marionette": "1.0.0", + "marionette-react-basic-hooks": "0.1.1", + "markdown-it-js": "0.1.0", + "marked": "0.1.0", + "matrices": "5.0.1", + "matryoshka": "1.0.0", + "maybe": "6.0.0", + "media-types": "6.0.0", + "meowclient": "1.0.0", + "midi": "4.0.0", + "milkdown": "0.1.0", + "milkis": "9.0.0", + "mimetype": "0.0.1", + "minibench": "4.0.1", + "mmorph": "7.0.0", + "monad-control": "5.0.0", + "monad-logger": "1.3.1", + "monad-loops": "0.5.0", + "monad-unlift": "1.0.1", + "monoid-extras": "0.0.1", + "monoidal": "0.16.0", + "morello": "0.4.0", + "mote": "3.0.0", + "motion": "4.0.0", + "motsunabe": "2.0.0", + "mvc": "0.0.1", + "mysql": "6.0.1", + "n3": "0.1.0", + "nano-id": "1.1.0", + "nanoid": "0.1.0", + "naturals": "3.0.0", + "nested-functor": "0.2.1", + "newtype": "5.0.0", + "next-purs-rsc": "0.1.0", + "nextjs": "0.1.1", + "nextui": "0.2.0", + "node-buffer": "9.0.0", + "node-child-process": "11.1.0", + "node-event-emitter": "3.0.0", + "node-execa": "5.0.0", + "node-fs": "9.2.0", + "node-glob-basic": "2.0.0", + "node-http": "9.1.0", + "node-http2": "1.1.1", + "node-human-signals": "1.0.0", + "node-net": "5.1.0", + "node-os": "5.1.0", + "node-path": "5.0.1", + "node-process": "11.2.0", + "node-readline": "8.1.1", + "node-sqlite3": "8.0.0", + "node-stream-pipes": "2.1.6", + "node-streams": "9.0.1", + "node-tls": "0.3.1", + "node-url": "7.0.1", + "node-workerbees": "0.3.1", + "node-zlib": "0.4.0", + "nonempty": "7.0.0", + "now": "6.0.0", + "npm-package-json": "2.0.0", + "nqueens": "0.1.4", + "nullable": "6.0.0", + "numberfield": "0.2.2", + "numbers": "9.0.1", + "oak": "3.1.1", + "oak-debug": "1.2.2", + "object-maps": "0.3.0", + "ocarina": "1.5.4", + "oooooooooorrrrrrrmm-lib": "0.0.1", + "open-colors-scales-and-schemes": "1.0.0", + "open-drawing": "6.0.4", + "open-folds": "6.4.0", + "open-foreign-generic": "11.0.3", + "open-memoize": "6.2.0", + "open-mkdirp-aff": "1.2.0", + "open-pairing": "6.2.0", + "open-smolder": "12.0.2", + "options": "7.0.0", + "optparse": "5.0.1", + "ordered-collections": "3.2.0", + "ordered-set": "0.5.0", + "orders": "6.0.0", + "org-doc": "0.1.0", + "owoify": "1.2.0", + "pairs": "9.0.1", + "parallel": "7.0.0", + "parsing": "11.0.0", + "parsing-dataview": "3.2.4", + "partial": "4.0.0", + "pathy": "9.0.0", + "pha": "0.13.0", + "phaser": "0.7.0", + "phylio": "1.1.2", + "pipes": "8.0.0", + "pirates-charm": "0.0.1", + "play": "1.0.0", + "pmock": "0.9.0", + "point-free": "1.0.0", + "pointed-list": "0.5.1", + "polymorphic-vectors": "4.0.0", + "posix-types": "6.0.0", + "postgresql": "2.0.21", + "precise": "6.0.0", + "precise-datetime": "7.0.0", + "prelude": "6.0.2", + "prettier-printer": "3.0.0", + "printf": "0.1.0", + "priority-queue": "0.1.2", + "profunctor": "6.0.1", + "profunctor-lenses": "8.0.0", + "prospero": "0.1.0", + "protobuf": "4.4.0", + "ps-spa": "0.7.1", + "psa-utils": "8.0.0", + "psci-support": "6.0.0", + "punycode": "1.0.0", + "pursfmt": "0.17.0", + "qualified-do": "2.2.0", + "quantities": "12.2.0", + "quickcheck": "8.0.1", + "quickcheck-combinators": "0.1.3", + "quickcheck-laws": "7.0.0", + "quickcheck-utf8": "0.0.0", + "random": "6.0.0", + "rationals": "6.0.0", + "rdf": "0.1.0", + "react": "11.0.0", + "react-aria": "0.2.0", + "react-basic": "17.0.0", + "react-basic-classic": "3.0.0", + "react-basic-dnd": "10.1.0", + "react-basic-dom": "7.0.0", + "react-basic-dom-beta": "0.1.1", + "react-basic-emotion": "7.1.0", + "react-basic-hooks": "9.1.1", + "react-basic-storybook": "2.0.0", + "react-dnd-kit": "0.6.0", + "react-dom": "8.0.0", + "react-halo": "3.0.0", + "react-icons": "1.1.5", + "react-markdown": "0.1.0", + "react-testing-library": "4.0.1", + "react-virtuoso": "1.0.0", + "reactix": "0.6.1", + "read": "1.0.1", + "recharts": "1.1.0", + "record": "4.0.0", + "record-extra": "5.0.1", + "record-extra-srghma": "0.2.8", + "record-ptional-fields": "0.1.2", + "record-studio": "1.0.4", + "ref-lifted": "0.0.2", + "refs": "6.0.0", + "remotedata": "5.0.1", + "repr": "0.5.0", + "resize-arrays": "0.0.1", + "resize-observer": "1.0.0", + "resource": "2.0.1", + "resourcet": "1.0.0", + "result": "1.0.3", + "return": "0.2.0", + "ring-modules": "5.0.1", + "rito": "0.3.4", + "roman": "0.4.0", + "rough-notation": "1.0.2", + "routing": "11.0.0", + "routing-duplex": "0.7.0", + "run": "5.0.0", + "safe-coerce": "2.0.0", + "safely": "4.0.1", + "school-of-music": "1.3.0", + "selection-foldable": "0.2.0", + "selective-functors": "1.0.1", + "semirings": "7.0.0", + "shuffle": "2.0.0", + "sigil": "0.3.0", + "sigil-hats": "0.3.0", + "signal": "13.0.0", + "simple-emitter": "3.0.1", + "simple-i18n": "2.0.1", + "simple-json": "9.0.0", + "simple-json-generics": "0.2.1", + "simple-ulid": "3.0.0", + "sized-matrices": "1.0.0", + "sized-vectors": "5.0.2", + "slug": "3.2.0", + "small-ffi": "4.0.1", + "soundfonts": "4.1.0", + "sparse-matrices": "2.0.1", + "sparse-polynomials": "3.0.1", + "spec": "8.1.2", + "spec-discovery": "8.4.1", + "spec-mocha": "5.1.1", + "spec-node": "0.0.3", + "spec-quickcheck": "5.0.2", + "spec-reporter-xunit": "0.7.1", + "splitmix": "2.1.0", + "ssrs": "1.0.0", + "st": "6.2.0", + "statistics": "0.3.2", + "strictlypositiveint": "1.0.1", + "string-parsers": "8.0.0", + "strings": "6.0.1", + "strings-extra": "4.0.0", + "stringutils": "0.0.13", + "structured-logging": "1.0.0", + "substitute": "0.2.3", + "supabase": "0.1.0", + "supply": "0.2.0", + "svg-parser": "3.0.0", + "systemd-journald": "0.3.0", + "tagged": "4.0.2", + "tailrec": "6.1.0", + "tanstack-query": "3.0.0", + "tecton": "0.2.1", + "tecton-halogen": "0.2.0", + "temporal": "0.1.0", + "test-unit": "17.0.0", + "text-formatting": "0.1.0", + "thermite": "6.3.1", + "thermite-dom": "0.3.1", + "these": "6.0.0", + "threading": "0.0.3", + "tidy": "0.11.1", + "tidy-codegen": "4.0.1", + "tldr": "0.0.0", + "toestand": "0.9.0", + "transformation-matrix": "1.0.1", + "transformers": "6.1.0", + "transit": "1.0.0", + "tree-rose": "4.0.2", + "trivial-unfold": "0.5.0", + "ts-bridge": "4.0.0", + "tuples": "7.0.0", + "two-or-more": "1.0.0", + "type-equality": "4.0.1", + "typedenv": "2.0.1", + "typelevel": "6.0.0", + "typelevel-lists": "2.1.0", + "typelevel-peano": "1.0.1", + "typelevel-prelude": "7.0.0", + "typelevel-regex": "0.0.3", + "typelevel-rows": "0.1.0", + "typisch": "0.4.0", + "uint": "7.0.0", + "ulid": "3.0.1", + "uncurried-transformers": "1.1.0", + "undefined": "2.0.0", + "undefined-is-not-a-problem": "1.1.0", + "unfoldable": "6.0.0", + "unicode": "6.0.0", + "unique": "0.6.1", + "unlift": "1.0.1", + "unordered-collections": "3.1.0", + "unsafe-coerce": "6.0.0", + "unsafe-reference": "5.0.0", + "untagged-to-tagged": "0.1.4", + "untagged-union": "1.0.0", + "uri": "9.0.0", + "url-immutable": "1.0.0", + "url-regex-safe": "0.1.1", + "uuid": "9.0.0", + "uuidv4": "1.0.0", + "validation": "6.0.0", + "variant": "8.0.0", + "variant-encodings": "2.0.0", + "variant-gen": "1.0.0", + "vectorfield": "1.0.1", + "vectors": "2.1.0", + "versions": "7.0.0", + "visx": "0.0.2", + "vitest": "2.0.0", + "wasm-base": "0.1.1", + "web-chain": "1.0.1", + "web-clipboard": "6.0.0", + "web-cssom": "2.0.0", + "web-cssom-view": "0.1.0", + "web-dom": "6.0.0", + "web-dom-parser": "8.0.0", + "web-dom-xpath": "3.0.0", + "web-encoding": "3.0.0", + "web-events": "4.0.0", + "web-fetch": "4.0.1", + "web-file": "4.0.0", + "web-geometry": "0.1.0", + "web-html": "4.1.1", + "web-pointerevents": "2.0.0", + "web-proletarian": "1.0.0", + "web-promise": "3.2.0", + "web-resize-observer": "2.1.0", + "web-router": "1.0.0", + "web-socket": "4.0.0", + "web-storage": "5.0.0", + "web-streams": "4.0.0", + "web-touchevents": "4.0.0", + "web-uievents": "5.0.0", + "web-url": "2.0.0", + "web-workers": "1.1.0", + "web-xhr": "5.0.1", + "webb-aff-list": "0.0.2", + "webb-array": "0.0.2", + "webb-channel": "0.0.3", + "webb-commandline": "0.0.3", + "webb-directory": "0.0.7", + "webb-file": "0.0.1", + "webb-map": "0.0.1", + "webb-monad": "0.0.2", + "webb-mutex": "0.0.7", + "webb-parsing": "0.0.5", + "webb-random": "0.0.1", + "webb-refer": "0.0.3", + "webb-set": "0.0.1", + "webb-slot": "0.0.1", + "webb-stateful": "0.0.3", + "webb-string": "0.0.1", + "webb-test": "0.0.1", + "webb-thread": "0.0.2", + "webb-writer": "0.0.3", + "webextension-polyfill": "0.1.0", + "webgpu": "0.0.1", + "which": "2.0.0", + "whine-core": "0.0.34", + "xterm": "1.0.0", + "yaml-next": "3.1.1", + "yoga-acp-om": "0.1.1", + "yoga-better-auth": "0.2.2", + "yoga-bun-yoga": "0.2.1", + "yoga-config": "0.2.1", + "yoga-country": "3.0.0", + "yoga-docker-compose": "0.1.1", + "yoga-dynamodb": "0.1.1", + "yoga-elasticsearch": "0.1.1", + "yoga-fastify": "0.5.1", + "yoga-fastify-om": "0.4.4", + "yoga-fetch": "1.0.1", + "yoga-fetch-om": "0.6.3", + "yoga-heroui": "2.0.2", + "yoga-http-api": "0.3.1", + "yoga-jaeger": "0.1.1", + "yoga-json": "5.2.1", + "yoga-language": "1.0.0", + "yoga-next-fastify": "0.1.1", + "yoga-om": "2.2.0", + "yoga-om-layer": "2.1.0", + "yoga-om-strom": "0.4.2", + "yoga-om-workerbees": "0.1.2", + "yoga-opentelemetry": "0.2.0", + "yoga-options": "0.1.1", + "yoga-pino": "0.1.1", + "yoga-postgres": "6.0.0", + "yoga-react": "1.0.2", + "yoga-react-dom": "2.0.1", + "yoga-react-native": "0.2.1", + "yoga-react-om": "0.2.0", + "yoga-redis": "0.1.0", + "yoga-shadcn": "1.0.5", + "yoga-sql-types": "0.1.0", + "yoga-sqlite": "0.3.2", + "yoga-sse": "0.1.1", + "yoga-subtlecrypto": "0.1.0", + "yoga-test-docker": "0.1.2", + "yoga-timezone": "1.0.0", + "yoga-tree": "1.0.0", + "yoga-tree-svg": "0.1.0", + "yoga-tree-utils": "1.0.0", + "z3": "0.0.2", + "zipperarray": "2.0.0" + } + }, + "extra_packages": {} + }, + "packages": { + "aff": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-9BRIrSdRoYybfiUmBqgKJ66cPqxYHb277bVWQMn/9sg=", + "dependencies": [ + "control", + "datetime", + "effect", + "either", + "exceptions", + "functions", + "newtype", + "parallel", + "partial", + "prelude", + "st", + "tailrec", + "transformers", + "unsafe-coerce" + ] + }, + "ansi": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-tOUaXJFzPSfBVAqLI8hc+Tz2M1rg16cXqyHaK/3SmFg=", + "dependencies": [ + "foldable-traversable", + "lists", + "prelude" + ] + }, + "argonaut-codecs": { + "type": "registry", + "version": "9.1.0", + "integrity": "sha256-K910SBrmYallESsm8pxJYThs7lig6hxX3M4PW33Cgew=", + "dependencies": [ + "argonaut-core", + "arrays", + "bifunctors", + "either", + "foldable-traversable", + "foreign-object", + "identity", + "integers", + "lists", + "maybe", + "nonempty", + "ordered-collections", + "prelude", + "record", + "strings", + "tuples" + ] + }, + "argonaut-core": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-gYZihtBIKthVuXXoiPphMookSf8M5aHyFYkcIWqlxTM=", + "dependencies": [ + "arrays", + "control", + "either", + "foreign-object", + "functions", + "gen", + "maybe", + "nonempty", + "prelude", + "strings", + "tailrec" + ] + }, + "arraybuffer-types": { + "type": "registry", + "version": "3.0.2", + "integrity": "sha256-p05cJnSkyeoB7VHzMyc2Eb1RwUaB7Nl0sQSqEGNEUD8=", + "dependencies": [] + }, + "arrays": { + "type": "registry", + "version": "7.3.0", + "integrity": "sha256-GD4z7LCi9wzi7FCQqbWhvs8paoUK9NO+HwgXZ+KP8Rk=", + "dependencies": [ + "bifunctors", + "control", + "foldable-traversable", + "functions", + "maybe", + "nonempty", + "partial", + "prelude", + "safe-coerce", + "st", + "tailrec", + "tuples", + "unfoldable", + "unsafe-coerce" + ] + }, + "avar": { + "type": "registry", + "version": "5.0.1", + "integrity": "sha256-8V4SxF4TIWZ9Ik1P4lPzIRUAZeFBe8w5WA2VcCEKsIk=", + "dependencies": [ + "aff", + "effect", + "either", + "exceptions", + "functions", + "maybe", + "prelude" + ] + }, + "bifunctors": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-CvZRb8uI75eKIqiYntR+k05Wk6tKlMS5w8sCA2AFna0=", + "dependencies": [ + "const", + "either", + "newtype", + "prelude", + "tuples" + ] + }, + "catenable-lists": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-7+i/MHBLIRh604iCNT4ENWRWE/wuHIotER4kpdX9Ve0=", + "dependencies": [ + "control", + "foldable-traversable", + "lists", + "maybe", + "prelude", + "tuples", + "unfoldable" + ] + }, + "console": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-3T5PPz1mATZmV0C4GzkCkpLlCa5xG7u8ZNgnLrrrI1Q=", + "dependencies": [ + "effect", + "prelude" + ] + }, + "const": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-S+m0lQsxnji0z1XRUmkn+3RFuWJ5CXWuIr1u3i8Bfoc=", + "dependencies": [ + "invariant", + "newtype", + "prelude" + ] + }, + "contravariant": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-nuckEWqL80NaPmR/l9AUyrfycNh18XcvlZV9PAamwqc=", + "dependencies": [ + "const", + "either", + "newtype", + "prelude", + "tuples" + ] + }, + "control": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-0vxyYh5FL+ilxgLo954w1LqCUC0RSIivNNlb9CaNUQg=", + "dependencies": [ + "newtype", + "prelude" + ] + }, + "datetime": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-tbv6eDXy6QOD7YSknxYSbsDF32OC2JrNbSBpzMs7Doc=", + "dependencies": [ + "bifunctors", + "control", + "either", + "enums", + "foldable-traversable", + "functions", + "gen", + "integers", + "lists", + "maybe", + "newtype", + "numbers", + "ordered-collections", + "partial", + "prelude", + "tuples" + ] + }, + "distributive": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-netyJK4B32PDYHD0tF2AenKgo3urzbI770ycM0pArAo=", + "dependencies": [ + "identity", + "newtype", + "prelude", + "tuples", + "type-equality" + ] + }, + "effect": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-DdqU3bncRTjgMVPPRlAuGHVeajSPEcRaRhNuio7if6s=", + "dependencies": [ + "prelude" + ] + }, + "either": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-tBHx3PgtH4GZOApZCDkcM7szRTYJinrUrVGWazQCUUg=", + "dependencies": [ + "control", + "invariant", + "maybe", + "prelude" + ] + }, + "enums": { + "type": "registry", + "version": "6.0.1", + "integrity": "sha256-sdZOmLX5+5pASGpvVyT0vSD5BBYQjZiayjV5XiPutso=", + "dependencies": [ + "control", + "either", + "gen", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tuples", + "unfoldable" + ] + }, + "exceptions": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-nRrr+N0wk0TUFOWLR7e1n1oxcXo/X345bQUtoY9lW6A=", + "dependencies": [ + "effect", + "either", + "maybe", + "prelude" + ] + }, + "exists": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-vtLbrWNaI+pzx/2fw2AQnCovoLtcosClIhjO26QKkh8=", + "dependencies": [ + "unsafe-coerce" + ] + }, + "exitcodes": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-xBl4aFSEQ05Owp1ZvO6OxxvLK3LVzU35RSbj79SsePQ=", + "dependencies": [ + "enums", + "maybe", + "prelude" + ] + }, + "foldable-traversable": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-NGGWyCio/xjce6fPP7y3wwg7CheqllID6aJudDxbWhA=", + "dependencies": [ + "bifunctors", + "const", + "control", + "either", + "functors", + "identity", + "maybe", + "newtype", + "orders", + "prelude", + "tuples" + ] + }, + "foreign": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-jiDRMVQfovGsbbA/FzbzYf6iWk9i2b5gNrIjz+gFfsI=", + "dependencies": [ + "either", + "functions", + "integers", + "lists", + "maybe", + "prelude", + "strings", + "transformers", + "unsafe-coerce" + ] + }, + "foreign-object": { + "type": "registry", + "version": "4.1.0", + "integrity": "sha256-x/Q7r80z/vmHRKvPwhYmHP/DnJciPtsyGfRTMzayKIU=", + "dependencies": [ + "arrays", + "foldable-traversable", + "functions", + "gen", + "lists", + "maybe", + "prelude", + "st", + "tailrec", + "tuples", + "typelevel-prelude", + "unfoldable", + "unsafe-coerce" + ] + }, + "fork": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-0keBVeZZg1eCZEy/En1CohVW829gQUqKtqBNIRa93/A=", + "dependencies": [ + "aff", + "prelude", + "transformers" + ] + }, + "free": { + "type": "registry", + "version": "7.1.0", + "integrity": "sha256-tUBInfUpRQEw4u94GWcYW7EYdmSdDHSRn88a+C0eltU=", + "dependencies": [ + "catenable-lists", + "control", + "distributive", + "either", + "exists", + "foldable-traversable", + "invariant", + "lazy", + "maybe", + "prelude", + "tailrec", + "transformers", + "tuples", + "unsafe-coerce" + ] + }, + "functions": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-0jgtOr+SFO4UScKc40oA/9Vdcf2rLn3h3vZlY0KfqVo=", + "dependencies": [ + "prelude" + ] + }, + "functors": { + "type": "registry", + "version": "5.0.0", + "integrity": "sha256-W1o/4wcp6S3chodYL8uixlXK2mfr1L+SzM1R+whqUco=", + "dependencies": [ + "bifunctors", + "const", + "contravariant", + "control", + "distributive", + "either", + "invariant", + "maybe", + "newtype", + "prelude", + "profunctor", + "tuples", + "unsafe-coerce" + ] + }, + "gen": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-kyOateeOtQa07vfTMYeSuCKdelgKE1R65fwKkZ10wsY=", + "dependencies": [ + "either", + "foldable-traversable", + "identity", + "maybe", + "newtype", + "nonempty", + "prelude", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "heterogeneous": { + "type": "registry", + "version": "0.7.0", + "integrity": "sha256-pQwcFvhWL8noktxaoD7FlLs2F2lYf3QHoyO0VOWO3I0=", + "dependencies": [ + "either", + "foldable-traversable", + "functors", + "prelude", + "record", + "tuples", + "variant" + ] + }, + "identity": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-RY/iXPpxpqvKHYfJeFVNI1J06kohB9rbtWYuha8t0LE=", + "dependencies": [ + "control", + "invariant", + "newtype", + "prelude" + ] + }, + "integers": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-Y8yozC1uHRLcruobEyv5/bMKzE1BoKJ/olHv6o+bgm8=", + "dependencies": [ + "maybe", + "numbers", + "prelude" + ] + }, + "invariant": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-HyoT1I5qIHRq8RSZji6zZDvqnpVjLw748utrKwZtqsw=", + "dependencies": [ + "control", + "prelude" + ] + }, + "js-date": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-DNQrp4xYc8o80jtxo0aOkUeXGi6h0Xidkk2ZQ8Y4l5Y=", + "dependencies": [ + "datetime", + "effect", + "enums", + "foreign", + "functions", + "integers", + "maybe", + "prelude" + ] + }, + "js-uri": { + "type": "registry", + "version": "3.1.0", + "integrity": "sha256-7waHOctAfqhhw540FNJ7C/YsDMQW9TmA+SpHhduH6Uw=", + "dependencies": [ + "functions", + "maybe", + "prelude" + ] + }, + "justifill": { + "type": "registry", + "version": "0.5.0", + "integrity": "sha256-IwoDO72+IROcUvFIwnronb/ny8SepssgTUG3Qp2TEKg=", + "dependencies": [ + "maybe", + "prelude", + "record", + "typelevel-prelude" + ] + }, + "lazy": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-MHRC+1Pc+AjortBp4b/e1e6KpEpsDwaJBNBB7TOL+1I=", + "dependencies": [ + "control", + "foldable-traversable", + "invariant", + "prelude" + ] + }, + "lists": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-/mGd7wLoU+wsTcqii7SSUByxsvwvjnu2PjwAD47yYb4=", + "dependencies": [ + "bifunctors", + "control", + "foldable-traversable", + "lazy", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "literals": { + "type": "registry", + "version": "1.0.2", + "integrity": "sha256-ZkGRFD6gb8etYvyMYpX1Z7lx1Tql7R1VGnD1Dzinup8=", + "dependencies": [ + "integers", + "maybe", + "numbers", + "partial", + "prelude", + "typelevel-prelude", + "unsafe-coerce" + ] + }, + "maybe": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-8X6XEgtZ5lqfkEuc1hWOofnL6mwhk8gSJTxwvbR/SbY=", + "dependencies": [ + "control", + "invariant", + "newtype", + "prelude" + ] + }, + "mmorph": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-Cfltaq+tfYjuSoSBN/b8cSQZbvZTqIRs6ebQewbIkGs=", + "dependencies": [ + "bifunctors", + "either", + "free", + "functors", + "identity", + "maybe", + "newtype", + "prelude", + "transformers", + "tuples" + ] + }, + "newtype": { + "type": "registry", + "version": "5.0.0", + "integrity": "sha256-dt6w0cty4OS+Pjt9fsh3iU6ottqSU83mdAZkaEEvo6c=", + "dependencies": [ + "prelude", + "safe-coerce" + ] + }, + "node-buffer": { + "type": "registry", + "version": "9.0.0", + "integrity": "sha256-RdQjilmEHqsT4fwpCr8Mavw8KTafYrS3ZM6zeAAVAl8=", + "dependencies": [ + "arraybuffer-types", + "effect", + "functions", + "maybe", + "nullable", + "partial", + "prelude", + "st", + "unsafe-coerce" + ] + }, + "node-child-process": { + "type": "registry", + "version": "11.1.0", + "integrity": "sha256-Um7g75gXKEX51ZlviJWocTjUENUW1qHgqGqhYKkka74=", + "dependencies": [ + "aff", + "datetime", + "effect", + "either", + "exceptions", + "foreign", + "foreign-object", + "functions", + "maybe", + "node-buffer", + "node-event-emitter", + "node-fs", + "node-os", + "node-streams", + "nullable", + "parallel", + "partial", + "posix-types", + "prelude", + "refs", + "safe-coerce", + "unsafe-coerce" + ] + }, + "node-event-emitter": { + "type": "registry", + "version": "3.0.0", + "integrity": "sha256-wodx71NxJBPXOaawFn01V1ByYB2vT+I3RuV2giOVKMg=", + "dependencies": [ + "effect", + "either", + "functions", + "maybe", + "nullable", + "prelude", + "unsafe-coerce" + ] + }, + "node-fs": { + "type": "registry", + "version": "9.2.0", + "integrity": "sha256-fxioTSm9y47WuYs9F/7nxCh/RVDCl3Kr3Hg779J4SJA=", + "dependencies": [ + "aff", + "datetime", + "effect", + "either", + "enums", + "exceptions", + "functions", + "integers", + "js-date", + "maybe", + "node-buffer", + "node-path", + "node-streams", + "nullable", + "partial", + "prelude", + "strings" + ] + }, + "node-http": { + "type": "registry", + "version": "9.1.0", + "integrity": "sha256-V6EFML/uqvBEUlQsph0VPuLQCtZdn51HJTa6yxh7YTk=", + "dependencies": [ + "arrays", + "datetime", + "effect", + "exceptions", + "foreign", + "foreign-object", + "maybe", + "node-buffer", + "node-event-emitter", + "node-net", + "node-streams", + "node-tls", + "node-url", + "nullable", + "prelude", + "unsafe-coerce" + ] + }, + "node-net": { + "type": "registry", + "version": "5.1.0", + "integrity": "sha256-e2kxHXolOzYD/OkZekYlVPwCl/b4WqyLOodA6QX7FQI=", + "dependencies": [ + "datetime", + "effect", + "exceptions", + "maybe", + "node-event-emitter", + "node-fs", + "node-streams", + "nullable", + "partial", + "prelude", + "unsafe-coerce" + ] + }, + "node-os": { + "type": "registry", + "version": "5.1.0", + "integrity": "sha256-UtQiPiZy5ouV832ubww/U8KlpVYny9xsW8WWfYOEgtA=", + "dependencies": [ + "arrays", + "bifunctors", + "control", + "datetime", + "effect", + "either", + "exceptions", + "foreign", + "foreign-object", + "functions", + "maybe", + "node-buffer", + "nullable", + "partial", + "posix-types", + "prelude", + "unsafe-coerce" + ] + }, + "node-path": { + "type": "registry", + "version": "5.0.1", + "integrity": "sha256-j7n/SmpVz0FOMJl4XZop3ofJ+MeIPkMNqUEUKHEL6Us=", + "dependencies": [ + "effect" + ] + }, + "node-process": { + "type": "registry", + "version": "11.2.0", + "integrity": "sha256-onzKeNmaeYfN3HSDPqSFTrrP2Yl9tnVsfKKhnf2plxM=", + "dependencies": [ + "effect", + "exceptions", + "foreign", + "foreign-object", + "maybe", + "node-event-emitter", + "node-streams", + "nullable", + "posix-types", + "prelude", + "strings" + ] + }, + "node-streams": { + "type": "registry", + "version": "9.0.1", + "integrity": "sha256-yuVGm/R/tBr4Nphi+a1a984Z0fkmN9Q5wWtSmbmJTpA=", + "dependencies": [ + "aff", + "arrays", + "effect", + "either", + "exceptions", + "maybe", + "node-buffer", + "node-event-emitter", + "nullable", + "prelude", + "refs", + "st", + "tailrec", + "unsafe-coerce" + ] + }, + "node-tls": { + "type": "registry", + "version": "0.3.1", + "integrity": "sha256-TRTFNDfY65UUN5dZO+00qwNc4Ab7cpj2mi7B0VIKq3w=", + "dependencies": [ + "effect", + "either", + "exceptions", + "foreign", + "maybe", + "node-buffer", + "node-event-emitter", + "node-net", + "nullable", + "partial", + "prelude", + "unsafe-coerce" + ] + }, + "node-url": { + "type": "registry", + "version": "7.0.1", + "integrity": "sha256-4h+vxO0RMrLN85hAQnoOjN6qD0jRIODhQcBIJXkat/4=", + "dependencies": [ + "effect", + "foreign", + "functions", + "maybe", + "nullable", + "prelude", + "tuples" + ] + }, + "nonempty": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-Ctkq8/+KiGqCE53Y/LvibA/coy7ev9HtRZU+GYS7yfQ=", + "dependencies": [ + "control", + "foldable-traversable", + "maybe", + "prelude", + "tuples", + "unfoldable" + ] + }, + "now": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-mTyG4s8tps3XIf0jjV/lME2/QlwMzrQly2wqfSSUM3o=", + "dependencies": [ + "datetime", + "effect", + "prelude" + ] + }, + "nullable": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-CDAZk+L9Sc0GCFTkE8n+qdp4Ys8avvnkU+m2hVALt7M=", + "dependencies": [ + "functions", + "maybe", + "prelude" + ] + }, + "numbers": { + "type": "registry", + "version": "9.0.1", + "integrity": "sha256-ZydYckgwRAnRaFC7pu6fADhzdwX+UqHZrfJyet64zls=", + "dependencies": [ + "functions", + "maybe", + "prelude" + ] + }, + "open-memoize": { + "type": "registry", + "version": "6.2.0", + "integrity": "sha256-yJLuVYX8FocHIJ+6q7efH/Pj4S+e1Y57DZ5Dn7qf4ww=", + "dependencies": [ + "either", + "integers", + "lazy", + "lists", + "maybe", + "partial", + "prelude", + "strings", + "tuples" + ] + }, + "optparse": { + "type": "registry", + "version": "5.0.1", + "integrity": "sha256-2btDjHPRR0uujUQJuZAN9AzvVoXe7yG6IwnY5evERhQ=", + "dependencies": [ + "arrays", + "bifunctors", + "control", + "effect", + "either", + "enums", + "exists", + "exitcodes", + "foldable-traversable", + "free", + "integers", + "lazy", + "lists", + "maybe", + "newtype", + "node-buffer", + "node-process", + "node-streams", + "nonempty", + "numbers", + "open-memoize", + "partial", + "prelude", + "strings", + "tailrec", + "transformers", + "tuples" + ] + }, + "ordered-collections": { + "type": "registry", + "version": "3.2.0", + "integrity": "sha256-NaEXc2cz/7lJfxPWEja4XlZbGxuRqJwFKQJjsJf51kQ=", + "dependencies": [ + "arrays", + "control", + "foldable-traversable", + "functions", + "gen", + "lists", + "maybe", + "newtype", + "partial", + "prelude", + "safe-coerce", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "orders": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-nSMxZK7wxyDULkjZqvMyB71mVo6b0AyLLHosDVbv1XM=", + "dependencies": [ + "newtype", + "prelude" + ] + }, + "parallel": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-bAGpVhrFz2IyHkA4MR7+tE/19FZ7dzYBdYPgK5svkqw=", + "dependencies": [ + "control", + "effect", + "either", + "foldable-traversable", + "functors", + "maybe", + "newtype", + "prelude", + "profunctor", + "refs", + "transformers" + ] + }, + "partial": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-mdrlJBAgFMh79hNRW39uv7c+BwnnaOrAMmdh7+VhEhs=", + "dependencies": [] + }, + "pipes": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-dtUNpG8BGVr7pu6mQZyAnUAftUHgNS7f0QH3Kw5UTpQ=", + "dependencies": [ + "aff", + "control", + "effect", + "either", + "foldable-traversable", + "identity", + "lists", + "maybe", + "mmorph", + "newtype", + "prelude", + "tailrec", + "transformers", + "tuples" + ] + }, + "posix-types": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-Je5jG439F/SFO/IvVevZnWVxDIonrehlKuJkefP2lHE=", + "dependencies": [ + "maybe", + "newtype", + "prelude" + ] + }, + "prelude": { + "type": "registry", + "version": "6.0.2", + "integrity": "sha256-IqykrDRquGUD/LRSad7y75hZv3bUsGQ4knc8tdez8Qw=", + "dependencies": [] + }, + "profunctor": { + "type": "registry", + "version": "6.0.1", + "integrity": "sha256-Ow0mJC+PIIRq/a3mzCWY5vxuTgR/e+Ee68+mWeSRnWY=", + "dependencies": [ + "control", + "distributive", + "either", + "exists", + "invariant", + "newtype", + "prelude", + "tuples" + ] + }, + "record": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-WQ8fqp4X1wTA70J4qUcPW4Z7DCwx6e5KJnT/EuTdWSc=", + "dependencies": [ + "functions", + "prelude", + "unsafe-coerce" + ] + }, + "record-studio": { + "type": "registry", + "version": "1.0.4", + "integrity": "sha256-CRnFvSXpDDzio+buibUxFU9zPZDd7/lzrYC1Ya3FuIw=", + "dependencies": [ + "heterogeneous", + "lists", + "prelude", + "record", + "typelevel-prelude", + "unsafe-coerce" + ] + }, + "refs": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-KKD5G9dR2SauuDGULUJsxjqDOEi1Jqm+2Sq5U2mY8YU=", + "dependencies": [ + "effect", + "prelude" + ] + }, + "routing-duplex": { + "type": "registry", + "version": "0.7.0", + "integrity": "sha256-rQw9yC01qE/LS134zucIhLD6GFcVUzHX5HyzwosdGXM=", + "dependencies": [ + "arrays", + "control", + "either", + "foldable-traversable", + "integers", + "js-uri", + "lazy", + "maybe", + "newtype", + "prelude", + "profunctor", + "record", + "strings", + "tuples" + ] + }, + "safe-coerce": { + "type": "registry", + "version": "2.0.0", + "integrity": "sha256-EJrxtKt5xC7TYjBZrSBO/J7Aw3DmtilYjt4olpAXWVc=", + "dependencies": [ + "unsafe-coerce" + ] + }, + "spec": { + "type": "registry", + "version": "8.1.2", + "integrity": "sha256-klPPJ6lBQI1CGOAdLJ+ZoGRt8XZippkTKjn53BrSkL0=", + "dependencies": [ + "aff", + "ansi", + "arrays", + "avar", + "bifunctors", + "control", + "datetime", + "effect", + "either", + "exceptions", + "foldable-traversable", + "fork", + "identity", + "integers", + "lists", + "maybe", + "newtype", + "now", + "ordered-collections", + "parallel", + "pipes", + "prelude", + "refs", + "strings", + "tailrec", + "transformers", + "tuples" + ] + }, + "spec-node": { + "type": "registry", + "version": "0.0.3", + "integrity": "sha256-8/9+g0obbamV0YtqzmttbWs8HaWF7CEeW+eDtqzuAAo=", + "dependencies": [ + "aff", + "argonaut-codecs", + "argonaut-core", + "arrays", + "control", + "datetime", + "effect", + "either", + "foldable-traversable", + "identity", + "integers", + "maybe", + "newtype", + "node-buffer", + "node-fs", + "node-process", + "now", + "numbers", + "optparse", + "ordered-collections", + "partial", + "prelude", + "spec", + "strings", + "tuples" + ] + }, + "st": { + "type": "registry", + "version": "6.2.0", + "integrity": "sha256-WI4MEkkwUd4pnwZQ3G8VKWgX5t1RSNJludm5e9boaRo=", + "dependencies": [ + "effect", + "partial", + "prelude", + "tailrec", + "unsafe-coerce" + ] + }, + "strings": { + "type": "registry", + "version": "6.0.1", + "integrity": "sha256-FNto2hoNW5Da6W6crIk77YXMagBvOGHZE1kO7eZ1vLM=", + "dependencies": [ + "arrays", + "control", + "either", + "enums", + "foldable-traversable", + "gen", + "integers", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tailrec", + "tuples", + "unfoldable", + "unsafe-coerce" + ] + }, + "tailrec": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-xrorCfP0xV1wubs27idQCHQqdvSUuqmmL/am7Ji1wVU=", + "dependencies": [ + "bifunctors", + "effect", + "either", + "identity", + "maybe", + "partial", + "prelude", + "refs" + ] + }, + "transformers": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-QJmgNT/y7ljPHSsXaW4zxF/982BFiQ90KNL1g/NtEOQ=", + "dependencies": [ + "control", + "distributive", + "effect", + "either", + "exceptions", + "foldable-traversable", + "identity", + "lazy", + "maybe", + "newtype", + "prelude", + "st", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "tuples": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-BKy7EfK8S1KeTCwyWqyW1wwcpSAQuh3IsczSVgS6fzY=", + "dependencies": [ + "control", + "invariant", + "prelude" + ] + }, + "type-equality": { + "type": "registry", + "version": "4.0.1", + "integrity": "sha256-BBqYOSnAKmayRvR5mtZoCf4SlYs2ipatD/+5nQx73aw=", + "dependencies": [] + }, + "typelevel-prelude": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-+pHi14/40mTj/+lmCWqL0T7iXIXD1+NSg/KItyyoB0A=", + "dependencies": [ + "prelude", + "type-equality" + ] + }, + "unfoldable": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-BK/6By1sKp/ztk+9CF3q43SV0QDTLVdsGqFerKHSmbg=", + "dependencies": [ + "foldable-traversable", + "maybe", + "partial", + "prelude", + "tuples" + ] + }, + "unsafe-coerce": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-0L1QsaY20OILjfU5TV72d3U/tSjhmL9hJ32WMp857Lk=", + "dependencies": [] + }, + "untagged-union": { + "type": "registry", + "version": "1.0.0", + "integrity": "sha256-MQvpb13TZEBoi9n/AoQ7ugniSQqbN6XQmAjii9pqJRk=", + "dependencies": [ + "either", + "foreign", + "foreign-object", + "literals", + "maybe", + "newtype", + "prelude", + "tuples", + "unsafe-coerce" + ] + }, + "variant": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-Ydrgl8liWEwYQOWW76PdZtg3vxKpoKgsnmFyTLgZkoU=", + "dependencies": [ + "control", + "enums", + "foldable-traversable", + "lists", + "maybe", + "partial", + "prelude", + "type-equality", + "unsafe-coerce" + ] + } + } +} diff --git a/spago.yaml b/spago.yaml new file mode 100644 index 0000000..5c54e6e --- /dev/null +++ b/spago.yaml @@ -0,0 +1,58 @@ +package: + name: httpurple + dependencies: + - aff + - arrays + - bifunctors + - console + - control + - effect + - either + - exceptions + - foldable-traversable + - foreign-object + - js-uri + - justifill + - literals + - maybe + - newtype + - node-buffer + - node-event-emitter + - node-fs + - node-http + - node-net + - node-process + - node-streams + - ordered-collections + - posix-types + - prelude + - profunctor + - record + - record-studio + - refs + - routing-duplex + - safe-coerce + - strings + - transformers + - tuples + - type-equality + - typelevel-prelude + - unsafe-coerce + - untagged-union + test: + main: Test.Main + dependencies: + - exceptions + - foreign + - node-child-process + - spec + - spec-node + - transformers + - unsafe-coerce + - typelevel-prelude + - js-date + - nullable + - tailrec +workspace: + packageSet: + registry: 77.6.0 diff --git a/src/HTTPurple/Server.purs b/src/HTTPurple/Server.purs index b177e27..45085c8 100644 --- a/src/HTTPurple/Server.purs +++ b/src/HTTPurple/Server.purs @@ -238,9 +238,14 @@ serveInternal performM inputOptions maybeNodeMiddleware settings = do routingSettings = merge settings { notFoundHandler: fromMaybe defaultNotFoundHandler $ filledOptions.notFoundHandler } - handler req rep = launchAff_ $ performM $ case maybeNodeMiddleware of - Just nodeMiddleware -> handleExtRequestWithMiddleware (merge routingSettings { nodeMiddleware }) req rep - Nothing -> handleRequest routingSettings req rep + handler req rep = + let + action = case maybeNodeMiddleware of + Just nodeMiddleware -> handleExtRequestWithMiddleware (merge routingSettings { nodeMiddleware }) req rep + Nothing -> handleRequest routingSettings req rep + in + launchAff_ (performM action) + sslOptions = { certFile: _, keyFile: _ } <$> filledOptions.certFile <*> filledOptions.keyFile netServer <- case sslOptions of Just { certFile, keyFile } -> do diff --git a/test.dhall b/test.dhall deleted file mode 100644 index 28613ff..0000000 --- a/test.dhall +++ /dev/null @@ -1,17 +0,0 @@ -let conf = ./spago.dhall - -in conf // { - sources = conf.sources # [ "test/**/*.purs", "docs/Examples/**/*.purs" ], - dependencies = conf.dependencies # [ - , "exceptions" - , "foreign" - , "node-child-process" - , "spec" - , "transformers" - , "unsafe-coerce" - , "typelevel-prelude" - , "js-date" - , "nullable" - , "tailrec" - ] -} diff --git a/docs/Examples/AsyncResponse/Main.purs b/test/Examples/AsyncResponse/Main.purs similarity index 97% rename from docs/Examples/AsyncResponse/Main.purs rename to test/Examples/AsyncResponse/Main.purs index afbd65d..7ea4f4b 100644 --- a/docs/Examples/AsyncResponse/Main.purs +++ b/test/Examples/AsyncResponse/Main.purs @@ -3,7 +3,6 @@ module Examples.AsyncResponse.Main where import Prelude import Data.Generic.Rep (class Generic) -import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) import Effect.Console (log) import HTTPurple (Request, Response, ServerM, ok, serve) diff --git a/docs/Examples/BinaryRequest/Main.js b/test/Examples/BinaryRequest/Main.js similarity index 100% rename from docs/Examples/BinaryRequest/Main.js rename to test/Examples/BinaryRequest/Main.js diff --git a/docs/Examples/BinaryRequest/Main.purs b/test/Examples/BinaryRequest/Main.purs similarity index 98% rename from docs/Examples/BinaryRequest/Main.purs rename to test/Examples/BinaryRequest/Main.purs index 8ba0a86..8282985 100644 --- a/docs/Examples/BinaryRequest/Main.purs +++ b/test/Examples/BinaryRequest/Main.purs @@ -3,7 +3,6 @@ module Examples.BinaryRequest.Main where import Prelude import Data.Generic.Rep (class Generic) -import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) import Effect.Console (log) import HTTPurple (Request, Response, ServerM, ok, serve, toBuffer) diff --git a/docs/Examples/BinaryResponse/Main.purs b/test/Examples/BinaryResponse/Main.purs similarity index 93% rename from docs/Examples/BinaryResponse/Main.purs rename to test/Examples/BinaryResponse/Main.purs index 673804d..0e161d5 100644 --- a/docs/Examples/BinaryResponse/Main.purs +++ b/test/Examples/BinaryResponse/Main.purs @@ -3,10 +3,9 @@ module Examples.BinaryResponse.Main where import Prelude import Data.Generic.Rep (class Generic) -import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) import Effect.Console (log) -import HTTPurple (Request, ResponseHeaders, Response, ServerM, header, ok', serve) +import HTTPurple (Request, Response, ResponseHeaders, ServerM, header, ok', serve) import Node.FS.Aff (readFile) import Routing.Duplex as RD import Routing.Duplex.Generic as RG diff --git a/docs/Examples/Chunked/Main.purs b/test/Examples/Chunked/Main.purs similarity index 91% rename from docs/Examples/Chunked/Main.purs rename to test/Examples/Chunked/Main.purs index 49aa68d..49beefc 100644 --- a/docs/Examples/Chunked/Main.purs +++ b/test/Examples/Chunked/Main.purs @@ -3,12 +3,11 @@ module Examples.Chunked.Main where import Prelude import Data.Generic.Rep (class Generic) -import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) import Effect.Class (liftEffect) import Effect.Console (log) import HTTPurple (Request, Response, ServerM, ok, serve) -import Node.ChildProcess (defaultSpawnOptions, spawn, stdout) +import Node.ChildProcess (spawn, stdout) import Node.Stream (Readable) import Routing.Duplex as RD import Routing.Duplex.Generic as RG @@ -25,7 +24,7 @@ route = RD.root $ RG.sum -- | Run a script and return it's stdout stream runScript :: String -> Aff (Readable ()) runScript script = - liftEffect $ stdout <$> spawn "bash" [ "-c", script ] defaultSpawnOptions + liftEffect $ stdout <$> spawn "bash" [ "-c", script ] -- | Say 'hello world!' in chunks when run router :: Request Route -> Aff Response diff --git a/docs/Examples/CustomStack/Main.purs b/test/Examples/CustomStack/Main.purs similarity index 91% rename from docs/Examples/CustomStack/Main.purs rename to test/Examples/CustomStack/Main.purs index 617420f..81f35af 100644 --- a/docs/Examples/CustomStack/Main.purs +++ b/test/Examples/CustomStack/Main.purs @@ -31,7 +31,7 @@ sayHello _ = do -- | Boot up the server main :: ServerM main = - serve' (\a -> runReaderT a {name: "joe"}) { hostname: "localhost", port: 8080, onStarted } { route, router: sayHello } + serve' (\a -> runReaderT a { name: "joe" }) { hostname: "localhost", port: 8080, onStarted } { route, router: sayHello } where onStarted = do log " ┌───────────────────────────────────────┐" diff --git a/docs/Examples/ExtensibleMiddleware/Main.purs b/test/Examples/ExtensibleMiddleware/Main.purs similarity index 100% rename from docs/Examples/ExtensibleMiddleware/Main.purs rename to test/Examples/ExtensibleMiddleware/Main.purs diff --git a/docs/Examples/Headers/Main.purs b/test/Examples/Headers/Main.purs similarity index 96% rename from docs/Examples/Headers/Main.purs rename to test/Examples/Headers/Main.purs index 19681ec..1d93579 100644 --- a/docs/Examples/Headers/Main.purs +++ b/test/Examples/Headers/Main.purs @@ -5,7 +5,7 @@ import Prelude import Data.Generic.Rep (class Generic) import Effect.Aff (Aff) import Effect.Console (log) -import HTTPurple (Request, ResponseHeaders, Response, ServerM, ok', serve, (!@)) +import HTTPurple (Request, Response, ResponseHeaders, ServerM, ok', serve, (!@)) import HTTPurple.Headers (headers) import Routing.Duplex as RD import Routing.Duplex.Generic as RG diff --git a/docs/Examples/HelloWorld/Main.purs b/test/Examples/HelloWorld/Main.purs similarity index 100% rename from docs/Examples/HelloWorld/Main.purs rename to test/Examples/HelloWorld/Main.purs diff --git a/docs/Examples/JsonParsing/Main.js b/test/Examples/JsonParsing/Main.js similarity index 100% rename from docs/Examples/JsonParsing/Main.js rename to test/Examples/JsonParsing/Main.js diff --git a/docs/Examples/JsonParsing/Main.purs b/test/Examples/JsonParsing/Main.purs similarity index 100% rename from docs/Examples/JsonParsing/Main.purs rename to test/Examples/JsonParsing/Main.purs diff --git a/docs/Examples/Middleware/Main.purs b/test/Examples/Middleware/Main.purs similarity index 99% rename from docs/Examples/Middleware/Main.purs rename to test/Examples/Middleware/Main.purs index c36c2c4..996f9bd 100644 --- a/docs/Examples/Middleware/Main.purs +++ b/test/Examples/Middleware/Main.purs @@ -4,7 +4,6 @@ import Prelude hiding ((/)) import Data.Either (Either(..)) import Data.Generic.Rep (class Generic) -import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) import Effect.Class (liftEffect) import Effect.Console (log) diff --git a/docs/Examples/MultiRoute/Main.purs b/test/Examples/MultiRoute/Main.purs similarity index 97% rename from docs/Examples/MultiRoute/Main.purs rename to test/Examples/MultiRoute/Main.purs index 860d923..d83e270 100644 --- a/docs/Examples/MultiRoute/Main.purs +++ b/test/Examples/MultiRoute/Main.purs @@ -3,7 +3,6 @@ module Examples.MultiRoute.Main where import Prelude hiding ((/)) import Data.Generic.Rep (class Generic) -import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) import Effect.Console (log) import HTTPurple (Request, Response, ServerM, ok, serve) diff --git a/docs/Examples/NodeMiddleware/Main.js b/test/Examples/NodeMiddleware/Main.js similarity index 100% rename from docs/Examples/NodeMiddleware/Main.js rename to test/Examples/NodeMiddleware/Main.js diff --git a/docs/Examples/NodeMiddleware/Main.purs b/test/Examples/NodeMiddleware/Main.purs similarity index 100% rename from docs/Examples/NodeMiddleware/Main.purs rename to test/Examples/NodeMiddleware/Main.purs diff --git a/docs/Examples/PathSegments/Main.purs b/test/Examples/PathSegments/Main.purs similarity index 98% rename from docs/Examples/PathSegments/Main.purs rename to test/Examples/PathSegments/Main.purs index 27d3bfc..61d2b91 100644 --- a/docs/Examples/PathSegments/Main.purs +++ b/test/Examples/PathSegments/Main.purs @@ -3,7 +3,6 @@ module Examples.PathSegments.Main where import Prelude hiding ((/)) import Data.Generic.Rep (class Generic) -import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) import Effect.Console (log) import HTTPurple (Request, Response, ServerM, ok, serve) diff --git a/docs/Examples/Post/Main.purs b/test/Examples/Post/Main.purs similarity index 97% rename from docs/Examples/Post/Main.purs rename to test/Examples/Post/Main.purs index 2a30f87..40b235e 100644 --- a/docs/Examples/Post/Main.purs +++ b/test/Examples/Post/Main.purs @@ -3,7 +3,6 @@ module Examples.Post.Main where import Prelude import Data.Generic.Rep (class Generic) -import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) import Effect.Console (log) import HTTPurple (Method(Post), Request, Response, ServerM, notFound, ok, serve, toString) diff --git a/docs/Examples/QueryParameters/Main.purs b/test/Examples/QueryParameters/Main.purs similarity index 100% rename from docs/Examples/QueryParameters/Main.purs rename to test/Examples/QueryParameters/Main.purs diff --git a/docs/Examples/SSL/Main.purs b/test/Examples/SSL/Main.purs similarity index 98% rename from docs/Examples/SSL/Main.purs rename to test/Examples/SSL/Main.purs index e1e527e..a82ea03 100644 --- a/docs/Examples/SSL/Main.purs +++ b/test/Examples/SSL/Main.purs @@ -3,7 +3,6 @@ module Examples.SSL.Main where import Prelude import Data.Generic.Rep (class Generic) -import Data.Maybe (Maybe(..)) import Effect.Aff (Aff) import Effect.Console (log) import HTTPurple (Request, Response, ServerM, ok, serve) diff --git a/test/Test/HTTPurple/RequestSpec.purs b/test/Test/HTTPurple/RequestSpec.purs index 9627287..3975157 100644 --- a/test/Test/HTTPurple/RequestSpec.purs +++ b/test/Test/HTTPurple/RequestSpec.purs @@ -3,8 +3,7 @@ module Test.HTTPurple.RequestSpec where import Prelude import Control.Monad.Error.Class (throwError) -import Data.Bitraversable (rtraverse) -import Data.Either (Either(..), either, fromRight) +import Data.Either (Either, either) import Data.Generic.Rep (class Generic) import Data.Maybe (Maybe) import Data.Tuple (Tuple(Tuple)) @@ -12,9 +11,9 @@ import Effect.Aff (Aff) import Effect.Exception (error) import Foreign.Object (singleton) import HTTPurple.Body (toString) -import HTTPurple.Headers (headers, mkRequestHeaders) +import HTTPurple.Headers (mkRequestHeaders) import HTTPurple.Method (Method(Post)) -import HTTPurple.Request (fromHTTPRequest, fullPath) +import HTTPurple.Request (fromHTTPRequest) import HTTPurple.Version (Version(HTTP1_1)) import Routing.Duplex as RD import Routing.Duplex.Generic as G diff --git a/test/Test/HTTPurple/ServerSpec.purs b/test/Test/HTTPurple/ServerSpec.purs index ccfeabe..1ff75ae 100644 --- a/test/Test/HTTPurple/ServerSpec.purs +++ b/test/Test/HTTPurple/ServerSpec.purs @@ -4,8 +4,7 @@ import Prelude import Control.Monad.Except (throwError) import Data.Generic.Rep (class Generic) -import Effect.Aff (Aff) -import Effect.Class (liftEffect) +import Effect.Aff (Aff, bracket) import Effect.Exception (error) import Foreign.Object (empty) import HTTPurple.Request (Request) @@ -14,7 +13,7 @@ import Routing.Duplex (RouteDuplex') import Routing.Duplex as RD import Routing.Duplex.Generic as G import Routing.Duplex.Generic as RG -import Test.HTTPurple.TestHelpers (Test, get, get', getStatus, serveAwaitStarted, (?=)) +import Test.HTTPurple.TestHelpers (Test, get, get', getStatus, serveAwaitClosed, serveAwaitStarted, (?=)) import Test.Spec (describe, it) import Test.Spec.Assertions (expectError) @@ -34,37 +33,43 @@ serveSpec :: Test serveSpec = describe "serve" do it "boots a server on the given port" do - close <- serveAwaitStarted { hostname: "localhost", port: 8080 } { route, router: mockRouter } - out <- get 8080 empty "/test" - liftEffect $ close $ pure unit - out ?= "/test" + bracket + (serveAwaitStarted { hostname: "localhost", port: 8080 } { route, router: mockRouter }) + serveAwaitClosed + \_ -> do + out <- get 8080 empty "/test" + out ?= "/test" it "responds with a 500 upon unhandled exceptions" do let router _ = throwError $ error "fail!" - close <- serveAwaitStarted { hostname: "localhost", port: 8080 } { route, router } - status <- getStatus 8080 empty "/test" - liftEffect $ close $ pure unit - status ?= 500 + bracket + (serveAwaitStarted { hostname: "localhost", port: 8080 } { route, router }) + serveAwaitClosed + \_ -> do + status <- getStatus 8080 empty "/test" + status ?= 500 serve'Spec :: Test serve'Spec = describe "serve'" do it "boots a server with the given options" do - close <- - serveAwaitStarted { hostname: "localhost", port: 8080 } { route, router: mockRouter } - out <- get 8080 empty "/test" - liftEffect $ close $ pure unit - out ?= "/test" + bracket + (serveAwaitStarted { hostname: "localhost", port: 8080 } { route, router: mockRouter }) + serveAwaitClosed + \_ -> do + out <- get 8080 empty "/test" + out ?= "/test" serveSecureSpec :: Test serveSecureSpec = describe "serveSecure" do describe "with valid key and cert files" do it "boots a server on the given port" do - close <- - serveAwaitStarted { hostname: "localhost", port: 8080, certFile: "./test/Mocks/Certificate.cer", keyFile: "./test/Mocks/Key.key" } { route, router: mockRouter } - out <- get' 8080 empty "/test" - liftEffect $ close $ pure unit - out ?= "/test" + bracket + (serveAwaitStarted { hostname: "localhost", port: 8080, certFile: "./test/Mocks/Certificate.cer", keyFile: "./test/Mocks/Key.key" } { route, router: mockRouter }) + serveAwaitClosed + \_ -> do + out <- get' 8080 empty "/test" + out ?= "/test" describe "with invalid key and cert files" do it "throws" do expectError $ serveAwaitStarted { hostname: "localhost", port: 8080, certFile: "", keyFile: "" } { route, router: mockRouter } @@ -76,11 +81,12 @@ serveSecure'Spec = it "boots a server on the given port" do let options = { hostname: "localhost", port: 8080, certFile: "./test/Mocks/Certificate.cer", keyFile: "./test/Mocks/Key.key" } - close <- - serveAwaitStarted options { route, router: mockRouter } - out <- get' 8080 empty "/test" - liftEffect $ close $ pure unit - out ?= "/test" + bracket + (serveAwaitStarted options { route, router: mockRouter }) + serveAwaitClosed + \_ -> do + out <- get' 8080 empty "/test" + out ?= "/test" serverSpec :: Test serverSpec = diff --git a/test/Test/HTTPurple/TestHelpers.js b/test/Test/HTTPurple/TestHelpers.js index b1ba368..0e429d5 100644 --- a/test/Test/HTTPurple/TestHelpers.js +++ b/test/Test/HTTPurple/TestHelpers.js @@ -1,5 +1,6 @@ import { Readable } from "stream"; import * as HTTP from "http"; +import * as HTTPS from "https"; class MockResponse extends HTTP.OutgoingMessage { body = ""; @@ -68,6 +69,12 @@ export const mockRequestImpl = /** @type {() => MockResponse} */ export const mockResponse = () => new MockResponse(); +/** @type {(opts: HTTP.RequestOptions) => () => HTTP.ClientRequest} */ +export const httpRequestOptsNoAgentImpl = (opts) => () => HTTP.request({ ...opts, agent: false }); + +/** @type {(opts: HTTPS.RequestOptions) => () => HTTP.ClientRequest} */ +export const httpsRequestOptsNoAgentImpl = (opts) => () => HTTPS.request({ ...opts, agent: false }); + /** @type {(s: string) => Readable} */ export const stringToStream = (str) => { const stream = new Readable(); diff --git a/test/Test/HTTPurple/TestHelpers.purs b/test/Test/HTTPurple/TestHelpers.purs index f67721e..509ea6c 100644 --- a/test/Test/HTTPurple/TestHelpers.purs +++ b/test/Test/HTTPurple/TestHelpers.purs @@ -13,7 +13,6 @@ import Effect (Effect) import Effect.Aff (Aff, delay, effectCanceler, makeAff, nonCanceler) import Effect.Aff.Compat (mkEffectFn1) import Effect.Class (liftEffect) -import Effect.Console (log) import Effect.Exception (Error) import Effect.Ref as Ref import Foreign (Foreign) @@ -27,12 +26,12 @@ import Node.Buffer (alloc, concat, toString) as Buffer import Node.Encoding (Encoding(UTF8)) import Node.EventEmitter (EventHandle(..), once_) import Node.EventEmitter.UtilTypes (EventHandle1) -import Node.HTTP as HTTP +import Node.HTTP (RequestOptions) import Node.HTTP.ClientRequest as HTTPClient import Node.HTTP.IncomingMessage as IM import Node.HTTP.OutgoingMessage as OM -import Node.HTTP.Types (IMClientRequest, IncomingMessage, ServerResponse) -import Node.HTTPS as HTTPS +import Node.HTTP.Types (ClientRequest, IMClientRequest, IncomingMessage, ServerResponse) +import Node.HTTPS (SecureRequestOptions) import Node.Net.Socket as Socket import Node.Net.Types (Socket) import Node.Stream (Readable) @@ -84,6 +83,13 @@ serveAwaitStarted cfg rt = Ref.write (Just stop) stopRef pure $ effectCanceler $ stop $ pure unit +-- | Closes a server and suspends the `Aff` until the server has fully shut down, +-- | ensuring the port is released before proceeding and preventing `EADDRINUSE` +serveAwaitClosed :: (Effect Unit -> Effect Unit) -> Aff Unit +serveAwaitClosed close = makeAff \done -> do + close (done (Right unit)) + pure nonCanceler + infix 1 shouldEqual as ?= -- | The type for integration tests. @@ -105,7 +111,7 @@ request :: request secure port' method' headers' path' body = makeAff \done -> do req <- case secure of - true -> HTTPS.requestOpts + true -> httpsRequestOptsNoAgent { method: method' , host: "localhost" , port: port' @@ -113,7 +119,7 @@ request secure port' method' headers' path' body = , headers: unsafeCoerce headers' :: Object Foreign , rejectUnauthorized: false } - false -> HTTP.requestOpts + false -> httpRequestOptsNoAgent { method: method' , host: "localhost" , port: port' @@ -121,9 +127,14 @@ request secure port' method' headers' path' body = , headers: unsafeCoerce headers' :: Object Foreign } let + errorH :: EventHandle1 ClientRequest Error + errorH = EventHandle "error" mkEffectFn1 + connectionAttemptFailedH :: forall t. EventHandle1 (Socket t) Error connectionAttemptFailedH = EventHandle "connectionAttemptFailed" mkEffectFn1 + req # once_ errorH (Left >>> done) + req # once_ HTTPClient.socketH ( \socket -> once_ Stream.errorH (Left >>> done) (Socket.toDuplex socket) @@ -137,6 +148,16 @@ request secure port' method' headers' path' body = $ Stream.end stream pure nonCanceler +httpRequestOptsNoAgent :: forall r trash. Union r trash (RequestOptions ()) => { | r } -> Effect ClientRequest +httpRequestOptsNoAgent = httpRequestOptsNoAgentImpl + +foreign import httpRequestOptsNoAgentImpl :: forall r. { | r } -> Effect ClientRequest + +httpsRequestOptsNoAgent :: forall r trash. Union r trash SecureRequestOptions => { | r } -> Effect ClientRequest +httpsRequestOptsNoAgent = httpsRequestOptsNoAgentImpl + +foreign import httpsRequestOptsNoAgentImpl :: forall r. { | r } -> Effect ClientRequest + -- | Same as `request` but without. request' :: Boolean -> diff --git a/test/Test/Main.purs b/test/Test/Main.purs index 0d70137..bbbb8af 100644 --- a/test/Test/Main.purs +++ b/test/Test/Main.purs @@ -2,7 +2,6 @@ module Test.Main where import Prelude -import Effect.Aff (launchAff_) import Test.HTTPurple.BodySpec (bodySpec) import Test.HTTPurple.HeadersSpec (headersSpec) import Test.HTTPurple.IntegrationSpec (integrationSpec) @@ -19,10 +18,10 @@ import Test.HTTPurple.UtilsSpec (utilsSpec) import Test.HTTPurple.VersionSpec (versionSpec) import Test.Spec (describe) import Test.Spec.Reporter (specReporter) -import Test.Spec.Runner (runSpec) +import Test.Spec.Runner.Node (runSpecAndExitProcess) main :: TestSuite -main = launchAff_ $ runSpec [ specReporter ] $ describe "HTTPurple" do +main = runSpecAndExitProcess [ specReporter ] $ describe "HTTPurple" do bodySpec headersSpec lookupSpec