diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 17809e8..a8ad873 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,31 +4,34 @@ on: push: branches: [master] pull_request: + branches: [master] jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: purescript-contrib/setup-purescript@main + - name: Set up a PureScript toolchain + uses: purescript-contrib/setup-purescript@main with: - purescript: "unstable" + purescript: "latest" + purs-tidy: "0.11.0" # "latest" + spago: "unstable" - - uses: actions/setup-node@v2 + - name: Cache PureScript dependencies + uses: actions/cache@v4 with: - node-version: "14" - - - name: Install dependencies - run: | - npm install -g bower - npm install - bower install --production + key: ${{ runner.os }}-spago-${{ hashFiles('**/spago.lock') }} + path: | + .spago + output - name: Build source - run: npm run-script build + run: spago build --censor-stats --strict --ensure-ranges --pedantic-packages - name: Run tests - run: | - bower install - npm run-script test --if-present + run: spago test --offline --censor-stats --strict --pedantic-packages + + - name: Verify formatting + run: purs-tidy check src test diff --git a/bower.json b/bower.json deleted file mode 100644 index e3ff576..0000000 --- a/bower.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "purescript-halogen-vdom-string-renderer", - "license": "Apache-2.0", - "repository": { - "type": "git", - "url": "https://github.com/purescript-halogen/purescript-halogen-vdom-string-renderer.git" - }, - "ignore": ["**/.*", "node_modules", "bower_components", "output"], - "dependencies": { - "purescript-prelude": "^6.0.0", - "purescript-halogen-vdom": "^8.0.0", - "purescript-ordered-collections": "^3.0.0", - "purescript-foreign": "^7.0.0" - } -} diff --git a/spago.lock b/spago.lock new file mode 100644 index 0000000..01ce3fe --- /dev/null +++ b/spago.lock @@ -0,0 +1,1785 @@ +{ + "workspace": { + "packages": { + "halogen-vdom-string-renderer": { + "path": "./", + "core": { + "dependencies": [ + { + "arrays": ">=7.3.0 <8.0.0" + }, + { + "foreign": ">=7.0.0 <8.0.0" + }, + { + "halogen-vdom": ">=8.0.0 <9.0.0" + }, + { + "maybe": ">=6.0.0 <7.0.0" + }, + { + "numbers": ">=9.0.1 <10.0.0" + }, + { + "ordered-collections": ">=3.2.0 <4.0.0" + }, + { + "prelude": ">=6.0.2 <7.0.0" + }, + { + "strings": ">=6.0.1 <7.0.0" + }, + { + "tuples": ">=7.0.0 <8.0.0" + }, + { + "unsafe-coerce": ">=6.0.0 <7.0.0" + } + ], + "build_plan": [ + "arrays", + "bifunctors", + "const", + "contravariant", + "control", + "datetime", + "distributive", + "effect", + "either", + "enums", + "exceptions", + "exists", + "foldable-traversable", + "foreign", + "foreign-object", + "functions", + "functors", + "gen", + "halogen-vdom", + "identity", + "integers", + "invariant", + "js-date", + "lazy", + "lists", + "maybe", + "media-types", + "newtype", + "nonempty", + "now", + "nullable", + "numbers", + "ordered-collections", + "orders", + "partial", + "prelude", + "profunctor", + "refs", + "safe-coerce", + "st", + "strings", + "tailrec", + "transformers", + "tuples", + "type-equality", + "typelevel-prelude", + "unfoldable", + "unsafe-coerce", + "web-dom", + "web-events", + "web-file", + "web-html", + "web-storage" + ] + }, + "test": { + "dependencies": [ + "effect", + "spec", + "spec-node" + ], + "build_plan": [ + "aff", + "ansi", + "argonaut-codecs", + "argonaut-core", + "arraybuffer-types", + "arrays", + "avar", + "bifunctors", + "catenable-lists", + "console", + "const", + "contravariant", + "control", + "datetime", + "distributive", + "effect", + "either", + "enums", + "exceptions", + "exists", + "exitcodes", + "foldable-traversable", + "foreign", + "foreign-object", + "fork", + "free", + "functions", + "functors", + "gen", + "identity", + "integers", + "invariant", + "js-date", + "lazy", + "lists", + "maybe", + "mmorph", + "newtype", + "node-buffer", + "node-event-emitter", + "node-fs", + "node-path", + "node-process", + "node-streams", + "nonempty", + "now", + "nullable", + "numbers", + "open-memoize", + "optparse", + "ordered-collections", + "orders", + "parallel", + "partial", + "pipes", + "posix-types", + "prelude", + "profunctor", + "record", + "refs", + "safe-coerce", + "spec", + "spec-node", + "st", + "strings", + "tailrec", + "transformers", + "tuples", + "type-equality", + "typelevel-prelude", + "unfoldable", + "unsafe-coerce" + ] + } + } + }, + "package_set": { + "address": { + "registry": "64.1.1" + }, + "compiler": ">=0.15.15 <0.16.0", + "content": { + "abc-parser": "2.0.1", + "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", + "b64": "0.0.8", + "barbies": "1.0.1", + "barlow-lens": "0.9.0", + "benchlib": "0.0.4", + "bifunctors": "6.1.0", + "bigints": "7.0.1", + "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", + "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", + "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.0.1", + "csv-stream": "2.3.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": "12.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.10.3", + "elmish-html": "0.9.0", + "elmish-testing-library": "0.3.2", + "email-validate": "7.0.0", + "encoding": "0.0.9", + "enums": "6.0.1", + "env-names": "0.4.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", + "ezfetch": "1.1.0", + "fahrtwind": "2.0.0", + "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-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.3.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": "1.0.1", + "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.0", + "gojs": "0.1.1", + "grain": "3.0.0", + "grain-router": "3.0.0", + "grain-virtualized": "3.0.0", + "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.6.0", + "homogeneous": "0.4.0", + "http-methods": "6.0.0", + "httpurple": "4.0.0", + "huffman": "0.4.0", + "humdrum": "0.0.1", + "hyrule": "2.3.8", + "identity": "6.0.0", + "identy": "4.0.1", + "indexed-db": "1.0.0", + "indexed-monad": "3.0.0", + "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.1.4", + "js-iterators": "0.1.1", + "js-maps": "0.1.2", + "js-promise": "1.0.0", + "js-promise-aff": "1.0.0", + "js-timers": "6.1.0", + "js-uri": "3.1.0", + "jsdom": "1.0.0", + "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", + "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", + "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", + "milkis": "9.0.0", + "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", + "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", + "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", + "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-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.4.0", + "orders": "6.0.0", + "owoify": "1.2.0", + "pairs": "9.0.1", + "parallel": "7.0.0", + "parsing": "10.3.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", + "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.20", + "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", + "protobuf": "4.4.0", + "psa-utils": "8.0.0", + "psci-support": "6.0.0", + "punycode": "1.0.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": "8.2.0", + "react-basic-storybook": "2.0.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-ptional-fields": "0.1.2", + "record-studio": "1.0.4", + "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": "1.1.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.1.0", + "small-ffi": "4.0.1", + "soundfonts": "4.1.0", + "sparse-matrices": "2.0.1", + "sparse-polynomials": "3.0.1", + "spec": "8.1.1", + "spec-discovery": "8.4.0", + "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.12", + "substitute": "0.2.3", + "supply": "0.2.0", + "svg-parser": "3.0.0", + "systemd-journald": "0.3.0", + "tagged": "4.0.2", + "tailrec": "6.1.0", + "tanstack-query": "2.0.0", + "tecton": "0.2.1", + "tecton-halogen": "0.2.0", + "test-unit": "17.0.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", + "tree-rose": "4.0.2", + "trivial-unfold": "0.4.1", + "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", + "uuid": "9.0.0", + "uuidv4": "1.0.0", + "validation": "6.0.0", + "variant": "8.0.0", + "variant-encodings": "2.0.0", + "vectorfield": "1.0.1", + "vectors": "2.1.0", + "versions": "7.0.0", + "visx": "0.0.2", + "vitest": "1.0.0", + "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.0", + "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", + "webextension-polyfill": "0.1.0", + "webgpu": "0.0.1", + "which": "2.0.0", + "whine-core": "0.0.28", + "xterm": "1.0.0", + "yoga-fetch": "1.0.1", + "yoga-json": "5.1.0", + "yoga-om": "0.1.0", + "yoga-postgres": "6.0.0", + "yoga-react-dom": "1.0.1", + "yoga-subtlecrypto": "0.1.0", + "yoga-tree": "1.0.0", + "z3": "0.0.2", + "zipperarray": "2.0.0" + } + }, + "extra_packages": {} + }, + "packages": { + "aff": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-5MmdI4+0RHBtSBy+YlU3/Cq4R5W2ih3OaRedJIrVHdk=", + "dependencies": [ + "bifunctors", + "control", + "datetime", + "effect", + "either", + "exceptions", + "foldable-traversable", + "functions", + "maybe", + "newtype", + "parallel", + "prelude", + "refs", + "tailrec", + "transformers", + "unsafe-coerce" + ] + }, + "ansi": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-ZMB6HD+q9CXvn9fRCmJ8dvuDrOVHcjombL3oNOerVnE=", + "dependencies": [ + "foldable-traversable", + "lists", + "strings" + ] + }, + "argonaut-codecs": { + "type": "registry", + "version": "9.1.0", + "integrity": "sha256-N6efXByUeg848ompEqJfVvZuZPfdRYDGlTDFn0G0Oh8=", + "dependencies": [ + "argonaut-core", + "arrays", + "effect", + "foreign-object", + "identity", + "integers", + "maybe", + "nonempty", + "ordered-collections", + "prelude", + "record" + ] + }, + "argonaut-core": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-RC82GfAjItydxrO24cdX373KHVZiLqybu19b5X8u7B4=", + "dependencies": [ + "arrays", + "control", + "either", + "foreign-object", + "functions", + "gen", + "maybe", + "nonempty", + "prelude", + "strings", + "tailrec" + ] + }, + "arraybuffer-types": { + "type": "registry", + "version": "3.0.2", + "integrity": "sha256-mQKokysYVkooS4uXbO+yovmV/s8b138Ws3zQvOwIHRA=", + "dependencies": [] + }, + "arrays": { + "type": "registry", + "version": "7.3.0", + "integrity": "sha256-tmcklBlc/muUtUfr9RapdCPwnlQeB3aSrC4dK85gQlc=", + "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-f+bRR3qQPa/GVe4UbLQiJBy7+PzJkUCwT6qNn0UlkMY=", + "dependencies": [ + "aff", + "effect", + "either", + "exceptions", + "functions", + "maybe" + ] + }, + "bifunctors": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-6enQzl1vqnFTQZ1WX9BnoOOVdPGO9WZvVXldHckVQvY=", + "dependencies": [ + "const", + "either", + "newtype", + "prelude", + "tuples" + ] + }, + "catenable-lists": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-76vYENhwF4BWTBsjeLuErCH2jqVT4M3R1HX+4RwSftA=", + "dependencies": [ + "control", + "foldable-traversable", + "lists", + "maybe", + "prelude", + "tuples", + "unfoldable" + ] + }, + "console": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-CxmAzjgyuGDmt9FZW51VhV6rBPwR6o0YeKUzA9rSzcM=", + "dependencies": [ + "effect", + "prelude" + ] + }, + "const": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-tNrxDW8D8H4jdHE2HiPzpLy08zkzJMmGHdRqt5BQuTc=", + "dependencies": [ + "invariant", + "newtype", + "prelude" + ] + }, + "contravariant": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-TP+ooAp3vvmdjfQsQJSichF5B4BPDHp3wAJoWchip6c=", + "dependencies": [ + "const", + "either", + "newtype", + "prelude", + "tuples" + ] + }, + "control": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-sH7Pg9E96JCPF9PIA6oQ8+BjTyO/BH1ZuE/bOcyj4Jk=", + "dependencies": [ + "newtype", + "prelude" + ] + }, + "datetime": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-g/5X5BBegQWLpI9IWD+sY6mcaYpzzlW5lz5NBzaMtyI=", + "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-HTDdmEnzigMl+02SJB88j+gAXDx9VKsbvR4MJGDPbOQ=", + "dependencies": [ + "identity", + "newtype", + "prelude", + "tuples", + "type-equality" + ] + }, + "effect": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-eBtZu+HZcMa5HilvI6kaDyVX3ji8p0W9MGKy2K4T6+M=", + "dependencies": [ + "prelude" + ] + }, + "either": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-6hgTPisnMWVwQivOu2PKYcH8uqjEOOqDyaDQVUchTpY=", + "dependencies": [ + "control", + "invariant", + "maybe", + "prelude" + ] + }, + "enums": { + "type": "registry", + "version": "6.0.1", + "integrity": "sha256-HWaD73JFLorc4A6trKIRUeDMdzE+GpkJaEOM1nTNkC8=", + "dependencies": [ + "control", + "either", + "gen", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tuples", + "unfoldable" + ] + }, + "exceptions": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-K0T89IHtF3vBY7eSAO7eDOqSb2J9kZGAcDN5+IKsF8E=", + "dependencies": [ + "effect", + "either", + "maybe", + "prelude" + ] + }, + "exists": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-A0JQHpTfo1dNOj9U5/Fd3xndlRSE0g2IQWOGor2yXn8=", + "dependencies": [ + "unsafe-coerce" + ] + }, + "exitcodes": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-4wxViTbyOoyKJ/WaRGI6+hZmgMKI5Miv16lSwefiLSM=", + "dependencies": [ + "enums" + ] + }, + "foldable-traversable": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-fLeqRYM4jUrZD5H4WqcwUgzU7XfYkzO4zhgtNc3jcWM=", + "dependencies": [ + "bifunctors", + "const", + "control", + "either", + "functors", + "identity", + "maybe", + "newtype", + "orders", + "prelude", + "tuples" + ] + }, + "foreign": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-1ORiqoS3HW+qfwSZAppHPWy4/6AQysxZ2t29jcdUMNA=", + "dependencies": [ + "either", + "functions", + "identity", + "integers", + "lists", + "maybe", + "prelude", + "strings", + "transformers" + ] + }, + "foreign-object": { + "type": "registry", + "version": "4.1.0", + "integrity": "sha256-q24okj6mT+yGHYQ+ei/pYPj5ih6sTbu7eDv/WU56JVo=", + "dependencies": [ + "arrays", + "foldable-traversable", + "functions", + "gen", + "lists", + "maybe", + "prelude", + "st", + "tailrec", + "tuples", + "typelevel-prelude", + "unfoldable" + ] + }, + "fork": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-X7u0SuCvFbLbzuNEKLBNuWjmcroqMqit4xEzpQwAP7E=", + "dependencies": [ + "aff" + ] + }, + "free": { + "type": "registry", + "version": "7.1.0", + "integrity": "sha256-JAumgEsGSzJCNLD8AaFvuX7CpqS5yruCngi6yI7+V5k=", + "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-adMyJNEnhGde2unHHAP79gPtlNjNqzgLB8arEOn9hLI=", + "dependencies": [ + "prelude" + ] + }, + "functors": { + "type": "registry", + "version": "5.0.0", + "integrity": "sha256-zfPWWYisbD84MqwpJSZFlvM6v86McM68ob8p9s27ywU=", + "dependencies": [ + "bifunctors", + "const", + "contravariant", + "control", + "distributive", + "either", + "invariant", + "maybe", + "newtype", + "prelude", + "profunctor", + "tuples", + "unsafe-coerce" + ] + }, + "gen": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-f7yzAXWwr+xnaqEOcvyO3ezKdoes8+WXWdXIHDBCAPI=", + "dependencies": [ + "either", + "foldable-traversable", + "identity", + "maybe", + "newtype", + "nonempty", + "prelude", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "halogen-vdom": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-5UMDekaYNSM3jtpfWoWTbmZ38rIcnguzGRW3z+IQgV4=", + "dependencies": [ + "bifunctors", + "effect", + "foreign", + "foreign-object", + "maybe", + "prelude", + "refs", + "tuples", + "unsafe-coerce", + "web-html" + ] + }, + "identity": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-4wY0XZbAksjY6UAg99WkuKyJlQlWAfTi2ssadH0wVMY=", + "dependencies": [ + "control", + "invariant", + "newtype", + "prelude" + ] + }, + "integers": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-sf+sK26R1hzwl3NhXR7WAu9zCDjQnfoXwcyGoseX158=", + "dependencies": [ + "maybe", + "numbers", + "prelude" + ] + }, + "invariant": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-RGWWyYrz0Hs1KjPDA+87Kia67ZFBhfJ5lMGOMCEFoLo=", + "dependencies": [ + "control", + "prelude" + ] + }, + "js-date": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-6TVF4DWg5JL+jRAsoMssYw8rgOVALMUHT1CuNZt8NRo=", + "dependencies": [ + "datetime", + "effect", + "exceptions", + "foreign", + "integers", + "now" + ] + }, + "lazy": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-lMsfFOnlqfe4KzRRiW8ot5ge6HtcU3Eyh2XkXcP5IgU=", + "dependencies": [ + "control", + "foldable-traversable", + "invariant", + "prelude" + ] + }, + "lists": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-EKF15qYqucuXP2lT/xPxhqy58f0FFT6KHdIB/yBOayI=", + "dependencies": [ + "bifunctors", + "control", + "foldable-traversable", + "lazy", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "maybe": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-5cCIb0wPwbat2PRkQhUeZO0jcAmf8jCt2qE0wbC3v2Q=", + "dependencies": [ + "control", + "invariant", + "newtype", + "prelude" + ] + }, + "media-types": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-n/4FoGBasbVSYscGVRSyBunQ6CZbL3jsYL+Lp01mc9k=", + "dependencies": [ + "newtype", + "prelude" + ] + }, + "mmorph": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-urZlZNNqGeQFe5D/ClHlR8QgGBNHTMFPtJ5S5IpflTQ=", + "dependencies": [ + "free", + "functors", + "transformers" + ] + }, + "newtype": { + "type": "registry", + "version": "5.0.0", + "integrity": "sha256-gdrQu8oGe9eZE6L3wOI8ql/igOg+zEGB5ITh2g+uttw=", + "dependencies": [ + "prelude", + "safe-coerce" + ] + }, + "node-buffer": { + "type": "registry", + "version": "9.0.0", + "integrity": "sha256-PWE2DJ5ruBLCmeA/fUiuySEFmUJ/VuRfyrnCuVZBlu4=", + "dependencies": [ + "arraybuffer-types", + "effect", + "maybe", + "nullable", + "st", + "unsafe-coerce" + ] + }, + "node-event-emitter": { + "type": "registry", + "version": "3.0.0", + "integrity": "sha256-Qw0MjsT4xRH2j2i4K8JmRjcMKnH5z1Cw39t00q4LE4w=", + "dependencies": [ + "effect", + "either", + "functions", + "maybe", + "nullable", + "prelude", + "unsafe-coerce" + ] + }, + "node-fs": { + "type": "registry", + "version": "9.2.0", + "integrity": "sha256-Sg0vkXycEzkEerX6hLccz21Ygd9w1+QSk1thotRZPGI=", + "dependencies": [ + "datetime", + "effect", + "either", + "enums", + "exceptions", + "functions", + "integers", + "js-date", + "maybe", + "node-buffer", + "node-path", + "node-streams", + "nullable", + "partial", + "prelude", + "strings", + "unsafe-coerce" + ] + }, + "node-path": { + "type": "registry", + "version": "5.0.1", + "integrity": "sha256-ePOElFamHkffhwJcS0Ozq4A14rflnkasFU6X2B8/yXs=", + "dependencies": [ + "effect" + ] + }, + "node-process": { + "type": "registry", + "version": "11.2.0", + "integrity": "sha256-+2MQDYChjGbVbapCyJtuWYwD41jk+BntF/kcOTKBMVs=", + "dependencies": [ + "effect", + "foreign", + "foreign-object", + "maybe", + "node-event-emitter", + "node-streams", + "posix-types", + "prelude", + "unsafe-coerce" + ] + }, + "node-streams": { + "type": "registry", + "version": "9.0.1", + "integrity": "sha256-7RJ6RqjOlhW+QlDFQNUHlkCG/CuYTTLT8yary5jhhsU=", + "dependencies": [ + "aff", + "arrays", + "effect", + "either", + "exceptions", + "maybe", + "node-buffer", + "node-event-emitter", + "nullable", + "prelude", + "refs", + "st", + "tailrec", + "unsafe-coerce" + ] + }, + "nonempty": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-54ablJZUHGvvlTJzi3oXyPCuvY6zsrWJuH/dMJ/MFLs=", + "dependencies": [ + "control", + "foldable-traversable", + "maybe", + "prelude", + "tuples", + "unfoldable" + ] + }, + "now": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-xZ7x37ZMREfs6GCDw/h+FaKHV/3sPWmtqBZRGTxybQY=", + "dependencies": [ + "datetime", + "effect" + ] + }, + "nullable": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-yiGBVl3AD+Guy4kNWWeN+zl1gCiJK+oeIFtZtPCw4+o=", + "dependencies": [ + "effect", + "functions", + "maybe" + ] + }, + "numbers": { + "type": "registry", + "version": "9.0.1", + "integrity": "sha256-/9M6aeMDBdB4cwYDeJvLFprAHZ49EbtKQLIJsneXLIk=", + "dependencies": [ + "functions", + "maybe" + ] + }, + "open-memoize": { + "type": "registry", + "version": "6.2.0", + "integrity": "sha256-p1m7wF3aHQ80yUvqMs20OTMl496WS6YpKlmI2Nkg9j0=", + "dependencies": [ + "either", + "integers", + "lazy", + "lists", + "maybe", + "partial", + "prelude", + "strings", + "tuples" + ] + }, + "optparse": { + "type": "registry", + "version": "5.0.1", + "integrity": "sha256-cEzEkNW4q0gZlXl4z0zn+H2vs6l2UAp7NPHCsois73k=", + "dependencies": [ + "aff", + "arrays", + "bifunctors", + "console", + "control", + "effect", + "either", + "enums", + "exists", + "exitcodes", + "foldable-traversable", + "free", + "gen", + "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-o9jqsj5rpJmMdoe/zyufWHFjYYFTTsJpgcuCnqCO6PM=", + "dependencies": [ + "arrays", + "foldable-traversable", + "gen", + "lists", + "maybe", + "partial", + "prelude", + "st", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "orders": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-nBA0g3/ai0euH8q9pSbGqk53W2q6agm/dECZTHcoink=", + "dependencies": [ + "newtype", + "prelude" + ] + }, + "parallel": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-gUC9i4Txnx9K9RcMLsjujbwZz6BB1bnE2MLvw4GIw5o=", + "dependencies": [ + "control", + "effect", + "either", + "foldable-traversable", + "functors", + "maybe", + "newtype", + "prelude", + "profunctor", + "refs", + "transformers" + ] + }, + "partial": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-fwXerld6Xw1VkReh8yeQsdtLVrjfGiVuC5bA1Wyo/J4=", + "dependencies": [] + }, + "pipes": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-kvfqGM4cPA/wCcBHbp5psouFw5dZGvku2462x7ZBwSY=", + "dependencies": [ + "aff", + "lists", + "mmorph", + "prelude", + "tailrec", + "transformers", + "tuples" + ] + }, + "posix-types": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-ZfFz8RR1lee/o/Prccyeut3Q+9tYd08mlR72sIh6GzA=", + "dependencies": [ + "maybe", + "prelude" + ] + }, + "prelude": { + "type": "registry", + "version": "6.0.2", + "integrity": "sha256-kiAPZxihtAel8uRiTNdccf4qylp/9J3jNkEHNAD0MsE=", + "dependencies": [] + }, + "profunctor": { + "type": "registry", + "version": "6.0.1", + "integrity": "sha256-E58hSYdJvF2Qjf9dnWLPlJKh2Z2fLfFLkQoYi16vsFk=", + "dependencies": [ + "control", + "distributive", + "either", + "exists", + "invariant", + "newtype", + "prelude", + "tuples" + ] + }, + "record": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-Za5U85bTRJEfGK5Sk4hM41oXy84YQI0I8TL3WUn1Qzg=", + "dependencies": [ + "functions", + "prelude", + "unsafe-coerce" + ] + }, + "refs": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-Vgwne7jIbD3ZMoLNNETLT8Litw6lIYo3MfYNdtYWj9s=", + "dependencies": [ + "effect", + "prelude" + ] + }, + "safe-coerce": { + "type": "registry", + "version": "2.0.0", + "integrity": "sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU=", + "dependencies": [ + "unsafe-coerce" + ] + }, + "spec": { + "type": "registry", + "version": "8.1.1", + "integrity": "sha256-EM7UfQIaSgiw13LJ4ZASkfYmmRDKIlec3nYbGKFqGhk=", + "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-Bjzg6l4uOfMN/FV0SKuT1Mm8eMP9sloLGVcY/0MeMnI=", + "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-z9X0WsOUlPwNx9GlCC+YccCyz8MejC8Wb0C4+9fiBRY=", + "dependencies": [ + "partial", + "prelude", + "tailrec", + "unsafe-coerce" + ] + }, + "strings": { + "type": "registry", + "version": "6.0.1", + "integrity": "sha256-WssD3DbX4OPzxSdjvRMX0yvc9+pS7n5gyPv5I2Trb7k=", + "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-Xx19ECVDRrDWpz9D2GxQHHV89vd61dnXxQm0IcYQHGk=", + "dependencies": [ + "bifunctors", + "effect", + "either", + "identity", + "maybe", + "partial", + "prelude", + "refs" + ] + }, + "transformers": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-3Bm+Z6tsC/paG888XkywDngJ2JMos+JfOhRlkVfb7gI=", + "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-1rXgTomes9105BjgXqIw0FL6Fz1lqqUTLWOumhWec1M=", + "dependencies": [ + "control", + "invariant", + "prelude" + ] + }, + "type-equality": { + "type": "registry", + "version": "4.0.1", + "integrity": "sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw=", + "dependencies": [] + }, + "typelevel-prelude": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-uFF2ph+vHcQpfPuPf2a3ukJDFmLhApmkpTMviHIWgJM=", + "dependencies": [ + "prelude", + "type-equality" + ] + }, + "unfoldable": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-JtikvJdktRap7vr/K4ITlxUX1QexpnqBq0G/InLr6eg=", + "dependencies": [ + "foldable-traversable", + "maybe", + "partial", + "prelude", + "tuples" + ] + }, + "unsafe-coerce": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-IqIYW4Vkevn8sI+6aUwRGvd87tVL36BBeOr0cGAE7t0=", + "dependencies": [] + }, + "web-dom": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-1kSKWFDI4LupdmpjK01b1MMxDFW7jvatEgPgVmCmSBQ=", + "dependencies": [ + "web-events" + ] + }, + "web-events": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-YDt8b6u1tzGtnWyNRodne57iO8FNSGPaTCVzBUyUn4k=", + "dependencies": [ + "datetime", + "enums", + "foreign", + "nullable" + ] + }, + "web-file": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-1h5jPBkvjY71jLEdwVadXCx86/2inNoMBO//Rd3eCSU=", + "dependencies": [ + "foreign", + "media-types", + "web-dom" + ] + }, + "web-html": { + "type": "registry", + "version": "4.1.0", + "integrity": "sha256-ByqS/h1/yG+hjCOnOQp7L1QpIWzQENNKB1kaHtpEhlE=", + "dependencies": [ + "js-date", + "web-dom", + "web-file", + "web-storage" + ] + }, + "web-storage": { + "type": "registry", + "version": "5.0.0", + "integrity": "sha256-q+6lxcnfWxus0/nDeFVtF1V+tLehZvvXQ0cduYPLksY=", + "dependencies": [ + "nullable", + "web-events" + ] + } + } +} diff --git a/spago.yaml b/spago.yaml new file mode 100644 index 0000000..4267d03 --- /dev/null +++ b/spago.yaml @@ -0,0 +1,29 @@ +package: + name: halogen-vdom-string-renderer + publish: + license: Apache-2.0 + version: 0.5.0 + location: + githubOwner: purescript-halogen + githubRepo: purescript-halogen-vdom-string-renderer + dependencies: + - arrays: ">=7.3.0 <8.0.0" + - foreign: ">=7.0.0 <8.0.0" + - halogen-vdom: ">=8.0.0 <9.0.0" + - maybe: ">=6.0.0 <7.0.0" + - numbers: ">=9.0.1 <10.0.0" + - ordered-collections: ">=3.2.0 <4.0.0" + - prelude: ">=6.0.2 <7.0.0" + - strings: ">=6.0.1 <7.0.0" + - tuples: ">=7.0.0 <8.0.0" + - unsafe-coerce: ">=6.0.0 <7.0.0" + test: + main: Test.Main + dependencies: + - effect + - spec + - spec-node +workspace: + packageSet: + registry: 64.1.1 + extraPackages: {} diff --git a/src/Halogen/VDom/DOM/StringRenderer.purs b/src/Halogen/VDom/DOM/StringRenderer.purs index 37223c7..311fe63 100644 --- a/src/Halogen/VDom/DOM/StringRenderer.purs +++ b/src/Halogen/VDom/DOM/StringRenderer.purs @@ -6,10 +6,11 @@ import Halogen.VDom.DOM.Prop (Prop(..), PropValue) import Data.Array as A import Foreign (unsafeToForeign, typeOf) import Data.Maybe (Maybe(..)) +import Data.Number.Format as Data.Number.Format import Data.String as S import Data.Set as Set import Halogen.VDom.StringRenderer as VSR -import Halogen.VDom.StringRenderer.Util (escape) +import Halogen.VDom.StringRenderer.Util (escapeAttributeValue, escapeHtmlEntity) import Unsafe.Coerce (unsafeCoerce) render ∷ ∀ i w. (w → String) → VDom (Array (Prop i)) w → String @@ -31,19 +32,23 @@ renderProp = case _ of Ref _ → Nothing renderAttr ∷ String → String → Maybe String -renderAttr name value = Just $ escape name <> "=\"" <> escape value <> "\"" +renderAttr name value = Just $ escapeHtmlEntity name <> "=\"" <> escapeAttributeValue value <> "\"" propNameToAttrName ∷ String → String propNameToAttrName = case _ of "htmlFor" → "for" "className" → "class" + "httpEquiv" → "http-equiv" + "acceptCharset" → "accept-charset" p → p renderProperty ∷ String → PropValue → Maybe String renderProperty name prop = case typeOf (unsafeToForeign prop) of - "string" → renderAttr name' $ (unsafeCoerce ∷ PropValue → String) prop - "number" → renderAttr name' $ show ((unsafeCoerce ∷ PropValue → String) prop) - "boolean" → Just $ escape name' + "string" → renderAttr name' $ (unsafeCoerce ∷ PropValue → String) prop + "number" → renderAttr name' $ Data.Number.Format.toString ((unsafeCoerce ∷ PropValue → Number) prop) + "boolean" → + if ((unsafeCoerce :: PropValue -> Boolean) prop) then Just $ escapeHtmlEntity name' + else Nothing _ → Nothing where name' = propNameToAttrName name diff --git a/src/Halogen/VDom/StringRenderer.purs b/src/Halogen/VDom/StringRenderer.purs index 9b4c1a4..b44cf4a 100644 --- a/src/Halogen/VDom/StringRenderer.purs +++ b/src/Halogen/VDom/StringRenderer.purs @@ -9,9 +9,8 @@ import Data.Array as A import Data.Maybe (Maybe, maybe) import Data.String as S import Data.Tuple (snd) - import Halogen.VDom (VDom(..), ElemName(..), Namespace(..), runGraft) -import Halogen.VDom.StringRenderer.Util (escape) +import Halogen.VDom.StringRenderer.Util (cleanAndEscapeTextNode, cleanNonXnvName, escapeHtmlEntity) -- | Type used to determine whether an element can be rendered as self-closing -- | element, for example, "
". @@ -35,7 +34,7 @@ render getTagType renderAttrs renderWidget = go where go ∷ VDom attrs widget → String go = case _ of - Text s → escape s + Text s → cleanAndEscapeTextNode s Elem namespace elementName attrs children → renderElement namespace elementName attrs children Keyed namespace elementName attrs kchildren → renderElement namespace elementName attrs (map snd kchildren) Widget widget → renderWidget widget @@ -45,9 +44,9 @@ render getTagType renderAttrs renderWidget = go renderElement maybeNamespace elemName@(ElemName name) attrs children = let as = renderAttrs attrs - as' = maybe as (\(Namespace ns) -> "xmlns=\"" <> escape ns <> "\"" <> if S.null as then "" else " " <> as) maybeNamespace + as' = maybe as (\(Namespace ns) -> "xmlns=\"" <> escapeHtmlEntity ns <> "\"" <> if S.null as then "" else " " <> as) maybeNamespace + name' = cleanNonXnvName name in - "<" <> name <> (if S.null as' then "" else " ") <> as' <> - if A.null children - then if getTagType elemName == SelfClosingTag then "/>" else "> name <> ">" - else ">" <> S.joinWith "" (map go children) <> " name <> ">" + "<" <> name' <> (if S.null as' then "" else " ") <> as' <> + if A.null children then if getTagType elemName == SelfClosingTag then "/>" else "> name' <> ">" + else ">" <> S.joinWith "" (map go children) <> " name' <> ">" diff --git a/src/Halogen/VDom/StringRenderer/Util.purs b/src/Halogen/VDom/StringRenderer/Util.purs index 4371ac6..8816a44 100644 --- a/src/Halogen/VDom/StringRenderer/Util.purs +++ b/src/Halogen/VDom/StringRenderer/Util.purs @@ -1,22 +1,76 @@ -module Halogen.VDom.StringRenderer.Util (escape) where +module Halogen.VDom.StringRenderer.Util where import Prelude -import Data.String.Regex (Regex, replace') -import Data.String.Regex.Flags (global) + +import Data.String.Regex (Regex, replace', replace) +import Data.String.Regex.Flags (global, unicode) import Data.String.Regex.Unsafe (unsafeRegex) -escapeRegex ∷ Regex -escapeRegex = unsafeRegex "[\\\"\\\'/&<>]" global - -escapeChar ∷ String → String -escapeChar = case _ of - "\"" → """ - "'" → "'" - "/" → "/" - "&" → "&" - "<" → "<" - ">" → ">" - ch → ch - -escape ∷ String → String -escape = replace' escapeRegex (const <<< escapeChar) +-- TODO: use https://github.com/mathiasbynens/he ? +escapeHtmlEntity ∷ String → String +escapeHtmlEntity = replace' escapeRegex (const <<< escapeChar) + where + escapeRegex ∷ Regex + escapeRegex = unsafeRegex """[&"'<>\t\n\r\/]""" global + + escapeChar ∷ String → String + escapeChar = case _ of + "&" -> "&" + "\"" -> """ + "'" → "'" + "<" -> "<" + ">" -> ">" + "\t" -> " " + "\n" -> " " + "\r" -> " " + "/" → "/" + ch → ch + +-- just like https://github.com/jsdom/w3c-xmlserializer/blob/83115f8ecce8ed77a2a907c74407b2c671751463/lib/attributes.js#L24 +-- NOTE: it will not escape / in https://mywebsite.com (check this test https://github.com/jsdom/w3c-xmlserializer/blob/83115f8ecce8ed77a2a907c74407b2c671751463/test/test.js#L58-L70) +escapeAttributeValue ∷ String → String +escapeAttributeValue = replace' escapeRegex (const <<< escapeChar) + where + escapeRegex ∷ Regex + escapeRegex = unsafeRegex """[&"<>\t\n\r]""" (global <> unicode) + + escapeChar ∷ String → String + escapeChar = case _ of + "&" -> "&" + "\"" -> """ + "<" -> "<" + ">" -> ">" + "\t" -> " " + "\n" -> " " + "\r" -> " " + ch → ch + +-- just like https://github.com/jsdom/xml-name-validator/blob/836f307eec81279d2b1655587892e38a1effe039/lib/xml-name-validator.js#L4 +-- but will just remove all chars that are not `name` +-- +-- Where we use it in ``? We use it to clean `my-element` and `my-attr`. +-- Just like w3c-xmlserializer does for element names (https://github.com/jsdom/w3c-xmlserializer/blob/83115f8ecce8ed77a2a907c74407b2c671751463/lib/serialize.js#L178) and attribute names (https://github.com/jsdom/w3c-xmlserializer/blob/83115f8ecce8ed77a2a907c74407b2c671751463/lib/attributes.js#L112). +cleanNonXnvName ∷ String → String +cleanNonXnvName = replace invalidCharsRegex "" + where + invalidCharsRegex = unsafeRegex """[^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u{10000}-\u{EFFFF}\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]""" (global <> unicode) + +-- just like https://github.com/jsdom/w3c-xmlserializer/blob/83115f8ecce8ed77a2a907c74407b2c671751463/lib/serialize.js#L155 +-- removes all non XML_CHAR characters and changes escapes &<> +cleanAndEscapeTextNode ∷ String → String +cleanAndEscapeTextNode = replace' escapeRegex (const <<< escapeChar) <<< cleanInvalidChars + where + cleanInvalidChars :: String -> String + cleanInvalidChars = replace invalidCharsRegex "" + where + invalidCharsRegex = unsafeRegex """[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u{10000}-\u{10FFFF}]""" (global <> unicode) + + escapeRegex ∷ Regex + escapeRegex = unsafeRegex "[&<>]" global + + escapeChar ∷ String → String + escapeChar = case _ of + "&" → "&" + "<" → "<" + ">" → ">" + ch → ch diff --git a/test/Test/Main.purs b/test/Test/Main.purs new file mode 100644 index 0000000..901c861 --- /dev/null +++ b/test/Test/Main.purs @@ -0,0 +1,116 @@ +module Test.Main where + +import Prelude + +import Data.Maybe (Maybe(..)) +import Data.Tuple (Tuple) +import Data.Tuple.Nested ((/\)) +import Effect (Effect) +import Halogen.VDom (VDom, ElemName(..)) +import Halogen.VDom as V +import Halogen.VDom.DOM.Prop (Prop(..), PropValue, propFromBoolean, propFromInt, propFromNumber, propFromString) +import Halogen.VDom.DOM.StringRenderer (render) +import Test.Spec (describe, it) +import Test.Spec.Assertions (shouldEqual) +import Test.Spec.Reporter (consoleReporter) +import Test.Spec.Runner.Node (runSpecAndExitProcess) +import Unsafe.Coerce (unsafeCoerce) + +attr ∷ ∀ a. String → String → Prop a +attr key value = Attribute Nothing key value + +class IsPropValue v where + toPropValue :: v -> PropValue + +instance isPropValueString :: IsPropValue String where + toPropValue = propFromString + +instance isPropValueBoolean :: IsPropValue Boolean where + toPropValue = propFromBoolean + +instance isPropValueInt :: IsPropValue Int where + toPropValue = propFromInt + +instance isPropValueNumber :: IsPropValue Number where + toPropValue = propFromNumber + +prop :: forall a v. IsPropValue v => String -> v -> Prop a +prop key value = Property key (toPropValue value) + +infixr 1 attr as := +infixr 1 prop as .= + +elem ∷ ∀ a. String → Array (Prop a) → Array (VDom (Array (Prop a)) a) → VDom (Array (Prop a)) a +elem n a c = V.Elem Nothing (ElemName n) a (unsafeCoerce c) + +keyed ∷ ∀ a. String → Array (Prop a) → Array (Tuple String (VDom (Array (Prop a)) a)) → VDom (Array (Prop a)) a +keyed n a c = V.Keyed Nothing (ElemName n) a (unsafeCoerce c) + +text ∷ ∀ a. String → VDom (Array (Prop Void)) a +text a = V.Text a + +main ∷ Effect Unit +main = runSpecAndExitProcess [ consoleReporter ] do + it "works" do + let + html ∷ VDom (Array (Prop Void)) Void + html = + elem "div" [ "className" .= "container", "id" := "root" ] + [ elem "label" [ "htmlFor" .= "username" ] + [ text "Username" ] + , elem "input" [ "id" := "input" ] [] + , elem "a" [ "href" := "index" ] [ text "Inbox" ] + , keyed "div" [] + [ "0" /\ elem "span" [] [ text "0" ] + , "1" /\ elem "span" [] [ text "1" ] + ] + ] + render absurd html `shouldEqual` """
Inbox
01
""" + it "should not escape links in prop attrs" do + let + html ∷ VDom (Array (Prop Void)) Void + html = + elem "script" + [ "async" := "" + , "type" := "application/javascript" + , "src" := "chunks/defaultVendors~main-063769ad5d827b791041.js" + ] + [] + render absurd html `shouldEqual` """""" + it "but should escape links prop names" do + let + html ∷ VDom (Array (Prop Void)) Void + html = + elem "script" + [ "application/javascript" := "type" + , "chunks/defaultVendors~main-063769ad5d827b791041.js" := "src" + ] + [] + render absurd html `shouldEqual` """""" + it "but should render int, boolean, number props" do + let + html ∷ VDom (Array (Prop Void)) Void + html = + elem "input" + [ "maxLength" .= 255 -- Int + , "step" .= 0.5 -- Number + , "disabled" .= true -- Boolean + , "readonly" .= false -- Boolean + ] + [] + render absurd html `shouldEqual` """""" + describe "escape chars" do + let + mkElem char = elem ("div" <> char <> "test") [ "attr" <> char <> "key" := "attr" <> char <> "val", "prop" <> char <> "key" .= "prop" <> char <> "val" ] [] + mkTest char expected = it char $ render absurd (mkElem char) `shouldEqual` expected + + mkTest "\"" """""" + mkTest "'" """""" + mkTest "/" """""" + mkTest "\\" """""" + mkTest "`" """""" + mkTest "?" """""" + mkTest "!" """""" + mkTest "@" """""" + mkTest "#" """""" + mkTest "$" """"""