├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── assets ├── blau-azul.png ├── green-leaf.png ├── purple-kite.png └── red-velvet.png ├── bower.json ├── package-lock.json ├── package.json ├── packages.dhall ├── spago.dhall ├── src └── Lazy │ ├── Joe.js │ └── Joe.purs ├── test.dhall └── test └── Main.purs /.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | /.pulp-cache/ 4 | /output/ 5 | /generated-docs/ 6 | /.psc-package/ 7 | /.psc* 8 | /.purs* 9 | /.psa* 10 | /.spago 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | 4 | ## v1.0.0 5 | 6 | Initial release. Supports: 7 | 8 | - importing module (defaults) 9 | - currying functions 10 | - scoping functions to a module or object 11 | - effectful functions 12 | - variadic functions (varargs) 13 | - `new` constructor 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT No Attribution 2 | 3 | Copyright 2021 Jan Schulte 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | software and associated documentation files (the "Software"), to deal in the Software 7 | without restriction, including without limitation the rights to use, copy, modify, 8 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🎷 purescript-lazy-joe 🦥 2 | 3 | Zero boilerplate ffi for purescript. 4 | 5 | For these days when you got the blues and are just too lazy to write ffi code. 6 | 7 | ## ToC 8 | * [Installation](#installation) 9 | * [Quickstart](#quickstart) 10 | * [Usage](#usage) 11 | * [Method chaining](#method-chaining) 12 | * [Uncurried functions](#uncurried-functions) 13 | * [Vararg functions](#vararg-functions) 14 | * [Scoped functions](#scoped-functions) 15 | * [Effectful functions](#effectful-functions) 16 | * [`new` constructor](#new-constructor) 17 | * [Credits](#credits) 18 | 19 | ## Installation 20 | 21 | ``` 22 | spago install lazy-joe 23 | ``` 24 | 25 | ## Quickstart 26 | 27 | ``` 28 | main :: Effect Unit 29 | main = launchAff_ do 30 | { red } <- fromDefault "chalk" -- import a module 31 | log $ red "Red velvet 🎂" -- use a function 32 | ``` 33 | 34 | ## Usage 35 | 36 | Imagine we want to use the amazing [`chalk`](https://github.com/chalk/chalk) js library for terminal styling in our purescript code. 37 | 38 | We start by installing chalk. 39 | ``` 40 | npm install chalk 41 | ``` 42 | 43 | `chalk` defines a number of functions and combinators that allow you to write coloured text to your terminal. For instance the function `red` from `chalk` prints a red string. In js you would use it like this: 44 | 45 | ```js 46 | import chalk from 'chalk'; 47 | 48 | console.log(chalk.red("Red velvet 🎂")); 49 | ``` 50 | 51 | Let's see how we can ffi this in our purescript code: 52 | 53 | ```purescript 54 | main :: Effect Unit 55 | main = launchAff_ do 56 | { red } <- fromDefault "chalk" 57 | log $ red "Red velvet 🎂" 58 | ``` 59 | Running it will print: 60 | 61 | 62 | ![red velvet in red letters](./assets/red-velvet.png) 63 | 64 | 65 | You can easily import the `default` export from a module using `fromDefault`. This will type red as `String -> String`. 66 | 67 | ### Method chaining 68 | 69 | In js method chaining is a common pattern. In purescript we can use function application to model this pattern. 70 | 71 | 72 | #### Example 73 | 74 | In chalk, you can combine different styles by chaining them: 75 | 76 | ```js 77 | import chalk from 'chalk'; 78 | 79 | console.log(chalk.underline.bold.green('Leaf 🍃')); 80 | ``` 81 | 82 | In purescript, we can use function application to model this method chaining: 83 | ```purescript 84 | main :: Effect Unit 85 | main = launchAff_ do 86 | { underline } <- fromDefault "chalk" 87 | log $ underline # \{ bold } -> bold # \{ green } -> green "Leaf 🍃" 88 | ``` 89 | 90 | Running it will print: 91 | 92 | ![green leaf printed in bold green underline](./assets/green-leaf.png). 93 | 94 | ### Uncurried functions 95 | 96 | js typically uses uncurried functions (e.g. `f(a,b,c) `) instead of curried functions (e.g. `f(a)(b)(c)` ) like purescript. Use `curried` to use the uncurried js function as a curried purescript function: 97 | 98 | ``` 99 | result = curried myFunc arg1 arg2 arg3 100 | ``` 101 | 102 | #### Example 103 | 104 | E.g. we can use the `blue` function as a three-argument uncurried function: 105 | 106 | ```js 107 | console.log(chalk.blue('blue', 'azul', 'blau')); 108 | ``` 109 | 110 | In purescript functions are curried, so we need to curry them using `curried`: 111 | 112 | ```purescript 113 | main :: Effect Unit 114 | main = launchAff_ do 115 | { blue } <- fromDefault "chalk" 116 | 117 | log $ curried blue "blue" "azul" "blau" 118 | ``` 119 | 120 | Running it will print: 121 | 122 | ![blue azul blau in blue colours](./assets/blau-azul.png) 123 | 124 | ### Vararg functions 125 | 126 | js functions are sometimes designed to be variadic, i.e. to have a variable number of arguments. Use `variadic myModuleOrFunc func` for functions that accept varargs: 127 | 128 | ```purescript 129 | let 130 | example1 = variadic func arg1 131 | example1 = variadic func arg1 arg2 arg3 132 | example1 = variadic func [arg1, arg2, arg3, arg4] 133 | ``` 134 | 135 | #### Eample 136 | 137 | In fact, the colour methods in `chalk` are variadic methods (as you have seen in the previous example) and you can pass an arbitrary number of arguments: 138 | ```js 139 | console.log(chalk.blue('Hello', 'world!', 'Hola', 'mundo!')); 140 | ``` 141 | 142 | If we need this variadic behaviour, we can use `variadic` to model this: 143 | ```purescript 144 | main :: Effect Unit 145 | main = launchAff_ do 146 | { blue } <- fromDefault "chalk" 147 | 148 | log $ variadic blue "Hello" 149 | log $ variadic blue "Hello" "world!" 150 | log $ variadic blue [ "Hello", "world!", "Hola", "mundo!"] 151 | ``` 152 | 153 | ### Scoped functions 154 | 155 | Sometimes js functions don't work in purescript, because they internally use `this` which fails to resolve in a curried contex. Use `scoped myModuleOrFunc func` you to make a function scoped: 156 | 157 | ```purescript 158 | result <- scoped myModuleOrFunc func arg1 arg2 159 | ``` 160 | 161 | #### Example 162 | 163 | Simply using the `rgb` function from `chalk` as we did before will fail because it uses `this` internally. To make it work again we will need to set the scope for the function to the module: 164 | 165 | ```purescript 166 | main :: Effect Unit 167 | main = launchAff_ do 168 | m@{ rgb } <- fromDefault "chalk" 169 | 170 | log $ scoped m (curried rgb) 129 37 218 # \{ bold } -> bold "PURPLE!!! 🪁" 171 | ``` 172 | 173 | Running it will print: 174 | 175 | ![purple in bold purple with a kite](./assets/purple-kite.png) 176 | 177 | ### Effectful functions 178 | 179 | js functions very often cause side-effects (e.g. like printing to the console). Use `effectful` you to catch these side-effects and return `Effect` instead: 180 | 181 | ```purescript 182 | let 183 | result :: Effect SomeResult 184 | result = effectful func arg1 arg2 185 | ``` 186 | 187 | #### Example 188 | 189 | Let's try another example and install minimalistic http-client `got`: 190 | 191 | ```console 192 | npm install got 193 | ``` 194 | 195 | With `got` we can create a simple http request using the `post` function and passing a url and a json body: 196 | ```js 197 | import got from 'got'; 198 | 199 | const {data} = await got.post('https://httpbin.org/anything', { 200 | json: { 201 | hello: '🌎' 202 | } 203 | }).json(); 204 | 205 | console.log(data); 206 | ``` 207 | 208 | Clearly, `post` is an effectful function, as it triggers a promise. So in purescript `post` will have the signature `Effect (Promise json)` which we can then be converted to an `Aff` using the `toAffE`. 209 | 210 | ```purescript 211 | main :: Effect Unit 212 | main = launchAff_ do 213 | { post } <- fromDefault "got" 214 | resp <- Promise.toAffE $ effectful (curried post) "https://httpbin.org/anything" { json: { hello: "🌎" } } >>= \{ json } -> json 215 | log resp.json 216 | ``` 217 | 218 | We import the `post` from `got`. The first thing we need to do is uncurry it, since it receives two arguments, the url and the json record. We then wrap it using `effectful` so that is run in an `Effect`. We can then call the effectful js function `json()` on the resulting `Promise` to get the body, so we can just `bind` (`>>=`) it. 219 | 220 | ### `new` constructor 221 | 222 | Use `new` to create new objects: 223 | 224 | ```purescript 225 | myModule <- fromDefault "my-module" 226 | let myObj = new myModule arg1 arg2 227 | ``` 228 | 229 | #### Example 230 | 231 | `fuse.js` is a library for fuzzy search. In js you use it by first creating a new `Fuse` object using `new` and passing the data as a list and some options: 232 | ```js 233 | const fuse = new Fuse(list, options); 234 | ``` 235 | Then you can search on this object: 236 | ```js 237 | const pattern = "my-search-pattern" 238 | fuse.search(pattern) 239 | ``` 240 | 241 | We first import the default export from `fuse.js` which gives us the class, which we can then pass to `new` to create the `Fuse` object: 242 | 243 | ```purescript 244 | fuse <- fromDefault "fuse.js" 245 | let 246 | list = 247 | [ { "title": "Old Man's War", "author": { "firstName": "John", "lastName": "Scalzi" } } 248 | , { "title": "The Lock Artist", "author": { "firstName": "Steve", "lastName": "Hamilton" } } 249 | ] 250 | options = 251 | { keys: [ "title", "author.firstName" ] 252 | } 253 | result :: Array { item :: { title :: String, author :: { firstName :: String, lastName :: String } } } <- 254 | (new fuse list options) # \f@{ search } -> effectful (scoped f search) "eve" 255 | 256 | logShow result 257 | ``` 258 | 259 | ## Credits 260 | 261 | Kudos to @paluh for writing the [`purescript-js-object`](https://github.com/paluh/purescript-js-object) library (check it out!), which basically inspired me to write this library. @paluh's library is probably the (type-)safer option, but I thought if I am already too lazy to write ffi, then I really want to be lazy and not write anything at all. So this library follows a different implementation approach to basically not require any ffi code, at the expense of more type-safety. 262 | -------------------------------------------------------------------------------- /assets/blau-azul.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rowtype-yoga/purescript-lazy-joe/80f20e15aa6a089c09bb3df406cecef5e15f99cf/assets/blau-azul.png -------------------------------------------------------------------------------- /assets/green-leaf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rowtype-yoga/purescript-lazy-joe/80f20e15aa6a089c09bb3df406cecef5e15f99cf/assets/green-leaf.png -------------------------------------------------------------------------------- /assets/purple-kite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rowtype-yoga/purescript-lazy-joe/80f20e15aa6a089c09bb3df406cecef5e15f99cf/assets/purple-kite.png -------------------------------------------------------------------------------- /assets/red-velvet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rowtype-yoga/purescript-lazy-joe/80f20e15aa6a089c09bb3df406cecef5e15f99cf/assets/red-velvet.png -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-lazy-joe", 3 | "license": [ 4 | "MIT-0" 5 | ], 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/sigma-andex/purescript-lazy-joe.git" 9 | }, 10 | "ignore": [ 11 | "**/.*", 12 | "node_modules", 13 | "bower_components", 14 | "output" 15 | ], 16 | "dependencies": { 17 | "purescript-aff": "^v7.0.0", 18 | "purescript-aff-promise": "^v4.0.0", 19 | "purescript-effect": "^v4.0.0", 20 | "purescript-functions": "^v6.0.0", 21 | "purescript-prelude": "^v6.0.0", 22 | "purescript-unsafe-coerce": "^v6.0.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-lazy-joe", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "purescript-lazy-joe", 9 | "version": "1.0.0", 10 | "license": "MIT-0", 11 | "devDependencies": { 12 | "chalk": "^5.0.1", 13 | "fuse.js": "^6.6.2", 14 | "got": "^12.1.0" 15 | } 16 | }, 17 | "node_modules/@sindresorhus/is": { 18 | "version": "4.6.0", 19 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", 20 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", 21 | "dev": true, 22 | "engines": { 23 | "node": ">=10" 24 | }, 25 | "funding": { 26 | "url": "https://github.com/sindresorhus/is?sponsor=1" 27 | } 28 | }, 29 | "node_modules/@szmarczak/http-timer": { 30 | "version": "5.0.1", 31 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", 32 | "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", 33 | "dev": true, 34 | "dependencies": { 35 | "defer-to-connect": "^2.0.1" 36 | }, 37 | "engines": { 38 | "node": ">=14.16" 39 | } 40 | }, 41 | "node_modules/@types/cacheable-request": { 42 | "version": "6.0.2", 43 | "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", 44 | "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", 45 | "dev": true, 46 | "dependencies": { 47 | "@types/http-cache-semantics": "*", 48 | "@types/keyv": "*", 49 | "@types/node": "*", 50 | "@types/responselike": "*" 51 | } 52 | }, 53 | "node_modules/@types/http-cache-semantics": { 54 | "version": "4.0.1", 55 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", 56 | "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", 57 | "dev": true 58 | }, 59 | "node_modules/@types/json-buffer": { 60 | "version": "3.0.0", 61 | "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", 62 | "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==", 63 | "dev": true 64 | }, 65 | "node_modules/@types/keyv": { 66 | "version": "3.1.4", 67 | "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", 68 | "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", 69 | "dev": true, 70 | "dependencies": { 71 | "@types/node": "*" 72 | } 73 | }, 74 | "node_modules/@types/node": { 75 | "version": "17.0.44", 76 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.44.tgz", 77 | "integrity": "sha512-gWYiOlu6Y4oyLYBvsJAPlwHbC8H4tX+tLsHy6Ee976wedwwZKrG2hFl3Y/HiH6bIyLTbDWQexQF/ohwKkOpUCg==", 78 | "dev": true 79 | }, 80 | "node_modules/@types/responselike": { 81 | "version": "1.0.0", 82 | "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", 83 | "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", 84 | "dev": true, 85 | "dependencies": { 86 | "@types/node": "*" 87 | } 88 | }, 89 | "node_modules/cacheable-lookup": { 90 | "version": "6.0.4", 91 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.0.4.tgz", 92 | "integrity": "sha512-mbcDEZCkv2CZF4G01kr8eBd/5agkt9oCqz75tJMSIsquvRZ2sL6Hi5zGVKi/0OSC9oO1GHfJ2AV0ZIOY9vye0A==", 93 | "dev": true, 94 | "engines": { 95 | "node": ">=10.6.0" 96 | } 97 | }, 98 | "node_modules/cacheable-request": { 99 | "version": "7.0.2", 100 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", 101 | "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", 102 | "dev": true, 103 | "dependencies": { 104 | "clone-response": "^1.0.2", 105 | "get-stream": "^5.1.0", 106 | "http-cache-semantics": "^4.0.0", 107 | "keyv": "^4.0.0", 108 | "lowercase-keys": "^2.0.0", 109 | "normalize-url": "^6.0.1", 110 | "responselike": "^2.0.0" 111 | }, 112 | "engines": { 113 | "node": ">=8" 114 | } 115 | }, 116 | "node_modules/cacheable-request/node_modules/get-stream": { 117 | "version": "5.2.0", 118 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 119 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 120 | "dev": true, 121 | "dependencies": { 122 | "pump": "^3.0.0" 123 | }, 124 | "engines": { 125 | "node": ">=8" 126 | }, 127 | "funding": { 128 | "url": "https://github.com/sponsors/sindresorhus" 129 | } 130 | }, 131 | "node_modules/cacheable-request/node_modules/lowercase-keys": { 132 | "version": "2.0.0", 133 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 134 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", 135 | "dev": true, 136 | "engines": { 137 | "node": ">=8" 138 | } 139 | }, 140 | "node_modules/chalk": { 141 | "version": "5.0.1", 142 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", 143 | "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", 144 | "dev": true, 145 | "engines": { 146 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 147 | }, 148 | "funding": { 149 | "url": "https://github.com/chalk/chalk?sponsor=1" 150 | } 151 | }, 152 | "node_modules/clone-response": { 153 | "version": "1.0.2", 154 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", 155 | "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", 156 | "dev": true, 157 | "dependencies": { 158 | "mimic-response": "^1.0.0" 159 | } 160 | }, 161 | "node_modules/compress-brotli": { 162 | "version": "1.3.8", 163 | "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz", 164 | "integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==", 165 | "dev": true, 166 | "dependencies": { 167 | "@types/json-buffer": "~3.0.0", 168 | "json-buffer": "~3.0.1" 169 | }, 170 | "engines": { 171 | "node": ">= 12" 172 | } 173 | }, 174 | "node_modules/decompress-response": { 175 | "version": "6.0.0", 176 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 177 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 178 | "dev": true, 179 | "dependencies": { 180 | "mimic-response": "^3.1.0" 181 | }, 182 | "engines": { 183 | "node": ">=10" 184 | }, 185 | "funding": { 186 | "url": "https://github.com/sponsors/sindresorhus" 187 | } 188 | }, 189 | "node_modules/decompress-response/node_modules/mimic-response": { 190 | "version": "3.1.0", 191 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 192 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", 193 | "dev": true, 194 | "engines": { 195 | "node": ">=10" 196 | }, 197 | "funding": { 198 | "url": "https://github.com/sponsors/sindresorhus" 199 | } 200 | }, 201 | "node_modules/defer-to-connect": { 202 | "version": "2.0.1", 203 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", 204 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", 205 | "dev": true, 206 | "engines": { 207 | "node": ">=10" 208 | } 209 | }, 210 | "node_modules/end-of-stream": { 211 | "version": "1.4.4", 212 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 213 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 214 | "dev": true, 215 | "dependencies": { 216 | "once": "^1.4.0" 217 | } 218 | }, 219 | "node_modules/form-data-encoder": { 220 | "version": "1.7.1", 221 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", 222 | "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", 223 | "dev": true 224 | }, 225 | "node_modules/fuse.js": { 226 | "version": "6.6.2", 227 | "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz", 228 | "integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==", 229 | "dev": true, 230 | "engines": { 231 | "node": ">=10" 232 | } 233 | }, 234 | "node_modules/get-stream": { 235 | "version": "6.0.1", 236 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", 237 | "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", 238 | "dev": true, 239 | "engines": { 240 | "node": ">=10" 241 | }, 242 | "funding": { 243 | "url": "https://github.com/sponsors/sindresorhus" 244 | } 245 | }, 246 | "node_modules/got": { 247 | "version": "12.1.0", 248 | "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", 249 | "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", 250 | "dev": true, 251 | "dependencies": { 252 | "@sindresorhus/is": "^4.6.0", 253 | "@szmarczak/http-timer": "^5.0.1", 254 | "@types/cacheable-request": "^6.0.2", 255 | "@types/responselike": "^1.0.0", 256 | "cacheable-lookup": "^6.0.4", 257 | "cacheable-request": "^7.0.2", 258 | "decompress-response": "^6.0.0", 259 | "form-data-encoder": "1.7.1", 260 | "get-stream": "^6.0.1", 261 | "http2-wrapper": "^2.1.10", 262 | "lowercase-keys": "^3.0.0", 263 | "p-cancelable": "^3.0.0", 264 | "responselike": "^2.0.0" 265 | }, 266 | "engines": { 267 | "node": ">=14.16" 268 | }, 269 | "funding": { 270 | "url": "https://github.com/sindresorhus/got?sponsor=1" 271 | } 272 | }, 273 | "node_modules/http-cache-semantics": { 274 | "version": "4.1.0", 275 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", 276 | "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", 277 | "dev": true 278 | }, 279 | "node_modules/http2-wrapper": { 280 | "version": "2.1.11", 281 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", 282 | "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", 283 | "dev": true, 284 | "dependencies": { 285 | "quick-lru": "^5.1.1", 286 | "resolve-alpn": "^1.2.0" 287 | }, 288 | "engines": { 289 | "node": ">=10.19.0" 290 | } 291 | }, 292 | "node_modules/http2-wrapper/node_modules/quick-lru": { 293 | "version": "5.1.1", 294 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 295 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", 296 | "dev": true, 297 | "engines": { 298 | "node": ">=10" 299 | }, 300 | "funding": { 301 | "url": "https://github.com/sponsors/sindresorhus" 302 | } 303 | }, 304 | "node_modules/json-buffer": { 305 | "version": "3.0.1", 306 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 307 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 308 | "dev": true 309 | }, 310 | "node_modules/keyv": { 311 | "version": "4.3.0", 312 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.0.tgz", 313 | "integrity": "sha512-C30Un9+63J0CsR7Wka5quXKqYZsT6dcRQ2aOwGcSc3RiQ4HGWpTAHlCA+puNfw2jA/s11EsxA1nCXgZRuRKMQQ==", 314 | "dev": true, 315 | "dependencies": { 316 | "compress-brotli": "^1.3.8", 317 | "json-buffer": "3.0.1" 318 | } 319 | }, 320 | "node_modules/lowercase-keys": { 321 | "version": "3.0.0", 322 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", 323 | "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", 324 | "dev": true, 325 | "engines": { 326 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 327 | }, 328 | "funding": { 329 | "url": "https://github.com/sponsors/sindresorhus" 330 | } 331 | }, 332 | "node_modules/mimic-response": { 333 | "version": "1.0.1", 334 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 335 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", 336 | "dev": true, 337 | "engines": { 338 | "node": ">=4" 339 | } 340 | }, 341 | "node_modules/normalize-url": { 342 | "version": "6.1.0", 343 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", 344 | "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", 345 | "dev": true, 346 | "engines": { 347 | "node": ">=10" 348 | }, 349 | "funding": { 350 | "url": "https://github.com/sponsors/sindresorhus" 351 | } 352 | }, 353 | "node_modules/once": { 354 | "version": "1.4.0", 355 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 356 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 357 | "dev": true, 358 | "dependencies": { 359 | "wrappy": "1" 360 | } 361 | }, 362 | "node_modules/p-cancelable": { 363 | "version": "3.0.0", 364 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", 365 | "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", 366 | "dev": true, 367 | "engines": { 368 | "node": ">=12.20" 369 | } 370 | }, 371 | "node_modules/pump": { 372 | "version": "3.0.0", 373 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 374 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 375 | "dev": true, 376 | "dependencies": { 377 | "end-of-stream": "^1.1.0", 378 | "once": "^1.3.1" 379 | } 380 | }, 381 | "node_modules/resolve-alpn": { 382 | "version": "1.2.1", 383 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", 384 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", 385 | "dev": true 386 | }, 387 | "node_modules/responselike": { 388 | "version": "2.0.0", 389 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", 390 | "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", 391 | "dev": true, 392 | "dependencies": { 393 | "lowercase-keys": "^2.0.0" 394 | } 395 | }, 396 | "node_modules/responselike/node_modules/lowercase-keys": { 397 | "version": "2.0.0", 398 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 399 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", 400 | "dev": true, 401 | "engines": { 402 | "node": ">=8" 403 | } 404 | }, 405 | "node_modules/wrappy": { 406 | "version": "1.0.2", 407 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 408 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 409 | "dev": true 410 | } 411 | }, 412 | "dependencies": { 413 | "@sindresorhus/is": { 414 | "version": "4.6.0", 415 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", 416 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", 417 | "dev": true 418 | }, 419 | "@szmarczak/http-timer": { 420 | "version": "5.0.1", 421 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", 422 | "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", 423 | "dev": true, 424 | "requires": { 425 | "defer-to-connect": "^2.0.1" 426 | } 427 | }, 428 | "@types/cacheable-request": { 429 | "version": "6.0.2", 430 | "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", 431 | "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", 432 | "dev": true, 433 | "requires": { 434 | "@types/http-cache-semantics": "*", 435 | "@types/keyv": "*", 436 | "@types/node": "*", 437 | "@types/responselike": "*" 438 | } 439 | }, 440 | "@types/http-cache-semantics": { 441 | "version": "4.0.1", 442 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", 443 | "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", 444 | "dev": true 445 | }, 446 | "@types/json-buffer": { 447 | "version": "3.0.0", 448 | "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", 449 | "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==", 450 | "dev": true 451 | }, 452 | "@types/keyv": { 453 | "version": "3.1.4", 454 | "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", 455 | "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", 456 | "dev": true, 457 | "requires": { 458 | "@types/node": "*" 459 | } 460 | }, 461 | "@types/node": { 462 | "version": "17.0.44", 463 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.44.tgz", 464 | "integrity": "sha512-gWYiOlu6Y4oyLYBvsJAPlwHbC8H4tX+tLsHy6Ee976wedwwZKrG2hFl3Y/HiH6bIyLTbDWQexQF/ohwKkOpUCg==", 465 | "dev": true 466 | }, 467 | "@types/responselike": { 468 | "version": "1.0.0", 469 | "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", 470 | "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", 471 | "dev": true, 472 | "requires": { 473 | "@types/node": "*" 474 | } 475 | }, 476 | "cacheable-lookup": { 477 | "version": "6.0.4", 478 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.0.4.tgz", 479 | "integrity": "sha512-mbcDEZCkv2CZF4G01kr8eBd/5agkt9oCqz75tJMSIsquvRZ2sL6Hi5zGVKi/0OSC9oO1GHfJ2AV0ZIOY9vye0A==", 480 | "dev": true 481 | }, 482 | "cacheable-request": { 483 | "version": "7.0.2", 484 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", 485 | "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", 486 | "dev": true, 487 | "requires": { 488 | "clone-response": "^1.0.2", 489 | "get-stream": "^5.1.0", 490 | "http-cache-semantics": "^4.0.0", 491 | "keyv": "^4.0.0", 492 | "lowercase-keys": "^2.0.0", 493 | "normalize-url": "^6.0.1", 494 | "responselike": "^2.0.0" 495 | }, 496 | "dependencies": { 497 | "get-stream": { 498 | "version": "5.2.0", 499 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 500 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 501 | "dev": true, 502 | "requires": { 503 | "pump": "^3.0.0" 504 | } 505 | }, 506 | "lowercase-keys": { 507 | "version": "2.0.0", 508 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 509 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", 510 | "dev": true 511 | } 512 | } 513 | }, 514 | "chalk": { 515 | "version": "5.0.1", 516 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", 517 | "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", 518 | "dev": true 519 | }, 520 | "clone-response": { 521 | "version": "1.0.2", 522 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", 523 | "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", 524 | "dev": true, 525 | "requires": { 526 | "mimic-response": "^1.0.0" 527 | } 528 | }, 529 | "compress-brotli": { 530 | "version": "1.3.8", 531 | "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz", 532 | "integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==", 533 | "dev": true, 534 | "requires": { 535 | "@types/json-buffer": "~3.0.0", 536 | "json-buffer": "~3.0.1" 537 | } 538 | }, 539 | "decompress-response": { 540 | "version": "6.0.0", 541 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 542 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 543 | "dev": true, 544 | "requires": { 545 | "mimic-response": "^3.1.0" 546 | }, 547 | "dependencies": { 548 | "mimic-response": { 549 | "version": "3.1.0", 550 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 551 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", 552 | "dev": true 553 | } 554 | } 555 | }, 556 | "defer-to-connect": { 557 | "version": "2.0.1", 558 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", 559 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", 560 | "dev": true 561 | }, 562 | "end-of-stream": { 563 | "version": "1.4.4", 564 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 565 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 566 | "dev": true, 567 | "requires": { 568 | "once": "^1.4.0" 569 | } 570 | }, 571 | "form-data-encoder": { 572 | "version": "1.7.1", 573 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", 574 | "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", 575 | "dev": true 576 | }, 577 | "fuse.js": { 578 | "version": "6.6.2", 579 | "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz", 580 | "integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==", 581 | "dev": true 582 | }, 583 | "get-stream": { 584 | "version": "6.0.1", 585 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", 586 | "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", 587 | "dev": true 588 | }, 589 | "got": { 590 | "version": "12.1.0", 591 | "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", 592 | "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", 593 | "dev": true, 594 | "requires": { 595 | "@sindresorhus/is": "^4.6.0", 596 | "@szmarczak/http-timer": "^5.0.1", 597 | "@types/cacheable-request": "^6.0.2", 598 | "@types/responselike": "^1.0.0", 599 | "cacheable-lookup": "^6.0.4", 600 | "cacheable-request": "^7.0.2", 601 | "decompress-response": "^6.0.0", 602 | "form-data-encoder": "1.7.1", 603 | "get-stream": "^6.0.1", 604 | "http2-wrapper": "^2.1.10", 605 | "lowercase-keys": "^3.0.0", 606 | "p-cancelable": "^3.0.0", 607 | "responselike": "^2.0.0" 608 | } 609 | }, 610 | "http-cache-semantics": { 611 | "version": "4.1.0", 612 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", 613 | "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", 614 | "dev": true 615 | }, 616 | "http2-wrapper": { 617 | "version": "2.1.11", 618 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", 619 | "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", 620 | "dev": true, 621 | "requires": { 622 | "quick-lru": "^5.1.1", 623 | "resolve-alpn": "^1.2.0" 624 | }, 625 | "dependencies": { 626 | "quick-lru": { 627 | "version": "5.1.1", 628 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 629 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", 630 | "dev": true 631 | } 632 | } 633 | }, 634 | "json-buffer": { 635 | "version": "3.0.1", 636 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 637 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 638 | "dev": true 639 | }, 640 | "keyv": { 641 | "version": "4.3.0", 642 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.0.tgz", 643 | "integrity": "sha512-C30Un9+63J0CsR7Wka5quXKqYZsT6dcRQ2aOwGcSc3RiQ4HGWpTAHlCA+puNfw2jA/s11EsxA1nCXgZRuRKMQQ==", 644 | "dev": true, 645 | "requires": { 646 | "compress-brotli": "^1.3.8", 647 | "json-buffer": "3.0.1" 648 | } 649 | }, 650 | "lowercase-keys": { 651 | "version": "3.0.0", 652 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", 653 | "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", 654 | "dev": true 655 | }, 656 | "mimic-response": { 657 | "version": "1.0.1", 658 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 659 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", 660 | "dev": true 661 | }, 662 | "normalize-url": { 663 | "version": "6.1.0", 664 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", 665 | "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", 666 | "dev": true 667 | }, 668 | "once": { 669 | "version": "1.4.0", 670 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 671 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 672 | "dev": true, 673 | "requires": { 674 | "wrappy": "1" 675 | } 676 | }, 677 | "p-cancelable": { 678 | "version": "3.0.0", 679 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", 680 | "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", 681 | "dev": true 682 | }, 683 | "pump": { 684 | "version": "3.0.0", 685 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 686 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 687 | "dev": true, 688 | "requires": { 689 | "end-of-stream": "^1.1.0", 690 | "once": "^1.3.1" 691 | } 692 | }, 693 | "resolve-alpn": { 694 | "version": "1.2.1", 695 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", 696 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", 697 | "dev": true 698 | }, 699 | "responselike": { 700 | "version": "2.0.0", 701 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", 702 | "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", 703 | "dev": true, 704 | "requires": { 705 | "lowercase-keys": "^2.0.0" 706 | }, 707 | "dependencies": { 708 | "lowercase-keys": { 709 | "version": "2.0.0", 710 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 711 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", 712 | "dev": true 713 | } 714 | } 715 | }, 716 | "wrappy": { 717 | "version": "1.0.2", 718 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 719 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 720 | "dev": true 721 | } 722 | } 723 | } 724 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-lazy-joe", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "spago -x test.dhall test" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT-0", 12 | "type": "module", 13 | "devDependencies": { 14 | "chalk": "^5.0.1", 15 | "fuse.js": "^6.6.2", 16 | "got": "^12.1.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages.dhall: -------------------------------------------------------------------------------- 1 | 2 | let upstream = 3 | https://github.com/purescript/package-sets/releases/download/psc-0.15.2-20220613/packages.dhall 4 | sha256:99f976d547980055179de2245e428f00212e36acd55d74144eab8ad8bf8570d8 5 | 6 | in upstream 7 | -------------------------------------------------------------------------------- /spago.dhall: -------------------------------------------------------------------------------- 1 | { name = "lazy-joe" 2 | , dependencies = 3 | [ "aff" 4 | , "aff-promise" 5 | , "effect" 6 | , "functions" 7 | , "prelude" 8 | , "unsafe-coerce" 9 | ] 10 | , packages = ./packages.dhall 11 | , sources = [ "src/**/*.purs" ] 12 | , license = "MIT-0" 13 | , repository = "https://github.com/sigma-andex/purescript-lazy-joe.git" 14 | } 15 | -------------------------------------------------------------------------------- /src/Lazy/Joe.js: -------------------------------------------------------------------------------- 1 | 2 | export const fromImpl = (name) => () => import(name).then(m => { return m }) 3 | 4 | export const fromDefaultImpl = (name) => () => import(name).then(m => { return m.default }) 5 | 6 | 7 | export const scoped1 = (m) => (f) => (a) => { 8 | const g = f.bind(m) 9 | return g(a) 10 | } 11 | 12 | export const scoped2 = (m) => (f) => (a) => (b) => { 13 | const g = f.bind(m) 14 | return g(a, b) 15 | } 16 | 17 | export const scoped3 = (m) => (f) => (a) => (b) => (c) => { 18 | const g = f.bind(m) 19 | return g(a, b, c) 20 | } 21 | 22 | export const scoped4 = (m) => (f) => (a) => (b) => (c) => (d) => { 23 | const g = f.bind(m) 24 | return g(a, b, c, d) 25 | } 26 | 27 | export const scoped5 = (m) => (f) => (a) => (b) => (c) => (d) => (e) => { 28 | const g = f.bind(m) 29 | return g(a, b, c, d, e) 30 | } 31 | 32 | export const effectful1 = (f) => (a) => () => f(a) 33 | 34 | export const effectful2 = (f) => (a) => (b) => () => f(a, b) 35 | 36 | export const effectful3 = (f) => (a) => (b) => (c) => () => f(a, b, c) 37 | 38 | export const effectful4 = (f) => (a) => (b) => (c) => (d) => () => f(a, b, c, d) 39 | 40 | export const effectful5 = (f) => (a) => (b) => (c) => (d) => (e) => () => f(a, b, c, d, e) 41 | 42 | export const variadicImpl = (f) => (args) => { 43 | return f(...args) 44 | } 45 | 46 | export const varargs1 = (a) => [a] 47 | export const varargs2 = (a) => (b) => [a, b] 48 | export const varargs3 = (a) => (b) => (c) => [a, b, c] 49 | export const varargs4 = (a) => (b) => (c) => (d) => [a, b, c, d] 50 | export const varargs5 = (a) => (b) => (c) => (d) => (e) => [a, b, c, d, e] 51 | 52 | export const new0 = (obj) => { 53 | return new obj() 54 | } 55 | 56 | export const new1 = (obj) => (arg1) => { 57 | return new obj(arg1) 58 | } 59 | 60 | export const new2 = (obj) => (arg1) => (arg2) => { 61 | return new obj(arg1, arg2) 62 | } 63 | 64 | export const new3 = (obj) => (arg1) => (arg2) => (arg3) => { 65 | return new obj(arg1, arg2, arg3) 66 | } 67 | 68 | export const new4 = (obj) => (arg1) => (arg2) => (arg3) => (arg4) => { 69 | return new obj(arg1, arg2, arg3, arg4) 70 | } 71 | 72 | export const new5 = (obj) => (arg1) => (arg2) => (arg3) => (arg4) => (arg5) => { 73 | return new obj(arg1, arg2, arg3, arg4, arg5) 74 | } 75 | -------------------------------------------------------------------------------- /src/Lazy/Joe.purs: -------------------------------------------------------------------------------- 1 | module Lazy.Joe 2 | ( Varargs 3 | , class Effectful 4 | , effectful 5 | , class New 6 | , new 7 | , class Scoped 8 | , scoped 9 | , class Curried 10 | , curried 11 | , class Variadic 12 | , variadic 13 | , from 14 | , fromDefault 15 | ) where 16 | 17 | import Prelude 18 | 19 | import Control.Promise (Promise) 20 | import Control.Promise as Promise 21 | import Data.Function.Uncurried (Fn0, Fn1, Fn2, Fn3, Fn4, Fn5, mkFn1, mkFn2, mkFn3, mkFn4, mkFn5, runFn1, runFn2, runFn3, runFn4, runFn5) 22 | import Effect (Effect) 23 | import Effect.Aff.Class (class MonadAff, liftAff) 24 | import Effect.Class (class MonadEffect, liftEffect) 25 | import Unsafe.Coerce (unsafeCoerce) 26 | 27 | foreign import fromImpl :: forall mod. String -> Effect (Promise mod) 28 | 29 | -- | Import a module 30 | from :: forall mod m. MonadAff m => String -> m { | mod } 31 | from = fromImpl >>> Promise.toAffE >>> liftAff 32 | 33 | foreign import fromDefaultImpl :: forall mod. String -> Effect (Promise mod) 34 | 35 | -- | Import a module with a `default` export 36 | fromDefault :: forall mod m. MonadAff m => String -> m mod 37 | fromDefault = fromDefaultImpl >>> Promise.toAffE >>> liftAff 38 | 39 | class Curried f output | output -> f where 40 | curried :: f -> output 41 | 42 | instance Curried (Fn5 a b c d e f) (a -> b -> c -> d -> e -> f) where 43 | curried = runFn5 44 | 45 | else instance Curried (Fn5 a b c d e f) (Fn5 a b c d e f) where 46 | curried = identity 47 | 48 | else instance Curried (Fn4 a b c d e) (a -> b -> c -> d -> e) where 49 | curried = runFn4 50 | 51 | else instance Curried (Fn4 a b c d e) (Fn4 a b c d e) where 52 | curried = identity 53 | 54 | else instance Curried (Fn3 a b c d) (a -> b -> c -> d) where 55 | curried = runFn3 56 | 57 | else instance Curried (Fn3 a b c d) (Fn3 a b c d) where 58 | curried = identity 59 | 60 | else instance Curried (Fn2 a b c) (a -> b -> c) where 61 | curried = runFn2 62 | 63 | else instance Curried (Fn2 a b c) (Fn2 a b c) where 64 | curried = identity 65 | 66 | else instance Curried (Fn1 a b) (Fn1 a b) where 67 | curried = identity 68 | 69 | else instance Curried (Fn1 a b) (a -> b) where 70 | curried = runFn1 71 | 72 | 73 | foreign import new0 :: forall a. Fn0 a -> a 74 | 75 | foreign import new1 :: forall a b. Fn1 a b -> a -> b 76 | 77 | foreign import new2 :: forall a b c. Fn2 a b c -> a -> b -> c 78 | 79 | foreign import new3 :: forall a b c d. Fn3 a b c d -> a -> b -> c -> d 80 | 81 | foreign import new4 :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> e 82 | 83 | foreign import new5 :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> f 84 | 85 | class New f output | output -> f where 86 | new :: f -> output 87 | 88 | instance New (Fn5 a b c d e f) (a -> b -> c -> d -> e -> f) where 89 | new f = \a -> \b -> \c -> \d -> \e -> new5 f a b c d e 90 | 91 | else instance New (Fn4 a b c d e) (a -> b -> c -> d -> e) where 92 | new f = \a -> \b -> \c -> \d -> new4 f a b c d 93 | 94 | else instance New (Fn3 a b c d) (a -> b -> c -> d) where 95 | new f = \a -> \b -> \c -> new3 f a b c 96 | 97 | else instance New (Fn2 a b c) (a -> b -> c) where 98 | new f = \a -> \b -> new2 f a b 99 | 100 | else instance New (Fn1 a b) (a -> b) where 101 | new f = \a -> new1 f a 102 | 103 | else instance New (Fn0 a) (a) where 104 | new f = new0 f 105 | 106 | class Effectful f output | output -> f where 107 | effectful :: f -> output 108 | 109 | foreign import effectful5 :: forall a b c d e f. Fn5 a b c d e f -> a -> b -> c -> d -> e -> Effect f 110 | 111 | foreign import effectful4 :: forall a b c d e. Fn4 a b c d e -> a -> b -> c -> d -> Effect e 112 | 113 | foreign import effectful3 :: forall a b c d. Fn3 a b c d -> a -> b -> c -> Effect d 114 | 115 | foreign import effectful2 :: forall a b c. Fn2 a b c -> a -> b -> Effect c 116 | 117 | foreign import effectful1 :: forall a b. Fn1 a b -> a -> Effect b 118 | 119 | instance MonadEffect eff => Effectful (Fn5 a b c d e f) (Fn5 a b c d e (eff f)) where 120 | effectful f = mkFn5 (\a -> \b -> \c -> \d -> \e -> effectful5 f a b c d e # liftEffect) 121 | 122 | else instance MonadEffect eff => Effectful (Fn5 a b c d e f) (a -> b -> c -> d -> e -> eff f) where 123 | effectful f = \a -> \b -> \c -> \d -> \e -> effectful5 f a b c d e # liftEffect 124 | 125 | else instance MonadEffect eff => Effectful (Fn4 a b c d e) (Fn4 a b c d (eff e)) where 126 | effectful f = mkFn4 (\a -> \b -> \c -> \d -> effectful4 f a b c d # liftEffect) 127 | 128 | else instance MonadEffect eff => Effectful (Fn4 a b c d e) (a -> b -> c -> d -> eff e) where 129 | effectful f = \a -> \b -> \c -> \d -> effectful4 f a b c d # liftEffect 130 | 131 | else instance MonadEffect eff => Effectful (Fn3 a b c d) (Fn3 a b c (eff d)) where 132 | effectful f = mkFn3 (\a -> \b -> \c -> effectful3 f a b c # liftEffect) 133 | 134 | else instance MonadEffect eff => Effectful (Fn3 a b c d) (a -> b -> c -> eff d) where 135 | effectful f = \a -> \b -> \c -> effectful3 f a b c # liftEffect 136 | 137 | else instance MonadEffect eff => Effectful (Fn2 a b c) (Fn2 a b (eff c)) where 138 | effectful f = mkFn2 (\a -> \b -> effectful2 f a b # liftEffect) 139 | 140 | else instance MonadEffect eff => Effectful (Fn2 a b c) (a -> b -> eff c) where 141 | effectful f = \a -> \b -> effectful2 f a b # liftEffect 142 | 143 | else instance MonadEffect eff => Effectful (Fn1 a b) (Fn1 a (eff b)) where 144 | effectful f = mkFn1 (\a -> effectful1 f a # liftEffect) 145 | 146 | else instance MonadEffect eff => Effectful (Fn1 a b) (a -> eff b) where 147 | effectful f = \a -> effectful1 f a # liftEffect 148 | 149 | foreign import scoped1 :: forall mod a b. mod -> Fn1 a b -> a -> b 150 | 151 | foreign import scoped2 :: forall mod a b c. mod -> Fn2 a b c -> a -> b -> c 152 | 153 | foreign import scoped3 :: forall mod a b c d. mod -> Fn3 a b c d -> a -> b -> c -> d 154 | 155 | foreign import scoped4 :: forall mod a b c d e. mod -> Fn4 a b c d e -> a -> b -> c -> d -> e 156 | 157 | foreign import scoped5 :: forall mod a b c d e f. mod -> Fn5 a b c d e f -> a -> b -> c -> d -> e -> f 158 | 159 | class Scoped f output | output -> f where 160 | scoped :: forall mod. mod -> f -> output 161 | 162 | instance Scoped (Fn5 a b c d e f) (Fn5 a b c d e f) where 163 | scoped m f = mkFn5 \a -> \b -> \c -> \d -> \e -> scoped5 m f a b c d e 164 | 165 | else instance Scoped (Fn5 a b c d e f) (a -> b -> c -> d -> e -> f) where 166 | scoped m f = \a -> \b -> \c -> \d -> \e -> scoped5 m f a b c d e 167 | 168 | else instance Scoped (Fn4 a b c d e) (Fn4 a b c d e) where 169 | scoped m f = mkFn4 \a -> \b -> \c -> \d -> scoped4 m f a b c d 170 | 171 | else instance Scoped (Fn4 a b c d e) (a -> b -> c -> d -> e) where 172 | scoped m f = \a -> \b -> \c -> \d -> scoped4 m f a b c d 173 | 174 | else instance Scoped (Fn3 a b c d) (Fn3 a b c d) where 175 | scoped m f = mkFn3 \a -> \b -> \c -> scoped3 m f a b c 176 | 177 | else instance Scoped (Fn3 a b c d) (a -> b -> c -> d) where 178 | scoped m f = \a -> \b -> \c -> scoped3 m f a b c 179 | 180 | else instance Scoped (Fn2 a b c) (Fn2 a b c) where 181 | scoped m f = mkFn2 (\a -> \b -> scoped2 m f a b) 182 | 183 | else instance Scoped (Fn2 a b c) (a -> b -> c) where 184 | scoped m f = \a -> \b -> scoped2 m f a b 185 | 186 | else instance Scoped (Fn1 a b) (Fn1 a b) where 187 | scoped m f = \a -> scoped1 m f a 188 | 189 | else instance Scoped (Fn1 a b) (a -> b) where 190 | scoped m f = mkFn1 (\a -> scoped1 m f a) 191 | 192 | 193 | foreign import variadicImpl :: forall output. (Varargs -> output) -> Varargs -> output 194 | 195 | class Variadic f output | output -> f where 196 | variadic :: f -> output 197 | 198 | foreign import data Varargs :: Type 199 | 200 | foreign import varargs1 :: forall a. a -> Varargs 201 | 202 | foreign import varargs2 :: forall a b. a -> b -> Varargs 203 | 204 | foreign import varargs3 :: forall a b c. a -> b -> c -> Varargs 205 | 206 | foreign import varargs4 :: forall a b c d. a -> b -> c -> d -> Varargs 207 | 208 | foreign import varargs5 :: forall a b c d e. a -> b -> c -> d -> e -> Varargs 209 | 210 | instance Variadic (Varargs -> f) (Fn5 a b c d e f) where 211 | variadic f = mkFn5 (\a -> \b -> \c -> \d -> \e -> variadicImpl f $ varargs5 a b c d e) 212 | 213 | else instance Variadic (Varargs -> f) (a -> b -> c -> d -> e -> f) where 214 | variadic f = \a -> \b -> \c -> \d -> \e -> variadicImpl f $ varargs5 a b c d e 215 | 216 | else instance Variadic (Varargs -> e) (Fn4 a b c d e) where 217 | variadic f = mkFn4 (\a -> \b -> \c -> \d -> variadicImpl f $ varargs4 a b c d) 218 | 219 | else instance Variadic (Varargs -> e) (a -> b -> c -> d -> e) where 220 | variadic f = \a -> \b -> \c -> \d -> variadicImpl f $ varargs4 a b c d 221 | 222 | else instance Variadic (Varargs -> d) (Fn3 a b c d) where 223 | variadic f = mkFn3 (\a -> \b -> \c -> variadicImpl f $ varargs3 a b c) 224 | 225 | else instance Variadic (Varargs -> d) (a -> b -> c -> d) where 226 | variadic f = \a -> \b -> \c -> variadicImpl f $ varargs3 a b c 227 | 228 | else instance Variadic (Varargs -> c) (Fn2 a b c) where 229 | variadic f = mkFn2 (\a -> \b -> variadicImpl f $ varargs2 a b) 230 | 231 | else instance Variadic (Varargs -> c) (a -> b -> c) where 232 | variadic f = \a -> \b -> variadicImpl f $ varargs2 a b 233 | 234 | else instance Variadic (Varargs -> b) (Array a -> b) where 235 | variadic f = \a -> variadicImpl f $ unsafeCoerce a 236 | 237 | else instance Variadic (Varargs -> b) (Fn1 a b) where 238 | variadic f = mkFn1 (\a -> variadicImpl f $ varargs1 a) 239 | 240 | else instance Variadic (Varargs -> b) (a -> b) where 241 | variadic f = \a -> variadicImpl f $ varargs1 a 242 | 243 | -------------------------------------------------------------------------------- /test.dhall: -------------------------------------------------------------------------------- 1 | let conf = ./spago.dhall 2 | 3 | in conf // { 4 | sources = conf.sources # [ "test/**/*.purs", "docs/Examples/**/*.purs" ], 5 | dependencies = conf.dependencies # [ 6 | , "spec" 7 | , "debug" 8 | , "console" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /test/Main.purs: -------------------------------------------------------------------------------- 1 | module Test.Main where 2 | 3 | import Prelude 4 | 5 | import Control.Promise as Promise 6 | import Effect (Effect) 7 | import Effect.Aff (Aff, launchAff_) 8 | import Effect.Class.Console (log, logShow) 9 | import Lazy.Joe (effectful, fromDefault, new, scoped, curried, variadic) 10 | 11 | main :: Effect Unit 12 | main = launchAff_ do 13 | m@{ blue, underline, rgb, green, red } <- fromDefault "chalk" 14 | 15 | log $ red "Red velvet 🎂" 16 | log $ variadic green "hello" 17 | log $ variadic green "hello" "world" 18 | log $ variadic green [ "hello", "world", "hallo", "welt", "hola", "mundo" ] 19 | 20 | let 21 | x = effectful (variadic blue) "hello" "wurst" 22 | y = effectful (variadic blue) "hello" 23 | log "Effects not run" 24 | x >>= log 25 | y >>= log 26 | 27 | let 28 | underlined :: Aff String 29 | underlined = underline # \{ bold } -> bold # \{ green: g } -> effectful g "grün" 30 | underlined >>= log 31 | 32 | log $ scoped m rgb 123 45 67 # \{ underline: u } -> u "Underlined reddish color" 33 | 34 | let 35 | c :: Aff String 36 | c = effectful (scoped m rgb) 123 45 67 <#> \{ underline: u } -> u "Underlined reddish color" 37 | 38 | log "Effect not run" 39 | c >>= log 40 | 41 | { post } <- fromDefault "got" 42 | resp <- Promise.toAffE $ effectful (curried post) "https://httpbin.org/anything" { json: { hello: "🌎" } } >>= \{ json } -> json 43 | log resp.json 44 | 45 | fuse <- fromDefault "fuse.js" 46 | let 47 | list = 48 | [ { "title": "Old Man's War", "author": { "firstName": "John", "lastName": "Scalzi" } } 49 | , { "title": "The Lock Artist", "author": { "firstName": "Steve", "lastName": "Hamilton" } } 50 | ] 51 | options = 52 | { keys: [ "title", "author.firstName" ] 53 | } 54 | result :: Array { item :: { title :: String, author :: { firstName :: String, lastName :: String } } } <- 55 | (new fuse list options) # \f@{ search } -> effectful (scoped f search) "eve" 56 | 57 | logShow result 58 | pure unit 59 | --------------------------------------------------------------------------------