├── .github └── workflows │ └── playwright.yml ├── .gitignore ├── .test ├── chai.js ├── mocha.css └── mocha.js ├── .vscode └── settings.json ├── README.md ├── ci ├── package-lock.json ├── package.json ├── pageWithCoverage.js ├── playwright.config.js └── tests │ └── mocha.spec.js ├── deno.jsonc ├── dist ├── raggedy.js ├── raggedy.js.map ├── raggedy.min.js └── raggedy.min.js.map ├── import_map.json ├── raggedy-dev.sublime-project ├── raggedy.js ├── src ├── grass.js └── index.js ├── tasks ├── add ├── audit ├── bundle ├── check ├── chrome ├── ci ├── ci-test ├── coverage ├── firefox ├── format ├── lint ├── outdated ├── serve ├── setup ├── test └── vendor ├── tests └── simpletest.js └── vendor ├── esm.sh ├── hash-wasm@4.9.0.js ├── hash-wasm@4.9.0.proxied.js └── v131 │ ├── hash-wasm@4.9.0 │ ├── denonext │ │ └── hash-wasm.mjs │ └── dist │ │ └── lib │ │ ├── WASMInterface.d.ts │ │ ├── adler32.d.ts │ │ ├── argon2.d.ts │ │ ├── bcrypt.d.ts │ │ ├── blake2b.d.ts │ │ ├── blake2s.d.ts │ │ ├── blake3.d.ts │ │ ├── crc32.d.ts │ │ ├── crc32c.d.ts │ │ ├── hmac.d.ts │ │ ├── index.d.ts │ │ ├── keccak.d.ts │ │ ├── md4.d.ts │ │ ├── md5.d.ts │ │ ├── pbkdf2.d.ts │ │ ├── ripemd160.d.ts │ │ ├── scrypt.d.ts │ │ ├── sha1.d.ts │ │ ├── sha224.d.ts │ │ ├── sha256.d.ts │ │ ├── sha3.d.ts │ │ ├── sha384.d.ts │ │ ├── sha512.d.ts │ │ ├── sm3.d.ts │ │ ├── util.d.ts │ │ ├── whirlpool.d.ts │ │ ├── xxhash128.d.ts │ │ ├── xxhash3.d.ts │ │ ├── xxhash32.d.ts │ │ └── xxhash64.d.ts │ └── node.ns.d.ts └── import_map.json /.github/workflows/playwright.yml: -------------------------------------------------------------------------------- 1 | name: Playwright Tests 2 | on: 3 | push: 4 | branches: [main, master] 5 | pull_request: 6 | branches: [main, master] 7 | jobs: 8 | test: 9 | timeout-minutes: 60 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | - uses: actions/setup-node@v3 14 | with: 15 | node-version: lts/* 16 | - name: Setup 17 | run: tasks/setup 18 | - name: Lint 19 | run: tasks/lint 20 | - name: JSDoc check 21 | run: tasks/check 22 | - name: Install CI dependencies 23 | run: tasks/ci 24 | - name: Install Playwright Browsers 25 | run: npx playwright install --with-deps 26 | - name: Run Playwright tests 27 | run: tasks/ci-test 28 | - uses: actions/upload-artifact@v3 29 | if: always() 30 | with: 31 | name: playwright-report 32 | path: playwright-report/ 33 | retention-days: 30 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage/ 24 | .coverage 25 | *.lcov 26 | 27 | # nyc test coverage 28 | .nyc_output 29 | 30 | # Compiled binary addons (https://nodejs.org/api/addons.html) 31 | build/Release 32 | 33 | # Dependency directories 34 | node_modules/ 35 | jspm_packages/ 36 | 37 | # Snowpack dependency directory (https://snowpack.dev/) 38 | web_modules/ 39 | 40 | # TypeScript cache 41 | *.tsbuildinfo 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # dotenv environment variable files 47 | .env 48 | .env.development.local 49 | .env.test.local 50 | .env.production.local 51 | .env.local 52 | 53 | # Ignore local binaries. If you're using your own .gitignore, this is the line to add to it. 54 | .bin/ 55 | *.sublime-workspace 56 | 57 | # This should not be saved 58 | playwright-report -------------------------------------------------------------------------------- /.test/mocha.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | :root { 4 | --mocha-color: #000; 5 | --mocha-bg-color: #fff; 6 | --mocha-pass-icon-color: #00d6b2; 7 | --mocha-pass-color: #fff; 8 | --mocha-pass-shadow-color: rgba(0,0,0,.2); 9 | --mocha-pass-mediump-color: #c09853; 10 | --mocha-pass-slow-color: #b94a48; 11 | --mocha-test-pending-color: #0b97c4; 12 | --mocha-test-pending-icon-color: #0b97c4; 13 | --mocha-test-fail-color: #c00; 14 | --mocha-test-fail-icon-color: #c00; 15 | --mocha-test-fail-pre-color: #000; 16 | --mocha-test-fail-pre-error-color: #c00; 17 | --mocha-test-html-error-color: #000; 18 | --mocha-box-shadow-color: #eee; 19 | --mocha-box-bottom-color: #ddd; 20 | --mocha-test-replay-color: #000; 21 | --mocha-test-replay-bg-color: #eee; 22 | --mocha-stats-color: #888; 23 | --mocha-stats-em-color: #000; 24 | --mocha-stats-hover-color: #eee; 25 | --mocha-error-color: #c00; 26 | 27 | --mocha-code-comment: #ddd; 28 | --mocha-code-init: #2f6fad; 29 | --mocha-code-string: #5890ad; 30 | --mocha-code-keyword: #8a6343; 31 | --mocha-code-number: #2f6fad; 32 | } 33 | 34 | @media (prefers-color-scheme: dark) { 35 | :root { 36 | --mocha-color: #fff; 37 | --mocha-bg-color: #222; 38 | --mocha-pass-icon-color: #00d6b2; 39 | --mocha-pass-color: #222; 40 | --mocha-pass-shadow-color: rgba(255,255,255,.2); 41 | --mocha-pass-mediump-color: #f1be67; 42 | --mocha-pass-slow-color: #f49896; 43 | --mocha-test-pending-color: #0b97c4; 44 | --mocha-test-pending-icon-color: #0b97c4; 45 | --mocha-test-fail-color: #f44; 46 | --mocha-test-fail-icon-color: #f44; 47 | --mocha-test-fail-pre-color: #fff; 48 | --mocha-test-fail-pre-error-color: #f44; 49 | --mocha-test-html-error-color: #fff; 50 | --mocha-box-shadow-color: #444; 51 | --mocha-box-bottom-color: #555; 52 | --mocha-test-replay-color: #fff; 53 | --mocha-test-replay-bg-color: #444; 54 | --mocha-stats-color: #aaa; 55 | --mocha-stats-em-color: #fff; 56 | --mocha-stats-hover-color: #444; 57 | --mocha-error-color: #f44; 58 | 59 | --mocha-code-comment: #ddd; 60 | --mocha-code-init: #9cc7f1; 61 | --mocha-code-string: #80d4ff; 62 | --mocha-code-keyword: #e3a470; 63 | --mocha-code-number: #4ca7ff; 64 | } 65 | } 66 | 67 | body { 68 | margin:0; 69 | background-color: var(--mocha-bg-color); 70 | color: var(--mocha-color); 71 | } 72 | 73 | #mocha { 74 | font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif; 75 | margin: 60px 50px; 76 | } 77 | 78 | #mocha ul, 79 | #mocha li { 80 | margin: 0; 81 | padding: 0; 82 | } 83 | 84 | #mocha ul { 85 | list-style: none; 86 | } 87 | 88 | #mocha h1, 89 | #mocha h2 { 90 | margin: 0; 91 | } 92 | 93 | #mocha h1 { 94 | margin-top: 15px; 95 | font-size: 1em; 96 | font-weight: 200; 97 | } 98 | 99 | #mocha h1 a { 100 | text-decoration: none; 101 | color: inherit; 102 | } 103 | 104 | #mocha h1 a:hover { 105 | text-decoration: underline; 106 | } 107 | 108 | #mocha .suite .suite h1 { 109 | margin-top: 0; 110 | font-size: .8em; 111 | } 112 | 113 | #mocha .hidden { 114 | display: none; 115 | } 116 | 117 | #mocha h2 { 118 | font-size: 12px; 119 | font-weight: normal; 120 | cursor: pointer; 121 | } 122 | 123 | #mocha .suite { 124 | margin-left: 15px; 125 | } 126 | 127 | #mocha .test { 128 | margin-left: 15px; 129 | overflow: hidden; 130 | } 131 | 132 | #mocha .test.pending:hover h2::after { 133 | content: '(pending)'; 134 | font-family: arial, sans-serif; 135 | } 136 | 137 | #mocha .test.pass.medium .duration { 138 | background: var(--mocha-pass-mediump-color); 139 | } 140 | 141 | #mocha .test.pass.slow .duration { 142 | background: var(--mocha-pass-slow-color); 143 | } 144 | 145 | #mocha .test.pass::before { 146 | content: '✓'; 147 | font-size: 12px; 148 | display: block; 149 | float: left; 150 | margin-right: 5px; 151 | color: var(--mocha-pass-icon-color); 152 | } 153 | 154 | #mocha .test.pass .duration { 155 | font-size: 9px; 156 | margin-left: 5px; 157 | padding: 2px 5px; 158 | color: var(--mocha-pass-color); 159 | -webkit-box-shadow: inset 0 1px 1px var(--mocha-pass-shadow-color); 160 | -moz-box-shadow: inset 0 1px 1px var(--mocha-pass-shadow-color); 161 | box-shadow: inset 0 1px 1px var(--mocha-pass-shadow-color); 162 | -webkit-border-radius: 5px; 163 | -moz-border-radius: 5px; 164 | -ms-border-radius: 5px; 165 | -o-border-radius: 5px; 166 | border-radius: 5px; 167 | } 168 | 169 | #mocha .test.pass.fast .duration { 170 | display: none; 171 | } 172 | 173 | #mocha .test.pending { 174 | color: var(--mocha-test-pending-color); 175 | } 176 | 177 | #mocha .test.pending::before { 178 | content: '◦'; 179 | color: var(--mocha-test-pending-icon-color); 180 | } 181 | 182 | #mocha .test.fail { 183 | color: var(--mocha-test-fail-color); 184 | } 185 | 186 | #mocha .test.fail pre { 187 | color: var(--mocha-test-fail-pre-color); 188 | } 189 | 190 | #mocha .test.fail::before { 191 | content: '✖'; 192 | font-size: 12px; 193 | display: block; 194 | float: left; 195 | margin-right: 5px; 196 | color: var(--mocha-test-fail-icon-color); 197 | } 198 | 199 | #mocha .test pre.error { 200 | color: var(--mocha-test-fail-pre-error-color); 201 | max-height: 300px; 202 | overflow: auto; 203 | } 204 | 205 | #mocha .test .html-error { 206 | overflow: auto; 207 | color: var(--mocha-test-html-error-color); 208 | display: block; 209 | float: left; 210 | clear: left; 211 | font: 12px/1.5 monaco, monospace; 212 | margin: 5px; 213 | padding: 15px; 214 | border: 1px solid var(--mocha-box-shadow-color); 215 | max-width: 85%; /*(1)*/ 216 | max-width: -webkit-calc(100% - 42px); 217 | max-width: -moz-calc(100% - 42px); 218 | max-width: calc(100% - 42px); /*(2)*/ 219 | max-height: 300px; 220 | word-wrap: break-word; 221 | border-bottom-color: var(--mocha-box-bottom-color); 222 | -webkit-box-shadow: 0 1px 3px var(--mocha-box-shadow-color); 223 | -moz-box-shadow: 0 1px 3px var(--mocha-box-shadow-color); 224 | box-shadow: 0 1px 3px var(--mocha-box-shadow-color); 225 | -webkit-border-radius: 3px; 226 | -moz-border-radius: 3px; 227 | border-radius: 3px; 228 | } 229 | 230 | #mocha .test .html-error pre.error { 231 | border: none; 232 | -webkit-border-radius: 0; 233 | -moz-border-radius: 0; 234 | border-radius: 0; 235 | -webkit-box-shadow: 0; 236 | -moz-box-shadow: 0; 237 | box-shadow: 0; 238 | padding: 0; 239 | margin: 0; 240 | margin-top: 18px; 241 | max-height: none; 242 | } 243 | 244 | /** 245 | * (1): approximate for browsers not supporting calc 246 | * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border) 247 | * ^^ seriously 248 | */ 249 | #mocha .test pre { 250 | display: block; 251 | float: left; 252 | clear: left; 253 | font: 12px/1.5 monaco, monospace; 254 | margin: 5px; 255 | padding: 15px; 256 | border: 1px solid var(--mocha-box-shadow-color); 257 | max-width: 85%; /*(1)*/ 258 | max-width: -webkit-calc(100% - 42px); 259 | max-width: -moz-calc(100% - 42px); 260 | max-width: calc(100% - 42px); /*(2)*/ 261 | word-wrap: break-word; 262 | border-bottom-color: var(--mocha-box-bottom-color); 263 | -webkit-box-shadow: 0 1px 3px var(--mocha-box-shadow-color); 264 | -moz-box-shadow: 0 1px 3px var(--mocha-box-shadow-color); 265 | box-shadow: 0 1px 3px var(--mocha-box-shadow-color); 266 | -webkit-border-radius: 3px; 267 | -moz-border-radius: 3px; 268 | border-radius: 3px; 269 | } 270 | 271 | #mocha .test h2 { 272 | position: relative; 273 | } 274 | 275 | #mocha .test a.replay { 276 | position: absolute; 277 | top: 3px; 278 | right: 0; 279 | text-decoration: none; 280 | vertical-align: middle; 281 | display: block; 282 | width: 15px; 283 | height: 15px; 284 | line-height: 15px; 285 | text-align: center; 286 | background: var(--mocha-test-replay-bg-color); 287 | font-size: 15px; 288 | -webkit-border-radius: 15px; 289 | -moz-border-radius: 15px; 290 | border-radius: 15px; 291 | -webkit-transition:opacity 200ms; 292 | -moz-transition:opacity 200ms; 293 | -o-transition:opacity 200ms; 294 | transition: opacity 200ms; 295 | opacity: 0.7; 296 | color: var(--mocha-test-replay-color); 297 | } 298 | 299 | #mocha .test:hover a.replay { 300 | box-shadow: 0 0 1px inset var(--mocha-test-replay-color); 301 | opacity: 1; 302 | } 303 | 304 | #mocha-report.pass .test.fail { 305 | display: none; 306 | } 307 | 308 | #mocha-report.fail .test.pass { 309 | display: none; 310 | } 311 | 312 | #mocha-report.pending .test.pass, 313 | #mocha-report.pending .test.fail { 314 | display: none; 315 | } 316 | #mocha-report.pending .test.pass.pending { 317 | display: block; 318 | } 319 | 320 | #mocha-error { 321 | color: var(--mocha-error-color); 322 | font-size: 1.5em; 323 | font-weight: 100; 324 | letter-spacing: 1px; 325 | } 326 | 327 | #mocha-stats { 328 | position: fixed; 329 | top: 15px; 330 | right: 10px; 331 | font-size: 12px; 332 | margin: 0; 333 | color: var(--mocha-stats-color); 334 | z-index: 1; 335 | } 336 | 337 | #mocha-stats .progress { 338 | float: right; 339 | padding-top: 0; 340 | 341 | /** 342 | * Set safe initial values, so mochas .progress does not inherit these 343 | * properties from Bootstrap .progress (which causes .progress height to 344 | * equal line height set in Bootstrap). 345 | */ 346 | height: auto; 347 | -webkit-box-shadow: none; 348 | -moz-box-shadow: none; 349 | box-shadow: none; 350 | background-color: initial; 351 | } 352 | 353 | #mocha-stats em { 354 | color: var(--mocha-stats-em-color); 355 | } 356 | 357 | #mocha-stats a { 358 | text-decoration: none; 359 | color: inherit; 360 | } 361 | 362 | #mocha-stats a:hover { 363 | border-bottom: 1px solid var(--mocha-stats-hover-color); 364 | } 365 | 366 | #mocha-stats li { 367 | display: inline-block; 368 | margin: 0 5px; 369 | list-style: none; 370 | padding-top: 11px; 371 | } 372 | 373 | #mocha-stats canvas { 374 | width: 40px; 375 | height: 40px; 376 | } 377 | 378 | #mocha code .comment { color: var(--mocha-code-comment); } 379 | #mocha code .init { color: var(--mocha-code-init); } 380 | #mocha code .string { color: var(--mocha-code-string); } 381 | #mocha code .keyword { color: var(--mocha-code-keyword); } 382 | #mocha code .number { color: var(--mocha-code-number); } 383 | 384 | @media screen and (max-device-width: 480px) { 385 | #mocha { 386 | margin: 60px 0px; 387 | } 388 | 389 | #mocha #stats { 390 | position: absolute; 391 | } 392 | } 393 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.enable": true, 3 | "deno.path": ".bin/deno", 4 | "deno.testing.enable": false, 5 | "editor.formatOnSave": true, 6 | "editor.defaultFormatter": "denoland.vscode-deno", 7 | "[javascript]": { 8 | "editor.defaultFormatter": "denoland.vscode-deno" 9 | }, 10 | "[json]": { 11 | "editor.defaultFormatter": "denoland.vscode-deno" 12 | }, 13 | "[jsonc]": { 14 | "editor.defaultFormatter": "denoland.vscode-deno" 15 | }, 16 | "[typescript]": { 17 | "editor.defaultFormatter": "denoland.vscode-deno" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Raggedy Dev setup 2 | 3 | _The browser is your runtime._ 4 | 5 | _The shell is your task runner._ 6 | 7 | **NOT FOR FRAMEWORKS**. 8 | 9 | This is an experiment in defining a minimalistic but full-featured environment 10 | for web development where the primary runtime for the project is the browser 11 | itself, not node or deno. 12 | 13 | Deno is used here to implement some dev tasks but only in a capacity that's 14 | similar to how bash or external command line tools work. You don't need to have 15 | deno installed to use this, the setup script will download a local copy that'll 16 | be used in just this project. 17 | 18 | ## All tasks are scripts in the `tasks/` directory 19 | 20 | Instead of a task runner this project uses the file system and your shell. Tasks 21 | are in the `tasks/` directory and are all executable scripts. Edit the scripts 22 | to configure them (although this is rarely necessary). 23 | 24 | ### Run `tasks/setup` first 25 | 26 | Running `tasks/setup` will download a pinned version of `deno` into `.bin`. This 27 | is the version that the task scripts will use. There is also a 28 | `.vscode/settings.json` file that tells your deno extension in VS Code to use 29 | the local binary. 30 | 31 | This setup doesn't interfere with your shell's `$PATH` in any way. 32 | 33 | The version is pinned to `v1.36.4`. This can be changed by editing the 34 | `DENO_VERSION` variable and the `DENO_SHA` checksum variable towards the top of 35 | the `tasks/setup` script. 36 | 37 | The `deno.jsonc` configuration file is set up so that deno knows that `js` files 38 | in this project are primarily for the browser. It is also documented with 39 | comments. It will use the provided `import_map.json` file as the project's 40 | primary import map 41 | 42 | The setup task will also generate a self-signed certificate that the `serve` 43 | task will then use to provide an `https` server. 44 | 45 | ### Run `tasks/serve` for unit testing in the browser with mocha 46 | 47 | Tests are based on mocha. 48 | 49 | Running `tasks/serve` will start up a simple `https` web server that hosts the 50 | current directory and an HTML page that runs all test files found in `tests/` 51 | and automatically includes the `import_map.json` file as an import map. 52 | 53 | This server is set up to deliver files with all the necessary headers to enable 54 | [cross-site isolation](https://web.dev/coop-coep/). This means that features 55 | such as `SharedArrayBuffer`, high resolution timers, and `Atomics.wait()`. As a 56 | result cross-origin resources are likely to break. At some point I'll update 57 | this to make this configurable so you can turn isolation off if necessary. 58 | 59 | This page will automatically refresh any time something in the current working 60 | directory is changed. 61 | 62 | Running `tasks/chrome` or `tasks/firefox` will attempt to launch browser 63 | instances with fresh profiles and, if necessary, exceptions for self-signed 64 | https certificates. 65 | 66 | For coverage, use the coverage panel in Chrome's development tools. 67 | 68 | To configure the test file (i.e. change mocha's interface or timeout settings), 69 | edit the configuration variables in the `tasks/serve` script itself. 70 | 71 | #### `.test` and `tests` 72 | 73 | The `.test` directory contains vendored copies of `mocha` and `chai` to simplify 74 | test setup. 75 | 76 | I've also included an example `simpletest.js` file that shows how `mocha` and 77 | `chai` are set up by default. 78 | 79 | ### Run `tasks/vendor` to vendor dependencies 80 | 81 | The `tasks/vendor` script will save local copies of your project and create an 82 | import map that the test server and the bundler will load automatically. 83 | 84 | That means your project will no longer be fetching those dependencies over the 85 | network. 86 | 87 | Re-run `tasks/vendor` whenever you modify the `import_map.json` file in the 88 | project root or whenever you add or remove an `http` dependency in your code. 89 | 90 | ### Run `tasks/lint` to lint your `.js` files 91 | 92 | Running `tasks/lint` will run deno's linter on the current directory with the 93 | current settings from `deno.jsonc`. The deno VS Code extension should also 94 | automatically lint files in your workspace. 95 | 96 | ### Run `tasks/format` to format your `.js` files 97 | 98 | Running `tasks/format` will run deno's formatter on the current directory with 99 | the current settings from `deno.jsonc`. The deno VS Code extension should also 100 | automatically format files in your workspace. 101 | 102 | ### Run `tasks/check` to type check your `.js` files 103 | 104 | Type checking JS files is disabled by default. You can enable this throughout 105 | the workspaces by setting `checkJS` to `true` in `deno.jsonc` or in individual 106 | files by including `// @ts-check` in the first line of the file. 107 | 108 | Running `tasks/check` will run deno's typescript checker on all files in the 109 | `src` directory. You can configure this in the `tasks/check` file. 110 | 111 | ### Run `tasks/bundle` to bundle your project 112 | 113 | Running `tasks/bundle` will bundle every `.js` file in the root of the project 114 | into `dist` using esbuild. It additionally will fetch modules over the network 115 | (or using deno's cache) just like the browser. 116 | 117 | This means you don't need to install packages locally in any way. Modules work 118 | just like they do in the browser and the bundler will use the 119 | `vendor/import_map.json` file if it exist to find modules, which means that 120 | dependencies that have been vendored with `tasks/vendor` should be automatically 121 | supported. 122 | 123 | Code-splitting is enabled so imports that are shared by the root entry points 124 | will be imported as shared chunks into the `dist/` directory. 125 | 126 | ## Experimental dependency-management with import maps 127 | 128 | `tasks/add`, `tasks/outdated`, and `tasks/audit` are a first pass at a bare 129 | mininum dependency-management system using import maps. 130 | 131 | `tasks/add npm:hash-wasm` will add a `npm:hash-wasm` entry to your import map 132 | `imports` that maps to the latest `esm.sh` url for the `hash-wasm` package. You 133 | can use semantic versioning so `tasks/add npm:hash-wasm@\^4.9 --exact` will 134 | create that entry directly without resolving it. 135 | 136 | `tasks/outdated` will resolve the url for the listed entry in the import map and 137 | the latest url for that package and compare the version in the two urls. 138 | Packages whose resolved mapped version is lower than the resolved latest version 139 | are listed. 140 | 141 | `tasks/audit` will load the dependency graph, using the graph tools made by the 142 | `deno` team, extract package names and versions from `esm.sh` urls that appear 143 | in the graph, submit those to 144 | [Sonatype's OSSIndex](https://ossindex.sonatype.org/about) and alert you if any 145 | of the packages you list in your import map are importing what looks like a 146 | vulnerable dependency. 147 | 148 | (My original plan was to use Github's REST API for global security advisories, 149 | but I couldn't get it to work with insecure scoped packages. They would always 150 | return as if they had no vulnerabilities.) 151 | 152 | ## Continuous Integration and automated test runs 153 | 154 | This setup includes continuous integration. Whenever you push to GitHub it will 155 | run an Action that installs [Playwright](https://playwright.dev/), runs the 156 | Mocha tests in Firefox, WebKit, and Chrome and passes or fails depending on the 157 | results of the Mocha unit tests. 158 | 159 | These tests only run in the action and you don't need to have node or a node 160 | version manager to use this setup. 161 | 162 | The GitHub Action workflow does this by running `tasks/ci`, 163 | `npx playwright install --with-deps`, and `tasks/ci-test`. 164 | 165 | If you already have node setup on your machine, you could use Playwright as a 166 | test runner for mocha with coverage. Just run `tasks/ci` to move the config 167 | files to project root, commit, and finally run 168 | `npx playwright install --with-deps`. 169 | 170 | then you can use `tasks/ci-test` to run the tests with coverage. 171 | 172 | This is error-prone if your platform isn't well-supported by the Playwright 173 | team. You may have to edit `playwright.config.js` and remove the `webkit` 174 | project for it to run. 175 | 176 | ### `tasks/ci` 177 | 178 | This task will copy the `package.json`, `package-lock.json` and 179 | `playwright.config.js` files from `ci/` into the project root that are necessary 180 | for Playwright tests to run. 181 | 182 | You can edit the original files in `ci/` for additional configuration. 183 | 184 | ### `tasks/ci-test` 185 | 186 | Run this task after `tasks/ci` to have Playwright run all of the tests files in 187 | `ci/tests`. You can include additional integration tests by adding Playwright 188 | test files to `ci/tests`. This task will automatically gather coverage 189 | information from Playwright and use the local copy of deno to both report 190 | coverage data to standard out (should be visible in Action logs) and to 191 | `cov_profile.lcov` which can be sent to coverage reporting services by adding 192 | their actions to the workflow. 193 | 194 | To automatically gather coverage data from additional integration tests, you 195 | need to import the `pageWithCoverage` fixture from `ci/pageWithCoverage.js` and 196 | use that as the main `page` object for interacting with the page. See 197 | `ci/tests/mocha-spec.js` as an example. 198 | 199 | ## Importing Raggedy Dev projects in other projects 200 | 201 | _This only works if you use URL module specifiers. Bare imports breaks default 202 | compatibility._ 203 | 204 | _We don't need no stinking package registry._ 205 | 206 | If you're using browser-compatible JS modules that fetch over HTTP, you don't 207 | need to publish your project on npm to distribute your module. 208 | 209 | Since a Raggedy Dev project is set up to use browser compatible importing, any 210 | content delivery network that lets you fetch files from a GitHub repository will 211 | serve to let you import the project. 212 | 213 | For this reason, build files in `dist` are _included in the commit_. 214 | 215 | `tasks/bundle` now creates two bundles for each entry point: 216 | 217 | **.min.js**: a minified bundle of the entry point and all of its dependencies 218 | **.js** (no .min): a bundle of local JS files only, all dependencies are 219 | external. 220 | 221 | This should mean that, for example, this should work for importing one of the 222 | main entry points for this sample project: 223 | 224 | ```js 225 | import * as raggedy from "https://esm.sh/gh/baldurbjarnason/raggedy-dev-setup@v1.1.0/dist/raggedy.js"; 226 | ``` 227 | 228 | With that you would get the `raggedy.js` entry point in the release tagged 229 | `v1.1.0`. 230 | 231 | If `raggedy.js` imports a dependency from `esm.sh` that's shared with something 232 | else you're importing, then we won't be loading thtat twice any more. 233 | 234 | However, if you aren't importing the module to use in your own JS code, but are 235 | instead adding a script to a web page, then the `.min.js` files would be a 236 | better fit as they are bundled to be standalone and minified. 237 | 238 | ```html 239 | 240 | ``` 241 | 242 | ## Visual Studio Code 243 | 244 | This setup includes workspace settings to enable the deno extension (if 245 | installed) and set the editor to use it to format on save for the file types 246 | that deno supports. 247 | 248 | ## Sublime Text 249 | 250 | This setup includes project settings to enable the deno extension (if installed) 251 | and set the editor to use it to format on save for the file types that deno 252 | supports. 253 | 254 | It also disables `LSP-typescript` in the project as that seems to conflict with 255 | `LSP-deno`. 256 | -------------------------------------------------------------------------------- /ci/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "raggedy-dev-setup", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "raggedy-dev-setup", 9 | "version": "1.0.0", 10 | "license": "UNLICENSED", 11 | "devDependencies": { 12 | "@playwright/test": "^1.37.1", 13 | "c8": "8.0.1" 14 | } 15 | }, 16 | "node_modules/@bcoe/v8-coverage": { 17 | "version": "0.2.3", 18 | "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", 19 | "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", 20 | "dev": true 21 | }, 22 | "node_modules/@istanbuljs/schema": { 23 | "version": "0.1.3", 24 | "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", 25 | "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", 26 | "dev": true, 27 | "engines": { 28 | "node": ">=8" 29 | } 30 | }, 31 | "node_modules/@jridgewell/resolve-uri": { 32 | "version": "3.1.1", 33 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", 34 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", 35 | "dev": true, 36 | "engines": { 37 | "node": ">=6.0.0" 38 | } 39 | }, 40 | "node_modules/@jridgewell/sourcemap-codec": { 41 | "version": "1.4.15", 42 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 43 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 44 | "dev": true 45 | }, 46 | "node_modules/@jridgewell/trace-mapping": { 47 | "version": "0.3.19", 48 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", 49 | "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", 50 | "dev": true, 51 | "dependencies": { 52 | "@jridgewell/resolve-uri": "^3.1.0", 53 | "@jridgewell/sourcemap-codec": "^1.4.14" 54 | } 55 | }, 56 | "node_modules/@playwright/test": { 57 | "version": "1.37.1", 58 | "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz", 59 | "integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==", 60 | "dev": true, 61 | "dependencies": { 62 | "@types/node": "*", 63 | "playwright-core": "1.37.1" 64 | }, 65 | "bin": { 66 | "playwright": "cli.js" 67 | }, 68 | "engines": { 69 | "node": ">=16" 70 | }, 71 | "optionalDependencies": { 72 | "fsevents": "2.3.2" 73 | } 74 | }, 75 | "node_modules/@types/istanbul-lib-coverage": { 76 | "version": "2.0.4", 77 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", 78 | "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", 79 | "dev": true 80 | }, 81 | "node_modules/@types/node": { 82 | "version": "20.6.0", 83 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", 84 | "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==", 85 | "dev": true 86 | }, 87 | "node_modules/ansi-regex": { 88 | "version": "5.0.1", 89 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 90 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 91 | "dev": true, 92 | "engines": { 93 | "node": ">=8" 94 | } 95 | }, 96 | "node_modules/ansi-styles": { 97 | "version": "4.3.0", 98 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 99 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 100 | "dev": true, 101 | "dependencies": { 102 | "color-convert": "^2.0.1" 103 | }, 104 | "engines": { 105 | "node": ">=8" 106 | }, 107 | "funding": { 108 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 109 | } 110 | }, 111 | "node_modules/balanced-match": { 112 | "version": "1.0.2", 113 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 114 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 115 | "dev": true 116 | }, 117 | "node_modules/brace-expansion": { 118 | "version": "1.1.11", 119 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 120 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 121 | "dev": true, 122 | "dependencies": { 123 | "balanced-match": "^1.0.0", 124 | "concat-map": "0.0.1" 125 | } 126 | }, 127 | "node_modules/c8": { 128 | "version": "8.0.1", 129 | "resolved": "https://registry.npmjs.org/c8/-/c8-8.0.1.tgz", 130 | "integrity": "sha512-EINpopxZNH1mETuI0DzRA4MZpAUH+IFiRhnmFD3vFr3vdrgxqi3VfE3KL0AIL+zDq8rC9bZqwM/VDmmoe04y7w==", 131 | "dev": true, 132 | "dependencies": { 133 | "@bcoe/v8-coverage": "^0.2.3", 134 | "@istanbuljs/schema": "^0.1.3", 135 | "find-up": "^5.0.0", 136 | "foreground-child": "^2.0.0", 137 | "istanbul-lib-coverage": "^3.2.0", 138 | "istanbul-lib-report": "^3.0.1", 139 | "istanbul-reports": "^3.1.6", 140 | "rimraf": "^3.0.2", 141 | "test-exclude": "^6.0.0", 142 | "v8-to-istanbul": "^9.0.0", 143 | "yargs": "^17.7.2", 144 | "yargs-parser": "^21.1.1" 145 | }, 146 | "bin": { 147 | "c8": "bin/c8.js" 148 | }, 149 | "engines": { 150 | "node": ">=12" 151 | } 152 | }, 153 | "node_modules/cliui": { 154 | "version": "8.0.1", 155 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", 156 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", 157 | "dev": true, 158 | "dependencies": { 159 | "string-width": "^4.2.0", 160 | "strip-ansi": "^6.0.1", 161 | "wrap-ansi": "^7.0.0" 162 | }, 163 | "engines": { 164 | "node": ">=12" 165 | } 166 | }, 167 | "node_modules/color-convert": { 168 | "version": "2.0.1", 169 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 170 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 171 | "dev": true, 172 | "dependencies": { 173 | "color-name": "~1.1.4" 174 | }, 175 | "engines": { 176 | "node": ">=7.0.0" 177 | } 178 | }, 179 | "node_modules/color-name": { 180 | "version": "1.1.4", 181 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 182 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 183 | "dev": true 184 | }, 185 | "node_modules/concat-map": { 186 | "version": "0.0.1", 187 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 188 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 189 | "dev": true 190 | }, 191 | "node_modules/convert-source-map": { 192 | "version": "1.9.0", 193 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", 194 | "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", 195 | "dev": true 196 | }, 197 | "node_modules/cross-spawn": { 198 | "version": "7.0.3", 199 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 200 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 201 | "dev": true, 202 | "dependencies": { 203 | "path-key": "^3.1.0", 204 | "shebang-command": "^2.0.0", 205 | "which": "^2.0.1" 206 | }, 207 | "engines": { 208 | "node": ">= 8" 209 | } 210 | }, 211 | "node_modules/emoji-regex": { 212 | "version": "8.0.0", 213 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 214 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 215 | "dev": true 216 | }, 217 | "node_modules/escalade": { 218 | "version": "3.1.1", 219 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 220 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 221 | "dev": true, 222 | "engines": { 223 | "node": ">=6" 224 | } 225 | }, 226 | "node_modules/find-up": { 227 | "version": "5.0.0", 228 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 229 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 230 | "dev": true, 231 | "dependencies": { 232 | "locate-path": "^6.0.0", 233 | "path-exists": "^4.0.0" 234 | }, 235 | "engines": { 236 | "node": ">=10" 237 | }, 238 | "funding": { 239 | "url": "https://github.com/sponsors/sindresorhus" 240 | } 241 | }, 242 | "node_modules/foreground-child": { 243 | "version": "2.0.0", 244 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", 245 | "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", 246 | "dev": true, 247 | "dependencies": { 248 | "cross-spawn": "^7.0.0", 249 | "signal-exit": "^3.0.2" 250 | }, 251 | "engines": { 252 | "node": ">=8.0.0" 253 | } 254 | }, 255 | "node_modules/fs.realpath": { 256 | "version": "1.0.0", 257 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 258 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 259 | "dev": true 260 | }, 261 | "node_modules/fsevents": { 262 | "version": "2.3.2", 263 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 264 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 265 | "dev": true, 266 | "hasInstallScript": true, 267 | "optional": true, 268 | "os": [ 269 | "darwin" 270 | ], 271 | "engines": { 272 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 273 | } 274 | }, 275 | "node_modules/get-caller-file": { 276 | "version": "2.0.5", 277 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 278 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 279 | "dev": true, 280 | "engines": { 281 | "node": "6.* || 8.* || >= 10.*" 282 | } 283 | }, 284 | "node_modules/glob": { 285 | "version": "7.2.3", 286 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 287 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 288 | "dev": true, 289 | "dependencies": { 290 | "fs.realpath": "^1.0.0", 291 | "inflight": "^1.0.4", 292 | "inherits": "2", 293 | "minimatch": "^3.1.1", 294 | "once": "^1.3.0", 295 | "path-is-absolute": "^1.0.0" 296 | }, 297 | "engines": { 298 | "node": "*" 299 | }, 300 | "funding": { 301 | "url": "https://github.com/sponsors/isaacs" 302 | } 303 | }, 304 | "node_modules/has-flag": { 305 | "version": "4.0.0", 306 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 307 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 308 | "dev": true, 309 | "engines": { 310 | "node": ">=8" 311 | } 312 | }, 313 | "node_modules/html-escaper": { 314 | "version": "2.0.2", 315 | "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", 316 | "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", 317 | "dev": true 318 | }, 319 | "node_modules/inflight": { 320 | "version": "1.0.6", 321 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 322 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 323 | "dev": true, 324 | "dependencies": { 325 | "once": "^1.3.0", 326 | "wrappy": "1" 327 | } 328 | }, 329 | "node_modules/inherits": { 330 | "version": "2.0.4", 331 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 332 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 333 | "dev": true 334 | }, 335 | "node_modules/is-fullwidth-code-point": { 336 | "version": "3.0.0", 337 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 338 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 339 | "dev": true, 340 | "engines": { 341 | "node": ">=8" 342 | } 343 | }, 344 | "node_modules/isexe": { 345 | "version": "2.0.0", 346 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 347 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 348 | "dev": true 349 | }, 350 | "node_modules/istanbul-lib-coverage": { 351 | "version": "3.2.0", 352 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", 353 | "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", 354 | "dev": true, 355 | "engines": { 356 | "node": ">=8" 357 | } 358 | }, 359 | "node_modules/istanbul-lib-report": { 360 | "version": "3.0.1", 361 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", 362 | "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", 363 | "dev": true, 364 | "dependencies": { 365 | "istanbul-lib-coverage": "^3.0.0", 366 | "make-dir": "^4.0.0", 367 | "supports-color": "^7.1.0" 368 | }, 369 | "engines": { 370 | "node": ">=10" 371 | } 372 | }, 373 | "node_modules/istanbul-reports": { 374 | "version": "3.1.6", 375 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", 376 | "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", 377 | "dev": true, 378 | "dependencies": { 379 | "html-escaper": "^2.0.0", 380 | "istanbul-lib-report": "^3.0.0" 381 | }, 382 | "engines": { 383 | "node": ">=8" 384 | } 385 | }, 386 | "node_modules/locate-path": { 387 | "version": "6.0.0", 388 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 389 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 390 | "dev": true, 391 | "dependencies": { 392 | "p-locate": "^5.0.0" 393 | }, 394 | "engines": { 395 | "node": ">=10" 396 | }, 397 | "funding": { 398 | "url": "https://github.com/sponsors/sindresorhus" 399 | } 400 | }, 401 | "node_modules/lru-cache": { 402 | "version": "6.0.0", 403 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 404 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 405 | "dev": true, 406 | "dependencies": { 407 | "yallist": "^4.0.0" 408 | }, 409 | "engines": { 410 | "node": ">=10" 411 | } 412 | }, 413 | "node_modules/make-dir": { 414 | "version": "4.0.0", 415 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", 416 | "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", 417 | "dev": true, 418 | "dependencies": { 419 | "semver": "^7.5.3" 420 | }, 421 | "engines": { 422 | "node": ">=10" 423 | }, 424 | "funding": { 425 | "url": "https://github.com/sponsors/sindresorhus" 426 | } 427 | }, 428 | "node_modules/minimatch": { 429 | "version": "3.1.2", 430 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 431 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 432 | "dev": true, 433 | "dependencies": { 434 | "brace-expansion": "^1.1.7" 435 | }, 436 | "engines": { 437 | "node": "*" 438 | } 439 | }, 440 | "node_modules/once": { 441 | "version": "1.4.0", 442 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 443 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 444 | "dev": true, 445 | "dependencies": { 446 | "wrappy": "1" 447 | } 448 | }, 449 | "node_modules/p-limit": { 450 | "version": "3.1.0", 451 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 452 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 453 | "dev": true, 454 | "dependencies": { 455 | "yocto-queue": "^0.1.0" 456 | }, 457 | "engines": { 458 | "node": ">=10" 459 | }, 460 | "funding": { 461 | "url": "https://github.com/sponsors/sindresorhus" 462 | } 463 | }, 464 | "node_modules/p-locate": { 465 | "version": "5.0.0", 466 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 467 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 468 | "dev": true, 469 | "dependencies": { 470 | "p-limit": "^3.0.2" 471 | }, 472 | "engines": { 473 | "node": ">=10" 474 | }, 475 | "funding": { 476 | "url": "https://github.com/sponsors/sindresorhus" 477 | } 478 | }, 479 | "node_modules/path-exists": { 480 | "version": "4.0.0", 481 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 482 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 483 | "dev": true, 484 | "engines": { 485 | "node": ">=8" 486 | } 487 | }, 488 | "node_modules/path-is-absolute": { 489 | "version": "1.0.1", 490 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 491 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 492 | "dev": true, 493 | "engines": { 494 | "node": ">=0.10.0" 495 | } 496 | }, 497 | "node_modules/path-key": { 498 | "version": "3.1.1", 499 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 500 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 501 | "dev": true, 502 | "engines": { 503 | "node": ">=8" 504 | } 505 | }, 506 | "node_modules/playwright-core": { 507 | "version": "1.37.1", 508 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz", 509 | "integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==", 510 | "dev": true, 511 | "bin": { 512 | "playwright-core": "cli.js" 513 | }, 514 | "engines": { 515 | "node": ">=16" 516 | } 517 | }, 518 | "node_modules/require-directory": { 519 | "version": "2.1.1", 520 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 521 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 522 | "dev": true, 523 | "engines": { 524 | "node": ">=0.10.0" 525 | } 526 | }, 527 | "node_modules/rimraf": { 528 | "version": "3.0.2", 529 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 530 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 531 | "dev": true, 532 | "dependencies": { 533 | "glob": "^7.1.3" 534 | }, 535 | "bin": { 536 | "rimraf": "bin.js" 537 | }, 538 | "funding": { 539 | "url": "https://github.com/sponsors/isaacs" 540 | } 541 | }, 542 | "node_modules/semver": { 543 | "version": "7.5.4", 544 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 545 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 546 | "dev": true, 547 | "dependencies": { 548 | "lru-cache": "^6.0.0" 549 | }, 550 | "bin": { 551 | "semver": "bin/semver.js" 552 | }, 553 | "engines": { 554 | "node": ">=10" 555 | } 556 | }, 557 | "node_modules/shebang-command": { 558 | "version": "2.0.0", 559 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 560 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 561 | "dev": true, 562 | "dependencies": { 563 | "shebang-regex": "^3.0.0" 564 | }, 565 | "engines": { 566 | "node": ">=8" 567 | } 568 | }, 569 | "node_modules/shebang-regex": { 570 | "version": "3.0.0", 571 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 572 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 573 | "dev": true, 574 | "engines": { 575 | "node": ">=8" 576 | } 577 | }, 578 | "node_modules/signal-exit": { 579 | "version": "3.0.7", 580 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", 581 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", 582 | "dev": true 583 | }, 584 | "node_modules/string-width": { 585 | "version": "4.2.3", 586 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 587 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 588 | "dev": true, 589 | "dependencies": { 590 | "emoji-regex": "^8.0.0", 591 | "is-fullwidth-code-point": "^3.0.0", 592 | "strip-ansi": "^6.0.1" 593 | }, 594 | "engines": { 595 | "node": ">=8" 596 | } 597 | }, 598 | "node_modules/strip-ansi": { 599 | "version": "6.0.1", 600 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 601 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 602 | "dev": true, 603 | "dependencies": { 604 | "ansi-regex": "^5.0.1" 605 | }, 606 | "engines": { 607 | "node": ">=8" 608 | } 609 | }, 610 | "node_modules/supports-color": { 611 | "version": "7.2.0", 612 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 613 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 614 | "dev": true, 615 | "dependencies": { 616 | "has-flag": "^4.0.0" 617 | }, 618 | "engines": { 619 | "node": ">=8" 620 | } 621 | }, 622 | "node_modules/test-exclude": { 623 | "version": "6.0.0", 624 | "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", 625 | "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", 626 | "dev": true, 627 | "dependencies": { 628 | "@istanbuljs/schema": "^0.1.2", 629 | "glob": "^7.1.4", 630 | "minimatch": "^3.0.4" 631 | }, 632 | "engines": { 633 | "node": ">=8" 634 | } 635 | }, 636 | "node_modules/v8-to-istanbul": { 637 | "version": "9.1.0", 638 | "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", 639 | "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", 640 | "dev": true, 641 | "dependencies": { 642 | "@jridgewell/trace-mapping": "^0.3.12", 643 | "@types/istanbul-lib-coverage": "^2.0.1", 644 | "convert-source-map": "^1.6.0" 645 | }, 646 | "engines": { 647 | "node": ">=10.12.0" 648 | } 649 | }, 650 | "node_modules/which": { 651 | "version": "2.0.2", 652 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 653 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 654 | "dev": true, 655 | "dependencies": { 656 | "isexe": "^2.0.0" 657 | }, 658 | "bin": { 659 | "node-which": "bin/node-which" 660 | }, 661 | "engines": { 662 | "node": ">= 8" 663 | } 664 | }, 665 | "node_modules/wrap-ansi": { 666 | "version": "7.0.0", 667 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 668 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 669 | "dev": true, 670 | "dependencies": { 671 | "ansi-styles": "^4.0.0", 672 | "string-width": "^4.1.0", 673 | "strip-ansi": "^6.0.0" 674 | }, 675 | "engines": { 676 | "node": ">=10" 677 | }, 678 | "funding": { 679 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 680 | } 681 | }, 682 | "node_modules/wrappy": { 683 | "version": "1.0.2", 684 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 685 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 686 | "dev": true 687 | }, 688 | "node_modules/y18n": { 689 | "version": "5.0.8", 690 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 691 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 692 | "dev": true, 693 | "engines": { 694 | "node": ">=10" 695 | } 696 | }, 697 | "node_modules/yallist": { 698 | "version": "4.0.0", 699 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 700 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 701 | "dev": true 702 | }, 703 | "node_modules/yargs": { 704 | "version": "17.7.2", 705 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", 706 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", 707 | "dev": true, 708 | "dependencies": { 709 | "cliui": "^8.0.1", 710 | "escalade": "^3.1.1", 711 | "get-caller-file": "^2.0.5", 712 | "require-directory": "^2.1.1", 713 | "string-width": "^4.2.3", 714 | "y18n": "^5.0.5", 715 | "yargs-parser": "^21.1.1" 716 | }, 717 | "engines": { 718 | "node": ">=12" 719 | } 720 | }, 721 | "node_modules/yargs-parser": { 722 | "version": "21.1.1", 723 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 724 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", 725 | "dev": true, 726 | "engines": { 727 | "node": ">=12" 728 | } 729 | }, 730 | "node_modules/yocto-queue": { 731 | "version": "0.1.0", 732 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 733 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 734 | "dev": true, 735 | "engines": { 736 | "node": ">=10" 737 | }, 738 | "funding": { 739 | "url": "https://github.com/sponsors/sindresorhus" 740 | } 741 | } 742 | } 743 | } 744 | -------------------------------------------------------------------------------- /ci/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "raggedy-dev-setup", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "npx playwright test" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "UNLICENSED", 12 | "devDependencies": { 13 | "@playwright/test": "^1.37.1", 14 | "c8": "8.0.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ci/pageWithCoverage.js: -------------------------------------------------------------------------------- 1 | import { test as base } from "@playwright/test"; 2 | import * as fs from "node:fs/promises"; 3 | import * as url from "node:url"; 4 | export { expect } from "@playwright/test"; 5 | import { randomUUID } from "node:crypto"; 6 | 7 | // This new "test" can be used in multiple test files, and each of them will get the fixtures. 8 | // You need to use the import map to properly load modules and this means that you need to either use HTTP dependencies or rebase the vendored import map (like tasks/serve does) 9 | export const test = base.extend({ 10 | pageWithCoverage: async ({ page, browserName }, use) => { 11 | if (browserName === "chromium") { 12 | await page.coverage.startJSCoverage(); 13 | } 14 | await use(page); 15 | 16 | if (browserName === "chromium") { 17 | const coverage = await page.coverage.stopJSCoverage(); 18 | await fs.mkdir("coverage", { recursive: true }); 19 | let result = []; 20 | await fs.mkdir("coverage/tmp", { recursive: true }); 21 | for (let index = 0; index < coverage.length; index++) { 22 | const cov = coverage[index]; 23 | const curl = new URL(cov.url); 24 | if ( 25 | curl.hostname === "localhost" && curl.pathname !== "/" && 26 | !curl.pathname.startsWith("/vendor/") && 27 | !curl.pathname.startsWith("/.test/") 28 | ) { 29 | const path = curl.pathname.replace("/", ""); 30 | cov.url = url.pathToFileURL(path); 31 | result = result.concat(cov); 32 | } 33 | } 34 | const uuid = randomUUID(); 35 | await fs.writeFile( 36 | `coverage/tmp/${uuid}.json`, 37 | JSON.stringify({ result }), 38 | ); 39 | } 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /ci/playwright.config.js: -------------------------------------------------------------------------------- 1 | const { devices, defineConfig } = require("@playwright/test"); 2 | 3 | export default defineConfig({ 4 | // Look for test files in the "tests" directory, relative to this configuration file. 5 | testDir: "ci/tests", 6 | 7 | // Run all tests in parallel. 8 | fullyParallel: true, 9 | 10 | // Fail the build on CI if you accidentally left test.only in the source code. 11 | forbidOnly: !!process.env.CI, 12 | 13 | // Retry on CI only. 14 | retries: process.env.CI ? 2 : 0, 15 | 16 | // Opt out of parallel tests on CI. 17 | workers: process.env.CI ? 1 : undefined, 18 | 19 | // Reporter to use 20 | reporter: "html", 21 | 22 | use: { 23 | // Base URL to use in actions like `await page.goto('/')`. 24 | baseURL: "https://localhost:8888/", 25 | ignoreHTTPSErrors: true, 26 | // Collect trace when retrying the failed test. 27 | trace: "on-first-retry", 28 | }, 29 | // Configure projects for major browsers. 30 | projects: [ 31 | { 32 | name: "chromium", 33 | use: { ...devices["Desktop Chrome"] }, 34 | }, 35 | 36 | { 37 | name: "firefox", 38 | use: { ...devices["Desktop Firefox"] }, 39 | }, 40 | 41 | { 42 | name: "webkit", 43 | use: { ...devices["Desktop Safari"] }, 44 | }, 45 | ], 46 | // Run your local dev server before starting the tests. 47 | webServer: { 48 | command: "tasks/serve", 49 | url: "https://localhost:8888/", 50 | reuseExistingServer: !process.env.CI, 51 | stdout: "ignore", 52 | stderr: "pipe", 53 | ignoreHTTPSErrors: true, 54 | }, 55 | }); 56 | -------------------------------------------------------------------------------- /ci/tests/mocha.spec.js: -------------------------------------------------------------------------------- 1 | import { expect, test } from "../pageWithCoverage.js"; 2 | 3 | test("Mocha Test Suite", async ({ pageWithCoverage: page }) => { 4 | await page.goto("/"); 5 | const results = await page.waitForFunction(() => { 6 | if (window._testResults) { 7 | return window._testResults; 8 | } 9 | }); 10 | const json = await results.jsonValue(); 11 | // Expect a title "to contain" a substring. 12 | await expect(json.failure).toBeFalsy(); 13 | }); 14 | -------------------------------------------------------------------------------- /deno.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | // I'm disabling the lockfile because this isn't a deno project, per se, and it was failing checks for no good reason in CI 3 | "lock": false, 4 | // So, a big reason to use deno is for type checking and I strongly prefer deno's typescript checking behaviour over typescript's own, especially for browser code. 5 | "compilerOptions": { 6 | // Set checkJS here to true to opt in to type checking in each file and if you need to disable type checking for a JS file then including "// @ts-nocheck" (no quotes) at the top of the file should do it. 7 | // With checkJS set to false (the default) then a "// @ts-check" (no quotes) at the top of a file will enable checking. 8 | "checkJs": false, 9 | "lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns"] 10 | }, 11 | "lint": { 12 | "exclude": [".test/", "dist/", "vendor/"], 13 | "rules": { 14 | "tags": ["recommended"], 15 | "exclude": ["ban-ts-comment"] 16 | } 17 | }, 18 | // Tabs are more accessible 19 | "fmt": { 20 | "exclude": [".test/", "dist/", "vendor/"], 21 | "useTabs": true 22 | }, 23 | // Defer to an external import map as that's simpler for other scripts to parse than a jsonc file. 24 | "importMap": "./vendor/import_map.json" 25 | } 26 | // Most of the time the above will work for both browser and deno code, especially since the point of this setup is to focus on browser code. 27 | // To type check deno only worker code you need to set "lib" in those file specifically. Something like: 28 | /// 29 | /// 30 | 31 | // Or for deno only code 32 | /// 33 | /// 34 | 35 | // Or for regular workers code 36 | /// 37 | /// 38 | /// 39 | /// 40 | -------------------------------------------------------------------------------- /dist/raggedy.js: -------------------------------------------------------------------------------- 1 | // src/grass.js 2 | import { blake3 } from "https://esm.sh/hash-wasm@4.8.0"; 3 | async function grass() { 4 | const grassHash = await blake3("Grass!"); 5 | console.log("Grass!", grassHash); 6 | return grassHash; 7 | } 8 | 9 | // src/index.js 10 | function grassy() { 11 | console.log("dingus"); 12 | return grass(); 13 | } 14 | export { 15 | grassy 16 | }; 17 | //# sourceMappingURL=raggedy.js.map 18 | -------------------------------------------------------------------------------- /dist/raggedy.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "sources": ["../src/grass.js", "../src/index.js"], 4 | "sourcesContent": ["import { blake3 } from \"npm:hash-wasm\";\nexport async function grass() {\n\tconst grassHash = await blake3(\"Grass!\");\n\tconsole.log(\"Grass!\", grassHash);\n\treturn grassHash;\n}\n", "import { grass } from \"./grass.js\";\n\nexport function grassy() {\n\tconsole.log(\"dingus\");\n\treturn grass();\n}\n"], 5 | "mappings": ";AAAA,SAAS,cAAc;AACvB,eAAsB,QAAQ;AAC7B,QAAM,YAAY,MAAM,OAAO,QAAQ;AACvC,UAAQ,IAAI,UAAU,SAAS;AAC/B,SAAO;AACR;;;ACHO,SAAS,SAAS;AACxB,UAAQ,IAAI,QAAQ;AACpB,SAAO,MAAM;AACd;", 6 | "names": [] 7 | } 8 | -------------------------------------------------------------------------------- /dist/raggedy.min.js: -------------------------------------------------------------------------------- 1 | var P=globalThis||(typeof window<"u"?window:self);function S(A,I,g,B){function C(E){return E instanceof g?E:new g(function(F){F(E)})}return new(g||(g=Promise))(function(E,F){function h(D){try{a(B.next(D))}catch(G){F(G)}}function e(D){try{a(B.throw(D))}catch(G){F(G)}}function a(D){D.done?E(D.value):C(D.value).then(h,e)}a((B=B.apply(A,I||[])).next())})}var o=class{constructor(){this.mutex=Promise.resolve()}lock(){let A=()=>{};return this.mutex=this.mutex.then(()=>new Promise(A)),new Promise(I=>{A=I})}dispatch(A){return S(this,void 0,void 0,function*(){let I=yield this.lock();try{return yield Promise.resolve(A())}finally{I()}})}},N;function b(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:P}var f=b(),J=(N=f.Buffer)!==null&&N!==void 0?N:null,v=f.TextEncoder?new f.TextEncoder:null;function Z(A,I){return(A&15)+(A>>6|A>>3&8)<<4|(I&15)+(I>>6|I>>3&8)}function T(A,I){let g=I.length>>1;for(let B=0;B>>4;A[B++]=E>9?E+l:E+s,E=I[C]&15,A[B++]=E>9?E+l:E+s}return String.fromCharCode.apply(null,A)}var q=J!==null?A=>{if(typeof A=="string"){let I=J.from(A,"utf8");return new Uint8Array(I.buffer,I.byteOffset,I.length)}if(J.isBuffer(A))return new Uint8Array(A.buffer,A.byteOffset,A.length);if(ArrayBuffer.isView(A))return new Uint8Array(A.buffer,A.byteOffset,A.byteLength);throw new Error("Invalid data type!")}:A=>{if(typeof A=="string")return v.encode(A);if(ArrayBuffer.isView(A))return new Uint8Array(A.buffer,A.byteOffset,A.byteLength);throw new Error("Invalid data type!")},X="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",H=new Uint8Array(256);for(let A=0;A>4,C+=1,B[C]=(h&15)<<4|e>>2,C+=1,B[C]=(e&3)<<6|a&63,C+=1}return B}var U=16*1024,n=4,AA=new o,K=new Map;function IA(A,I){return S(this,void 0,void 0,function*(){let g=null,B=null,C=!1;if(typeof WebAssembly>"u")throw new Error("WebAssembly is not supported in this environment!");let E=(Q,i=0)=>{B.set(Q,i)},F=()=>B,h=()=>g.exports,e=Q=>{g.exports.Hash_SetMemorySize(Q);let i=g.exports.Hash_GetBuffer(),c=g.exports.memory.buffer;B=new Uint8Array(c,i,Q)},a=()=>new DataView(g.exports.memory.buffer).getUint32(g.exports.STATE_SIZE,!0),D=AA.dispatch(()=>S(this,void 0,void 0,function*(){if(!K.has(A.name)){let i=_(A.data),c=WebAssembly.compile(i);K.set(A.name,c)}let Q=yield K.get(A.name);g=yield WebAssembly.instantiate(Q,{})})),G=()=>S(this,void 0,void 0,function*(){g||(yield D);let Q=g.exports.Hash_GetBuffer(),i=g.exports.memory.buffer;B=new Uint8Array(i,Q,U)}),p=(Q=null)=>{C=!0,g.exports.Hash_Init(Q)},m=Q=>{let i=0;for(;i{if(!C)throw new Error("update() called before init()");let i=q(Q);m(i)},r=new Uint8Array(I*2),Y=(Q,i=null)=>{if(!C)throw new Error("digest() called before init()");return C=!1,g.exports.Hash_Final(i),Q==="binary"?B.slice(0,I):R(r,B,I)},u=()=>{if(!C)throw new Error("save() can only be called after init() and before digest()");let Q=g.exports.Hash_GetState(),i=a(),c=g.exports.memory.buffer,w=new Uint8Array(c,Q,i),y=new Uint8Array(n+i);return T(y,A.hash),y.set(w,n),y},O=Q=>{if(!(Q instanceof Uint8Array))throw new Error("load() expects an Uint8Array generated by save()");let i=g.exports.Hash_GetState(),c=a(),w=n+c,y=g.exports.memory.buffer;if(Q.length!==w)throw new Error(`Bad state length (expected ${w} bytes, got ${Q.length})`);if(!j(A.hash,Q.subarray(0,n)))throw new Error("This state was written by an incompatible hash implementation");let W=Q.subarray(n);new Uint8Array(y,i,c).set(W),C=!0},t=Q=>typeof Q=="string"?Q.length!0;break;case"blake2b":case"blake2s":d=(Q,i)=>i<=512&&t(Q);break;case"blake3":d=(Q,i)=>i===0&&t(Q);break;case"xxhash64":case"xxhash3":case"xxhash128":d=()=>!1;break}let L=(Q,i=null,c=null)=>{if(!d(Q,i))return p(i),M(Q),Y("hex",c);let w=q(Q);return B.set(w),g.exports.Hash_Calculate(w.length,i,c),R(r,B,I)};return yield G(),{getMemory:F,writeMemory:E,getExports:h,setMemorySize:e,init:p,update:M,digest:Y,save:u,load:O,calculate:L,hashLength:I}})}function gA(A,I,g){return S(this,void 0,void 0,function*(){let B=yield A.lock(),C=yield IA(I,g);return B(),C})}var oA=new o;var cA=new o;var hA=new DataView(new ArrayBuffer(4));var FA=new o;var BA="blake3",QA="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FWogFCAfc0EZdyIVaiIUIBhqIB0gFHNBEHciFCAlaiIYIBVzQRR3IhVqIhkgFHNBGHciFCAYaiIYaiIdICBzQRR3Ih9qIiA2AgAgACAXICQgHHNBGHciHCAeaiIeIBtzQRl3IhtqIAFqIgEgFmogASAUc0EQdyIBICtqIhQgG3NBFHciFmoiFyABc0EYdyIBNgI4IAAgGCAVc0EZdyIVIC5qIANqIgMgE2ogAyAcc0EQdyIDIAIgImoiAmoiIiAVc0EUdyIVaiITNgIEIAAgASAUaiIBNgIkIAAgAiAFc0EZdyICIBlqICFqIgUgGmogBSAnc0EQdyIFIB5qIhQgAnNBFHciAmoiGjYCCCAAICAgEnNBGHciEiAdaiIhNgIoIAAgEyADc0EYdyIDNgIwIAAgASAWc0EZdzYCECAAIBogBXNBGHciATYCNCAAICEgH3NBGXc2AhQgACABIBRqIgE2AiAgACADICJqIgUgFXNBGXc2AhggACASNgI8IAAgASACc0EZdzYCHCAAIBc2AgwgACAFNgIsC7cDAwR/A34FfyMAQdABayIBJAACQCAAe6ciAkEALQCQigEiA08NACABQShqIQQDQCABQQApA4CJASIANwMAIAFBACkDiIkBIgU3AwggAUEAKQOQiQEiBjcDECABQQApA5iJASIHNwMYIAEgA0EFdCIDQdGJAWoiCCkDADcDKCABIANB2YkBaiIJKQMANwMwIAEgA0HhiQFqIgopAwA3AzggASADQemJAWoiCykDADcDQEEALQCKigEhDCABQcAAOgBoIAEgDEEEciIMOgBpIAFCADcDICABIANB8YkBaikDADcDSCABIANB+YkBaikDADcDUCABIANBgYoBaikDADcDWCABIANBiYoBaikDADcDYCABIAc3A4gBIAEgBjcDgAEgASAFNwN4IAEgADcDcCABQZABaiABQfAAaiAEQcAAQgAgDBADIAsgASkDyAEgASkDqAGFNwMAIAogASkDwAEgASkDoAGFNwMAIAkgASkDuAEgASkDmAGFNwMAIAggASkDsAEgASkDkAGFNwMAQQBBAC0AkIoBQX9qIgM6AJCKASACIANB/wFxIgNJDQALCyABQdABaiQAC/oLBAR/BH4GfwF+IwBB0AJrIgUkAAJAAkAgAUGACEsNAEEAIQYgASEHQQAhCAJAIAFB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IQwDQCABQbABaiABIAsgCUH/AXEgCCACQQhyQf8BcRADIAEgASkD2AEiDSABKQO4AYU3A3ggASABKQPgASIOIAEpA8ABhTcDgAEgASAGIAEpA+gBIg+FNwOoASABIAUgDoU3A6ABIAEgBCANhTcDmAEgASADIAEpA9ABIg2FNwOQASABIA8gASkDyAGFNwOIASAAQcAAIABBwABJGyIQQX9qIQkgASANIAEpA7ABhSINNwNwIA2nIREgCiEHIAwhAgJAA0AgAiAROgAAIAlFDQEgCUF/aiEJIAJBAWohAiAHLQAAIREgB0EBaiEHDAALCyAAIBBrIgBFDQIgDCAQaiEMIAhCAXwhCCABKQMIIQQgASkDACEDIAEpAxghBiABKQMQIQUgAS0AaSECIAEtAGghCQwACwsCQAJAAkBBAC0AiYoBIglBBnRBAEEALQCIigEiDGtGDQAgAUHgAGpBACkDgIoBNwMAIAFB2ABqQQApA/iJATcDACABQdAAakEAKQPwiQE3AwAgAUHIAGpBACkD6IkBNwMAIAFBwABqQQApA+CJATcDACABQThqQQApA9iJATcDACABQTBqQQApA9CJATcDACABQQApA8iJATcDKCABQQApA8CJASIINwMgIAFBACkDuIkBIg03AxggAUEAKQOwiQEiDjcDECABQQApA6iJASIPNwMIIAFBACkDoIkBIgM3AwBBAC0AiooBIQcgAUHuAGogAUG0AWovAQA7AQAgASABKAGwATYBaiABIAw6AGggASAHIAlFckECciIJOgBpDAELIAFB4ABqIAJBfmoiAkEFdCIJQcmKAWopAwA3AwAgAUHYAGogCUHBigFqKQMANwMAIAFB0ABqIAlBuYoBaikDADcDACABQcgAaiAJQbGKAWopAwA3AwBBwAAhDCABQcAAaiAJQamKAWopAwA3AwAgAUE4aiAJQaGKAWopAwA3AwAgAUEwaiAJQZmKAWopAwA3AwBCACEIIAFCADcDICABQQApA5iJASINNwMYIAFBACkDkIkBIg43AxAgAUEAKQOIiQEiDzcDCCABQQApA4CJASIDNwMAIAEgCUGRigFqKQMANwMoQQAtAIqKASEJIAFB7gBqIAFBsAFqQQRqLwEAOwEAIAEgASgBsAE2AWogASAJQQRyIgk6AGkgAUHAADoAaCACRQ0BCyACQX9qIgdBBXQiEUGRigFqKQMAIQQgEUGZigFqKQMAIQUgEUGhigFqKQMAIQYgEUGpigFqKQMAIRIgASANNwOIASABIA43A4ABIAEgDzcDeCABIAM3A3AgAUGwAWogAUHwAGogAUEoaiIQIAwgCCAJQf8BcRADIAFBwAA6AGggASASNwNAIAEgBjcDOCABIAU3AzAgASAENwMoIAFCADcDICABQQApA5iJASIINwMYIAFBACkDkIkBIg03AxAgAUEAKQOIiQEiDjcDCCABQQApA4CJASIPNwMAIAFBAC0AiooBQQRyIgk6AGkgASABKQPoASABKQPIAYU3A2AgASABKQPgASABKQPAAYU3A1ggASABKQPYASABKQO4AYU3A1AgASABKQPQASABKQOwAYU3A0ggAUHuAGogAUGwAWpBBGoiDC8BADsBACABIAEoAbABNgFqIAdFDQAgAUHqAGohESACQQV0QemJAWohAgNAIAJBaGopAwAhAyACQXBqKQMAIQQgAkF4aikDACEFIAIpAwAhBiABIAg3A4gBIAEgDTcDgAEgASAONwN4IAEgDzcDcCABQbABaiABQfAAaiAQQcAAQgAgCUH/AXEQAyABQcAAOgBoIAEgBjcDQCABIAU3AzggASAENwMwIAEgAzcDKCABQgA3AyAgAUEAKQOYiQEiCDcDGCABQQApA5CJASINNwMQIAFBACkDiIkBIg43AwggAUEAKQOAiQEiDzcDACABQQAtAIqKAUEEciIJOgBpIAEgASkD6AEgASkDyAGFNwNgIAEgASkD4AEgASkDwAGFNwNYIAEgASkD2AEgASkDuAGFNwNQIAEgASkD0AEgASkDsAGFNwNIIBFBBGogDC8BADsBACARIAEoAbABNgEAIAJBYGohAiAHQX9qIgcNAAsLIAFB8ABqQQFyIQogAUEoaiELQgAhCEGACSEMQcAAIQIDQCABQbABaiABIAsgAkH/AXEgCCAJQQhyQf8BcRADIAEgASkD2AEiDSABKQO4AYU3A3ggASABKQPgASIOIAEpA8ABhTcDgAEgASABKQPoASIPIAEpA8gBhTcDiAEgASABKQMAIAEpA9ABIgOFNwOQASABIA0gASkDCIU3A5gBIAEgDiABKQMQhTcDoAEgASADIAEpA7ABhSINNwNwIAEgDyABKQMYhTcDqAEgAEHAACAAQcAASRsiEEF/aiECIA2nIREgCiEHIAwhCQJAA0AgCSAROgAAIAJFDQEgAkF/aiECIAlBAWohCSAHLQAAIREgB0EBaiEHDAALCyAAIBBrIgBFDQEgDCAQaiEMIAhCAXwhCCABLQBpIQkgAS0AaCECDAALCyABQfABaiQAC6MCAQR+AkACQCAAQSBGDQBCq7OP/JGjs/DbACEBQv+kuYjFkdqCm38hAkLy5rvjo6f9p6V/IQNC58yn0NbQ67O7fyEEQQAhAAwBC0EAKQOYCSEBQQApA5AJIQJBACkDiAkhA0EAKQOACSEEQRAhAAtBACAAOgCKigFBAEIANwOAigFBAEIANwP4iQFBAEIANwPwiQFBAEIANwPoiQFBAEIANwPgiQFBAEIANwPYiQFBAEIANwPQiQFBAEIANwPIiQFBAEIANwPAiQFBACABNwO4iQFBACACNwOwiQFBACADNwOoiQFBACAENwOgiQFBACABNwOYiQFBACACNwOQiQFBACADNwOIiQFBACAENwOAiQFBAEEAOgCQigFBAEEAOwGIigELBgAgABABCwYAIAAQBgsGAEGAiQELqwIBBH4CQAJAIAFBIEYNAEKrs4/8kaOz8NsAIQNC/6S5iMWR2oKbfyEEQvLmu+Ojp/2npX8hBULnzKfQ1tDrs7t/IQZBACEBDAELQQApA5gJIQNBACkDkAkhBEEAKQOICSEFQQApA4AJIQZBECEBC0EAIAE6AIqKAUEAQgA3A4CKAUEAQgA3A/iJAUEAQgA3A/CJAUEAQgA3A+iJAUEAQgA3A+CJAUEAQgA3A9iJAUEAQgA3A9CJAUEAQgA3A8iJAUEAQgA3A8CJAUEAIAM3A7iJAUEAIAQ3A7CJAUEAIAU3A6iJAUEAIAY3A6CJAUEAIAM3A5iJAUEAIAQ3A5CJAUEAIAU3A4iJAUEAIAY3A4CJAUEAQQA6AJCKAUEAQQA7AYiKASAAEAEgAhAGCwsLAQBBgAgLBHgHAAA=",CA="e8655383",iA={name:BA,data:QA,hash:CA},EA=new o,k=null;function z(A){return!Number.isInteger(A)||A<8||A%8!==0?new Error("Invalid variant! Valid values: 8, 16, ..."):null}function V(A,I=256,g=null){if(z(I))return Promise.reject(z(I));let B=null,C=0;if(g!==null){if(B=q(g),B.length!==32)return Promise.reject(new Error("Key length must be exactly 32 bytes"));C=32}let E=I/8,F=E;if(k===null||k.hashLength!==E)return gA(EA,iA,E).then(h=>(k=h,C===32&&k.writeMemory(B),k.calculate(A,C,F)));try{C===32&&k.writeMemory(B);let h=k.calculate(A,C,F);return Promise.resolve(h)}catch(h){return Promise.reject(h)}}var DA=new o;var aA=new o;var wA=new o;var kA=new o;var eA=new o;var GA=new o;var dA=new o;var yA=new o;var nA=new o;var HA=new o;var SA=new o;var UA=new o;var tA=new o;var NA=new ArrayBuffer(8);var JA=new o;var KA=new ArrayBuffer(8);var fA=new o;var qA=new ArrayBuffer(8);var pA=new o;var MA=new o;var rA=new o;async function x(){let A=await V("Grass!");return console.log("Grass!",A),A}function mA(){return console.log("dingus"),x()}export{mA as grassy}; 2 | /*! Bundled license information: 3 | 4 | hash-wasm/dist/index.esm.js: 5 | (*! 6 | * hash-wasm (https://www.npmjs.com/package/hash-wasm) 7 | * (c) Dani Biro 8 | * @license MIT 9 | *) 10 | (*! ***************************************************************************** 11 | Copyright (c) Microsoft Corporation. 12 | 13 | Permission to use, copy, modify, and/or distribute this software for any 14 | purpose with or without fee is hereby granted. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 17 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 19 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22 | PERFORMANCE OF THIS SOFTWARE. 23 | ***************************************************************************** *) 24 | */ 25 | //# sourceMappingURL=raggedy.min.js.map 26 | -------------------------------------------------------------------------------- /import_map.json: -------------------------------------------------------------------------------- 1 | { 2 | "imports": { 3 | "npm:hash-wasm": "https://esm.sh/hash-wasm@^4.9" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /raggedy-dev.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": { 8 | "LSP": { 9 | "Deno": { 10 | "enabled": true, 11 | "command": ["./.bin/deno", "lsp"], 12 | "settings": { 13 | "deno.config": "./deno.jsonc", 14 | "deno.enable": true, 15 | "deno.lint": true, 16 | "deno.suggest.imports.autoDiscover": true 17 | } 18 | }, 19 | "LSP-typescript": { 20 | "enabled": false 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /raggedy.js: -------------------------------------------------------------------------------- 1 | // This is an example root module that is the primary entry point for the project. 2 | export * from "./src/index.js"; 3 | -------------------------------------------------------------------------------- /src/grass.js: -------------------------------------------------------------------------------- 1 | import { blake3 } from "npm:hash-wasm"; 2 | export async function grass() { 3 | const grassHash = await blake3("Grass!"); 4 | console.log("Grass!", grassHash); 5 | return grassHash; 6 | } 7 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { grass } from "./grass.js"; 2 | 3 | export function grassy() { 4 | console.log("dingus"); 5 | return grass(); 6 | } 7 | -------------------------------------------------------------------------------- /tasks/add: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S ./.bin/deno run --allow-net --allow-read --allow-write 2 | 3 | // This script is a fairly straightforward automation of the process of: 4 | // 1. Loading a version-less esm.sh url for an npm package. 5 | // 2. Taking the resulting versioned url. 6 | // 3. Adding that versioned url to your import map, mapped to the package name. 7 | // 8 | // The reason we do this is to make sure that we aren't hardcoding package versions in our code and managing it from a central place. 9 | import { parse } from "https://deno.land/std@0.202.0/flags/mod.ts"; 10 | 11 | // A possible future feature would be a flag to let you use any server that uses esm.sh's url structure. 12 | // A very definite future feature is supporting the gh: prefix to add github packages 13 | const parsedArgs = parse(Deno.args); 14 | const packages = parsedArgs._; 15 | 16 | const IMPORT_MAP_PATH = "import_map.json"; 17 | 18 | const importMap = JSON.parse(await Deno.readTextFile(IMPORT_MAP_PATH)); 19 | 20 | console.log( 21 | `\n%ctasks/add %c${packages.join(" ")}\n`, 22 | "font-weight: bold", 23 | "font-weight: normal", 24 | ); 25 | 26 | for (const packageName of packages) { 27 | const name = String(packageName).replace("npm:", ""); 28 | if (parsedArgs.exact) { 29 | // If you're explicitly including a version tag, then we're going to assume you know what you're doing. 30 | const prefix = name.split("@")[0]; 31 | const url = `https://esm.sh/${name}`; 32 | importMap.imports[`npm:${prefix}`] = url; 33 | 34 | console.log( 35 | `mapping %cnpm:${prefix} %cto %c${url}`, 36 | "font-weight: bold; color: blue", 37 | "font-weight: normal; color: inherit", 38 | "font-weight: bold", 39 | ); 40 | } else { 41 | const url = `https://esm.sh/${name}`; 42 | const result = await fetch(url, { 43 | method: "HEAD", 44 | redirect: "follow", 45 | }); 46 | if (result.ok) { 47 | importMap.imports[`npm:${name}`] = result.url; 48 | console.log( 49 | `mapping %cnpm:${name} %cto %c${result.url}`, 50 | "font-weight: bold; color: blue", 51 | "font-weight: normal; color: inherit", 52 | "font-weight: bold", 53 | ); 54 | } else { 55 | console.log( 56 | `package %${packageName} %cnot found.`, 57 | "font-weight: bold; color: blue", 58 | "font-weight: normal; color: inherit", 59 | ); 60 | } 61 | } 62 | } 63 | 64 | await Deno.writeTextFile( 65 | IMPORT_MAP_PATH, 66 | JSON.stringify(importMap, null, "\t"), 67 | ); 68 | 69 | const VENDOR_MAP = "vendor/import_map.json"; 70 | 71 | const file = await Deno.stat(VENDOR_MAP); 72 | if (file.isFile) { 73 | console.log( 74 | "\n%cvendor/import_map.json %cdetected", 75 | "font-weight: bold", 76 | "font-weight: normal", 77 | ); 78 | console.log( 79 | "Remember to run %ctasks/vendor %cagain", 80 | "font-weight: bold", 81 | "font-weight: normal", 82 | ); 83 | } 84 | 85 | console.log( 86 | "\n%ctasks/add: %cdone\n", 87 | "font-weight: bold", 88 | "font-weight: bold; color: green", 89 | ); 90 | -------------------------------------------------------------------------------- /tasks/audit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S ./.bin/deno run --allow-net --allow-read --allow-env --allow-write 2 | // @ts-nocheck 3 | 4 | import { createCache } from "https://deno.land/x/deno_cache@0.6.0/mod.ts"; 5 | import { createGraph } from "https://deno.land/x/deno_graph@0.55.0/mod.ts"; 6 | // import { format, gt, parse } from "https://deno.land/std@0.202.0/semver/mod.ts"; 7 | 8 | // Warning! This is super messy at the moment. 9 | 10 | const IMPORT_MAP_PATH = "import_map.json"; 11 | 12 | console.log( 13 | `\n%ctasks/audit\n`, 14 | "font-weight: bold", 15 | ); 16 | 17 | const importMap = JSON.parse(await Deno.readTextFile(IMPORT_MAP_PATH)); 18 | const packages = Object.keys(importMap.imports); 19 | 20 | // create a cache where the location will be determined environmentally 21 | const cache = createCache(); 22 | // destructuring the two functions we need to pass to the graph 23 | const { cacheInfo, load } = cache; 24 | 25 | const rootPackages = {}; 26 | for (const packageName of packages) { 27 | const name = String(packageName); 28 | // console.log(name); 29 | if (name.startsWith("npm:")) { 30 | // We aren't going to look at non-npm mappings. 31 | // Might add support for gh: mappings later 32 | const url = importMap.imports[name]; 33 | // console.log(url); 34 | // create a graph that will use the cache above to load and cache dependencies 35 | const graph = await createGraph(url, { 36 | cacheInfo, 37 | load, 38 | }); 39 | 40 | // log out the console a similar output to `deno info` on the command line. 41 | // console.log(graph); 42 | rootPackages[name] = listModules(graph.modules); 43 | const advisories = await fetchAdvisories(rootPackages[name]); 44 | if (advisories.length !== 0) { 45 | console.log( 46 | `Package %c${name} %chas vulnerable dependencies: `, 47 | "font-weight: bold; color: yellow", 48 | "font-weight: normal; color: inherit", 49 | ); 50 | console.log(`\t%c${advisories.join(" ")}`, "font-weight: bold"); 51 | } 52 | } 53 | } 54 | 55 | function listModules(graph, indent = "") { 56 | let packages = []; 57 | listModulesInternal(graph, indent); 58 | return Array.from(new Set(packages)); 59 | function listModulesInternal(graph, indent = "") { 60 | graph.forEach((entry) => { 61 | if (entry.mediaType && entry.mediaType !== "Dts") { 62 | const identity = getVersion(entry.specifier); 63 | packages = packages.concat(identity); 64 | // console.log(indent + entry.specifier); 65 | } 66 | if (entry.dependencies) { 67 | listModulesInternal(entry.dependencies, indent + "\t"); 68 | } 69 | }); 70 | } 71 | } 72 | 73 | function getVersion(url) { 74 | const urlObject = new URL(url); 75 | let pathParts = urlObject.pathname.split("/").filter((segment) => segment); 76 | if (pathParts[0].startsWith("v")) { 77 | pathParts = pathParts.slice(1); 78 | } 79 | let packagePart = pathParts[0]; 80 | let version; 81 | if (packagePart.startsWith("@")) { 82 | const versionParts = pathParts[1].split("@").filter((segment) => segment); 83 | packagePart = `${packagePart}/${versionParts[0]}`; 84 | version = versionParts[1]; 85 | } else { 86 | const versionParts = packagePart.split("@").filter((segment) => segment); 87 | packagePart = versionParts[0]; 88 | version = versionParts[1]; 89 | } 90 | 91 | // console.log(packagePart, version); 92 | return `${packagePart}@${version}`; 93 | } 94 | 95 | async function fetchAdvisories(identities) { 96 | // So I can't figure out how to get the github API to return advisories on scoped npm packages. 97 | // const url = 98 | // `https://api.github.com/advisories?type=reviewed&ecosystem=npm&affects=${ 99 | // encodeURIComponent(identities.join(",")) 100 | // }`; 101 | // Using the Sonatype OSSIndex instead 102 | const url = "https://ossindex.sonatype.org/api/v3/component-report"; 103 | const coordinates = identities.map((identity) => { 104 | if (identity.startsWith("@")) { 105 | return `pkg:npm/%40${identity.slice(1)}`; 106 | } else { 107 | return `pkg:npm/${identity}`; 108 | } 109 | }); 110 | const body = { 111 | coordinates, 112 | }; 113 | const result = await fetch(url, { 114 | method: "POST", 115 | body: JSON.stringify(body), 116 | headers: { 117 | accept: "application/vnd.ossindex.component-report.v1+json", 118 | "content-type": 119 | "application/vnd.ossindex.component-report-request.v1+json", 120 | }, 121 | }); 122 | if (result.ok) { 123 | const advisories = await result.json(); 124 | let unsafe = []; 125 | for (const advisory of advisories) { 126 | if (advisory.vulnerabilities && advisory.vulnerabilities.length !== 0) { 127 | unsafe = unsafe.concat( 128 | decodeURIComponent(advisory.coordinates.replace("pkg:npm/", "")), 129 | ); 130 | } 131 | } 132 | return unsafe; 133 | // if (advisories && Array.isArray(advisories)) { 134 | // return advisories.map((advisory) => advisory.vulnerabilities).flat(); 135 | // } 136 | } else { 137 | return []; 138 | } 139 | } 140 | 141 | console.log( 142 | "\n%ctasks/add: %cdone\n", 143 | "font-weight: bold", 144 | "font-weight: bold; color: green", 145 | ); 146 | -------------------------------------------------------------------------------- /tasks/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S ./.bin/deno run --allow-net --allow-read --allow-write --allow-env --allow-run --allow-sys 2 | // @ts-nocheck 3 | import * as esbuild from "https://deno.land/x/esbuild@v0.19.2/mod.js"; 4 | import { expandGlobSync } from "https://deno.land/std@0.201.0/fs/mod.ts"; 5 | import { 6 | fromFileUrl, 7 | relative, 8 | toFileUrl, 9 | } from "https://deno.land/std@0.201.0/path/mod.ts"; 10 | import { 11 | resolveImportMap, 12 | resolveModuleSpecifier, 13 | } from "https://deno.land/x/importmap@0.2.1/mod.ts"; 14 | import { createCache } from "https://deno.land/x/deno_cache@0.6.0/mod.ts"; 15 | 16 | const outdir = "dist"; 17 | const splitting = true; 18 | const minify = true; 19 | 20 | // We should load the vendored import map first if it exists. 21 | let vendorImportMap; 22 | try { 23 | const baseURL = new URL(`vendor/`, toFileUrl(Deno.cwd() + "/")); 24 | const importMapObject = resolveImportMap( 25 | JSON.parse(await Deno.readTextFile("vendor/import_map.json")), 26 | baseURL, 27 | ); 28 | vendorImportMap = importMapObject; 29 | } catch (_err) { 30 | // 31 | } 32 | const originalImportMap = JSON.parse( 33 | await Deno.readTextFile("import_map.json"), 34 | ); 35 | 36 | // So, existing esbuild plugins don't actually resolve importmaps properly. 37 | // Ended up writing my own. 38 | function denoCache(external = false) { 39 | const importMap = external ? originalImportMap : vendorImportMap; 40 | const loader = createCache(); 41 | return { 42 | name: "deno-cache", 43 | setup(build) { 44 | build.onResolve({ filter: /.*/ }, async (args) => { 45 | // Paths through this: importer is http, importer is empty, importer is full path. 46 | let resolvedPath; 47 | if (args.importer === "") { 48 | resolvedPath = resolveModuleSpecifier( 49 | args.path, 50 | importMap, 51 | toFileUrl(args.resolveDir + "/"), 52 | ); 53 | } else if (args.importer.startsWith("http")) { 54 | resolvedPath = resolveModuleSpecifier( 55 | args.path, 56 | importMap, 57 | new URL(args.importer), 58 | ); 59 | } else { 60 | resolvedPath = resolveModuleSpecifier( 61 | args.path, 62 | importMap, 63 | toFileUrl(args.importer), 64 | ); 65 | } 66 | const moduleUrl = new URL(resolvedPath); 67 | let path; 68 | if (moduleUrl.protocol === "file:") { 69 | path = fromFileUrl(new URL(resolvedPath)); 70 | return { 71 | path, 72 | namespace: "file", 73 | }; 74 | } else if (moduleUrl.protocol.startsWith("http")) { 75 | return { 76 | path: resolvedPath, 77 | namespace: "deno-cache", 78 | external, 79 | }; 80 | } 81 | if (args.namespace === "deno-cache") { 82 | return { 83 | path: new URL(resolvedPath, args.importer).toString(), 84 | namespace: "deno-cache", 85 | }; 86 | } 87 | }); 88 | build.onLoad({ filter: /.*/, namespace: "deno-cache" }, async (args) => { 89 | const file = await loader.load(new URL(args.path), void 0, "use"); 90 | const contents = file.content; 91 | return { contents, loader: "js" }; 92 | }); 93 | }, 94 | }; 95 | } 96 | 97 | // We assume that every .js file in the project root is an entry-point. 98 | 99 | const entryPoints = Array.from(expandGlobSync("*.js")).map(( 100 | walkEntry, 101 | ) => walkEntry.path) 102 | .map((path) => { 103 | return relative(Deno.cwd(), path); 104 | }) 105 | .filter((entry) => { 106 | // Let's not include playwright files if they appear 107 | if (!entry.endsWith("playwright.config.js")) return entry; 108 | }); 109 | 110 | // Need to do a non-minified bundle as well for export 111 | await esbuild 112 | .build({ 113 | entryPoints, 114 | bundle: true, 115 | entryNames: "[dir]/[name].min", 116 | outdir, 117 | format: "esm", 118 | splitting, 119 | minify, 120 | sourcemap: true, 121 | plugins: [denoCache()], 122 | }); 123 | await esbuild 124 | .build({ 125 | entryPoints, 126 | bundle: true, 127 | outdir, 128 | format: "esm", 129 | splitting, 130 | minify: false, 131 | sourcemap: true, 132 | plugins: [denoCache(true)], 133 | }); 134 | 135 | esbuild.stop(); 136 | 137 | // const baseURL = new URL(`http://localhost:${port}/`); 138 | console.log("\n%ctasks/bundle\n", "font-weight: bold"); 139 | for (const path of entryPoints) { 140 | console.log( 141 | `%c${path}:`, 142 | "font-weight: bold", 143 | ); 144 | const fullPath = `dist/${path}`; 145 | const fullFile = await Deno.stat(fullPath); 146 | if (fullFile.isFile) { 147 | console.log( 148 | `Bundled size of %c${fullPath} %c(dependencies external) in bytes: %c${fullFile.size}`, 149 | "font-weight: bold", 150 | "font-weight: normal", 151 | "font-weight: bold; color: yellow", 152 | ); 153 | } 154 | const minPath = `dist/${path.replace(".js", ".min.js")}`; 155 | const file = await Deno.stat(minPath); 156 | if (file.isFile) { 157 | console.log( 158 | `Bundled size of %c${minPath} %cin bytes: %c${file.size}`, 159 | "font-weight: bold", 160 | "font-weight: normal", 161 | "font-weight: bold; color: yellow", 162 | ); 163 | } 164 | } 165 | console.log( 166 | "\n%ctasks/bundle: %cdone\n", 167 | "font-weight: bold", 168 | "font-weight: bold; color: green", 169 | ); 170 | -------------------------------------------------------------------------------- /tasks/check: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | shopt -s extglob 4 | shopt -s globstar 5 | 6 | SRC_DIR=src/ 7 | TEST_DIR=tests/ 8 | 9 | ## Got to use the non-vendor import map as the vendored one will cause errors 10 | ./.bin/deno check $SRC_DIR**/*.js $TEST_DIR**/*.js --import-map=import_map.json -------------------------------------------------------------------------------- /tasks/chrome: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | CHROME_PATHS=( \ 5 | "/opt/homebrew-cask/Caskroom/google-chrome-dev/latest/Google Chrome.app/Contents/MacOS/Google Chrome" \ 6 | "/opt/homebrew-cask/Caskroom/google-chrome/latest/Google Chrome.app/Contents/MacOS/Google Chrome" \ 7 | "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ 8 | "chrome" \ 9 | "chrome-browser" \ 10 | "chromium" \ 11 | ) 12 | for i in "${CHROME_PATHS[@]}" 13 | do 14 | if command -v $i &> /dev/null; then 15 | CHROME=$i 16 | fi 17 | done 18 | 19 | 20 | DATA_DIR="$(mktemp -d -t 'chrome-unsafe_data_dir.XXXXXXXXXX')" 21 | "${CHROME}" \ 22 | --ignore-certificate-errors \ 23 | --no-default-browser-check \ 24 | --no-first-run \ 25 | --non-secure \ 26 | --user-data-dir="${DATA_DIR}" \ 27 | https://localhost:8888/ >/dev/null 2>&1 &! -------------------------------------------------------------------------------- /tasks/ci: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | cp ci/package.json package.json 5 | cp ci/package-lock.json package-lock.json 6 | cp ci/playwright.config.js playwright.config.js 7 | npm ci -------------------------------------------------------------------------------- /tasks/ci-test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | rm -rf coverage/tmp 5 | npx playwright test 6 | tasks/coverage -------------------------------------------------------------------------------- /tasks/coverage: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | shopt -s extglob 4 | shopt -s globstar 5 | 6 | 7 | 8 | npx c8 report -------------------------------------------------------------------------------- /tasks/firefox: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | FIREFOX_PATHS=( \ 5 | "/Applications/Firefox.app/Contents/MacOS/firefox" \ 6 | "firefox" 7 | ) 8 | for i in "${FIREFOX_PATHS[@]}" 9 | do 10 | if command -v $i &> /dev/null; then 11 | FIREFOX=$i 12 | fi 13 | done 14 | 15 | 16 | DATA_DIR="$(mktemp -d -t 'firefox-unsafe_data_dir.XXXXXXXXXX')" 17 | "${FIREFOX}" -profile $DATA_DIR -no-remote -new-instance \ 18 | https://localhost:8888/ >/dev/null 2>&1 &! -------------------------------------------------------------------------------- /tasks/format: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | ./.bin/deno fmt -------------------------------------------------------------------------------- /tasks/lint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | ./.bin/deno lint -------------------------------------------------------------------------------- /tasks/outdated: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S ./.bin/deno run --allow-net --allow-read 2 | // @ts-nocheck 3 | // This script is a fairly straightforward automation of the process of: 4 | // 1. Loading a version-less esm.sh url for an npm package. 5 | // 2. Taking the resulting versioned url. 6 | // 3. Comparing the version in that url with the one saved in the import map 7 | // 4. Listing the packages whose latest url contains a newer version number 8 | // 9 | import { format, gt, parse } from "https://deno.land/std@0.202.0/semver/mod.ts"; 10 | 11 | const IMPORT_MAP_PATH = "import_map.json"; 12 | 13 | const importMap = JSON.parse(await Deno.readTextFile(IMPORT_MAP_PATH)); 14 | const packages = Object.keys(importMap.imports); 15 | 16 | console.log( 17 | `\n%ctasks/outdated\n`, 18 | "font-weight: bold", 19 | ); 20 | 21 | let noUpdates = true; 22 | for (const packageName of packages) { 23 | const name = String(packageName); 24 | if (name.startsWith("npm:")) { 25 | // We aren't going to look at non-npm mappings. 26 | // Might add support for gh: mappings later 27 | const url = importMap.imports[name]; 28 | let version; 29 | // Because esm.sh urls can use semantic versioning or release tags, we have to resolve the url if we can to get the actual current version 30 | const result = await fetch(url, { 31 | method: "HEAD", 32 | redirect: "follow", 33 | }); 34 | if (result.ok) { 35 | version = getVersion(result.url); 36 | } else { 37 | version = getVersion(url); 38 | } 39 | const latest = `https://esm.sh/${String(packageName).replace("npm:", "")}`; 40 | const latestResult = await fetch(latest, { 41 | method: "HEAD", 42 | redirect: "follow", 43 | }); 44 | if (result.ok) { 45 | const latestVersion = getVersion(latestResult.url); 46 | if (gt(latestVersion, version)) { 47 | noUpdates = false; 48 | console.log( 49 | `%c${packageName} %chas been updated from %c${ 50 | format(version) 51 | } %cto %c${format(latestVersion)}`, 52 | "font-weight: bold; color: blue", 53 | "font-weight: normal; color: inherit", 54 | "font-weight: bold", 55 | "font-weight: normal; color: inherit", 56 | "font-weight: bold", 57 | ); 58 | } 59 | } 60 | } 61 | } 62 | 63 | if (noUpdates) { 64 | console.log("Your dependencies seem to be up-to-date."); 65 | } else { 66 | console.log( 67 | "\nUse %ctasks/add PACKAGE_NAME %cto update a package's url to its latest version", 68 | "font-weight: bold;", 69 | "font-weight: normal;", 70 | ); 71 | } 72 | 73 | function getVersion(url) { 74 | const urlObject = new URL(url); 75 | let pathParts = urlObject.pathname.split("/").filter((segment) => segment); 76 | if (pathParts[0].startsWith("v")) { 77 | pathParts = pathParts.slice(1); 78 | } 79 | let packagePart = pathParts[0]; 80 | let version; 81 | if (packagePart.startsWith("@")) { 82 | const versionParts = pathParts[1].split("@").filter((segment) => segment); 83 | packagePart = `${packagePart}/${versionParts[0]}`; 84 | version = versionParts[1]; 85 | } else { 86 | const versionParts = packagePart.split("@").filter((segment) => segment); 87 | packagePart = versionParts[0]; 88 | version = versionParts[1]; 89 | } 90 | return parse(version); 91 | } 92 | 93 | console.log( 94 | "\n%ctasks/outdated: %cdone\n", 95 | "font-weight: bold", 96 | "font-weight: bold; color: green", 97 | ); 98 | -------------------------------------------------------------------------------- /tasks/serve: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S ./.bin/deno run --allow-net --allow-read 2 | // @ts-nocheck 3 | import { serveDir } from "https://deno.land/std@0.201.0/http/file_server.ts"; 4 | import { expandGlobSync } from "https://deno.land/std@0.201.0/fs/mod.ts"; 5 | import { relative } from "https://deno.land/std@0.201.0/path/mod.ts"; 6 | import { 7 | ServerSentEvent, 8 | ServerSentEventStreamTarget, 9 | } from "https://deno.land/std@0.201.0/http/server_sent_event.ts"; 10 | import { parse } from "https://deno.land/std@0.201.0/flags/mod.ts"; 11 | import { resolveImportMap } from "https://deno.land/x/importmap@0.2.1/mod.ts"; 12 | 13 | const parsedArgs = parse(Deno.args); 14 | 15 | // CONFIG 16 | 17 | const port = parsedArgs.port || 8888; 18 | const mochaInterface = parsedArgs.interface || "bdd"; 19 | const mochaTimeout = parsedArgs.timeout || 2000; 20 | const watch = parsedArgs["no-watch"] ? false : true; 21 | 22 | // ENDCONFIG 23 | 24 | const cert = await Deno.readTextFile(".bin/dev.cert"); 25 | const key = await Deno.readTextFile(".bin/dev.key"); 26 | 27 | Deno.serve({ cert, key, port }, async (req) => { 28 | const pathname = new URL(req.url).pathname; 29 | if (pathname === "/") { 30 | return handle(handle(await supportfiles())); 31 | } else if (pathname === "/.changes") { 32 | return handleChanges(); 33 | } else { 34 | return handle(await serveDir(req)); 35 | } 36 | }); 37 | 38 | if (watch) { 39 | const _watcher = startWatch(); 40 | } 41 | 42 | let targets = []; 43 | 44 | function handleChanges() { 45 | const target = new ServerSentEventStreamTarget(); 46 | targets = targets.concat(target); 47 | return target.asResponse(); 48 | } 49 | 50 | async function startWatch() { 51 | const watcher = Deno.watchFs(Deno.cwd()); 52 | for await (const event of watcher) { 53 | const paths = event.paths.filter((path) => path.endsWith(".js")); 54 | if (paths.length !== 0) { 55 | const evt = new ServerSentEvent( 56 | "change", 57 | { change: event.paths }, 58 | ); 59 | for (const target of targets) { 60 | target.dispatchEvent(evt); 61 | } 62 | } 63 | } 64 | } 65 | 66 | /** 67 | * Handles the request. Adds the headers needed for cross origin isolation 68 | * 69 | * @param {Response} response - A response. 70 | * @returns {Response} This is the result 71 | */ 72 | function handle(response) { 73 | const newHeaders = new Headers(response.headers); 74 | newHeaders.set("Cross-Origin-Embedder-Policy", "require-corp"); 75 | newHeaders.set("Cross-Origin-Resource-Policy", "cross-origin"); 76 | newHeaders.set("Cross-Origin-Opener-Policy", "same-origin"); 77 | return new Response(response.body, { 78 | status: response.status, 79 | statusText: response.statusText, 80 | headers: newHeaders, 81 | }); 82 | } 83 | 84 | /** 85 | * @param {Request} req - A request. 86 | * @returns {Promise} This is the result 87 | */ 88 | function supportfiles() { 89 | return renderTestHTML(); 90 | } 91 | 92 | async function renderTestHTML() { 93 | const testFiles = Array.from(expandGlobSync("tests/**/*.js")).map(( 94 | walkEntry, 95 | ) => walkEntry.path).map((path) => { 96 | path = relative(Deno.cwd(), path); 97 | return ``; 98 | }).join("\n"); 99 | 100 | // We should load the vendored import map first. 101 | let importMap; 102 | try { 103 | const baseURL = new URL(`https://localhost:${port}/vendor/`); 104 | const importMapObject = resolveImportMap( 105 | JSON.parse(await Deno.readTextFile("vendor/import_map.json")), 106 | baseURL, 107 | ); 108 | importMap = JSON.stringify( 109 | importMapObject, 110 | ); 111 | } catch (_err) { 112 | importMap = await Deno.readTextFile("import_map.json"); 113 | } 114 | 115 | const body = ` 116 | 117 | 118 | 119 | Mocha Tests 120 | 121 | 122 | 125 | 126 | 127 |
128 | 129 | 130 | 131 | 132 | 146 | 147 | ${testFiles} 148 | 149 | 150 | `; 151 | return new Response(body, { 152 | status: 200, 153 | headers: { 154 | "content-type": "text/html; charset=utf-8", 155 | }, 156 | }); 157 | } 158 | -------------------------------------------------------------------------------- /tasks/setup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | platform=$(uname -ms) 4 | 5 | 6 | BBlack='\033[1;30m' 7 | Color_Off='\033[0m' 8 | BGreen='\033[1;32m' 9 | # Configuration 10 | 11 | # We pin versions in this house because we don't like moving targets 12 | DENO_VERSION="v1.36.4" 13 | DENO_SHA="2c3ba45690cf8ace6f48882317024528bc733f23863f94936ec6018a02bbca4a" 14 | 15 | 16 | echo 17 | echo -e "${BBlack}tasks/setup${Color_Off}:" 18 | 19 | # End configuration 20 | 21 | mkdir -p .bin 22 | 23 | # This bit is from the deno install script, MIT licenced, https://github.com/denoland/deno 24 | 25 | echo 26 | echo "Installing deno" 27 | 28 | if ! command -v unzip >/dev/null; then 29 | echo "Error: unzip is required to install Deno (see: https://github.com/denoland/deno_install#unzip-is-required )." 1>&2 30 | exit 1 31 | fi 32 | 33 | # The setup script we're currently in doesn't actually support windows except possibly by accident. 34 | 35 | case $(uname -sm) in 36 | "Darwin x86_64") target="x86_64-apple-darwin" ;; 37 | "Darwin arm64") target="aarch64-apple-darwin" ;; 38 | "Linux aarch64") 39 | echo "Error: Official Deno builds for Linux aarch64 are not available. (see: https://github.com/denoland/deno/issues/1846 )" 1>&2 40 | exit 1 41 | ;; 42 | *) target="x86_64-unknown-linux-gnu" ;; 43 | esac 44 | deno_uri="https://github.com/denoland/deno/releases/download/${DENO_VERSION}/deno-${target}.zip" 45 | 46 | EXE=".bin/deno" 47 | 48 | curl --fail --location --progress-bar --output "$EXE.zip" "$deno_uri" 49 | echo 50 | unzip -d ".bin" -o "$EXE.zip" 51 | echo 52 | echo "Checking the integrity of the download with sha256sum" 53 | echo "$DENO_SHA $EXE" | sha256sum --check 54 | chmod +x "$EXE" 55 | rm "$EXE.zip" 56 | 57 | # This bit is just bog standard openssl key generation 58 | 59 | echo 60 | echo "Generating key and cert files for https test server" 61 | openssl req -x509 -newkey rsa:4096 -keyout $PWD/.bin/dev.key -out $PWD/.bin/dev.cert -days 9999 -nodes -subj /CN=127.0.0.1 &> /dev/null 62 | 63 | echo "Setup done" 64 | echo -e "${BBlack}tasks/setup${Color_Off}: ${BGreen}done${Color_Off}" 65 | echo -------------------------------------------------------------------------------- /tasks/test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | 4 | BROWSER=tasks/chrome 5 | # BROWSER=tasks/firefox 6 | 7 | 8 | 9 | $BROWSER & 10 | tasks/serve -------------------------------------------------------------------------------- /tasks/vendor: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | shopt -s extglob 4 | shopt -s globstar 5 | 6 | SRC_DIR=src/ 7 | TEST_DIR=tests/ 8 | BBlack='\033[1;30m' 9 | Color_Off='\033[0m' 10 | BGreen='\033[1;32m' 11 | 12 | 13 | echo 14 | echo -e "${BBlack}tasks/vendor${Color_Off}:" 15 | echo -e "Downloading local copies of the imports in $BBlack$SRC_DIR$Color_Off and $BBlack$TEST_DIR$Color_Off" 16 | ./.bin/deno vendor $SRC_DIR**/*.js $TEST_DIR**/*.js --force --import-map=import_map.json &> /dev/null 17 | echo -e "Combined import map created at ${BBlack}vendor/import_map.json${Color_Off}." 18 | echo -e "To update the combined import map, edit your original import map in project root and re-run ${BBlack}tasks/vendor${Color_Off}" 19 | echo -e "${BBlack}tasks/vendor${Color_Off}: ${BGreen}done${Color_Off}" 20 | echo -------------------------------------------------------------------------------- /tests/simpletest.js: -------------------------------------------------------------------------------- 1 | import { grassy } from "../src/index.js"; 2 | 3 | const { assert } = chai; 4 | 5 | describe("Array", function () { 6 | describe("#indexOf()", function () { 7 | it("should return -1 when the value is not present", async function () { 8 | await grassy(); 9 | assert.equal([1, 2, 3].indexOf(4), -1); 10 | }); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/hash-wasm@4.9.0.js: -------------------------------------------------------------------------------- 1 | // @deno-types="https://esm.sh/v131/hash-wasm@4.9.0/dist/lib/index.d.ts" 2 | export * from "./hash-wasm@4.9.0.proxied.js"; 3 | -------------------------------------------------------------------------------- /vendor/esm.sh/hash-wasm@4.9.0.proxied.js: -------------------------------------------------------------------------------- 1 | /* esm.sh - hash-wasm@4.9.0 */ 2 | export * from "/v131/hash-wasm@4.9.0/denonext/hash-wasm.mjs"; 3 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/WASMInterface.d.ts: -------------------------------------------------------------------------------- 1 | import { IDataType } from './util.d.ts'; 2 | export declare const MAX_HEAP: number; 3 | declare type ThenArg = T extends Promise ? U : T extends ((...args: any[]) => Promise) ? V : T; 4 | export declare type IHasher = { 5 | /** 6 | * Initializes hash state to default value 7 | */ 8 | init: () => IHasher; 9 | /** 10 | * Updates the hash content with the given data 11 | */ 12 | update: (data: IDataType) => IHasher; 13 | /** 14 | * Calculates the hash of all of the data passed to be hashed with hash.update(). 15 | * Defaults to hexadecimal string 16 | * @param outputType If outputType is "binary", it returns Uint8Array. Otherwise it 17 | * returns hexadecimal string 18 | */ 19 | digest: { 20 | (outputType: 'binary'): Uint8Array; 21 | (outputType?: 'hex'): string; 22 | }; 23 | /** 24 | * Save the current internal state of the hasher for later resumption with load(). 25 | * Cannot be called before .init() or after .digest() 26 | * 27 | * Note that this state can include arbitrary information about the value being hashed (e.g. 28 | * could include N plaintext bytes from the value), so needs to be treated as being as 29 | * sensitive as the input value itself. 30 | */ 31 | save: () => Uint8Array; 32 | /** 33 | * Resume a state that was created by save(). If this state was not created by a 34 | * compatible build of hash-wasm, an exception will be thrown. 35 | */ 36 | load: (state: Uint8Array) => IHasher; 37 | /** 38 | * Block size in bytes 39 | */ 40 | blockSize: number; 41 | /** 42 | * Digest size in bytes 43 | */ 44 | digestSize: number; 45 | }; 46 | export declare function WASMInterface(binary: any, hashLength: number): Promise<{ 47 | getMemory: () => Uint8Array; 48 | writeMemory: (data: Uint8Array, offset?: number) => void; 49 | getExports: () => any; 50 | setMemorySize: (totalSize: number) => void; 51 | init: (bits?: number) => void; 52 | update: (data: IDataType) => void; 53 | digest: (outputType: 'hex' | 'binary', padding?: number) => Uint8Array | string; 54 | save: () => Uint8Array; 55 | load: (state: Uint8Array) => void; 56 | calculate: (data: IDataType, initParam?: any, digestParam?: any) => string; 57 | hashLength: number; 58 | }>; 59 | export declare type IWASMInterface = ThenArg>; 60 | export {}; 61 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/adler32.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates Adler-32 hash. The resulting 32-bit hash is stored in 5 | * network byte order (big-endian). 6 | * 7 | * @param data Input data (string, Buffer or TypedArray) 8 | * @returns Computed hash as a hexadecimal string 9 | */ 10 | export declare function adler32(data: IDataType): Promise; 11 | /** 12 | * Creates a new Adler-32 hash instance 13 | */ 14 | export declare function createAdler32(): Promise; 15 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/argon2.d.ts: -------------------------------------------------------------------------------- 1 | import { IDataType } from './util.d.ts'; 2 | export interface IArgon2Options { 3 | /** 4 | * Password (or message) to be hashed 5 | */ 6 | password: IDataType; 7 | /** 8 | * Salt (usually containing random bytes) 9 | */ 10 | salt: IDataType; 11 | /** 12 | * Number of iterations to perform 13 | */ 14 | iterations: number; 15 | /** 16 | * Degree of parallelism 17 | */ 18 | parallelism: number; 19 | /** 20 | * Amount of memory to be used in kibibytes (1024 bytes) 21 | */ 22 | memorySize: number; 23 | /** 24 | * Output size in bytes 25 | */ 26 | hashLength: number; 27 | /** 28 | * Desired output type. Defaults to 'hex' 29 | */ 30 | outputType?: 'hex' | 'binary' | 'encoded'; 31 | } 32 | interface IArgon2OptionsBinary { 33 | outputType: 'binary'; 34 | } 35 | declare type Argon2ReturnType = T extends IArgon2OptionsBinary ? Uint8Array : string; 36 | /** 37 | * Calculates hash using the argon2i password-hashing function 38 | * @returns Computed hash 39 | */ 40 | export declare function argon2i(options: T): Promise>; 41 | /** 42 | * Calculates hash using the argon2id password-hashing function 43 | * @returns Computed hash 44 | */ 45 | export declare function argon2id(options: T): Promise>; 46 | /** 47 | * Calculates hash using the argon2d password-hashing function 48 | * @returns Computed hash 49 | */ 50 | export declare function argon2d(options: T): Promise>; 51 | export interface Argon2VerifyOptions { 52 | /** 53 | * Password to be verified 54 | */ 55 | password: IDataType; 56 | /** 57 | * A previously generated argon2 hash in the 'encoded' output format 58 | */ 59 | hash: string; 60 | } 61 | /** 62 | * Verifies password using the argon2 password-hashing function 63 | * @returns True if the encoded hash matches the password 64 | */ 65 | export declare function argon2Verify(options: Argon2VerifyOptions): Promise; 66 | export {}; 67 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/bcrypt.d.ts: -------------------------------------------------------------------------------- 1 | import { IDataType } from './util.d.ts'; 2 | export interface BcryptOptions { 3 | /** 4 | * Password to be hashed 5 | */ 6 | password: IDataType; 7 | /** 8 | * Salt (16 bytes long - usually containing random bytes) 9 | */ 10 | salt: IDataType; 11 | /** 12 | * Number of iterations to perform (4 - 31) 13 | */ 14 | costFactor: number; 15 | /** 16 | * Desired output type. Defaults to 'encoded' 17 | */ 18 | outputType?: 'hex' | 'binary' | 'encoded'; 19 | } 20 | interface IBcryptOptionsBinary { 21 | outputType: 'binary'; 22 | } 23 | declare type BcryptReturnType = T extends IBcryptOptionsBinary ? Uint8Array : string; 24 | /** 25 | * Calculates hash using the bcrypt password-hashing function 26 | * @returns Computed hash 27 | */ 28 | export declare function bcrypt(options: T): Promise>; 29 | export interface BcryptVerifyOptions { 30 | /** 31 | * Password to be verified 32 | */ 33 | password: IDataType; 34 | /** 35 | * A previously generated bcrypt hash in the 'encoded' output format 36 | */ 37 | hash: string; 38 | } 39 | /** 40 | * Verifies password using bcrypt password-hashing function 41 | * @returns True if the encoded hash matches the password 42 | */ 43 | export declare function bcryptVerify(options: BcryptVerifyOptions): Promise; 44 | export {}; 45 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/blake2b.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates BLAKE2b hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @param bits Number of output bits, which has to be a number 7 | * divisible by 8, between 8 and 512. Defaults to 512. 8 | * @param key Optional key (string, Buffer or TypedArray). Maximum length is 64 bytes. 9 | * @returns Computed hash as a hexadecimal string 10 | */ 11 | export declare function blake2b(data: IDataType, bits?: number, key?: IDataType): Promise; 12 | /** 13 | * Creates a new BLAKE2b hash instance 14 | * @param bits Number of output bits, which has to be a number 15 | * divisible by 8, between 8 and 512. Defaults to 512. 16 | * @param key Optional key (string, Buffer or TypedArray). Maximum length is 64 bytes. 17 | */ 18 | export declare function createBLAKE2b(bits?: number, key?: IDataType): Promise; 19 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/blake2s.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates BLAKE2s hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @param bits Number of output bits, which has to be a number 7 | * divisible by 8, between 8 and 256. Defaults to 256. 8 | * @param key Optional key (string, Buffer or TypedArray). Maximum length is 32 bytes. 9 | * @returns Computed hash as a hexadecimal string 10 | */ 11 | export declare function blake2s(data: IDataType, bits?: number, key?: IDataType): Promise; 12 | /** 13 | * Creates a new BLAKE2s hash instance 14 | * @param bits Number of output bits, which has to be a number 15 | * divisible by 8, between 8 and 256. Defaults to 256. 16 | * @param key Optional key (string, Buffer or TypedArray). Maximum length is 32 bytes. 17 | */ 18 | export declare function createBLAKE2s(bits?: number, key?: IDataType): Promise; 19 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/blake3.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates BLAKE3 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @param bits Number of output bits, which has to be a number 7 | * divisible by 8. Defaults to 256. 8 | * @param key Optional key (string, Buffer or TypedArray). Length should be 32 bytes. 9 | * @returns Computed hash as a hexadecimal string 10 | */ 11 | export declare function blake3(data: IDataType, bits?: number, key?: IDataType): Promise; 12 | /** 13 | * Creates a new BLAKE3 hash instance 14 | * @param bits Number of output bits, which has to be a number 15 | * divisible by 8. Defaults to 256. 16 | * @param key Optional key (string, Buffer or TypedArray). Length should be 32 bytes. 17 | */ 18 | export declare function createBLAKE3(bits?: number, key?: IDataType): Promise; 19 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/crc32.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates CRC-32 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function crc32(data: IDataType): Promise; 9 | /** 10 | * Creates a new CRC-32 hash instance 11 | */ 12 | export declare function createCRC32(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/crc32c.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates CRC-32C hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function crc32c(data: IDataType): Promise; 9 | /** 10 | * Creates a new CRC-32C hash instance 11 | */ 12 | export declare function createCRC32C(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/hmac.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates HMAC hash 5 | * @param hash Hash algorithm to use. It has to be the return value of a function like createSHA1() 6 | * @param key Key (string, Buffer or TypedArray) 7 | */ 8 | export declare function createHMAC(hash: Promise, key: IDataType): Promise; 9 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './adler32.d.ts'; 2 | export * from './argon2.d.ts'; 3 | export * from './blake2b.d.ts'; 4 | export * from './blake2s.d.ts'; 5 | export * from './blake3.d.ts'; 6 | export * from './crc32.d.ts'; 7 | export * from './crc32c.d.ts'; 8 | export * from './md4.d.ts'; 9 | export * from './md5.d.ts'; 10 | export * from './sha1.d.ts'; 11 | export * from './sha3.d.ts'; 12 | export * from './keccak.d.ts'; 13 | export * from './sha224.d.ts'; 14 | export * from './sha256.d.ts'; 15 | export * from './sha384.d.ts'; 16 | export * from './sha512.d.ts'; 17 | export * from './xxhash32.d.ts'; 18 | export * from './xxhash64.d.ts'; 19 | export * from './xxhash3.d.ts'; 20 | export * from './xxhash128.d.ts'; 21 | export * from './ripemd160.d.ts'; 22 | export * from './hmac.d.ts'; 23 | export * from './pbkdf2.d.ts'; 24 | export * from './scrypt.d.ts'; 25 | export * from './bcrypt.d.ts'; 26 | export * from './whirlpool.d.ts'; 27 | export * from './sm3.d.ts'; 28 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/keccak.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | declare type IValidBits = 224 | 256 | 384 | 512; 4 | /** 5 | * Calculates Keccak hash 6 | * @param data Input data (string, Buffer or TypedArray) 7 | * @param bits Number of output bits. Valid values: 224, 256, 384, 512 8 | * @returns Computed hash as a hexadecimal string 9 | */ 10 | export declare function keccak(data: IDataType, bits?: IValidBits): Promise; 11 | /** 12 | * Creates a new Keccak hash instance 13 | * @param bits Number of output bits. Valid values: 224, 256, 384, 512 14 | */ 15 | export declare function createKeccak(bits?: IValidBits): Promise; 16 | export {}; 17 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/md4.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates MD4 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function md4(data: IDataType): Promise; 9 | /** 10 | * Creates a new MD4 hash instance 11 | */ 12 | export declare function createMD4(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/md5.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates MD5 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function md5(data: IDataType): Promise; 9 | /** 10 | * Creates a new MD5 hash instance 11 | */ 12 | export declare function createMD5(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/pbkdf2.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | export interface IPBKDF2Options { 4 | /** 5 | * Password (or message) to be hashed 6 | */ 7 | password: IDataType; 8 | /** 9 | * Salt (usually containing random bytes) 10 | */ 11 | salt: IDataType; 12 | /** 13 | * Number of iterations to perform 14 | */ 15 | iterations: number; 16 | /** 17 | * Output size in bytes 18 | */ 19 | hashLength: number; 20 | /** 21 | * Hash algorithm to use. It has to be the return value of a function like createSHA1() 22 | */ 23 | hashFunction: Promise; 24 | /** 25 | * Desired output type. Defaults to 'hex' 26 | */ 27 | outputType?: 'hex' | 'binary'; 28 | } 29 | interface IPBKDF2OptionsBinary { 30 | outputType: 'binary'; 31 | } 32 | declare type PBKDF2ReturnType = T extends IPBKDF2OptionsBinary ? Uint8Array : string; 33 | /** 34 | * Generates a new PBKDF2 hash for the supplied password 35 | */ 36 | export declare function pbkdf2(options: T): Promise>; 37 | export {}; 38 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/ripemd160.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates RIPEMD-160 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function ripemd160(data: IDataType): Promise; 9 | /** 10 | * Creates a new RIPEMD-160 hash instance 11 | */ 12 | export declare function createRIPEMD160(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/scrypt.d.ts: -------------------------------------------------------------------------------- 1 | import { IDataType } from './util.d.ts'; 2 | export interface ScryptOptions { 3 | /** 4 | * Password (or message) to be hashed 5 | */ 6 | password: IDataType; 7 | /** 8 | * Salt (usually containing random bytes) 9 | */ 10 | salt: IDataType; 11 | /** 12 | * CPU / memory cost - must be a power of 2 (e.g. 1024) 13 | */ 14 | costFactor: number; 15 | /** 16 | * Block size (8 is commonly used) 17 | */ 18 | blockSize: number; 19 | /** 20 | * Degree of parallelism 21 | */ 22 | parallelism: number; 23 | /** 24 | * Output size in bytes 25 | */ 26 | hashLength: number; 27 | /** 28 | * Output data type. Defaults to hexadecimal string 29 | */ 30 | outputType?: 'hex' | 'binary'; 31 | } 32 | interface IScryptOptionsBinary { 33 | outputType: 'binary'; 34 | } 35 | declare type ScryptReturnType = T extends IScryptOptionsBinary ? Uint8Array : string; 36 | /** 37 | * Calculates hash using the scrypt password-based key derivation function 38 | * @returns Computed hash as a hexadecimal string or as 39 | * Uint8Array depending on the outputType option 40 | */ 41 | export declare function scrypt(options: T): Promise>; 42 | export {}; 43 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/sha1.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates SHA-1 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function sha1(data: IDataType): Promise; 9 | /** 10 | * Creates a new SHA-1 hash instance 11 | */ 12 | export declare function createSHA1(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/sha224.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates SHA-2 (SHA-224) hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function sha224(data: IDataType): Promise; 9 | /** 10 | * Creates a new SHA-2 (SHA-224) hash instance 11 | */ 12 | export declare function createSHA224(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/sha256.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates SHA-2 (SHA-256) hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function sha256(data: IDataType): Promise; 9 | /** 10 | * Creates a new SHA-2 (SHA-256) hash instance 11 | */ 12 | export declare function createSHA256(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/sha3.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | declare type IValidBits = 224 | 256 | 384 | 512; 4 | /** 5 | * Calculates SHA-3 hash 6 | * @param data Input data (string, Buffer or TypedArray) 7 | * @param bits Number of output bits. Valid values: 224, 256, 384, 512 8 | * @returns Computed hash as a hexadecimal string 9 | */ 10 | export declare function sha3(data: IDataType, bits?: IValidBits): Promise; 11 | /** 12 | * Creates a new SHA-3 hash instance 13 | * @param bits Number of output bits. Valid values: 224, 256, 384, 512 14 | */ 15 | export declare function createSHA3(bits?: IValidBits): Promise; 16 | export {}; 17 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/sha384.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates SHA-2 (SHA-384) hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function sha384(data: IDataType): Promise; 9 | /** 10 | * Creates a new SHA-2 (SHA-384) hash instance 11 | */ 12 | export declare function createSHA384(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/sha512.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates SHA-2 (SHA-512) hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function sha512(data: IDataType): Promise; 9 | /** 10 | * Creates a new SHA-2 (SHA-512) hash instance 11 | */ 12 | export declare function createSHA512(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/sm3.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates SM3 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function sm3(data: IDataType): Promise; 9 | /** 10 | * Creates a new SM3 hash instance 11 | */ 12 | export declare function createSM3(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/util.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | export declare type ITypedArray = Uint8Array | Uint16Array | Uint32Array; 3 | export declare type IDataType = string | Buffer | ITypedArray; 4 | export declare function intArrayToString(arr: Uint8Array, len: number): string; 5 | export declare function writeHexToUInt8(buf: Uint8Array, str: string): void; 6 | export declare function hexStringEqualsUInt8(str: string, buf: Uint8Array): boolean; 7 | export declare function getDigestHex(tmpBuffer: Uint8Array, input: Uint8Array, hashLength: number): string; 8 | export declare const getUInt8Buffer: (data: IDataType) => Uint8Array; 9 | export declare function encodeBase64(data: Uint8Array, pad?: boolean): string; 10 | export declare function getDecodeBase64Length(data: string): number; 11 | export declare function decodeBase64(data: string): Uint8Array; 12 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/whirlpool.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates Whirlpool hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @returns Computed hash as a hexadecimal string 7 | */ 8 | export declare function whirlpool(data: IDataType): Promise; 9 | /** 10 | * Creates a new Whirlpool hash instance 11 | */ 12 | export declare function createWhirlpool(): Promise; 13 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/xxhash128.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates xxHash128 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @param seedLow Lower 32 bits of the number used to 7 | * initialize the internal state of the algorithm (defaults to 0) 8 | * @param seedHigh Higher 32 bits of the number used to 9 | * initialize the internal state of the algorithm (defaults to 0) 10 | * @returns Computed hash as a hexadecimal string 11 | */ 12 | export declare function xxhash128(data: IDataType, seedLow?: number, seedHigh?: number): Promise; 13 | /** 14 | * Creates a new xxHash128 hash instance 15 | * @param seedLow Lower 32 bits of the number used to 16 | * initialize the internal state of the algorithm (defaults to 0) 17 | * @param seedHigh Higher 32 bits of the number used to 18 | * initialize the internal state of the algorithm (defaults to 0) 19 | */ 20 | export declare function createXXHash128(seedLow?: number, seedHigh?: number): Promise; 21 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/xxhash3.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates xxHash3 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @param seedLow Lower 32 bits of the number used to 7 | * initialize the internal state of the algorithm (defaults to 0) 8 | * @param seedHigh Higher 32 bits of the number used to 9 | * initialize the internal state of the algorithm (defaults to 0) 10 | * @returns Computed hash as a hexadecimal string 11 | */ 12 | export declare function xxhash3(data: IDataType, seedLow?: number, seedHigh?: number): Promise; 13 | /** 14 | * Creates a new xxHash3 hash instance 15 | * @param seedLow Lower 32 bits of the number used to 16 | * initialize the internal state of the algorithm (defaults to 0) 17 | * @param seedHigh Higher 32 bits of the number used to 18 | * initialize the internal state of the algorithm (defaults to 0) 19 | */ 20 | export declare function createXXHash3(seedLow?: number, seedHigh?: number): Promise; 21 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/xxhash32.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates xxHash32 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @param seed Number used to initialize the internal state of the algorithm (defaults to 0) 7 | * @returns Computed hash as a hexadecimal string 8 | */ 9 | export declare function xxhash32(data: IDataType, seed?: number): Promise; 10 | /** 11 | * Creates a new xxHash32 hash instance 12 | * @param data Input data (string, Buffer or TypedArray) 13 | * @param seed Number used to initialize the internal state of the algorithm (defaults to 0) 14 | */ 15 | export declare function createXXHash32(seed?: number): Promise; 16 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/hash-wasm@4.9.0/dist/lib/xxhash64.d.ts: -------------------------------------------------------------------------------- 1 | import { IHasher } from './WASMInterface.d.ts'; 2 | import { IDataType } from './util.d.ts'; 3 | /** 4 | * Calculates xxHash64 hash 5 | * @param data Input data (string, Buffer or TypedArray) 6 | * @param seedLow Lower 32 bits of the number used to 7 | * initialize the internal state of the algorithm (defaults to 0) 8 | * @param seedHigh Higher 32 bits of the number used to 9 | * initialize the internal state of the algorithm (defaults to 0) 10 | * @returns Computed hash as a hexadecimal string 11 | */ 12 | export declare function xxhash64(data: IDataType, seedLow?: number, seedHigh?: number): Promise; 13 | /** 14 | * Creates a new xxHash64 hash instance 15 | * @param seedLow Lower 32 bits of the number used to 16 | * initialize the internal state of the algorithm (defaults to 0) 17 | * @param seedHigh Higher 32 bits of the number used to 18 | * initialize the internal state of the algorithm (defaults to 0) 19 | */ 20 | export declare function createXXHash64(seedLow?: number, seedHigh?: number): Promise; 21 | -------------------------------------------------------------------------------- /vendor/esm.sh/v131/node.ns.d.ts: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------* 2 | * * 3 | * GLOBAL * 4 | * * 5 | ------------------------------------------------*/ 6 | 7 | type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex"; 8 | 9 | type WithImplicitCoercion = T | { valueOf(): T }; 10 | 11 | /** 12 | * Raw data is stored in instances of the Buffer class. 13 | * A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized. 14 | * Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' 15 | */ 16 | declare class Buffer extends Uint8Array { 17 | /** 18 | * Allocates a new buffer containing the given {str}. 19 | * 20 | * @param str String to store in buffer. 21 | * @param encoding encoding to use, optional. Default is 'utf8' 22 | * @deprecated since v10.0.0 - Use `Buffer.from(string[, encoding])` instead. 23 | */ 24 | constructor(str: string, encoding?: BufferEncoding); 25 | /** 26 | * Allocates a new buffer of {size} octets. 27 | * 28 | * @param size count of octets to allocate. 29 | * @deprecated since v10.0.0 - Use `Buffer.alloc()` instead (also see `Buffer.allocUnsafe()`). 30 | */ 31 | constructor(size: number); 32 | /** 33 | * Allocates a new buffer containing the given {array} of octets. 34 | * 35 | * @param array The octets to store. 36 | * @deprecated since v10.0.0 - Use `Buffer.from(array)` instead. 37 | */ 38 | constructor(array: Uint8Array); 39 | /** 40 | * Produces a Buffer backed by the same allocated memory as 41 | * the given {ArrayBuffer}/{SharedArrayBuffer}. 42 | * 43 | * 44 | * @param arrayBuffer The ArrayBuffer with which to share memory. 45 | * @deprecated since v10.0.0 - Use `Buffer.from(arrayBuffer[, byteOffset[, length]])` instead. 46 | */ 47 | constructor(arrayBuffer: ArrayBuffer | SharedArrayBuffer); 48 | /** 49 | * Allocates a new buffer containing the given {array} of octets. 50 | * 51 | * @param array The octets to store. 52 | * @deprecated since v10.0.0 - Use `Buffer.from(array)` instead. 53 | */ 54 | constructor(array: ReadonlyArray); 55 | /** 56 | * Copies the passed {buffer} data onto a new {Buffer} instance. 57 | * 58 | * @param buffer The buffer to copy. 59 | * @deprecated since v10.0.0 - Use `Buffer.from(buffer)` instead. 60 | */ 61 | constructor(buffer: Buffer); 62 | /** 63 | * When passed a reference to the .buffer property of a TypedArray instance, 64 | * the newly created Buffer will share the same allocated memory as the TypedArray. 65 | * The optional {byteOffset} and {length} arguments specify a memory range 66 | * within the {arrayBuffer} that will be shared by the Buffer. 67 | * 68 | * @param arrayBuffer The .buffer property of any TypedArray or a new ArrayBuffer() 69 | */ 70 | static from(arrayBuffer: WithImplicitCoercion, byteOffset?: number, length?: number): Buffer; 71 | /** 72 | * Creates a new Buffer using the passed {data} 73 | * @param data data to create a new Buffer 74 | */ 75 | static from(data: Uint8Array | ReadonlyArray): Buffer; 76 | static from(data: WithImplicitCoercion | string>): Buffer; 77 | /** 78 | * Creates a new Buffer containing the given JavaScript string {str}. 79 | * If provided, the {encoding} parameter identifies the character encoding. 80 | * If not provided, {encoding} defaults to 'utf8'. 81 | */ 82 | static from(str: WithImplicitCoercion | { [Symbol.toPrimitive](hint: 'string'): string }, encoding?: BufferEncoding): Buffer; 83 | /** 84 | * Creates a new Buffer using the passed {data} 85 | * @param values to create a new Buffer 86 | */ 87 | static of(...items: number[]): Buffer; 88 | /** 89 | * Returns true if {obj} is a Buffer 90 | * 91 | * @param obj object to test. 92 | */ 93 | static isBuffer(obj: any): obj is Buffer; 94 | /** 95 | * Returns true if {encoding} is a valid encoding argument. 96 | * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' 97 | * 98 | * @param encoding string to test. 99 | */ 100 | static isEncoding(encoding: string): encoding is BufferEncoding; 101 | /** 102 | * Gives the actual byte length of a string. encoding defaults to 'utf8'. 103 | * This is not the same as String.prototype.length since that returns the number of characters in a string. 104 | * 105 | * @param string string to test. 106 | * @param encoding encoding used to evaluate (defaults to 'utf8') 107 | */ 108 | static byteLength( 109 | string: string | NodeJS.ArrayBufferView | ArrayBuffer | SharedArrayBuffer, 110 | encoding?: BufferEncoding 111 | ): number; 112 | /** 113 | * Returns a buffer which is the result of concatenating all the buffers in the list together. 114 | * 115 | * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. 116 | * If the list has exactly one item, then the first item of the list is returned. 117 | * If the list has more than one item, then a new Buffer is created. 118 | * 119 | * @param list An array of Buffer objects to concatenate 120 | * @param totalLength Total length of the buffers when concatenated. 121 | * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. 122 | */ 123 | static concat(list: ReadonlyArray, totalLength?: number): Buffer; 124 | /** 125 | * The same as buf1.compare(buf2). 126 | */ 127 | static compare(buf1: Uint8Array, buf2: Uint8Array): number; 128 | /** 129 | * Allocates a new buffer of {size} octets. 130 | * 131 | * @param size count of octets to allocate. 132 | * @param fill if specified, buffer will be initialized by calling buf.fill(fill). 133 | * If parameter is omitted, buffer will be filled with zeros. 134 | * @param encoding encoding used for call to buf.fill while initalizing 135 | */ 136 | static alloc(size: number, fill?: string | Buffer | number, encoding?: BufferEncoding): Buffer; 137 | /** 138 | * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents 139 | * of the newly created Buffer are unknown and may contain sensitive data. 140 | * 141 | * @param size count of octets to allocate 142 | */ 143 | static allocUnsafe(size: number): Buffer; 144 | /** 145 | * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents 146 | * of the newly created Buffer are unknown and may contain sensitive data. 147 | * 148 | * @param size count of octets to allocate 149 | */ 150 | static allocUnsafeSlow(size: number): Buffer; 151 | /** 152 | * This is the number of bytes used to determine the size of pre-allocated, internal Buffer instances used for pooling. This value may be modified. 153 | */ 154 | static poolSize: number; 155 | 156 | write(string: string, encoding?: BufferEncoding): number; 157 | write(string: string, offset: number, encoding?: BufferEncoding): number; 158 | write(string: string, offset: number, length: number, encoding?: BufferEncoding): number; 159 | toString(encoding?: BufferEncoding, start?: number, end?: number): string; 160 | toJSON(): { type: 'Buffer'; data: number[] }; 161 | equals(otherBuffer: Uint8Array): boolean; 162 | compare( 163 | otherBuffer: Uint8Array, 164 | targetStart?: number, 165 | targetEnd?: number, 166 | sourceStart?: number, 167 | sourceEnd?: number 168 | ): number; 169 | copy(targetBuffer: Uint8Array, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; 170 | /** 171 | * Returns a new `Buffer` that references **the same memory as the original**, but offset and cropped by the start and end indices. 172 | * 173 | * This method is incompatible with `Uint8Array#slice()`, which returns a copy of the original memory. 174 | * 175 | * @param begin Where the new `Buffer` will start. Default: `0`. 176 | * @param end Where the new `Buffer` will end (not inclusive). Default: `buf.length`. 177 | */ 178 | slice(begin?: number, end?: number): Buffer; 179 | /** 180 | * Returns a new `Buffer` that references **the same memory as the original**, but offset and cropped by the start and end indices. 181 | * 182 | * This method is compatible with `Uint8Array#subarray()`. 183 | * 184 | * @param begin Where the new `Buffer` will start. Default: `0`. 185 | * @param end Where the new `Buffer` will end (not inclusive). Default: `buf.length`. 186 | */ 187 | subarray(begin?: number, end?: number): Buffer; 188 | writeBigInt64BE(value: bigint, offset?: number): number; 189 | writeBigInt64LE(value: bigint, offset?: number): number; 190 | writeBigUInt64BE(value: bigint, offset?: number): number; 191 | writeBigUInt64LE(value: bigint, offset?: number): number; 192 | writeUIntLE(value: number, offset: number, byteLength: number): number; 193 | writeUIntBE(value: number, offset: number, byteLength: number): number; 194 | writeIntLE(value: number, offset: number, byteLength: number): number; 195 | writeIntBE(value: number, offset: number, byteLength: number): number; 196 | readBigUInt64BE(offset?: number): bigint; 197 | readBigUInt64LE(offset?: number): bigint; 198 | readBigInt64BE(offset?: number): bigint; 199 | readBigInt64LE(offset?: number): bigint; 200 | readUIntLE(offset: number, byteLength: number): number; 201 | readUIntBE(offset: number, byteLength: number): number; 202 | readIntLE(offset: number, byteLength: number): number; 203 | readIntBE(offset: number, byteLength: number): number; 204 | readUInt8(offset?: number): number; 205 | readUInt16LE(offset?: number): number; 206 | readUInt16BE(offset?: number): number; 207 | readUInt32LE(offset?: number): number; 208 | readUInt32BE(offset?: number): number; 209 | readInt8(offset?: number): number; 210 | readInt16LE(offset?: number): number; 211 | readInt16BE(offset?: number): number; 212 | readInt32LE(offset?: number): number; 213 | readInt32BE(offset?: number): number; 214 | readFloatLE(offset?: number): number; 215 | readFloatBE(offset?: number): number; 216 | readDoubleLE(offset?: number): number; 217 | readDoubleBE(offset?: number): number; 218 | reverse(): this; 219 | swap16(): Buffer; 220 | swap32(): Buffer; 221 | swap64(): Buffer; 222 | writeUInt8(value: number, offset?: number): number; 223 | writeUInt16LE(value: number, offset?: number): number; 224 | writeUInt16BE(value: number, offset?: number): number; 225 | writeUInt32LE(value: number, offset?: number): number; 226 | writeUInt32BE(value: number, offset?: number): number; 227 | writeInt8(value: number, offset?: number): number; 228 | writeInt16LE(value: number, offset?: number): number; 229 | writeInt16BE(value: number, offset?: number): number; 230 | writeInt32LE(value: number, offset?: number): number; 231 | writeInt32BE(value: number, offset?: number): number; 232 | writeFloatLE(value: number, offset?: number): number; 233 | writeFloatBE(value: number, offset?: number): number; 234 | writeDoubleLE(value: number, offset?: number): number; 235 | writeDoubleBE(value: number, offset?: number): number; 236 | 237 | fill(value: string | Uint8Array | number, offset?: number, end?: number, encoding?: BufferEncoding): this; 238 | 239 | indexOf(value: string | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number; 240 | lastIndexOf(value: string | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number; 241 | entries(): IterableIterator<[number, number]>; 242 | includes(value: string | number | Buffer, byteOffset?: number, encoding?: BufferEncoding): boolean; 243 | keys(): IterableIterator; 244 | values(): IterableIterator; 245 | } 246 | 247 | interface NodeModule extends NodeJS.Module { } 248 | 249 | interface EventEmitter { 250 | addListener(event: string | symbol, listener: (...args: any[]) => void): this; 251 | on(event: string | symbol, listener: (...args: any[]) => void): this; 252 | once(event: string | symbol, listener: (...args: any[]) => void): this; 253 | removeListener(event: string | symbol, listener: (...args: any[]) => void): this; 254 | off(event: string | symbol, listener: (...args: any[]) => void): this; 255 | removeAllListeners(event?: string | symbol): this; 256 | setMaxListeners(n: number): this; 257 | getMaxListeners(): number; 258 | listeners(event: string | symbol): Function[]; 259 | rawListeners(event: string | symbol): Function[]; 260 | emit(event: string | symbol, ...args: any[]): boolean; 261 | listenerCount(event: string | symbol): number; 262 | // Added in Node 6... 263 | prependListener(event: string | symbol, listener: (...args: any[]) => void): this; 264 | prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; 265 | eventNames(): Array; 266 | } 267 | 268 | /*----------------------------------------------* 269 | * * 270 | * GLOBAL INTERFACES * 271 | * * 272 | *-----------------------------------------------*/ 273 | declare namespace NodeJS { 274 | interface InspectOptions { 275 | /** 276 | * If set to `true`, getters are going to be 277 | * inspected as well. If set to `'get'` only getters without setter are going 278 | * to be inspected. If set to `'set'` only getters having a corresponding 279 | * setter are going to be inspected. This might cause side effects depending on 280 | * the getter function. 281 | * @default `false` 282 | */ 283 | getters?: 'get' | 'set' | boolean; 284 | showHidden?: boolean; 285 | /** 286 | * @default 2 287 | */ 288 | depth?: number | null; 289 | colors?: boolean; 290 | customInspect?: boolean; 291 | showProxy?: boolean; 292 | maxArrayLength?: number | null; 293 | /** 294 | * Specifies the maximum number of characters to 295 | * include when formatting. Set to `null` or `Infinity` to show all elements. 296 | * Set to `0` or negative to show no characters. 297 | * @default Infinity 298 | */ 299 | maxStringLength?: number | null; 300 | breakLength?: number; 301 | /** 302 | * Setting this to `false` causes each object key 303 | * to be displayed on a new line. It will also add new lines to text that is 304 | * longer than `breakLength`. If set to a number, the most `n` inner elements 305 | * are united on a single line as long as all properties fit into 306 | * `breakLength`. Short array elements are also grouped together. Note that no 307 | * text will be reduced below 16 characters, no matter the `breakLength` size. 308 | * For more information, see the example below. 309 | * @default `true` 310 | */ 311 | compact?: boolean | number; 312 | sorted?: boolean | ((a: string, b: string) => number); 313 | } 314 | 315 | interface CallSite { 316 | /** 317 | * Value of "this" 318 | */ 319 | getThis(): any; 320 | 321 | /** 322 | * Type of "this" as a string. 323 | * This is the name of the function stored in the constructor field of 324 | * "this", if available. Otherwise the object's [[Class]] internal 325 | * property. 326 | */ 327 | getTypeName(): string | null; 328 | 329 | /** 330 | * Current function 331 | */ 332 | getFunction(): Function | undefined; 333 | 334 | /** 335 | * Name of the current function, typically its name property. 336 | * If a name property is not available an attempt will be made to try 337 | * to infer a name from the function's context. 338 | */ 339 | getFunctionName(): string | null; 340 | 341 | /** 342 | * Name of the property [of "this" or one of its prototypes] that holds 343 | * the current function 344 | */ 345 | getMethodName(): string | null; 346 | 347 | /** 348 | * Name of the script [if this function was defined in a script] 349 | */ 350 | getFileName(): string | null; 351 | 352 | /** 353 | * Current line number [if this function was defined in a script] 354 | */ 355 | getLineNumber(): number | null; 356 | 357 | /** 358 | * Current column number [if this function was defined in a script] 359 | */ 360 | getColumnNumber(): number | null; 361 | 362 | /** 363 | * A call site object representing the location where eval was called 364 | * [if this function was created using a call to eval] 365 | */ 366 | getEvalOrigin(): string | undefined; 367 | 368 | /** 369 | * Is this a toplevel invocation, that is, is "this" the global object? 370 | */ 371 | isToplevel(): boolean; 372 | 373 | /** 374 | * Does this call take place in code defined by a call to eval? 375 | */ 376 | isEval(): boolean; 377 | 378 | /** 379 | * Is this call in native V8 code? 380 | */ 381 | isNative(): boolean; 382 | 383 | /** 384 | * Is this a constructor call? 385 | */ 386 | isConstructor(): boolean; 387 | } 388 | 389 | interface ErrnoException extends Error { 390 | errno?: number; 391 | code?: string; 392 | path?: string; 393 | syscall?: string; 394 | stack?: string; 395 | } 396 | 397 | interface ReadableStream extends EventEmitter { 398 | readable: boolean; 399 | read(size?: number): string | Buffer; 400 | setEncoding(encoding: BufferEncoding): this; 401 | pause(): this; 402 | resume(): this; 403 | isPaused(): boolean; 404 | pipe(destination: T, options?: { end?: boolean; }): T; 405 | unpipe(destination?: WritableStream): this; 406 | unshift(chunk: string | Uint8Array, encoding?: BufferEncoding): void; 407 | wrap(oldStream: ReadableStream): this; 408 | [Symbol.asyncIterator](): AsyncIterableIterator; 409 | } 410 | 411 | interface WritableStream extends EventEmitter { 412 | writable: boolean; 413 | write(buffer: Uint8Array | string, cb?: (err?: Error | null) => void): boolean; 414 | write(str: string, encoding?: BufferEncoding, cb?: (err?: Error | null) => void): boolean; 415 | end(cb?: () => void): void; 416 | end(data: string | Uint8Array, cb?: () => void): void; 417 | end(str: string, encoding?: BufferEncoding, cb?: () => void): void; 418 | } 419 | 420 | interface ReadWriteStream extends ReadableStream, WritableStream { } 421 | 422 | interface Global { 423 | Array: typeof Array; 424 | ArrayBuffer: typeof ArrayBuffer; 425 | Boolean: typeof Boolean; 426 | Buffer: typeof Buffer; 427 | DataView: typeof DataView; 428 | Date: typeof Date; 429 | Error: typeof Error; 430 | EvalError: typeof EvalError; 431 | Float32Array: typeof Float32Array; 432 | Float64Array: typeof Float64Array; 433 | Function: typeof Function; 434 | Infinity: typeof Infinity; 435 | Int16Array: typeof Int16Array; 436 | Int32Array: typeof Int32Array; 437 | Int8Array: typeof Int8Array; 438 | Intl: typeof Intl; 439 | JSON: typeof JSON; 440 | Map: MapConstructor; 441 | Math: typeof Math; 442 | NaN: typeof NaN; 443 | Number: typeof Number; 444 | Object: typeof Object; 445 | Promise: typeof Promise; 446 | RangeError: typeof RangeError; 447 | ReferenceError: typeof ReferenceError; 448 | RegExp: typeof RegExp; 449 | Set: SetConstructor; 450 | String: typeof String; 451 | Symbol: Function; 452 | SyntaxError: typeof SyntaxError; 453 | TypeError: typeof TypeError; 454 | URIError: typeof URIError; 455 | Uint16Array: typeof Uint16Array; 456 | Uint32Array: typeof Uint32Array; 457 | Uint8Array: typeof Uint8Array; 458 | Uint8ClampedArray: typeof Uint8ClampedArray; 459 | WeakMap: WeakMapConstructor; 460 | WeakSet: WeakSetConstructor; 461 | clearImmediate: (immediateId: Immediate) => void; 462 | clearInterval: (intervalId: Timeout) => void; 463 | clearTimeout: (timeoutId: Timeout) => void; 464 | decodeURI: typeof decodeURI; 465 | decodeURIComponent: typeof decodeURIComponent; 466 | encodeURI: typeof encodeURI; 467 | encodeURIComponent: typeof encodeURIComponent; 468 | escape: (str: string) => string; 469 | eval: typeof eval; 470 | global: Global; 471 | isFinite: typeof isFinite; 472 | isNaN: typeof isNaN; 473 | parseFloat: typeof parseFloat; 474 | parseInt: typeof parseInt; 475 | setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => Immediate; 476 | setInterval: (callback: (...args: any[]) => void, ms?: number, ...args: any[]) => Timeout; 477 | setTimeout: (callback: (...args: any[]) => void, ms?: number, ...args: any[]) => Timeout; 478 | queueMicrotask: typeof queueMicrotask; 479 | undefined: typeof undefined; 480 | unescape: (str: string) => string; 481 | gc: () => void; 482 | v8debug?: any; 483 | } 484 | 485 | interface RefCounted { 486 | ref(): this; 487 | unref(): this; 488 | } 489 | 490 | // compatibility with older typings 491 | interface Timer extends RefCounted { 492 | hasRef(): boolean; 493 | refresh(): this; 494 | [Symbol.toPrimitive](): number; 495 | } 496 | 497 | interface Immediate extends RefCounted { 498 | hasRef(): boolean; 499 | _onImmediate: Function; // to distinguish it from the Timeout class 500 | } 501 | 502 | interface Timeout extends Timer { 503 | hasRef(): boolean; 504 | refresh(): this; 505 | [Symbol.toPrimitive](): number; 506 | } 507 | 508 | type TypedArray = 509 | | Uint8Array 510 | | Uint8ClampedArray 511 | | Uint16Array 512 | | Uint32Array 513 | | Int8Array 514 | | Int16Array 515 | | Int32Array 516 | | BigUint64Array 517 | | BigInt64Array 518 | | Float32Array 519 | | Float64Array; 520 | type ArrayBufferView = TypedArray | DataView; 521 | 522 | interface Require { 523 | (id: string): any; 524 | resolve: RequireResolve; 525 | cache: Dict; 526 | /** 527 | * @deprecated 528 | */ 529 | extensions: RequireExtensions; 530 | main: Module | undefined; 531 | } 532 | 533 | interface RequireResolve { 534 | (id: string, options?: { paths?: string[]; }): string; 535 | paths(request: string): string[] | null; 536 | } 537 | 538 | interface RequireExtensions extends Dict<(m: Module, filename: string) => any> { 539 | '.js': (m: Module, filename: string) => any; 540 | '.json': (m: Module, filename: string) => any; 541 | '.node': (m: Module, filename: string) => any; 542 | } 543 | interface Module { 544 | exports: any; 545 | require: Require; 546 | id: string; 547 | filename: string; 548 | loaded: boolean; 549 | /** @deprecated since 14.6.0 Please use `require.main` and `module.children` instead. */ 550 | parent: Module | null | undefined; 551 | children: Module[]; 552 | /** 553 | * @since 11.14.0 554 | * 555 | * The directory name of the module. This is usually the same as the path.dirname() of the module.id. 556 | */ 557 | path: string; 558 | paths: string[]; 559 | } 560 | 561 | interface Dict { 562 | [key: string]: T | undefined; 563 | } 564 | 565 | interface ReadOnlyDict { 566 | readonly [key: string]: T | undefined; 567 | } 568 | } 569 | -------------------------------------------------------------------------------- /vendor/import_map.json: -------------------------------------------------------------------------------- 1 | { 2 | "imports": { 3 | "npm:hash-wasm": "./esm.sh/hash-wasm@4.9.0.js", 4 | "https://esm.sh/": "./esm.sh/" 5 | }, 6 | "scopes": { 7 | "./esm.sh/": { 8 | "/v131/hash-wasm@4.9.0/denonext/hash-wasm.mjs": "./esm.sh/v131/hash-wasm@4.9.0/denonext/hash-wasm.mjs" 9 | } 10 | } 11 | } 12 | --------------------------------------------------------------------------------