├── .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 |
--------------------------------------------------------------------------------